summaryrefslogtreecommitdiff
path: root/plugins/workflow_objc/MessageHandler.cpp
diff options
context:
space:
mode:
authorkat <kat@vector35.com>2025-06-20 16:17:01 -0400
committerkat <kat@vector35.com>2025-06-23 10:40:55 -0400
commit76215b86ff629da58aa94d4cf4093d2e67017412 (patch)
tree06af88506096351e99053ab5ed9901ff892801f3 /plugins/workflow_objc/MessageHandler.cpp
parent17b2cb59846073fdbc08235555fd68cdb6852c42 (diff)
Move workflow_objc to API repo, remove CFString & relptr renderers
Diffstat (limited to 'plugins/workflow_objc/MessageHandler.cpp')
-rw-r--r--plugins/workflow_objc/MessageHandler.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/plugins/workflow_objc/MessageHandler.cpp b/plugins/workflow_objc/MessageHandler.cpp
new file mode 100644
index 00000000..5c3422b2
--- /dev/null
+++ b/plugins/workflow_objc/MessageHandler.cpp
@@ -0,0 +1,63 @@
+#include "MessageHandler.h"
+
+using namespace BinaryNinja;
+
+MessageHandler::MessageHandler(Ref<BinaryView> data)
+{
+ m_msgSendFunctions = findMsgSendFunctions(data);
+}
+
+std::set<uint64_t> MessageHandler::findMsgSendFunctions(BinaryNinja::Ref<BinaryNinja::BinaryView> data)
+{
+ std::set<uint64_t> results;
+
+ const auto authStubsSection = data->GetSectionByName("__auth_stubs");
+ const auto stubsSection = data->GetSectionByName("__stubs");
+ const auto authGotSection = data->GetSectionByName("__auth_got");
+ const auto gotSection = data->GetSectionByName("__got");
+ const auto laSymbolPtrSection = data->GetSectionByName("__la_symbol_ptr");
+
+ // Shorthand to check if a symbol lies in a given section.
+ auto sectionContains = [](Ref<Section> section, Ref<Symbol> symbol) {
+ const auto start = section->GetStart();
+ const auto length = section->GetLength();
+ const auto address = symbol->GetAddress();
+
+ return (uint64_t)(address - start) <= length;
+ };
+
+ // There can be multiple `_objc_msgSend` symbols in the same binary; there
+ // may even be lots. Some of them are valid, others aren't. In order of
+ // preference, `_objc_msgSend` symbols in the following sections are
+ // preferred:
+ //
+ // 1. __auth_stubs
+ // 2. __stubs
+ // 3. __auth_got
+ // 4. __got
+ // ?. __la_symbol_ptr
+ //
+ // There is often an `_objc_msgSend` symbol that is a stub function, found
+ // in the `__stubs` section, which will come with an imported symbol of the
+ // same name in the `__got` section. Not all `__objc_msgSend` calls will be
+ // routed through the stub function, making it important to make note of
+ // both symbols' addresses. Furthermore, on ARM64, the `__auth{stubs,got}`
+ // sections are preferred over their unauthenticated counterparts.
+ const auto candidates = data->GetSymbolsByName("_objc_msgSend");
+ for (const auto& c : candidates) {
+ if ((authStubsSection && sectionContains(authStubsSection, c))
+ || (stubsSection && sectionContains(stubsSection, c))
+ || (authGotSection && sectionContains(authGotSection, c))
+ || (gotSection && sectionContains(gotSection, c))
+ || (laSymbolPtrSection && sectionContains(laSymbolPtrSection, c))) {
+ results.insert(c->GetAddress());
+ }
+ }
+
+ return results;
+}
+
+bool MessageHandler::isMessageSend(uint64_t functionAddress)
+{
+ return m_msgSendFunctions.count(functionAddress);
+}