From 99ed22fd9799ccfa0367b03de4d04d3b9ab26cd5 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Sun, 13 Jul 2025 23:44:13 -0700 Subject: [ObjC] Handle LLIL_TAILCALL instructions when analysis.objectiveC.resolveDynamicDispatch is enabled --- plugins/workflow_objc/Workflow.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'plugins/workflow_objc/Workflow.cpp') 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(); - 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(); + callDestExpr.Replace(llil->ConstPointer(callDestExpr.size, implAddress, callDestExpr)); + llilInsn.Replace(llil->Call(callDestExpr.exprIndex, llilInsn)); + break; + } + case LLIL_TAILCALL: { + auto callDestExpr = llilInsn.GetDestExpr(); + 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; } -- cgit v1.3.1