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
//---------------------------------------------------------------------------
/*
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
//---------------------------------------------------------------------------
@ -603,15 +522,7 @@ _FX void Syscall_ErrorForAsciiName(const UCHAR *name_a)
//---------------------------------------------------------------------------
extern unsigned int g_TrapFrameOffset;
#ifdef _WIN64
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
NTSTATUS Sbie_InvokeSyscall_asm(void* func, ULONG count, void* args);
_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);
#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);
#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) {
status = GetExceptionCode();

View File

@ -271,81 +271,23 @@ endif
ifdef _WIN64
; NTSTATUS Sbie_InvokeSyscall_hack(ULONG_PTR arg01, ... , ULONG_PTR arg19, void* func);
Sbie_InvokeSyscall_jmp PROC
jmp qword ptr [rsp+0A0h] ; 20th argument
Sbie_InvokeSyscall_jmp ENDP
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, ULONG_PTR count, void* args, ULONG_PTR dummy1, ..., ULONG_PTR dummy16);
Sbie_InvokeSyscall_hack PROC
; WARNING: when calling this function after the 3 used arguments 16 more dummy's must be passed
; to reserve the required stack space at the caller's stack which we will use
; note: (count & 0x0F) + 4 = 19 arguments are the absolute maximum
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, ULONG count, void* args);
Sbie_InvokeSyscall_asm PROC FRAME
; prolog
push rsi
push rdi
sub rsp, 98h ; 8 * 19 - prepare enough stack for up to 19 arguments
.allocstack(0A8h)
.endprolog
; 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:
; 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
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
jmp func_return
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
@ -373,7 +315,8 @@ copy_reg_args:
; call the function
call rax
; clear stack
func_return:
; epilog
add rsp, 98h
pop rdi
pop rsi
@ -384,24 +327,22 @@ Sbie_InvokeSyscall_asm ENDP
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
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args);
; 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
; prolog
push ebp
push esi
push edi
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
mov esi, dword ptr [ebp+10h+8h] ; source @args
@ -413,9 +354,8 @@ args_ok:
mov eax, dword ptr [ebp+10h+0h] ; @func
call eax
; clear stack
function_end:
func_return:
; epilog
mov esp,ebp
pop edi
pop esi