Add a setting to opt out of rewriting message sends with visible implementations#70
Conversation
|
I am very on board with this and think it may be better to have this as opt-in functionality, with a disclaimer on current accuracy; Especially now that we have the psuedo language. If we do decide we want these calls rewritten in some level of IL, I think this could return as an on-by-default feature, once we have better type information available to us (There is barebones Objective-C type info embedded in darwin typelib metadata.) I'll bring this up for discussion and see what our plan is. Thank you for the PR! |
|
My dream for this is having some way to mark a call as having multiple potential targets. The workflow could then populate each message send's potential target set with implementations from classes that it can see implement the message being sent, along with confidence derived from the type of the receiver parameter. If there's only one known receiver or the confidence is high it could be assumed to be the true call target, so double-clicking would take you to that implementation. Ideally there'd be some way for a user to override the analysis so it picks a different receiver (though maybe correctly typing the receiver would be sufficient to have the workflow update its confidence?). The same sort of mechanism could be useful for other forms of dynamic dispatch, such C++ vtables or calls via function pointers in general. |
…ementations The setting is on by default to preserve the current experience. It should likely be revisited as related changes are merged. I find this to be confusing as often as it is helpful since it picks the first implementation of the selector it sees without consideration for the type of the receiver. This is particularly annoying if the binary being analyzed implements a method with the same name as a commonly-used method on a system type (`-description` or `-path`, for instance), or has methods with generic names (`-initWithURL:`) on many types. Explicit cross-references from selectors to method implementations make it possible to see the potential implementations without rewriting the call, and an Objective-C pseudo-language (Vector35/binaryninja-api#6807) provides an even more natural representation of Objective-C message sends without these downsides.
…to setting language
94bdcd8 to
ba90800
Compare
| ssa->GetFunction()->SetAutoCallTypeAdjustment(ssa->GetFunction()->GetArchitecture(), insn.address, {funcType, BN_DEFAULT_CONFIDENCE}); | ||
| // -- | ||
|
|
||
| if (!BinaryNinja::Settings::Instance()->Get<bool>("core.function.objectiveC.assumeMessageSendTarget")) |
There was a problem hiding this comment.
I've fixed this in a force-push; typically with settings like this you might want to change per-view, you can pass the BinaryView as the second argument in Get, which takes the user's Open with Options overrides into account.
The setting is on by default to preserve the current experience. It should likely be revisited as related changes are merged.
I find this to be confusing as often as it is helpful since it picks the first implementation of the selector it sees without consideration for the type of the receiver.
This is particularly annoying if the binary being analyzed implements a method with the same name as a commonly-used method on a system type (
-descriptionor-path, for instance), or has methods with generic names (-initWithURL:) on many types.Explicit cross-references from selectors to method implementations (Vector35/binaryninja-api#6814) make it possible to see the potential implementations without rewriting the call, and an Objective-C pseudo-language (Vector35/binaryninja-api#6807) provides a more natural representation of Objective-C message sends without these downsides.