This commit is contained in:
DavidXanatos 2022-01-05 13:31:36 +01:00
parent 095e89934b
commit eb064d2c3e
2 changed files with 25 additions and 322 deletions

View File

@ -108,87 +108,6 @@ static BOOLEAN Syscall_GetKernelAddr(
#endif #endif
//---------------------------------------------------------------------------
/*
typedef NTSTATUS (*P_SystemService00)(void);
typedef NTSTATUS (*P_SystemService01)(
ULONG_PTR arg01);
typedef NTSTATUS (*P_SystemService02)(
ULONG_PTR arg01, ULONG_PTR arg02);
typedef NTSTATUS (*P_SystemService03)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03);
typedef NTSTATUS (*P_SystemService04)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04);
typedef NTSTATUS (*P_SystemService05)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05);
typedef NTSTATUS (*P_SystemService06)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06);
typedef NTSTATUS (*P_SystemService07)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07);
typedef NTSTATUS (*P_SystemService08)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08);
typedef NTSTATUS (*P_SystemService09)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09);
typedef NTSTATUS (*P_SystemService10)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10);
typedef NTSTATUS (*P_SystemService11)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11);
typedef NTSTATUS (*P_SystemService12)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12);
typedef NTSTATUS (*P_SystemService13)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13);
typedef NTSTATUS (*P_SystemService14)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14);
typedef NTSTATUS (*P_SystemService15)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15);
typedef NTSTATUS (*P_SystemService16)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16);
typedef NTSTATUS (*P_SystemService17)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16,
ULONG_PTR arg17);
typedef NTSTATUS (*P_SystemService18)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16,
ULONG_PTR arg17, ULONG_PTR arg18);
typedef NTSTATUS (*P_SystemService19)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16,
ULONG_PTR arg17, ULONG_PTR arg18, ULONG_PTR arg19);
// (count & 0x0F) + 4 -> 19 is absolute maximum
*/
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Variables // Variables
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -603,15 +522,7 @@ _FX void Syscall_ErrorForAsciiName(const UCHAR *name_a)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
extern unsigned int g_TrapFrameOffset; extern unsigned int g_TrapFrameOffset;
#ifdef _WIN64 NTSTATUS Sbie_InvokeSyscall_asm(void* func, ULONG count, void* args);
NTSTATUS Sbie_InvokeSyscall_hack(void* func, ULONG_PTR count, void* args, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16,
ULONG_PTR arg17, ULONG_PTR arg18, ULONG_PTR arg19);
#else
NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args);
#endif
_FX NTSTATUS Syscall_Invoke(SYSCALL_ENTRY *entry, ULONG_PTR *stack) _FX NTSTATUS Syscall_Invoke(SYSCALL_ENTRY *entry, ULONG_PTR *stack)
{ {
@ -628,155 +539,7 @@ _FX NTSTATUS Syscall_Invoke(SYSCALL_ENTRY *entry, ULONG_PTR *stack)
//DbgPrint("[syscall] request param count = %d\n", entry->param_count); //DbgPrint("[syscall] request param count = %d\n", entry->param_count);
#ifdef _WIN64
//
// Note: For some weird reason the x64 version of Sbie_InvokeSyscall_asm
// while working for 64 bit apps, makes 32 bit apps crash under wow64,
// this should not be possible yet it happens, hence we use a hacky workaround
// where our sys call invoker does not do a call but a jmp that seams to be fine.
// Therefore we need to re-use this functions stack, hence those many 0 args passed.
//
status = Sbie_InvokeSyscall_hack(entry->ntos_func, entry->param_count, stack, 0, // args 1-4 shadow space
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); // reserve stack for args 5-19
#else
status = Sbie_InvokeSyscall_asm(entry->ntos_func, entry->param_count, stack); status = Sbie_InvokeSyscall_asm(entry->ntos_func, entry->param_count, stack);
#endif
/*if (entry->param_count == 0) {
P_SystemService00 nt = (P_SystemService00)entry->ntos_func;
status = nt();
} else if (entry->param_count == 1) {
P_SystemService01 nt = (P_SystemService01)entry->ntos_func;
status = nt(stack[0]);
} else if (entry->param_count == 2) {
P_SystemService02 nt = (P_SystemService02)entry->ntos_func;
status = nt(stack[0], stack[1]);
} else if (entry->param_count == 3) {
P_SystemService03 nt = (P_SystemService03)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2]);
} else if (entry->param_count == 4) {
P_SystemService04 nt = (P_SystemService04)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3]);
} else if (entry->param_count == 5) {
P_SystemService05 nt = (P_SystemService05)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4]);
} else if (entry->param_count == 6) {
P_SystemService06 nt = (P_SystemService06)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5]);
} else if (entry->param_count == 7) {
P_SystemService07 nt = (P_SystemService07)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6]);
} else if (entry->param_count == 8) {
P_SystemService08 nt = (P_SystemService08)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7]);
} else if (entry->param_count == 9) {
P_SystemService09 nt = (P_SystemService09)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8]);
} else if (entry->param_count == 10) {
P_SystemService10 nt = (P_SystemService10)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9]);
} else if (entry->param_count == 11) {
P_SystemService11 nt = (P_SystemService11)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10]);
} else if (entry->param_count == 12) {
P_SystemService12 nt = (P_SystemService12)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11]);
} else if (entry->param_count == 13) {
P_SystemService13 nt = (P_SystemService13)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12]);
} else if (entry->param_count == 14) {
P_SystemService14 nt = (P_SystemService14)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13]);
} else if (entry->param_count == 15) {
P_SystemService15 nt = (P_SystemService15)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14]);
} else if (entry->param_count == 16) {
P_SystemService16 nt = (P_SystemService16)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15]);
} else if (entry->param_count == 17) {
P_SystemService17 nt = (P_SystemService17)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15], stack[16]);
} else if (entry->param_count == 18) {
P_SystemService18 nt = (P_SystemService18)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15], stack[16], stack[17]);
} else if (entry->param_count == 19) {
P_SystemService19 nt = (P_SystemService19)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15], stack[16], stack[17],
stack[18]);
} else {
status = STATUS_INVALID_SYSTEM_SERVICE;
}*/
} __except (EXCEPTION_EXECUTE_HANDLER) { } __except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode(); status = GetExceptionCode();

View File

@ -271,25 +271,21 @@ endif
ifdef _WIN64 ifdef _WIN64
; NTSTATUS Sbie_InvokeSyscall_hack(ULONG_PTR arg01, ... , ULONG_PTR arg19, void* func); ; NTSTATUS Sbie_InvokeSyscall_asm(void* func, ULONG count, void* args);
Sbie_InvokeSyscall_jmp PROC Sbie_InvokeSyscall_asm PROC FRAME
jmp qword ptr [rsp+0A0h] ; 20th argument
Sbie_InvokeSyscall_jmp ENDP
; prolog
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, ULONG_PTR count, void* args, ULONG_PTR dummy1, ..., ULONG_PTR dummy16); push rsi
Sbie_InvokeSyscall_hack PROC push rdi
sub rsp, 98h ; 8 * 19 - prepare enough stack for up to 19 arguments
; WARNING: when calling this function after the 3 used arguments 16 more dummy's must be passed .allocstack(0A8h)
; to reserve the required stack space at the caller's stack which we will use .endprolog
; note: (count & 0x0F) + 4 = 19 arguments are the absolute maximum
; quick sanity check ; quick sanity check
cmp rdx, 13h ; if count > 19 cmp rdx, 13h ; if count > 19
jle arg_count_ok jle arg_count_ok
mov rax, 0C000001Ch ; return STATUS_INVALID_SYSTEM_SERVICE mov rax, 0C000001Ch ; return STATUS_INVALID_SYSTEM_SERVICE
ret jmp func_return
arg_count_ok: arg_count_ok:
; save our 3 relevant arguments to spare registers ; save our 3 relevant arguments to spare registers
@ -297,60 +293,6 @@ arg_count_ok:
mov r10, rdx ; count mov r10, rdx ; count
mov rax, rcx ; func mov rax, rcx ; func
; check if we have higher arguments and if not skip
cmp r10, 4
jle copy_reg_args
push rsi
push rdi
; copy arguments 5-19
mov rsi, r11 ; source
add rsi, 20h
mov rdi, rsp ; destination
add rdi, 38h ; 28h + 8h + 8h
mov rcx, r10 ; arg count
sub rcx, 4 ; skip the register passed args
rep movsq
pop rdi
pop rsi
copy_reg_args:
; copy arguments 1-4
mov r9, qword ptr [r11+18h]
mov r8, qword ptr [r11+10h]
mov rdx, qword ptr [r11+08h]
mov rcx, qword ptr [r11+00h]
; "call" the function
jmp rax
Sbie_InvokeSyscall_hack ENDP
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args);
Sbie_InvokeSyscall_asm PROC
; note: (count & 0x0F) + 4 = 19 arguments are the absolute maximum
; quick sanity check
cmp rdx, 13h ; if count > 19
jle arg_count_ok
mov rax, 0C000001Ch ; return STATUS_INVALID_SYSTEM_SERVICE
ret
arg_count_ok:
push rsi
push rdi
; prepare enough stack for up to 19 arguments
sub rsp, 98h
; save our 3 relevant arguments to spare registers
mov r11, r8 ; args
mov r10, rdx ; count
mov rax, rcx ; func
; check if we have higher arguments and if not skip ; check if we have higher arguments and if not skip
cmp r10, 4 cmp r10, 4
jle copy_reg_args jle copy_reg_args
@ -373,7 +315,8 @@ copy_reg_args:
; call the function ; call the function
call rax call rax
; clear stack func_return:
; epilog
add rsp, 98h add rsp, 98h
pop rdi pop rdi
pop rsi pop rsi
@ -384,24 +327,22 @@ Sbie_InvokeSyscall_asm ENDP
else else
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args); ; NTSTATUS Sbie_InvokeSyscall_asm(void* func, ULONG count, void* args);
_Sbie_InvokeSyscall_asm@12 PROC _Sbie_InvokeSyscall_asm@12 PROC
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args); ; prolog
; quick sanity check
cmp dword ptr [esp+04h+4h], 13h ; @count
jle args_ok
mov eax, 0C000001Ch ; return STATUS_INVALID_SYSTEM_SERVICE
ret 0Ch
args_ok:
; prepare enough stack for up to 19 arguments
push ebp push ebp
push esi push esi
push edi push edi
mov ebp, esp mov ebp, esp
sub esp, 4Ch sub esp, 4Ch ; 4 * 19 - prepare enough stack for up to 19 arguments
; quick sanity check
cmp dword ptr [ebp+10h+4h], 13h ; arg count @count
jle arg_count_ok
mov eax, 0C000001Ch ; return STATUS_INVALID_SYSTEM_SERVICE
jmp func_return
arg_count_ok:
; copy arguments 0-19 ; copy arguments 0-19
mov esi, dword ptr [ebp+10h+8h] ; source @args mov esi, dword ptr [ebp+10h+8h] ; source @args
@ -413,9 +354,8 @@ args_ok:
mov eax, dword ptr [ebp+10h+0h] ; @func mov eax, dword ptr [ebp+10h+0h] ; @func
call eax call eax
; clear stack func_return:
function_end: ; epilog
mov esp,ebp mov esp,ebp
pop edi pop edi
pop esi pop esi