--- title: "Syscall64" description: "Doing direct syscalls on all platforms" draft: false --- A slightly hacky way (C macros) to do direct syscalls on either x86 or x64 windows, without any code change. http://vcs.wacked.codes/wacked/syscall64 Use with this: ``` ;http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx format ms coff include 'u:\fasm\INCLUDE\win32wx.inc' public _syscall64 section '.text' code readable executable ; Converts the arguments and then executes SYSCALL ; 1. Param: Count of args to pass to syscall ; 2. Param: Syscall id ; 3. - X. Param: Params for syscall _syscall64: ; Those registers are pushed here so that the LEAVE instr cleans up the converted params without me needing to ; calc how much space those needed. Seriously what's 4*3 again? push edi push ebx push edx ; used by the x64 code push ebp mov ebp, esp ; Alloc space for params mov ecx, [ebp + 4*3 + 0x08] ; cnt cmp ecx, 4 ; Reserve shadow space jge @f mov ecx, 4 @@: shl ecx, 3 sub esp, ecx and esp, 0xFFFFFFF0 ; Align stack ; Convert params to x64 mov edi, esp ; Destination mov ecx, [ebp + 4*3 + 0x08] ; Count lea ebx, [ebp + 4*3 + 0x10] ; Source for params CONVERT_PARAMS_LOOP: test ecx, ecx je @f mov eax, [ebx] stosd ; mov dword[edi], dword[eax] edi += 4 mov eax, 0 stosd ; [edi] = 0 edi += 4 add ebx, 4 ; srcPtr++ dec ecx ; cnt-- jmp CONVERT_PARAMS_LOOP @@: ;mov eax, [ebp + 4*3 + 0x0C] ; Get syscall id call 0x33:X64_START X86_RETURN_FROM_X64: leave pop edx pop ebx pop edi ret ;align 16 X64_START: use64 mov eax, dword [ebp + 0x18] ; Get syscall id (4*3 = saved registers, ) ; Get args from shadow space mov rcx, [rsp + 8] mov rdx , [rsp + 0x10] mov r8, [rsp + 0x18] mov r9, [rsp + 0x20] mov r10,rcx syscall use32 retf ```