-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathdobby.h
178 lines (145 loc) · 4.28 KB
/
dobby.h
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#ifndef dobby_h
#define dobby_h
// obfuscated interface
#if 0
#define DobbyBuildVersion c343f74888dffad84d9ad08d9c433456
#define DobbyHook c8dc3ffa44f22dbd10ccae213dd8b1f8
#define DobbyInstrument b71e27bca2c362de90c1034f19d839f9
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
typedef uintptr_t addr_t;
typedef uint32_t addr32_t;
typedef uint64_t addr64_t;
#if defined(__arm64__) || defined(__aarch64__)
#define ARM64_TMP_REG_NDX_0 17
// float register
typedef union _FPReg {
__int128_t q;
struct {
double d1;
double d2;
} d;
struct {
float f1;
float f2;
float f3;
float f4;
} f;
} FPReg;
// register context
typedef struct _RegisterContext {
uint64_t dmmpy_0; // dummy placeholder
uint64_t sp;
uint64_t dmmpy_1; // dummy placeholder
union {
uint64_t x[29];
struct {
uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22,
x23, x24, x25, x26, x27, x28;
} regs;
} general;
uint64_t fp;
uint64_t lr;
union {
FPReg q[32];
struct {
FPReg q0, q1, q2, q3, q4, q5, q6, q7;
// [!!! READ ME !!!]
// for Arm64, can't access q8 - q31, unless you enable full floating-point register pack
FPReg q8, q9, q10, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21, q22, q23, q24, q25, q26, q27, q28, q29,
q30, q31;
} regs;
} floating;
} RegisterContext;
#elif defined(__arm__)
typedef struct _RegisterContext {
uint32_t dummy_0;
uint32_t dummy_1;
uint32_t dummy_2;
uint32_t sp;
union {
uint32_t r[13];
struct {
uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12;
} regs;
} general;
uint32_t lr;
} RegisterContext;
#elif defined(_M_IX86) || defined(__i386__)
typedef struct _RegisterContext {
union {
struct {
uint32_t eax, ebx, ecx, edx, ebp, esp, edi, esi;
} regs;
} general;
uint32_t flags;
} RegisterContext;
#elif defined(_M_X64) || defined(__x86_64__)
typedef struct _RegisterContext {
uint64_t dummy_0;
uint64_t rsp;
union {
struct {
uint64_t rax, rbx, rcx, rdx, rbp, rsp, rdi, rsi, r8, r9, r10, r11, r12, r13, r14, r15;
} regs;
} general;
uint64_t dummy_1;
uint64_t flags;
} RegisterContext;
#endif
#define RT_FAILED -1
#define RT_SUCCESS 0
typedef enum _RetStatus { RS_FAILED = -1, RS_SUCCESS = 0 } RetStatus;
typedef enum _PackageType {
kFunctionWrapper,
kFunctionInlineHook,
kDynamicBinaryInstrument
} PackageType,
HookEntryType;
typedef struct _HookEntryInfo {
uintptr_t hook_id;
union {
void *target_address;
void *function_address;
void *instruction_address;
};
} HookEntryInfo;
// DobbyWrap <==> DobbyInstrument, so use DobbyInstrument instead of DobbyWrap
#if 0
// wrap function with pre_call and post_call
typedef void (*PreCallTy)(RegisterContext *reg_ctx, const HookEntryInfo *info);
typedef void (*PostCallTy)(RegisterContext *reg_ctx, const HookEntryInfo *info);
int DobbyWrap(void *function_address, PreCallTy pre_call, PostCallTy post_call);
#endif
// return dobby build date
const char *DobbyBuildVersion();
// replace function
int DobbyHook(void *function_address, void *replace_call, void **origin_call);
// dynamic binary instrument for instruction
// [!!! READ ME !!!]
// for Arm64, can't access q8 - q31, unless you enable full floating-point register pack
typedef void (*DBICallTy)(RegisterContext *reg_ctx, const HookEntryInfo *info);
int DobbyInstrument(void *instr_address, DBICallTy dbi_call);
// destory and restore hook
int DobbyDestroy(void *address);
// iterate symbol table and find symbol
void *DobbySymbolResolver(const char *image_name, const char *symbol_name);
// near branch plugin
// [!!! READ ME !!!]
// for arm, Arm64, dobby will use b xxx instead of ldr absolute indirect branch
// for x64, dobby always use absolute indirect jump
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__)
void dobby_enable_near_branch_trampoline();
void dobby_disable_near_branch_trampoline();
#endif
// register linker load image callback
typedef void (*linker_load_callback_t)(const char *image_name, void *handle);
void dobby_register_image_load_callback(linker_load_callback_t func);
#ifdef __cplusplus
}
#endif
#endif