Skip to content

Commit e46f445

Browse files
committed
All of my pending changes
15 parents 1d741af + e39b96f + 553dd3d + 3384750 + 08d88d8 + faf44bc + 9debce0 + 0e784a1 + 32e2163 + 4c0b520 + e2bf0e7 + 3c785f6 + 47523e2 + 5ecf8d5 + 9ee047c commit e46f445

27 files changed

+3151
-3026
lines changed

lang/c/pseudoc.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,11 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
612612
needSeparator = hasBlocks;
613613

614614
// Emit the lines for the statement itself
615-
GetExprTextInternal(*i, tokens, settings, TopLevelOperatorPrecedence, true);
616-
tokens.NewLine();
615+
if (!ShouldSkipStatement(*i))
616+
{
617+
GetExprTextInternal(*i, tokens, settings, TopLevelOperatorPrecedence, true);
618+
tokens.NewLine();
619+
}
617620
}
618621
}();
619622
break;
@@ -2843,6 +2846,10 @@ TypePrinter* PseudoCFunction::GetTypePrinter() const
28432846
return m_typePrinter;
28442847
}
28452848

2849+
bool PseudoCFunction::ShouldSkipStatement(const BinaryNinja::HighLevelILInstruction& instr)
2850+
{
2851+
return false;
2852+
}
28462853

28472854
PseudoCFunctionType::PseudoCFunctionType(): LanguageRepresentationFunctionType("Pseudo C")
28482855
{

lang/c/pseudoc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class PseudoCFunction: public BinaryNinja::LanguageRepresentationFunction
5555

5656
BinaryNinja::TypePrinter* GetTypePrinter() const;
5757

58+
virtual bool ShouldSkipStatement(const BinaryNinja::HighLevelILInstruction& instr);
5859
virtual void GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelILInstruction& instr,
5960
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings,
6061
BNOperatorPrecedence precedence, bool statement);

lang/c/pseudoobjc.cpp

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,46 @@ std::optional<RuntimeCall> DetectRewrittenDirectObjCMethodCall(const HighLevelIL
188188
return RuntimeCall {RuntimeCall::MessageSend, constant, true};
189189
}
190190

191+
bool VariableIsObjCSuperStruct(const Variable& variable, Function& function)
192+
{
193+
auto variableName = function.GetVariableName(variable);
194+
if (variableName != "super")
195+
return false;
196+
197+
const auto variableType = function.GetVariableType(variable);
198+
if (!variableType || !variableType->IsNamedTypeRefer())
199+
return false;
200+
201+
const auto namedType = function.GetView()->GetTypeByRef(variableType->GetNamedTypeReference());
202+
if (!namedType || namedType->GetClass() != StructureTypeClass)
203+
return false;
204+
205+
if (namedType->GetStructureName().GetString() != "objc_super")
206+
return false;
207+
208+
return true;
209+
}
210+
211+
bool IsAssignmentToObjCSuperStructField(const HighLevelILInstruction& assignInstr, Function& function)
212+
{
213+
// Check if this is an assignment to a field of the objc_super struct
214+
// Pattern: HLIL_ASSIGN { dest = HLIL_STRUCT_FIELD { source = HLIL_VAR { super }, }, field = ... }
215+
216+
if (assignInstr.operation != HLIL_ASSIGN)
217+
return false;
218+
219+
const auto destExpr = assignInstr.GetDestExpr();
220+
if (destExpr.operation != HLIL_STRUCT_FIELD)
221+
return false;
222+
223+
const auto sourceExpr = destExpr.GetSourceExpr();
224+
if (sourceExpr.operation != HLIL_VAR)
225+
return false;
226+
227+
auto variable = sourceExpr.GetVariable<HLIL_VAR>();
228+
return VariableIsObjCSuperStruct(variable, function);
229+
}
230+
191231
} // unnamed namespace
192232

193233
PseudoObjCFunction::PseudoObjCFunction(LanguageRepresentationFunctionType* type, Architecture* arch, Function* owner,
@@ -213,7 +253,8 @@ void PseudoObjCFunction::GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelIL
213253
{
214254
case RuntimeCall::MessageSend:
215255
case RuntimeCall::MessageSendSuper:
216-
if (GetExpr_ObjCMsgSend(objCRuntimeCall->address, objCRuntimeCall->isRewritten, destExpr, tokens, settings, parameterExprs))
256+
if (GetExpr_ObjCMsgSend(objCRuntimeCall->address, objCRuntimeCall->type == RuntimeCall::MessageSendSuper,
257+
objCRuntimeCall->isRewritten, destExpr, tokens, settings, parameterExprs))
217258
{
218259
if (statement)
219260
tokens.AppendSemicolon();
@@ -260,7 +301,7 @@ void PseudoObjCFunction::GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelIL
260301
return PseudoCFunction::GetExpr_CALL_OR_TAILCALL(instr, tokens, settings, precedence, statement);
261302
}
262303

263-
bool PseudoObjCFunction::GetExpr_ObjCMsgSend(uint64_t msgSendAddress, bool isRewritten,
304+
bool PseudoObjCFunction::GetExpr_ObjCMsgSend(uint64_t msgSendAddress, bool isSuper, bool isRewritten,
264305
const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens, DisassemblySettings* settings,
265306
const std::vector<HighLevelILInstruction>& parameterExprs)
266307
{
@@ -279,7 +320,10 @@ bool PseudoObjCFunction::GetExpr_ObjCMsgSend(uint64_t msgSendAddress, bool isRew
279320

280321
tokens.AppendOpenBracket();
281322

282-
GetExprText(parameterExprs[0], tokens, settings);
323+
if (isSuper)
324+
tokens.Append(LocalVariableToken, "super", instr.address);
325+
else
326+
GetExprText(parameterExprs[0], tokens, settings);
283327

284328
for (size_t index = 2; index < parameterExprs.size(); index++)
285329
{
@@ -428,7 +472,7 @@ void PseudoObjCFunction::GetExpr_IMPORT(const BinaryNinja::HighLevelILInstructio
428472
BNOperatorPrecedence precedence, bool statement)
429473
{
430474
const auto constant = instr.GetConstant<HLIL_IMPORT>();
431-
auto symbol = GetHighLevelILFunction()->GetFunction()->GetView()->GetSymbolByAddress(constant);
475+
auto symbol = GetFunction()->GetView()->GetSymbolByAddress(constant);
432476
const auto symbolType = symbol->GetType();
433477

434478
if (symbol && (symbolType == ImportedDataSymbol || symbolType == ImportAddressSymbol))
@@ -450,6 +494,28 @@ void PseudoObjCFunction::GetExpr_IMPORT(const BinaryNinja::HighLevelILInstructio
450494
PseudoCFunction::GetExpr_IMPORT(instr, tokens, settings, precedence, statement);
451495
}
452496

497+
bool PseudoObjCFunction::ShouldSkipStatement(const BinaryNinja::HighLevelILInstruction& instr)
498+
{
499+
// Skip statements that are compiler-generated artifacts of Objective-C runtime calls
500+
// For now this is limited to the declaration / initialization of the `objc_super` variable
501+
// used for `objc_msgSendSuper` calls.
502+
switch (instr.operation)
503+
{
504+
case HLIL_VAR_DECLARE:
505+
if (VariableIsObjCSuperStruct(instr.GetVariable<HLIL_VAR_DECLARE>(), *GetFunction()))
506+
return true;
507+
break;
508+
case HLIL_ASSIGN:
509+
if (IsAssignmentToObjCSuperStructField(instr, *GetFunction()))
510+
return true;
511+
break;
512+
default:
513+
break;
514+
}
515+
516+
return PseudoCFunction::ShouldSkipStatement(instr);
517+
}
518+
453519

454520
PseudoObjCFunctionType::PseudoObjCFunctionType() : PseudoCFunctionType("Pseudo Objective-C") {}
455521

lang/c/pseudoobjc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ class PseudoObjCFunction : public PseudoCFunction
2121
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings,
2222
BNOperatorPrecedence precedence, bool statement) override;
2323

24+
bool ShouldSkipStatement(const BinaryNinja::HighLevelILInstruction& instr) override;
25+
2426
private:
25-
bool GetExpr_ObjCMsgSend(uint64_t msgSendAddress, bool isRewritten, const BinaryNinja::HighLevelILInstruction& expr,
27+
bool GetExpr_ObjCMsgSend(uint64_t msgSendAddress, bool isSuper, bool isRewritten, const BinaryNinja::HighLevelILInstruction& expr,
2628
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings,
2729
const std::vector<BinaryNinja::HighLevelILInstruction>& parameterExprs);
2830
bool GetExpr_GenericObjCRuntimeCall(uint64_t address, const BinaryNinja::HighLevelILInstruction& expr,

0 commit comments

Comments
 (0)