1
1
#include " api.hpp"
2
2
#include < ntimage.h>
3
3
4
- __declspec ( dllimport ) extern "C" void RtlPcToFileHeader( void * a1, IMAGE_DOS_HEADER * *a2 );
4
+ extern " C" {
5
+ __declspec ( dllimport ) void RtlPcToFileHeader( void * a1, IMAGE_DOS_HEADER** a2 );
6
+ };
5
7
6
- static void export_func ( lua_State* L, const char * name, void * ptr )
8
+ static void export_func ( lua_State* L, const char * name, const void * ptr )
7
9
{
8
10
native_function* fn = native_function::push ( L );
9
11
fn->address = ptr;
@@ -44,18 +46,66 @@ static void writedr3( uint64_t value ) { return __writedr( 3, value ); }
44
46
static void writedr6 ( uint64_t value ) { return __writedr ( 6 , value ); }
45
47
static void writedr7 ( uint64_t value ) { return __writedr ( 7 , value ); }
46
48
47
- static uint8_t inbyte ( uint16_t port ) { return __inbyte ( port ); }
48
- static uint16_t inword ( uint16_t port ) { return __inword ( port ); }
49
+ static uint32_t inbyte ( uint16_t port ) { return __inbyte ( port ); }
50
+ static uint32_t inword ( uint16_t port ) { return __inword ( port ); }
49
51
static uint32_t indword ( uint16_t port ) { return __indword ( port ); }
50
52
static void outbyte ( uint16_t port, uint8_t value ) { return __outbyte ( port, value ); }
51
53
static void outword ( uint16_t port, uint16_t value ) { return __outword ( port, value ); }
52
54
static void outdword ( uint16_t port, uint32_t value ) { return __outdword ( port, value ); }
53
55
54
56
static uint64_t readtsc () { return __rdtsc (); }
57
+ static uint32_t readtscpa () { uint32_t aux; __rdtscp ( &aux ); return aux; }
58
+ static uint32_t readtscp () { uint32_t aux; return __rdtscp ( &aux ); }
55
59
static uint64_t readpmc ( uint32_t pmc ) { return __readpmc ( pmc ); }
56
60
static uint64_t readgsbase () { return _readgsbase_u64 (); }
57
61
static uint64_t readfsbase () { return _readfsbase_u64 (); }
58
62
63
+ #pragma section(".stub", execute, read)
64
+ #pragma comment(linker,"/SECTION:.stub,ERW")
65
+
66
+ template <auto ... Ops>
67
+ struct as_code
68
+ {
69
+ __declspec ( allocate( " .stub" ) ) inline static const uint8_t data[] = { Ops..., 0xC3 };
70
+ constexpr operator const uint8_t *() const noexcept { return &data[ 0 ]; }
71
+ };
72
+ static constexpr const uint8_t * writecr2 = as_code<0x0F , 0x22 , 0xD1 >{};
73
+ static constexpr const uint8_t * syscall = as_code<0x0F , 0x05 >{};
74
+ static constexpr const uint8_t * sysretc = as_code<0x0F , 0x07 >{};
75
+ static constexpr const uint8_t * sysretq = as_code<0x48 , 0x0F , 0x07 >{};
76
+ static constexpr const uint8_t * sysenter = as_code<0x0F , 0x34 >{};
77
+ static constexpr const uint8_t * sysexit = as_code<0x0F , 0x35 >{};
78
+ static constexpr const uint8_t * lmsw = as_code<0x0F , 0x01 , 0xF1 >{};
79
+ static constexpr const uint8_t * smsw = as_code<0x0F , 0x01 , 0xF0 , 0x0F , 0xB7 , 0xC0 >{};
80
+ static constexpr const uint8_t * ltr = as_code<0x0F , 0x00 , 0xD9 >{};
81
+ static constexpr const uint8_t * str = as_code<0x66 , 0x0F , 0x00 , 0xC8 , 0x48 , 0x0F , 0xB7 , 0xC0 >{};
82
+ static constexpr const uint8_t * lidt = as_code<0x48 , 0x89 , 0x4C , 0x24 , 0x0A , 0x66 , 0x89 , 0x54 , 0x24 , 0x08 , 0x0F , 0x01 , 0x5C , 0x24 , 0x08 >{}; // void(u64, u16)
83
+ static constexpr const uint8_t * lgdt = as_code<0x48 , 0x89 , 0x4C , 0x24 , 0x0A , 0x66 , 0x89 , 0x54 , 0x24 , 0x08 , 0x0F , 0x01 , 0x54 , 0x24 , 0x08 >{}; // void(u64, u16)
84
+ static constexpr const uint8_t * sidt_b = as_code<0x0F , 0x01 , 0x4C , 0x24 , 0x08 , 0x48 , 0x8B , 0x44 , 0x24 , 0x0A >{}; // u64()
85
+ static constexpr const uint8_t * sidt_l = as_code<0x0F , 0x01 , 0x4C , 0x24 , 0x08 , 0x0F , 0xB7 , 0x44 , 0x24 , 0x08 >{}; // u64()
86
+ static constexpr const uint8_t * sgdt_b = as_code<0x0F , 0x01 , 0x44 , 0x24 , 0x08 , 0x48 , 0x8B , 0x44 , 0x24 , 0x0A >{}; // u64()
87
+ static constexpr const uint8_t * sgdt_l = as_code<0x0F , 0x01 , 0x44 , 0x24 , 0x08 , 0x0F , 0xB7 , 0x44 , 0x24 , 0x08 >{}; // u64()
88
+ static constexpr const uint8_t * lldt = as_code<0x0F , 0x00 , 0xD1 >{};
89
+ static constexpr const uint8_t * sldt = as_code<0x66 , 0x0F , 0x00 , 0xC0 , 0x0F , 0xB7 , 0xC0 >{};
90
+ static constexpr const uint8_t * invd = as_code<0x0F , 0x08 >{};
91
+ static constexpr const uint8_t * wbinvd = as_code<0x0F , 0x09 >{};
92
+ static constexpr const uint8_t * cli = as_code<0xFA >{};
93
+ static constexpr const uint8_t * sti = as_code<0xFB >{};
94
+
95
+ static void hlt () { __halt (); }
96
+ static void invlpg ( void * adr ) { __invlpg ( adr ); }
97
+ static void xsetbv ( uint32_t reg, uint64_t val ) { _xsetbv ( reg, val ); }
98
+ static uint64_t xgetbv ( uint32_t reg ) { return _xgetbv ( reg ); }
99
+ static void monitor ( void * adr ) { _mm_monitor ( adr, 0 , 0 ); }
100
+ static void mwait () { _mm_mwait ( 0 , 0 ); }
101
+
102
+ static uint64_t exec ( const char * code, size_t length, uint64_t rcx, uint64_t rdx )
103
+ {
104
+ __declspec ( allocate ( " .stub" ) ) static uint8_t space[ 0x1000 ];
105
+ memcpy ( space, code, length > 0x1000 ? 0x1000 : length );
106
+ return ( ( uint64_t ( __stdcall* )( uint64_t , uint64_t ) ) & space[ 0 ] )( rcx, rdx );
107
+ }
108
+
59
109
static void * read_svirt ( const void * src, size_t n )
60
110
{
61
111
static auto _MmCopyMemory = [ ] ()
@@ -156,6 +206,12 @@ static void export_all( lua_State* L, uint64_t image_address )
156
206
lua_createtable ( L, 0 , eat->NumberOfFunctions );
157
207
if ( names )
158
208
{
209
+ // Insert the base address to the table.
210
+ //
211
+ lua_pushstring ( L, " base_address" );
212
+ native_function::push ( L )->address = ( void * ) image_address;
213
+ lua_settable ( L, -3 );
214
+
159
215
// For each named export:
160
216
//
161
217
for ( int i = 0 ; i < eat->NumberOfNames ; i++ )
@@ -171,11 +227,10 @@ static void export_all( lua_State* L, uint64_t image_address )
171
227
address < ( export_dir.VirtualAddress + export_dir.Size ) )
172
228
continue ;
173
229
174
- // Insert the table.
230
+ // Insert to the table.
175
231
//
176
232
lua_pushstring ( L, name );
177
- native_function* fn = native_function::push ( L );
178
- fn->address = ( void * ) address;
233
+ native_function::push ( L )->address = ( void * ) address;
179
234
lua_settable ( L, -3 );
180
235
}
181
236
}
@@ -253,15 +308,45 @@ void lua::expose_api( lua_State* L )
253
308
export_func ( L, " outdword" , &outdword );
254
309
255
310
export_func ( L, " readtsc" , &readtsc );
311
+ export_func ( L, " readtscpa" , &readtscpa );
312
+ export_func ( L, " readtscp" , &readtscp );
256
313
export_func ( L, " readpmc" , &readpmc );
257
314
export_func ( L, " readgsbase" , &readgsbase );
258
315
export_func ( L, " readfsbase" , &readfsbase );
259
316
317
+ export_func ( L, " writecr2" , writecr2 );
318
+ export_func ( L, " syscall" , syscall );
319
+ export_func ( L, " sysretc" , sysretc );
320
+ export_func ( L, " sysretq" , sysretq );
321
+ export_func ( L, " sysenter" , sysenter );
322
+ export_func ( L, " sysexit" , sysexit );
323
+ export_func ( L, " lmsw" , lmsw );
324
+ export_func ( L, " smsw" , smsw );
325
+ export_func ( L, " ltr" , ltr );
326
+ export_func ( L, " str" , str );
327
+ export_func ( L, " lidt" , lidt );
328
+ export_func ( L, " lgdt" , lgdt );
329
+ export_func ( L, " lldt" , lldt );
330
+ export_func ( L, " sidt_b" , sidt_b );
331
+ export_func ( L, " sgdt_b" , sgdt_b );
332
+ export_func ( L, " sidt_l" , sidt_l );
333
+ export_func ( L, " sgdt_l" , sgdt_l );
334
+ export_func ( L, " sldt" , sldt );
335
+ export_func ( L, " invd" , invd );
336
+ export_func ( L, " wbinvd" , wbinvd );
337
+ export_func ( L, " cli" , cli );
338
+ export_func ( L, " sti" , sti );
339
+ export_func ( L, " invlpg" , invlpg );
340
+ export_func ( L, " xsetbv" , xsetbv );
341
+ export_func ( L, " xgetbv" , xgetbv );
342
+ export_func ( L, " monitor" , monitor );
343
+ export_func ( L, " mwait" , mwait );
344
+ export_func ( L, " exec" , exec );
345
+
260
346
// Export simpler helpers.
261
347
//
262
348
export_func ( L, " readps" , &read_sphys );
263
349
export_func ( L, " readvs" , &read_svirt );
264
-
265
350
export_func ( L, " attach_process" , &attach_process );
266
351
export_func ( L, " attach_pid" , &attach_pid );
267
352
export_func ( L, " detach" , &detach );
0 commit comments