@@ -99,6 +99,17 @@ std::optional<std::pair<uint64_t, Ref<Symbol>>> GetCallTargetInfo(const HighLeve
99
99
return std::make_pair (constant, symbol);
100
100
}
101
101
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
+
102
113
struct RuntimeCall
103
114
{
104
115
enum Type
@@ -198,6 +209,42 @@ std::optional<RuntimeCall> DetectRewrittenDirectObjCMethodCall(const HighLevelIL
198
209
return RuntimeCall {RuntimeCall::MessageSend, constant, true };
199
210
}
200
211
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
+
201
248
} // unnamed namespace
202
249
203
250
PseudoObjCFunction::PseudoObjCFunction (LanguageRepresentationFunctionType* type, Architecture* arch, Function* owner,
@@ -223,7 +270,8 @@ void PseudoObjCFunction::GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelIL
223
270
{
224
271
case RuntimeCall::MessageSend:
225
272
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))
227
275
{
228
276
if (statement)
229
277
tokens.AppendSemicolon ();
@@ -283,7 +331,7 @@ void PseudoObjCFunction::GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelIL
283
331
return PseudoCFunction::GetExpr_CALL_OR_TAILCALL (instr, tokens, settings, precedence, statement);
284
332
}
285
333
286
- bool PseudoObjCFunction::GetExpr_ObjCMsgSend (uint64_t msgSendAddress, bool isRewritten,
334
+ bool PseudoObjCFunction::GetExpr_ObjCMsgSend (uint64_t msgSendAddress, bool isSuper, bool isRewritten,
287
335
const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens, DisassemblySettings* settings,
288
336
const std::vector<HighLevelILInstruction>& parameterExprs)
289
337
{
@@ -302,7 +350,10 @@ bool PseudoObjCFunction::GetExpr_ObjCMsgSend(uint64_t msgSendAddress, bool isRew
302
350
303
351
tokens.AppendOpenBracket ();
304
352
305
- GetExprText (parameterExprs[0 ], tokens, settings);
353
+ if (isSuper)
354
+ tokens.Append (LocalVariableToken, " super" , instr.address );
355
+ else
356
+ GetExprText (parameterExprs[0 ], tokens, settings);
306
357
307
358
for (size_t index = 2 ; index < parameterExprs.size (); index++)
308
359
{
@@ -402,10 +453,7 @@ void PseudoObjCFunction::GetExpr_CONST_PTR(const BinaryNinja::HighLevelILInstruc
402
453
if (!hasVariable)
403
454
return PseudoCFunction::GetExpr_CONST_PTR (instr, tokens, settings, precedence, statement);
404
455
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 ());
409
457
if (!type || type->GetClass () != StructureTypeClass)
410
458
return PseudoCFunction::GetExpr_CONST_PTR (instr, tokens, settings, precedence, statement);
411
459
@@ -489,7 +537,7 @@ void PseudoObjCFunction::GetExpr_IMPORT(const BinaryNinja::HighLevelILInstructio
489
537
BNOperatorPrecedence precedence, bool statement)
490
538
{
491
539
const auto constant = instr.GetConstant <HLIL_IMPORT>();
492
- auto symbol = GetHighLevelILFunction ()-> GetFunction ()->GetView ()->GetSymbolByAddress (constant);
540
+ auto symbol = GetFunction ()->GetView ()->GetSymbolByAddress (constant);
493
541
const auto symbolType = symbol->GetType ();
494
542
495
543
if (symbol && (symbolType == ImportedDataSymbol || symbolType == ImportAddressSymbol))
@@ -511,6 +559,28 @@ void PseudoObjCFunction::GetExpr_IMPORT(const BinaryNinja::HighLevelILInstructio
511
559
PseudoCFunction::GetExpr_IMPORT (instr, tokens, settings, precedence, statement);
512
560
}
513
561
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
+
514
584
515
585
PseudoObjCFunctionType::PseudoObjCFunctionType () : PseudoCFunctionType(" Pseudo Objective-C" ) {}
516
586
0 commit comments