diff options
| -rw-r--r-- | objectivec/objc.cpp | 43 | ||||
| -rw-r--r-- | objectivec/objc.h | 9 | ||||
| -rw-r--r-- | view/macho/machoview.cpp | 4 | ||||
| -rw-r--r-- | view/sharedcache/core/ObjC.cpp | 25 | ||||
| -rw-r--r-- | view/sharedcache/core/ObjC.h | 5 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCacheController.cpp | 8 |
6 files changed, 54 insertions, 40 deletions
diff --git a/objectivec/objc.cpp b/objectivec/objc.cpp index 6f9c3cde..7d110450 100644 --- a/objectivec/objc.cpp +++ b/objectivec/objc.cpp @@ -1119,28 +1119,21 @@ void ObjCProcessor::ApplyMethodTypes(Class& cls) } } -Ref<Section> ObjCProcessor::GetSectionForImage(std::optional<std::string> imageName, const char* sectionName) +Ref<Section> ObjCProcessor::GetSectionWithName(const char* sectionName) { - if (imageName) - { - return m_data->GetSectionByName(*imageName + "::" + sectionName); - } - else - { - return m_data->GetSectionByName(sectionName); - } + return m_data->GetSectionByName(sectionName); } -void ObjCProcessor::PostProcessObjCSections(ObjCReader* reader, std::optional<std::string> imageName) +void ObjCProcessor::PostProcessObjCSections(ObjCReader* reader) { auto ptrSize = m_data->GetAddressSize(); - if (auto imageInfo = GetSectionForImage(imageName, "__objc_imageinfo")) + if (auto imageInfo = GetSectionWithName("__objc_imageinfo")) { auto start = imageInfo->GetStart(); auto type = Type::NamedType(m_data, m_typeNames.imageInfo); m_data->DefineDataVariable(start, type); } - if (auto selrefs = GetSectionForImage(imageName, "__objc_selrefs")) + if (auto selrefs = GetSectionWithName("__objc_selrefs")) { auto start = selrefs->GetStart(); auto end = selrefs->GetEnd(); @@ -1163,7 +1156,7 @@ void ObjCProcessor::PostProcessObjCSections(ObjCReader* reader, std::optional<st DefineObjCSymbol(DataSymbol, type, "selRef_" + sel, i, true); } } - if (auto superRefs = GetSectionForImage(imageName, "__objc_classrefs")) + if (auto superRefs = GetSectionWithName("__objc_classrefs")) { auto start = superRefs->GetStart(); auto end = superRefs->GetEnd(); @@ -1181,7 +1174,7 @@ void ObjCProcessor::PostProcessObjCSections(ObjCReader* reader, std::optional<st } } } - if (auto superRefs = GetSectionForImage(imageName, "__objc_superrefs")) + if (auto superRefs = GetSectionWithName("__objc_superrefs")) { auto start = superRefs->GetStart(); auto end = superRefs->GetEnd(); @@ -1199,7 +1192,7 @@ void ObjCProcessor::PostProcessObjCSections(ObjCReader* reader, std::optional<st } } } - if (auto protoRefs = GetSectionForImage(imageName, "__objc_protorefs")) + if (auto protoRefs = GetSectionWithName("__objc_protorefs")) { auto start = protoRefs->GetStart(); auto end = protoRefs->GetEnd(); @@ -1217,7 +1210,7 @@ void ObjCProcessor::PostProcessObjCSections(ObjCReader* reader, std::optional<st } } } - if (auto ivars = GetSectionForImage(imageName, "__objc_ivar")) + if (auto ivars = GetSectionWithName("__objc_ivar")) { auto start = ivars->GetStart(); auto end = ivars->GetEnd(); @@ -1258,7 +1251,7 @@ Ref<Symbol> ObjCProcessor::GetSymbol(uint64_t address) return m_data->GetSymbolByAddress(address); } -void ObjCProcessor::ProcessObjCData(std::optional<std::string> imageName) +void ObjCProcessor::ProcessObjCData() { m_symbolQueue = new SymbolQueue(); auto addrSize = m_data->GetAddressSize(); @@ -1426,26 +1419,26 @@ void ObjCProcessor::ProcessObjCData(std::optional<std::string> imageName) m_typeNames.protocol = finalizeStructureBuilder(m_data, protocolBuilder, "objc_protocol_t").first; m_data->BeginBulkModifySymbols(); - if (auto classList = GetSectionForImage(imageName, "__objc_classlist")) + if (auto classList = GetSectionWithName("__objc_classlist")) LoadClasses(reader.get(), classList); - if (auto nonLazyClassList = GetSectionForImage(imageName, "__objc_nlclslist")) + if (auto nonLazyClassList = GetSectionWithName("__objc_nlclslist")) LoadClasses(reader.get(), nonLazyClassList); // See: https://stackoverflow.com/a/15318325 GenerateClassTypes(); for (auto& [_, cls] : m_classes) ApplyMethodTypes(cls); - if (auto catList = GetSectionForImage(imageName, "__objc_catlist")) // Do this after loading class type data. + if (auto catList = GetSectionWithName("__objc_catlist")) // Do this after loading class type data. LoadCategories(reader.get(), catList); - if (auto nonLazyCatList = GetSectionForImage(imageName, "__objc_nlcatlist")) // Do this after loading class type data. + if (auto nonLazyCatList = GetSectionWithName("__objc_nlcatlist")) // Do this after loading class type data. LoadCategories(reader.get(), nonLazyCatList); for (auto& [_, cat] : m_categories) ApplyMethodTypes(cat); - if (auto protoList = GetSectionForImage(imageName, "__objc_protolist")) + if (auto protoList = GetSectionWithName("__objc_protolist")) LoadProtocols(reader.get(), protoList); - PostProcessObjCSections(reader.get(), imageName); + PostProcessObjCSections(reader.get()); auto id = m_data->BeginUndoActions(); m_symbolQueue->Process(); @@ -1460,7 +1453,7 @@ void ObjCProcessor::ProcessObjCData(std::optional<std::string> imageName) } -void ObjCProcessor::ProcessCFStrings(std::optional<std::string> imageName) +void ObjCProcessor::ProcessCFStrings() { m_symbolQueue = new SymbolQueue(); uint64_t ptrSize = m_data->GetAddressSize(); @@ -1495,7 +1488,7 @@ void ObjCProcessor::ProcessCFStrings(std::optional<std::string> imageName) m_typeNames.cfStringUTF16 = type.first; auto reader = GetReader(); - if (auto cfstrings = GetSectionForImage(imageName, "__cfstring")) + if (auto cfstrings = GetSectionWithName("__cfstring")) { auto start = cfstrings->GetStart(); auto end = cfstrings->GetEnd(); diff --git a/objectivec/objc.h b/objectivec/objc.h index 935773c1..dad86f08 100644 --- a/objectivec/objc.h +++ b/objectivec/objc.h @@ -314,8 +314,7 @@ namespace BinaryNinja { bool ApplyMethodType(Class& cls, Method& method, bool isInstanceMethod); void ApplyMethodTypes(Class& cls); - Ref<Section> GetSectionForImage(std::optional<std::string> imageName, const char* sectionName); - void PostProcessObjCSections(ObjCReader* reader, std::optional<std::string> imageName); + void PostProcessObjCSections(ObjCReader* reader); protected: Ref<BinaryView> m_data; @@ -327,13 +326,15 @@ namespace BinaryNinja { // Because an objective-c processor might have access to other non-view symbols that we want to retrieve. // By default, this will just get symbol at the address in the view. virtual Ref<Symbol> GetSymbol(uint64_t address); + virtual Ref<Section> GetSectionWithName(const char* sectionName); public: virtual ~ObjCProcessor() = default; ObjCProcessor(BinaryView* data, const char* loggerName, bool isBackedByDatabase, bool skipClassBaseProtocols = false); - void ProcessObjCData(std::optional<std::string> imageName); - void ProcessCFStrings(std::optional<std::string> imageName); + // TODO: Instead of passing in image name the processor must be given section refs in a structure that outlines all objc sections. + void ProcessObjCData(); + void ProcessCFStrings(); void AddRelocatedPointer(uint64_t location, uint64_t rewrite); }; } diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp index 86deee1d..cda602ad 100644 --- a/view/macho/machoview.cpp +++ b/view/macho/machoview.cpp @@ -2336,7 +2336,7 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_ if (parseCFStrings) { try { - m_objcProcessor->ProcessCFStrings(std::nullopt); + m_objcProcessor->ProcessCFStrings(); } catch (std::exception& ex) { @@ -2348,7 +2348,7 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_ if (parseObjCStructs) { try { - m_objcProcessor->ProcessObjCData(std::nullopt); + m_objcProcessor->ProcessObjCData(); } catch (std::exception& ex) { diff --git a/view/sharedcache/core/ObjC.cpp b/view/sharedcache/core/ObjC.cpp index 9fee4628..dc5c3856 100644 --- a/view/sharedcache/core/ObjC.cpp +++ b/view/sharedcache/core/ObjC.cpp @@ -170,6 +170,25 @@ Ref<Symbol> SharedCacheObjCProcessor::GetSymbol(uint64_t address) return symbol; } -SharedCacheObjCProcessor::SharedCacheObjCProcessor(BinaryView* data, bool isBackedByDatabase) : - ObjCProcessor(data, "SharedCache.ObjC", isBackedByDatabase, true) -{} +Ref<Section> SharedCacheObjCProcessor::GetSectionWithName(const char *sectionName) +{ + const auto controller = DSC::SharedCacheController::FromView(*m_data); + if (!controller) + return nullptr; + + const auto image = controller->GetCache().GetImageAt(m_imageAddress); + if (!image) + return nullptr; + + for (const auto& section : image->header->sectionNames) + if (section.find(sectionName) != std::string::npos) + return m_data->GetSectionByName(section); + + return nullptr; +} + +SharedCacheObjCProcessor::SharedCacheObjCProcessor(BinaryView *data, bool isBackedByDatabase, uint64_t imageAddress) + : ObjCProcessor(data, "SharedCache.ObjC", isBackedByDatabase, true) +{ + m_imageAddress = imageAddress; +} diff --git a/view/sharedcache/core/ObjC.h b/view/sharedcache/core/ObjC.h index 81e98f54..f44323d6 100644 --- a/view/sharedcache/core/ObjC.h +++ b/view/sharedcache/core/ObjC.h @@ -58,6 +58,7 @@ namespace DSCObjC { class SharedCacheObjCProcessor : public BinaryNinja::ObjCProcessor { std::optional<uint64_t> m_customRelativeMethodSelectorBase = std::nullopt; + uint64_t m_imageAddress; std::shared_ptr<BinaryNinja::ObjCReader> GetReader() override; @@ -65,8 +66,10 @@ namespace DSCObjC { BinaryNinja::Ref<BinaryNinja::Symbol> GetSymbol(uint64_t address) override; + BinaryNinja::Ref<BinaryNinja::Section> GetSectionWithName(const char *sectionName) override; + public: - SharedCacheObjCProcessor(BinaryNinja::BinaryView* data, bool isBackedByDatabase); + SharedCacheObjCProcessor(BinaryNinja::BinaryView* data, bool isBackedByDatabase, uint64_t imageAddress); uint64_t GetObjCRelativeMethodBaseAddress(BinaryNinja::ObjCReader* reader) override; }; diff --git a/view/sharedcache/core/SharedCacheController.cpp b/view/sharedcache/core/SharedCacheController.cpp index 13afb476..8d036b4a 100644 --- a/view/sharedcache/core/SharedCacheController.cpp +++ b/view/sharedcache/core/SharedCacheController.cpp @@ -215,16 +215,14 @@ bool SharedCacheController::ApplyImage(BinaryView& view, const CacheImage& image machoProcessor.ApplyHeader(*image.header); view.SetFunctionAnalysisUpdateDisabled(prevDisabledState); - // TODO: Passing in an image name here is weird considering this is shared with the MACHO view. - // TODO: We should abstract out the "image" into an objc image type that represents what is required, which ig is the name? // Load objective-c information. - auto objcProcessor = DSCObjC::SharedCacheObjCProcessor(&view, false); + auto objcProcessor = DSCObjC::SharedCacheObjCProcessor(&view, false, image.headerAddress); try { if (m_processObjC) - objcProcessor.ProcessObjCData(image.GetName()); + objcProcessor.ProcessObjCData(); if (m_processCFStrings) - objcProcessor.ProcessCFStrings(image.GetName()); + objcProcessor.ProcessCFStrings(); } catch (std::exception& e) { |
