Skip to content
This repository was archived by the owner on Jun 25, 2025. It is now read-only.

Add a setting to opt out of rewriting message sends with visible implementations #70

Merged
merged 2 commits into from
Jun 5, 2025

Conversation

bdash
Copy link

@bdash bdash commented May 8, 2025

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 (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.

@0cyn
Copy link
Member

0cyn commented May 30, 2025

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!

@bdash
Copy link
Author

bdash commented May 30, 2025

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.

bdash and others added 2 commits June 4, 2025 23:16
…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.
@0cyn 0cyn force-pushed the rewrite-message-send-setting branch from 94bdcd8 to ba90800 Compare June 5, 2025 04:06
Workflow.cpp Outdated
@@ -147,6 +147,8 @@ bool Workflow::rewriteMethodCall(LLILFunctionRef ssa, size_t insnIndex)
ssa->GetFunction()->SetAutoCallTypeAdjustment(ssa->GetFunction()->GetArchitecture(), insn.address, {funcType, BN_DEFAULT_CONFIDENCE});
// --

if (!BinaryNinja::Settings::Instance()->Get<bool>("core.function.objectiveC.assumeMessageSendTarget"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@0cyn 0cyn merged commit ba90800 into Vector35:master Jun 5, 2025
@bdash bdash deleted the rewrite-message-send-setting branch June 5, 2025 22:35
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants