forked from jonpalmisc/ObjectiveNinja
-
Notifications
You must be signed in to change notification settings - Fork 8
/
MessageHandler.cpp
63 lines (54 loc) · 2.45 KB
/
MessageHandler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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);
}