diff options
| author | Mark Rowe <mark@vector35.com> | 2025-07-13 23:44:13 -0700 |
|---|---|---|
| committer | Mark Rowe <mark@vector35.com> | 2025-07-13 23:49:43 -0700 |
| commit | 99ed22fd9799ccfa0367b03de4d04d3b9ab26cd5 (patch) | |
| tree | a0e15a0f8c34422fd7153bb69a435d6f39ebc219 /plugins/workflow_objc | |
| parent | 0fa224901c638c7190a4bc2526f517a74ca04b4d (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.cpp | 23 |
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; } |
