;++ ; ; Module Name: ; ; cs.asm ; ;-- .CODE ;++ ; ; PVOID ; MwGenericCall( ; _In_ ULONG SyscallNumber, ; _In_ ULONG ArgumentCount, ; _In_ va_list ArgumentList ; ) ; ;-- MwGenericCall PROC PUBLIC ; ; Save r12 to the shadow space. ; This register will be held as a temporary ; stack pointer for the syscall. ; mov qword ptr [rsp + 8], r12 ; ; eax = SyscallNumber ; r10 = ArgumentCount ; r11 = ArgumentList ; r12 = ArgumentList - sizeof(PVOID) ; (space for return address) ; mov eax, ecx mov r10d, edx mov r11, r8 lea r12, qword ptr [r11 - 8] ; ; Assign first 4 arguments (rcx, rdx, r8, r9) ; from the ArgumentList. ; cmp r10d, 1 cmovae rcx, qword ptr [r11 + 0] cmp r10d, 2 cmovae rdx, qword ptr [r11 + 8] cmp r10d, 3 cmovae r8, qword ptr [r11 + 16] cmp r10d, 4 cmovae r9, qword ptr [r11 + 24] ; ; The syscall handler expects the first ; parameter in the r10 register. ; mov r10, rcx ; ; Stack pivot, syscall, restore stack. ; xchg r12, rsp syscall xchg r12, rsp ; ; Restore r12 register from the shadow space. ; mov r12, qword ptr [rsp + 8] ret MwGenericCall ENDP END