BlackBone
Windows memory hacking library
 All Classes Functions
Wow64Local.h
1 #pragma once
2 
3 #include "../Include/Winheaders.h"
4 #include "../Include/NativeStructures.h"
5 #include "../Include/Macro.h"
6 #include "../Include/Types.h"
7 
8 #include <vector>
9 #include <type_traits>
10 
11 namespace blackbone
12 {
13 
18 {
19 public:
20  Wow64Local( void );
21  ~Wow64Local( void );
22 
23 
24 // unreferenced formal parameter, invalid operand size
25 #pragma warning(disable : 4409 4100)
26 
33  template< typename... Args >
34  DWORD64 X64Call( ptr_t func, Args... args )
35  {
36 
37 #ifdef _M_IX86
38 
39  int argC = sizeof...(Args);
40  int i = 0;
41  std::vector<DWORD64> vargs{ ((DWORD64)args)... };
42 
43  DWORD64 _rcx = (i < argC) ? vargs[i++] : 0;
44  DWORD64 _rdx = (i < argC) ? vargs[i++] : 0;
45  DWORD64 _r8 = (i < argC) ? vargs[i++] : 0;
46  DWORD64 _r9 = (i < argC) ? vargs[i++] : 0;
47  reg64 _rax;
48  _rax.v = 0;
49 
50  DWORD64 restArgs = (i < argC) ? (DWORD64)&vargs[i] : 0;
51 
52  // conversion to QWORD for easier use in inline assembly
53  DWORD64 _argC = argC - i;
54  DWORD64 _func = func;
55 
56  DWORD back_esp = 0;
57 
58  __asm
59  {
60  mov back_esp, esp
61 
62  ;//align esp to 16
63  and esp, 0xFFFFFFF0
64 
65  X64_Start();
66 
67  ;//fill first four arguments
68  push _rcx
69  X64_Pop(_RCX);
70  push _rdx
71  X64_Pop(_RDX);
72  push _r8
73  X64_Pop(_R8);
74  push _r9
75  X64_Pop(_R9);
76 
77  push edi
78 
79  push restArgs
80  X64_Pop(_RDI);
81 
82  push _argC
83  X64_Pop(_RAX);
84 
85  ;//put rest of arguments on the stack
86  test eax, eax
87  jz _ls_e
88  lea edi, dword ptr[edi + 8 * eax - 8]
89 
90  _ls:
91  test eax, eax
92  jz _ls_e
93  push dword ptr [edi]
94  sub edi, 8
95  sub eax, 1
96  jmp _ls
97  _ls_e:
98 
99  ;//create stack space for spilling registers
100  sub esp, 0x20
101  call _func
102 
103  ;//cleanup stack
104  push _argC
105  X64_Pop(_RCX);
106  lea esp, dword ptr[esp + 8 * ecx + 0x20]
107 
108  pop edi
109 
110  //set return value
111  X64_Push(_RAX);
112  pop _rax.dw[0]
113 
114  X64_End();
115 
116  mov esp, back_esp
117  }
118 
119  return _rax.v;
120 #else
121  return (DWORD64)STATUS_NOT_SUPPORTED;
122 #endif
123  }
124 
131  template<typename ...Args>
132  DWORD64 X64Syscall( int idx, Args... args )
133  {
134  #ifdef _M_IX86
135  int argC = sizeof...(Args);
136  int i = 0;
137  std::vector<DWORD64> vargs{ ((DWORD64)args)... };
138 
139  DWORD64 _rcx = (i < argC) ? vargs[i++] : 0;
140  DWORD64 _rdx = (i < argC) ? vargs[i++] : 0;
141  DWORD64 _r8 = (i < argC) ? vargs[i++] : 0;
142  DWORD64 _r9 = (i < argC) ? vargs[i++] : 0;
143  reg64 _rax;
144  _rax.v = 0;
145 
146  DWORD64 restArgs = (i < argC) ? (DWORD64)&vargs[i] : 0;
147 
148  //conversion to QWORD for easier use in inline assembly
149  DWORD64 _argC = argC - i;
150  DWORD back_esp = 0;
151 
152  __asm
153  {
154  ;//keep original esp in back_esp variable
155  mov back_esp, esp
156 
157  ;//align esp to 8, without aligned stack some syscalls may return errors !
158  and esp, 0xFFFFFFF8
159 
160  X64_Start();
161 
162  ;//fill first four arguments
163  push _rcx
164  X64_Pop(_RCX);
165  push _rdx
166  X64_Pop(_RDX);
167  push _r8
168  X64_Pop(_R8);
169  push _r9
170  X64_Pop(_R9);
171 
172  push edi
173 
174  push restArgs
175  X64_Pop(_RDI);
176 
177  push _argC
178  X64_Pop(_RAX);
179 
180  ;//put rest of arguments on the stack
181  test eax, eax
182  jz _ls_e
183  lea edi, dword ptr [edi + 8*eax - 8]
184 
185  _ls:
186  test eax, eax
187  jz _ls_e
188  push dword ptr [edi]
189  sub edi, 8
190  sub eax, 1
191  jmp _ls
192  _ls_e:
193 
194  ;//create stack space for spilling registers
195  sub esp, 0x28
196 
197  mov eax, idx
198  push _rcx
199  X64_Pop( _R10 );
200  EMIT( 0x0F ) EMIT( 0x05 ); // syscall
201 
202  ;//cleanup stack
203  push _argC
204  X64_Pop(_RCX);
205  lea esp, dword ptr [esp + 8*ecx + 0x20]
206 
207  pop edi
208 
209  ;//set return value
210  X64_Push(_RAX);
211  pop _rax.dw[0]
212 
213  X64_End();
214 
215  mov esp, back_esp
216  }
217 
218  return _rax.v;
219  #else
220  return STATUS_NOT_SUPPORTED;
221  #endif
222  }
223 #pragma warning(default : 4409 4100)
224 
231  BLACKBONE_API void memcpy64( DWORD64 /*dst*/, DWORD64 /*src*/, DWORD /*size*/ );
232 
238  BLACKBONE_API DWORD64 getTEB64( _TEB64& out );
239 
246  BLACKBONE_API DWORD64 GetModuleHandle64( const wchar_t* lpModuleName, DWORD* pSize = nullptr );
247 
253  BLACKBONE_API DWORD64 getNTDLL64( DWORD* pSize = nullptr );
254 
259  BLACKBONE_API DWORD64 getLdrGetProcedureAddress();
260 
267  BLACKBONE_API DWORD64 GetProcAddress64( DWORD64 hModule, const char* funcName );
268 
274  BLACKBONE_API DWORD64 LoadLibrary64( const wchar_t* path );
275 
276 private:
277  DWORD64 _ntdll64 = 0; // 64bit ntdll address
278  DWORD64 _LdrGetProcedureAddress = 0; // LdrGetProcedureAddress address in 64bit ntdll
279  DWORD _ntdll64Size = 0; // size of ntdll64 image
280 };
281 
282 }
Definition: NativeStructures.h:71
BLACKBONE_API void memcpy64(DWORD64, DWORD64, DWORD)
Copy memory beyond 4GB limit
Definition: Types.h:72
BLACKBONE_API DWORD64 LoadLibrary64(const wchar_t *path)
Load 64 bit module into current process
Definition: Wow64Local.cpp:229
DWORD64 X64Call(ptr_t func, Args...args)
Call 64 bit function
Definition: Wow64Local.h:34
BLACKBONE_API DWORD64 getTEB64(_TEB64 &out)
Get native bit TEB
Definition: Wow64Local.cpp:65
BLACKBONE_API DWORD64 GetProcAddress64(DWORD64 hModule, const char *funcName)
64 bit implementation of GetProcAddress
Definition: Wow64Local.cpp:203
BLACKBONE_API DWORD64 getNTDLL64(DWORD *pSize=nullptr)
Get 64 bit ntdll base
Definition: Wow64Local.cpp:140
WOW64-x64 interface
Definition: Wow64Local.h:17
BLACKBONE_API DWORD64 getLdrGetProcedureAddress()
Get 'LdrGetProcedureAddress' address
Definition: Wow64Local.cpp:161
BLACKBONE_API DWORD64 GetModuleHandle64(const wchar_t *lpModuleName, DWORD *pSize=nullptr)
Gets 64 bit module base
Definition: Wow64Local.cpp:99
DWORD64 X64Syscall(int idx, Args...args)
Perform a syscall
Definition: Wow64Local.h:132
Definition: AsmHelper32.cpp:6