@@ -184,12 +184,27 @@ bool Workflow::rewriteMethodCall(LLILFunctionRef ssa, size_t insnIndex)
184184 const auto llilIndex = ssa->GetNonSSAInstructionIndex (insnIndex);
185185 auto llilInsn = llil->GetInstruction (llilIndex);
186186
187- // Change the destination expression of the LLIL_CALL operation to point to
187+ // Change the destination expression of the call operation to point to
188188 // the method implementation. This turns the "indirect call" piped through
189189 // `objc_msgSend` and makes it a normal C-style function call.
190- auto callDestExpr = llilInsn.GetDestExpr <LLIL_CALL>();
191- callDestExpr.Replace (llil->ConstPointer (callDestExpr.size , implAddress, callDestExpr));
192- llilInsn.Replace (llil->Call (callDestExpr.exprIndex , llilInsn));
190+ switch (llilInsn.operation ) {
191+ case LLIL_CALL: {
192+ auto callDestExpr = llilInsn.GetDestExpr <LLIL_CALL>();
193+ callDestExpr.Replace (llil->ConstPointer (callDestExpr.size , implAddress, callDestExpr));
194+ llilInsn.Replace (llil->Call (callDestExpr.exprIndex , llilInsn));
195+ break ;
196+ }
197+ case LLIL_TAILCALL: {
198+ auto callDestExpr = llilInsn.GetDestExpr <LLIL_TAILCALL>();
199+ callDestExpr.Replace (llil->ConstPointer (callDestExpr.size , implAddress, callDestExpr));
200+ llilInsn.Replace (llil->TailCall (callDestExpr.exprIndex , llilInsn));
201+ break ;
202+ }
203+ default :
204+ const auto log = BinaryNinja::LogRegistry::GetLogger (PluginLoggerName);
205+ log->LogDebugF (" Unexpected LLIL operation {} for objc_msgSend call at {:#0x}" , llilInsn.operation , llilInsn.address );
206+ return false ;
207+ }
193208
194209 return true ;
195210}
0 commit comments