forked from Ares-Developers/Syringe
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathSyringe.h
More file actions
337 lines (277 loc) · 7.7 KB
/
Syringe.h
File metadata and controls
337 lines (277 loc) · 7.7 KB
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/*
SYRINGE.H
---------
Holds macros, structures, classes that are necessary to interact with Syringe correctly.
-pd
*/
#pragma once
#include <windows.h>
class LimitedRegister
{
protected:
DWORD data;
WORD* wordData()
{
return reinterpret_cast<WORD*>(&this->data);
}
BYTE* byteData()
{
return reinterpret_cast<BYTE*>(&this->data);
}
public:
WORD Get16()
{
return *this->wordData();
}
template<typename T>
inline T Get()
{
return *reinterpret_cast<T*>(&this->data);
}
template<typename T>
inline void Set(T value)
{
this->data = DWORD(value);
}
void Set16(WORD value)
{
*this->wordData() = value;
}
};
class ExtendedRegister : public LimitedRegister {
public:
BYTE Get8Hi()
{
return this->byteData()[1];
}
BYTE Get8Lo()
{
return this->byteData()[0];
}
void Set8Hi(BYTE value)
{
this->byteData()[1] = value;
}
void Set8Lo(BYTE value)
{
this->byteData()[0] = value;
}
};
class StackRegister : public ExtendedRegister {
public:
template<typename T>
inline T* lea(int byteOffset)
{
return reinterpret_cast<T*>(static_cast<DWORD>(this->data + static_cast<DWORD>(byteOffset)));
}
inline DWORD lea(int byteOffset)
{
return static_cast<DWORD>(this->data + static_cast<DWORD>(byteOffset));
}
template<typename T>
inline T At(int byteOffset)
{
return *reinterpret_cast<T*>(this->data + static_cast<DWORD>(byteOffset));
}
template<typename T>
inline void At(int byteOffset, T value)
{
*reinterpret_cast<T*>(this->data + static_cast<DWORD>(byteOffset)) = value;
}
};
//Macros to make the following a lot easier
#define REG_SHORTCUTS(reg) \
inline DWORD reg() \
{ return this->_ ## reg.Get<DWORD>(); } \
template<typename T> inline T reg() \
{ return this->_ ## reg.Get<T>(); } \
template<typename T> inline void reg(T value) \
{ this->_ ## reg.Set(value); } \
#define REG_SHORTCUTS_X(r) \
DWORD r ## X() \
{ return this->_E ## r ## X.Get16(); } \
void r ## X(WORD value) \
{ this->_E ## r ## X.Set16(value); } \
#define REG_SHORTCUTS_HL(r) \
DWORD r ## H() \
{ return this->_E ## r ## X.Get8Hi(); } \
void r ## H(BYTE value) \
{ this->_E ## r ## X.Set8Hi(value); } \
DWORD r ## L() \
{ return this->_E ## r ## X.Get8Lo(); } \
void r ## L(BYTE value) \
{ this->_E ## r ## X.Set8Lo(value); } \
#define REG_SHORTCUTS_XHL(r) \
REG_SHORTCUTS_X(r); \
REG_SHORTCUTS_HL(r); \
// A pointer to this class is passed as an argument to EXPORT functions
class REGISTERS
{
private:
DWORD origin;
DWORD flags;
LimitedRegister _EDI;
LimitedRegister _ESI;
StackRegister _EBP;
StackRegister _ESP;
ExtendedRegister _EBX;
ExtendedRegister _EDX;
ExtendedRegister _ECX;
ExtendedRegister _EAX;
public:
DWORD Origin()
{
return this->origin;
}
DWORD EFLAGS()
{
return this->flags;
}
void EFLAGS(DWORD value)
{
this->flags = value;
}
REG_SHORTCUTS(EAX);
REG_SHORTCUTS(EBX);
REG_SHORTCUTS(ECX);
REG_SHORTCUTS(EDX);
REG_SHORTCUTS(ESI);
REG_SHORTCUTS(EDI);
REG_SHORTCUTS(ESP);
REG_SHORTCUTS(EBP);
REG_SHORTCUTS_XHL(A);
REG_SHORTCUTS_XHL(B);
REG_SHORTCUTS_XHL(C);
REG_SHORTCUTS_XHL(D);
template<typename T>
inline T lea_Stack(int offset)
{
return reinterpret_cast<T>(this->_ESP.lea(offset));
}
template<>
inline DWORD lea_Stack(int offset)
{
return this->_ESP.lea(offset);
}
template<>
inline int lea_Stack(int offset)
{
return static_cast<int>(this->_ESP.lea(offset));
}
template<typename T>
inline T& ref_Stack(int offset)
{
return *this->lea_Stack<T*>(offset);
}
template<typename T>
inline T Stack(int offset)
{
return this->_ESP.At<T>(offset);
}
DWORD Stack32(int offset)
{
return this->_ESP.At<DWORD>(offset);
}
WORD Stack16(int offset)
{
return this->_ESP.At<WORD>(offset);
}
BYTE Stack8(int offset) {
return this->_ESP.At<BYTE>(offset);
}
template<typename T>
inline T Base(int offset)
{
return this->_EBP.At<T>(offset);
}
template<typename T>
inline void Stack(int offset, T value)
{
this->_ESP.At(offset, value);
}
void Stack16(int offset, WORD value)
{
this->_ESP.At(offset, value);
}
void Stack8(int offset, BYTE value)
{
this->_ESP.At(offset, value);
}
template<typename T>
inline void Base(int offset, T value)
{
this->_EBP.At(offset, value);
}
};
//Use this for DLL export functions
//e.g. EXPORT FunctionName(REGISTERS* R)
#define EXPORT extern "C" __declspec(dllexport) DWORD __cdecl
#define EXPORT_FUNC(name) extern "C" __declspec(dllexport) DWORD __cdecl name (REGISTERS *R)
//Handshake definitions
struct SyringeHandshakeInfo
{
int cbSize;
int num_hooks;
unsigned int checksum;
DWORD exeFilesize;
DWORD exeTimestamp;
unsigned int exeCRC;
int cchMessage;
char* Message;
};
#define SYRINGE_HANDSHAKE(pInfo) extern "C" __declspec(dllexport) HRESULT __cdecl SyringeHandshake(SyringeHandshakeInfo* pInfo)
#if SYR_VER == 2
#pragma pack(push, 16)
#pragma warning(push)
#pragma warning( disable : 4324)
__declspec(align(16)) struct hookdecl
{
unsigned int hookAddr;
unsigned int hookSize;
const char * hookName;
};
__declspec(align(16)) struct hostdecl
{
unsigned int hostChecksum;
const char * hostName;
};
#pragma warning(pop)
#pragma pack(pop)
#pragma section(".syhks00", read, write)
#pragma section(".syexe00", read, write)
namespace SyringeData
{
namespace Hooks { };
namespace Hosts { };
};
#define declhost(exename, checksum) \
namespace SyringeData { namespace Hosts { __declspec(allocate(".syexe00")) hostdecl _hst__ ## exename { checksum, #exename }; }; };
#define declhook(hook, funcname, size) \
namespace SyringeData { namespace Hooks { __declspec(allocate(".syhks00")) hookdecl _hk__ ## hook ## funcname { hook, size, #funcname }; }; };
#endif // SYR_VER == 2
// create empty macros
#ifndef declhost
#define declhost(exename, checksum)
#endif // declhost
#ifndef declhook
#define declhook(hook, funcname, size)
#endif // declhook
// Defines a hook at the specified address with the specified name and saving the specified amount of instruction bytes to be restored if return to the same address is used. In addition to the injgen-declaration, also includes the function opening.
#define DEFINE_HOOK(hook, funcname, size) \
declhook(hook, funcname, size) \
EXPORT_FUNC(funcname)
// Does the same as DEFINE_HOOK but no function opening, use for injgen-declaration when repeating the same hook at multiple addresses.
// CAUTION: funcname must be the same as in DEFINE_HOOK.
#define DEFINE_HOOK_AGAIN(hook, funcname, size) \
declhook(hook, funcname, size)
// Feature flags set by Syringe at injection time.
// DLLs can check these at runtime to verify that the running Syringe
// version supports the features they rely on. Each flag defaults to false
// and is set to true by Syringe after the DLL is loaded into the target
// process. If a DLL is loaded by an older Syringe that does not know about
// feature flags, the values will remain false.
namespace SyringeFeatures
{
extern "C" __declspec(dllexport) inline bool ESPModification = false;
extern "C" __declspec(dllexport) inline bool ZFPreservation = false;
}