View Single Post
  #3  
Old 01-01-2022, 02:53
DavidXanatos DavidXanatos is offline
Family
 
Join Date: Jun 2018
Posts: 179
Rept. Given: 2
Rept. Rcvd 46 Times in 32 Posts
Thanks Given: 58
Thanks Rcvd at 350 Times in 116 Posts
DavidXanatos Reputation: 46
and here we have the not lazy solution:

do_call.asm
Code:
.code

;----------------------------------------------------------------------------

ifdef _WIN64

Sbie_InvokeSyscall_asm PROC

     mov         qword ptr [rsp+20h], r9  
     mov         qword ptr [rsp+18h], r8  
     mov         qword ptr [rsp+10h], rdx  
     mov         qword ptr [rsp+8], rcx 
     
     ; 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 
     cmp         r10, 4
     jle         copy_reg_args
     ; copy arguments 5-19
     mov         rsi, r11 ; source
     add         rsi, 20h
     mov         rdi, rsp ; destination
     add         rdi, 20h
     mov         rcx, r10 ; arg count
     sub         rcx, 4   ; skip the register passed args
     rep movsq

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
     call        rax

     ; clear stack
     add         rsp, 98h  
     pop         rdi
     pop         rsi

     ret  

Sbie_InvokeSyscall_asm ENDP

else

_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
args_ok:

     ; prepare enough stack for up to 19 arguments
     push        ebp  
     push        esi
     push        edi
     mov         ebp, esp  
     sub         esp, 4Ch

     ; copy arguments 0-19
     mov         esi, dword ptr [ebp+10h+8h] ; source @args
     mov         edi, esp ; destination
     mov         ecx, dword ptr [ebp+10h+4h] ; arg count @count
     rep movsd

     ; call the function
     mov         eax, dword ptr [ebp+10h+0h] ; @func
     call        eax

     ; clear stack
function_end:

     mov         esp,ebp  
     pop         edi
     pop         esi
     pop         ebp
     ret  

_Sbie_InvokeSyscall_asm@12 ENDP
PUBLIC _Sbie_InvokeSyscall_asm@12

endif

;----------------------------------------------------------------------------

end
test.cpp:
Code:
#include <stdio.h>

NTSTATUS Test4(int arg1, int arg2, int arg3, int arg4)
{
    printf("arg1: %x, arg2: %x, arg3: %x, arg4: %x\r\n", arg1, arg2, arg3, arg4);
    return 0;
}

NTSTATUS Test8(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8)
{
    printf("arg1: %x, arg2: %x, arg3: %x, arg4: %x; arg5: %x, arg6: %x, arg7: %x, arg8: %x\r\n", arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
    return 0;
}

NTSTATUS Test19(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11, int arg12, int arg13, int arg14, int arg15, int arg16, int arg17, int arg18, int arg19)
{
    return 123;
}

NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args);

int main(int argc, char *argv[])
{
#ifdef _WIN64
    __int64 stack[19];
#else
    int stack[19];
#endif
    for (int i = 0; i < 19; i++)
        stack[i] = i + 1;

    Sbie_InvokeSyscall_asm(Test4, 4, stack);

    Sbie_InvokeSyscall_asm(Test8, 8, stack);

    Sbie_InvokeSyscall_asm(Test19, 19, stack);

    Sbie_InvokeSyscall_asm(Test19, 20, stack);

    return 0;
}

Last edited by DavidXanatos; 01-01-2022 at 05:42.
Reply With Quote
The Following 2 Users Say Thank You to DavidXanatos For This Useful Post:
niculaita (01-06-2022), WRP (01-02-2022)