summaryrefslogtreecommitdiff
path: root/plugins/workflow_objc
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2025-07-11 08:47:20 -0700
committerMark Rowe <mark@vector35.com>2025-07-13 10:20:50 -0700
commit6706cc871072965ac7f3e16baa4273a9a27d1f8d (patch)
tree209431f3ecb044906fa2ad66f4b3855fe9aaf87e /plugins/workflow_objc
parentb34d6b8b9e136743e74ff74242aafd3b52b7a8ee (diff)
[ObjC] Handle tail calls to objc_msgSend when applying call type adjustments
Diffstat (limited to 'plugins/workflow_objc')
-rw-r--r--plugins/workflow_objc/Workflow.cpp13
1 files changed, 7 insertions, 6 deletions
diff --git a/plugins/workflow_objc/Workflow.cpp b/plugins/workflow_objc/Workflow.cpp
index d2f9d556..97fc3dbb 100644
--- a/plugins/workflow_objc/Workflow.cpp
+++ b/plugins/workflow_objc/Workflow.cpp
@@ -86,7 +86,7 @@ bool Workflow::rewriteMethodCall(LLILFunctionRef ssa, size_t insnIndex)
const auto bv = function->GetView();
const auto llil = ssa->GetNonSSAForm();
const auto insn = ssa->GetInstruction(insnIndex);
- const auto params = insn.GetParameterExprs<LLIL_CALL_SSA>();
+ const auto params = insn.GetParameterExprs();
// The second parameter passed to the objc_msgSend call is the address of
// either the selector reference or the method's name, which in both cases
@@ -254,12 +254,13 @@ void Workflow::inlineMethodCalls(AnalysisContextRef ac)
const auto rewriteIfEligible = [bv, messageHandler, ssa](size_t insnIndex) {
auto insn = ssa->GetInstruction(insnIndex);
- if (insn.operation == LLIL_CALL_SSA)
+ if (insn.operation == LLIL_CALL_SSA || insn.operation == LLIL_TAILCALL_SSA)
{
// Filter out calls that aren't to `objc_msgSend`.
- auto callExpr = insn.GetDestExpr<LLIL_CALL_SSA>();
- bool isMessageSend = messageHandler->isMessageSend(callExpr.GetValue().value);
- if (auto symbol = bv->GetSymbolByAddress(callExpr.GetValue().value))
+ auto callExpr = insn.GetDestExpr();
+ auto callTarget = callExpr.GetValue().value;
+ bool isMessageSend = messageHandler->isMessageSend(callTarget);
+ if (auto symbol = bv->GetSymbolByAddress(callTarget))
isMessageSend = isMessageSend || symbol->GetRawName() == "_objc_msgSend";
if (!isMessageSend)
return false;
@@ -294,7 +295,7 @@ void Workflow::registerActivities()
const auto wf = BinaryNinja::Workflow::Instance("core.function.baseAnalysis")->Clone("core.function.objectiveC");
wf->RegisterActivity(new BinaryNinja::Activity(
ActivityID::ResolveMethodCalls, &Workflow::inlineMethodCalls));
- wf->Insert("core.function.translateTailCalls", ActivityID::ResolveMethodCalls);
+ wf->InsertAfter("core.function.translateTailCalls", ActivityID::ResolveMethodCalls);
BinaryNinja::Workflow::RegisterWorkflow(wf, WorkflowInfo);
}