From b6b98c07eb8ce704da4edf5a0b16959215a2c450 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Fri, 30 May 2025 09:16:48 -0700 Subject: [ObjC] Prefer displaying id rather than objc_object* --- lang/c/objctypes.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ lang/c/objctypes.h | 24 ++++++++++++++++++++++++ lang/c/pseudoobjc.cpp | 6 ++++++ lang/c/pseudoobjc.h | 1 + 4 files changed, 76 insertions(+) create mode 100644 lang/c/objctypes.cpp create mode 100644 lang/c/objctypes.h diff --git a/lang/c/objctypes.cpp b/lang/c/objctypes.cpp new file mode 100644 index 00000000..83a097be --- /dev/null +++ b/lang/c/objctypes.cpp @@ -0,0 +1,45 @@ +#include "objctypes.h" +#include "binaryninjaapi.h" + +using namespace BinaryNinja; + +namespace { + +bool IsPointerToObjCObject(const Ref& type) +{ + if (!type || type->GetClass() != PointerTypeClass) + return false; + + auto childType = type->GetChildType(); + if (!childType || childType->GetClass() != NamedTypeReferenceClass) + return false; + + auto namedType = childType->GetNamedTypeReference(); + return namedType && namedType->GetName().GetString() == "objc_object"; +} + +} // unnamed namespace + +PseudoObjCTypePrinter::PseudoObjCTypePrinter() : TypePrinter("Objective-C") {} + +std::vector PseudoObjCTypePrinter::GetTypeTokensBeforeName( + Ref type, Ref platform, uint8_t baseConfidence, Ref parentType, BNTokenEscapingType escaping) +{ + // It is idiomatic in Objective-C to use `id` rather than `objc_object*`. + if (IsPointerToObjCObject(type)) + return {InstructionTextToken {baseConfidence, TypeNameToken, "id"}}; + + return TypePrinter::GetDefault()->GetTypeTokensBeforeName(type, platform, baseConfidence, parentType, escaping); +} + +std::vector PseudoObjCTypePrinter::GetTypeTokensAfterName( + Ref type, Ref platform, uint8_t baseConfidence, Ref parentType, BNTokenEscapingType escaping) +{ + return TypePrinter::GetDefault()->GetTypeTokensAfterName(type, platform, baseConfidence, parentType, escaping); +} + +std::vector PseudoObjCTypePrinter::GetTypeLines(Ref type, const TypeContainer& types, + const QualifiedName& name, int paddingCols, bool collapsed, BNTokenEscapingType escaping) +{ + return TypePrinter::GetDefault()->GetTypeLines(type, types, name, paddingCols, collapsed, escaping); +} diff --git a/lang/c/objctypes.h b/lang/c/objctypes.h new file mode 100644 index 00000000..c9f0037d --- /dev/null +++ b/lang/c/objctypes.h @@ -0,0 +1,24 @@ +#pragma once + +#include "binaryninjaapi.h" + +class PseudoObjCTypePrinter : public BinaryNinja::TypePrinter +{ +public: + PseudoObjCTypePrinter(); + + std::vector GetTypeTokensBeforeName(BinaryNinja::Ref type, + BinaryNinja::Ref platform, + uint8_t baseConfidence = BN_FULL_CONFIDENCE, BinaryNinja::Ref parentType = nullptr, + BNTokenEscapingType escaping = NoTokenEscapingType) override; + + std::vector GetTypeTokensAfterName(BinaryNinja::Ref type, + BinaryNinja::Ref platform, + uint8_t baseConfidence = BN_FULL_CONFIDENCE, BinaryNinja::Ref parentType = nullptr, + BNTokenEscapingType escaping = NoTokenEscapingType) override; + + std::vector GetTypeLines(BinaryNinja::Ref type, + const BinaryNinja::TypeContainer& types, + const BinaryNinja::QualifiedName& name, int paddingCols = 64, bool collapsed = false, + BNTokenEscapingType escaping = NoTokenEscapingType) override; +}; diff --git a/lang/c/pseudoobjc.cpp b/lang/c/pseudoobjc.cpp index 7794e938..9b6dd0c7 100644 --- a/lang/c/pseudoobjc.cpp +++ b/lang/c/pseudoobjc.cpp @@ -2,6 +2,7 @@ #include "binaryninjaapi.h" #include "highlevelilinstruction.h" +#include "objctypes.h" #include #include #include @@ -518,3 +519,8 @@ Ref PseudoObjCFunctionType::Create( { return new PseudoObjCFunction(this, arch, owner, highLevelILFunction); } + +Ref PseudoObjCFunctionType::GetTypePrinter() +{ + return new PseudoObjCTypePrinter(); +} diff --git a/lang/c/pseudoobjc.h b/lang/c/pseudoobjc.h index d7d63196..5ee3d870 100644 --- a/lang/c/pseudoobjc.h +++ b/lang/c/pseudoobjc.h @@ -47,4 +47,5 @@ public: PseudoObjCFunctionType(); BinaryNinja::Ref Create(BinaryNinja::Architecture* arch, BinaryNinja::Function* owner, BinaryNinja::HighLevelILFunction* highLevelILFunction) override; + BinaryNinja::Ref GetTypePrinter() override; }; -- cgit v1.3.1