@@ -99,6 +99,17 @@ std::optional<std::pair<uint64_t, Ref<Symbol>>> GetCallTargetInfo(const HighLeve
9999 return std::make_pair (constant, symbol);
100100}
101101
102+ Ref<Type> TypeResolvingNamedTypeReference (Ref<Type> type, const Function& function)
103+ {
104+ if (!type || !type->IsNamedTypeRefer ())
105+ return type;
106+
107+ if (auto resolvedType = function.GetView ()->GetTypeByRef (type->GetNamedTypeReference ()))
108+ return resolvedType;
109+
110+ return type;
111+ }
112+
102113struct RuntimeCall
103114{
104115 enum Type
@@ -198,6 +209,42 @@ std::optional<RuntimeCall> DetectRewrittenDirectObjCMethodCall(const HighLevelIL
198209 return RuntimeCall {RuntimeCall::MessageSend, constant, true };
199210}
200211
212+ bool VariableIsObjCSuperStruct (const Variable& variable, Function& function)
213+ {
214+ auto variableName = function.GetVariableName (variable);
215+ if (variableName != " super" )
216+ return false ;
217+
218+ const auto variableType = TypeResolvingNamedTypeReference (function.GetVariableType (variable), function);
219+ if (!variableType || variableType->GetClass () != StructureTypeClass)
220+ return false ;
221+
222+ if (variableType->GetStructureName ().GetString () != " objc_super" )
223+ return false ;
224+
225+ return true ;
226+ }
227+
228+ bool IsAssignmentToObjCSuperStructField (const HighLevelILInstruction& assignInstr, Function& function)
229+ {
230+ // Check if this is an assignment to a field of the objc_super struct
231+ // Pattern: HLIL_ASSIGN { dest = HLIL_STRUCT_FIELD { source = HLIL_VAR { super }, }, field = ... }
232+
233+ if (assignInstr.operation != HLIL_ASSIGN)
234+ return false ;
235+
236+ const auto destExpr = assignInstr.GetDestExpr ();
237+ if (destExpr.operation != HLIL_STRUCT_FIELD)
238+ return false ;
239+
240+ const auto sourceExpr = destExpr.GetSourceExpr ();
241+ if (sourceExpr.operation != HLIL_VAR)
242+ return false ;
243+
244+ auto variable = sourceExpr.GetVariable <HLIL_VAR>();
245+ return VariableIsObjCSuperStruct (variable, function);
246+ }
247+
201248} // unnamed namespace
202249
203250PseudoObjCFunction::PseudoObjCFunction (LanguageRepresentationFunctionType* type, Architecture* arch, Function* owner,
@@ -223,7 +270,8 @@ void PseudoObjCFunction::GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelIL
223270 {
224271 case RuntimeCall::MessageSend:
225272 case RuntimeCall::MessageSendSuper:
226- if (GetExpr_ObjCMsgSend (objCRuntimeCall->address , objCRuntimeCall->isRewritten , destExpr, tokens, settings, parameterExprs))
273+ if (GetExpr_ObjCMsgSend (objCRuntimeCall->address , objCRuntimeCall->type == RuntimeCall::MessageSendSuper,
274+ objCRuntimeCall->isRewritten , destExpr, tokens, settings, parameterExprs))
227275 {
228276 if (statement)
229277 tokens.AppendSemicolon ();
@@ -283,7 +331,7 @@ void PseudoObjCFunction::GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelIL
283331 return PseudoCFunction::GetExpr_CALL_OR_TAILCALL (instr, tokens, settings, precedence, statement);
284332}
285333
286- bool PseudoObjCFunction::GetExpr_ObjCMsgSend (uint64_t msgSendAddress, bool isRewritten,
334+ bool PseudoObjCFunction::GetExpr_ObjCMsgSend (uint64_t msgSendAddress, bool isSuper, bool isRewritten,
287335 const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens, DisassemblySettings* settings,
288336 const std::vector<HighLevelILInstruction>& parameterExprs)
289337{
@@ -302,7 +350,10 @@ bool PseudoObjCFunction::GetExpr_ObjCMsgSend(uint64_t msgSendAddress, bool isRew
302350
303351 tokens.AppendOpenBracket ();
304352
305- GetExprText (parameterExprs[0 ], tokens, settings);
353+ if (isSuper)
354+ tokens.Append (LocalVariableToken, " super" , instr.address );
355+ else
356+ GetExprText (parameterExprs[0 ], tokens, settings);
306357
307358 for (size_t index = 2 ; index < parameterExprs.size (); index++)
308359 {
@@ -402,10 +453,7 @@ void PseudoObjCFunction::GetExpr_CONST_PTR(const BinaryNinja::HighLevelILInstruc
402453 if (!hasVariable)
403454 return PseudoCFunction::GetExpr_CONST_PTR (instr, tokens, settings, precedence, statement);
404455
405- auto type = variable.type ->IsNamedTypeRefer () ?
406- GetFunction ()->GetView ()->GetTypeByRef (variable.type ->GetNamedTypeReference ()) :
407- variable.type .GetValue ();
408-
456+ auto type = TypeResolvingNamedTypeReference (variable.type , *GetFunction ());
409457 if (!type || type->GetClass () != StructureTypeClass)
410458 return PseudoCFunction::GetExpr_CONST_PTR (instr, tokens, settings, precedence, statement);
411459
@@ -489,7 +537,7 @@ void PseudoObjCFunction::GetExpr_IMPORT(const BinaryNinja::HighLevelILInstructio
489537 BNOperatorPrecedence precedence, bool statement)
490538{
491539 const auto constant = instr.GetConstant <HLIL_IMPORT>();
492- auto symbol = GetHighLevelILFunction ()-> GetFunction ()->GetView ()->GetSymbolByAddress (constant);
540+ auto symbol = GetFunction ()->GetView ()->GetSymbolByAddress (constant);
493541 const auto symbolType = symbol->GetType ();
494542
495543 if (symbol && (symbolType == ImportedDataSymbol || symbolType == ImportAddressSymbol))
@@ -511,6 +559,28 @@ void PseudoObjCFunction::GetExpr_IMPORT(const BinaryNinja::HighLevelILInstructio
511559 PseudoCFunction::GetExpr_IMPORT (instr, tokens, settings, precedence, statement);
512560}
513561
562+ bool PseudoObjCFunction::ShouldSkipStatement (const BinaryNinja::HighLevelILInstruction& instr)
563+ {
564+ // Skip statements that are compiler-generated artifacts of Objective-C runtime calls
565+ // For now this is limited to the declaration / initialization of the `objc_super` variable
566+ // used for `objc_msgSendSuper` calls.
567+ switch (instr.operation )
568+ {
569+ case HLIL_VAR_DECLARE:
570+ if (VariableIsObjCSuperStruct (instr.GetVariable <HLIL_VAR_DECLARE>(), *GetFunction ()))
571+ return true ;
572+ break ;
573+ case HLIL_ASSIGN:
574+ if (IsAssignmentToObjCSuperStructField (instr, *GetFunction ()))
575+ return true ;
576+ break ;
577+ default :
578+ break ;
579+ }
580+
581+ return PseudoCFunction::ShouldSkipStatement (instr);
582+ }
583+
514584
515585PseudoObjCFunctionType::PseudoObjCFunctionType () : PseudoCFunctionType(" Pseudo Objective-C" ) {}
516586
0 commit comments