summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--objectivec/objc.cpp43
-rw-r--r--objectivec/objc.h9
-rw-r--r--view/macho/machoview.cpp4
-rw-r--r--view/sharedcache/core/ObjC.cpp25
-rw-r--r--view/sharedcache/core/ObjC.h5
-rw-r--r--view/sharedcache/core/SharedCacheController.cpp8
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)
{