Skip to content

Commit cbccfa0

Browse files
committed
Implemented many new intrinsics and a periodic worker.
1 parent 1584a01 commit cbccfa0

File tree

5 files changed

+156
-26
lines changed

5 files changed

+156
-26
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ x64/Release/
2020
LuaLib/x64/Release/
2121

2222
LuaLib/x64/Debug/
23+
24+
*.recipe

ActualConsole/main.cpp

+58-17
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,54 @@
33
#include <iostream>
44
#include <sstream>
55
#include <tuple>
6+
#include <mutex>
67
#include "../KernelLuaVm/driver_io.hpp"
78

9+
HANDLE device = CreateFileA
10+
(
11+
"\\\\.\\NtLua",
12+
GENERIC_READ | GENERIC_WRITE,
13+
FILE_SHARE_READ | FILE_SHARE_WRITE,
14+
NULL,
15+
OPEN_EXISTING,
16+
FILE_ATTRIBUTE_NORMAL,
17+
NULL
18+
);
19+
20+
void worker_thread()
21+
{
22+
bool prev_success = false;
23+
while ( 1 )
24+
{
25+
Sleep( prev_success ? 100 : 5000 );
26+
27+
ntlua_result result = { nullptr, nullptr };
28+
char worker_script[] = R"(
29+
if worker then
30+
worker()
31+
print("-")
32+
end
33+
)";
34+
35+
DWORD discarded = 0;
36+
DeviceIoControl(
37+
device,
38+
NTLUA_RUN,
39+
worker_script, sizeof( worker_script ),
40+
&result, sizeof( result ),
41+
&discarded, nullptr
42+
);
43+
44+
if ( result.outputs ) VirtualFree( result.outputs, 0, MEM_RELEASE );
45+
if ( result.errors ) VirtualFree( result.errors, 0, MEM_RELEASE );
46+
prev_success = !result.outputs;
47+
}
48+
}
49+
850
int main()
951
{
10-
// Create a handle to the device.
11-
//
12-
HANDLE device = CreateFileA
13-
(
14-
"\\\\.\\NtLua",
15-
GENERIC_READ | GENERIC_WRITE,
16-
FILE_SHARE_READ | FILE_SHARE_WRITE,
17-
NULL,
18-
OPEN_EXISTING,
19-
FILE_ATTRIBUTE_NORMAL,
20-
NULL
21-
);
2252
if ( device == INVALID_HANDLE_VALUE ) return 1;
53+
std::thread thr( &worker_thread );
2354

2455
// Enter REPL:
2556
//
@@ -42,6 +73,8 @@ int main()
4273
buffer += "\n" + buffer2;
4374
}
4475

76+
77+
4578
// Handle special commands:
4679
//
4780
if ( buffer == "clear" )
@@ -53,14 +86,22 @@ int main()
5386
return system( "cmd" );
5487
else if ( buffer == "exit" )
5588
return 0;
89+
else if ( buffer == "reset" )
90+
{
91+
DWORD discarded = 0;
92+
DeviceIoControl(
93+
device,
94+
NTLUA_RESET,
95+
&buffer[ 0 ], buffer.size() + 1,
96+
&discarded, sizeof( discarded ),
97+
&discarded, nullptr
98+
);
99+
continue;
100+
}
56101

57102
// Send IOCTL.
58103
//
59-
ntlua_result result = {
60-
nullptr,
61-
nullptr
62-
};
63-
104+
ntlua_result result = { nullptr, nullptr };
64105
DWORD discarded = 0;
65106
DeviceIoControl(
66107
device,

KernelLuaVm/KernelLuaVm.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
8383
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
8484
<IncludePath>$(SolutionDir)LuaLib;$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH)</IncludePath>
85+
<TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
8586
</PropertyGroup>
8687
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
8788
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>

KernelLuaVm/driver_io.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#pragma once
22

33
// Assuming the platform specific header is included already.
4-
#define NTLUA_RUN CTL_CODE( 0x13, 0x37, METHOD_BUFFERED, FILE_ANY_ACCESS )
4+
#define NTLUA_RUN CTL_CODE( 0x13, 0x37, METHOD_BUFFERED, FILE_ANY_ACCESS )
5+
#define NTLUA_RESET CTL_CODE( 0x13, 0x38, METHOD_BUFFERED, FILE_ANY_ACCESS )
56

67
// Shared structures.
78
//

KernelLuaVm/lua/api.cpp

+93-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "api.hpp"
22
#include <ntimage.h>
33

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+
};
57

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 )
79
{
810
native_function* fn = native_function::push( L );
911
fn->address = ptr;
@@ -44,18 +46,66 @@ static void writedr3( uint64_t value ) { return __writedr( 3, value ); }
4446
static void writedr6( uint64_t value ) { return __writedr( 6, value ); }
4547
static void writedr7( uint64_t value ) { return __writedr( 7, value ); }
4648

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 ); }
4951
static uint32_t indword( uint16_t port ) { return __indword( port ); }
5052
static void outbyte( uint16_t port, uint8_t value ) { return __outbyte( port, value ); }
5153
static void outword( uint16_t port, uint16_t value ) { return __outword( port, value ); }
5254
static void outdword( uint16_t port, uint32_t value ) { return __outdword( port, value ); }
5355

5456
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 ); }
5559
static uint64_t readpmc( uint32_t pmc ) { return __readpmc( pmc ); }
5660
static uint64_t readgsbase() { return _readgsbase_u64(); }
5761
static uint64_t readfsbase() { return _readfsbase_u64(); }
5862

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+
59109
static void* read_svirt( const void* src, size_t n )
60110
{
61111
static auto _MmCopyMemory = [ ] ()
@@ -156,6 +206,12 @@ static void export_all( lua_State* L, uint64_t image_address )
156206
lua_createtable( L, 0, eat->NumberOfFunctions );
157207
if ( names )
158208
{
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+
159215
// For each named export:
160216
//
161217
for ( int i = 0; i < eat->NumberOfNames; i++ )
@@ -171,11 +227,10 @@ static void export_all( lua_State* L, uint64_t image_address )
171227
address < ( export_dir.VirtualAddress + export_dir.Size ) )
172228
continue;
173229

174-
// Insert the table.
230+
// Insert to the table.
175231
//
176232
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;
179234
lua_settable( L, -3 );
180235
}
181236
}
@@ -253,15 +308,45 @@ void lua::expose_api( lua_State* L )
253308
export_func( L, "outdword", &outdword );
254309

255310
export_func( L, "readtsc", &readtsc );
311+
export_func( L, "readtscpa", &readtscpa );
312+
export_func( L, "readtscp", &readtscp );
256313
export_func( L, "readpmc", &readpmc );
257314
export_func( L, "readgsbase", &readgsbase );
258315
export_func( L, "readfsbase", &readfsbase );
259316

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+
260346
// Export simpler helpers.
261347
//
262348
export_func( L, "readps", &read_sphys );
263349
export_func( L, "readvs", &read_svirt );
264-
265350
export_func( L, "attach_process", &attach_process );
266351
export_func( L, "attach_pid", &attach_pid );
267352
export_func( L, "detach", &detach );

0 commit comments

Comments
 (0)