summaryrefslogtreecommitdiff
path: root/plugins/workflow_objc
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2025-07-13 23:44:13 -0700
committerMark Rowe <mark@vector35.com>2025-07-13 23:49:43 -0700
commit99ed22fd9799ccfa0367b03de4d04d3b9ab26cd5 (patch)
treea0e15a0f8c34422fd7153bb69a435d6f39ebc219 /plugins/workflow_objc
parent0fa224901c638c7190a4bc2526f517a74ca04b4d (diff)
[ObjC] Handle LLIL_TAILCALL instructions when analysis.objectiveC.resolveDynamicDispatch is enabled
Diffstat (limited to 'plugins/workflow_objc')
-rw-r--r--plugins/workflow_objc/Workflow.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/plugins/workflow_objc/Workflow.cpp b/plugins/workflow_objc/Workflow.cpp
index 97fc3dbb..e0986943 100644
--- a/plugins/workflow_objc/Workflow.cpp
+++ b/plugins/workflow_objc/Workflow.cpp
@@ -184,12 +184,27 @@ bool Workflow::rewriteMethodCall(LLILFunctionRef ssa, size_t insnIndex)
const auto llilIndex = ssa->GetNonSSAInstructionIndex(insnIndex);
auto llilInsn = llil->GetInstruction(llilIndex);
- // Change the destination expression of the LLIL_CALL operation to point to
+ // Change the destination expression of the call operation to point to
// the method implementation. This turns the "indirect call" piped through
// `objc_msgSend` and makes it a normal C-style function call.
- auto callDestExpr = llilInsn.GetDestExpr<LLIL_CALL>();
- callDestExpr.Replace(llil->ConstPointer(callDestExpr.size, implAddress, callDestExpr));
- llilInsn.Replace(llil->Call(callDestExpr.exprIndex, llilInsn));
+ switch (llilInsn.operation) {
+ case LLIL_CALL: {
+ auto callDestExpr = llilInsn.GetDestExpr<LLIL_CALL>();
+ callDestExpr.Replace(llil->ConstPointer(callDestExpr.size, implAddress, callDestExpr));
+ llilInsn.Replace(llil->Call(callDestExpr.exprIndex, llilInsn));
+ break;
+ }
+ case LLIL_TAILCALL: {
+ auto callDestExpr = llilInsn.GetDestExpr<LLIL_TAILCALL>();
+ callDestExpr.Replace(llil->ConstPointer(callDestExpr.size, implAddress, callDestExpr));
+ llilInsn.Replace(llil->TailCall(callDestExpr.exprIndex, llilInsn));
+ break;
+ }
+ default:
+ const auto log = BinaryNinja::LogRegistry::GetLogger(PluginLoggerName);
+ log->LogDebugF("Unexpected LLIL operation {} for objc_msgSend call at {:#0x}", llilInsn.operation, llilInsn.address);
+ return false;
+ }
return true;
}