-
Notifications
You must be signed in to change notification settings - Fork 0
/
mstl_eat.hpp
99 lines (76 loc) · 2.55 KB
/
mstl_eat.hpp
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#pragma once
#include "mstl_image_dir.hpp"
/*
@Address - pointer to function pointer
@hash_t - djb2 hash of name
*/
using export_t = std::pair<Address, hash_t>;
using exports_t = std::vector<export_t>;
class EAT : public IMAGE_DIR<IMAGE_DIRECTORY_ENTRY_EXPORT> {
private:
exports_t m_exports;
public:
__forceinline EAT() : IMAGE_DIR{}, m_exports{} {}
__forceinline ~EAT() {}
EAT(Address image_base):
IMAGE_DIR<IMAGE_DIRECTORY_ENTRY_EXPORT>(image_base) {
// sometimes there are no imports or exports for a module..
if(m_ptr)
init(image_base);
}
__forceinline void init(uintptr_t image_base) {
IMAGE_EXPORT_DIRECTORY *ed;
uint32_t *names, *fn_ptrs;
uint16_t *name_ordinals;
// get export directory
ed = as<IMAGE_EXPORT_DIRECTORY*>();
// first see if there are any exports
if (ed->NumberOfFunctions == 0 || ed->NumberOfNames == 0)
return;
// get arrays from rva
names = RVA<uint32_t*>(image_base, ed->AddressOfNames);
fn_ptrs = RVA<uint32_t*>(image_base, ed->AddressOfFunctions);
name_ordinals = RVA<uint16_t*>(image_base, ed->AddressOfNameOrdinals);
// check
if ( names == nullptr
|| fn_ptrs == nullptr
|| name_ordinals == nullptr)
return;
// stuff
for (size_t i{}; i < ed->NumberOfNames; ++i) {
m_exports.push_back(
export_t{
RVA(image_base, fn_ptrs[name_ordinals[i]]),
hash::djb2(RVA<const char*>(image_base, names[i]))
});
}
}
__forceinline exports_t& get_exports() {
return m_exports;
}
__forceinline bool get_export(hash_t export_hash, export_t& out) {
auto needle = std::find_if(
m_exports.begin(),
m_exports.end(),
[ & ](const export_t& it) {
return it.second == export_hash;
});
if (needle >= m_exports.end())
return false;
out = *needle;
return true;
}
__forceinline void hook_method(hash_t method_hash, Address hook) {
export_t ret;
if (!get_export(method_hash, ret))
return;
return ret.first.set(hook);
}
template<typename _T = Address>
__forceinline _T get_method(hash_t method_hash) {
export_t ret;
if (!get_export(method_hash, ret))
return _T{};
return ret.first.as<_T>();
}
};