; syscall_stubs.asm - user-mode INT 0x40 stubs exported by syscall.dll (MASM64) ; ; Calling convention (kernel side): ; RAX = syscall number ; RCX = arg 0 ; RDX = arg 1 ; R8 = arg 2 ; R9 = arg 3 ; R10 = arg 4 (our extension - loaded from the stack by SYSCALL_STUB6) ; R11 = arg 5 (our extension - loaded from the stack by SYSCALL_STUB6) ; ; User-mode callers follow standard MS x64: args 1-4 in RCX/RDX/R8/R9, ; args 5+ on the stack above the home area ([rsp+28h], [rsp+30h], ...). ; ; SYSCALL_STUB2 - 4 or fewer args: pure register passing, no stack read. ; SYSCALL_STUB6 - 5 or 6 args: loads [rsp+28h] -> R10 and [rsp+30h] -> R11. ; ; Handle lifecycle: ; SysCloseHandle is the single close stub for every object type. ; There is no SysCloseFile - files are closed through the unified path, ; exactly like mutexes, semaphores, events, and queues. INCLUDE syscall_nr.inc SYS_USER_APC_FRAME_Magic EQU 0 SYS_USER_APC_FRAME_OriginalRip EQU 8 SYS_USER_APC_FRAME_OriginalRsp EQU 16 SYS_USER_APC_FRAME_OriginalRflags EQU 24 SYS_USER_APC_FRAME_OriginalRax EQU 32 SYS_USER_APC_FRAME_Routine EQU 40 SYS_USER_APC_FRAME_NormalContext EQU 48 SYS_USER_APC_FRAME_SystemArgument1 EQU 56 SYS_USER_APC_FRAME_SystemArgument2 EQU 64 .CODE ; --------------------------------------------------------------------------- SYSCALL_STUB2 MACRO name, nr PUBLIC Sys&name Sys&name PROC EXPORT mov rax, nr int 40h ret Sys&name ENDP ENDM ; --------------------------------------------------------------------------- SYSCALL_STUB6 MACRO name, nr PUBLIC Sys&name Sys&name PROC EXPORT mov r10, [rsp+28h] ; 5th argument mov r11, [rsp+30h] ; 6th argument mov rax, nr int 40h ret Sys&name ENDP ENDM ; --------------------------------------------------------------------------- ; Process & thread lifecycle ; --------------------------------------------------------------------------- SYSCALL_STUB2 ExitProcess, SYS_EXIT_PROCESS SYSCALL_STUB2 ExitThread, SYS_EXIT_THREAD SYSCALL_STUB2 CreateProcess, SYS_CREATE_PROCESS SYSCALL_STUB2 WaitForProcess, SYS_WAIT_FOR_PROCESS SYSCALL_STUB2 GetProcessExitCode, SYS_GET_PROCESS_EXIT_CODE SYSCALL_STUB2 KillProcess, SYS_KILL_PROCESS SYSCALL_STUB2 GetProcessList, SYS_GET_PROCESS_LIST SYSCALL_STUB2 GetProcessPid, SYS_GET_PROCESS_PID SYSCALL_STUB2 CreateThread, SYS_CREATE_THREAD SYSCALL_STUB2 WaitThread, SYS_WAIT_THREAD SYSCALL_STUB2 GetCurrentTid, SYS_GET_CURRENT_TID SYSCALL_STUB2 GetCurrentPid, SYS_GET_CURRENT_PID SYSCALL_STUB2 SetThreadPriority, SYS_SET_THREAD_PRIORITY SYSCALL_STUB2 Yield, SYS_YIELD SYSCALL_STUB2 Sleep, SYS_SLEEP SYSCALL_STUB2 SetUserApcDispatcher, SYS_SET_USER_APC_DISPATCHER SYSCALL_STUB2 ApcReturn, SYS_APC_RETURN ; --------------------------------------------------------------------------- ; User APC dispatcher ; --------------------------------------------------------------------------- PUBLIC SysUserApcDispatcher SysUserApcDispatcher PROC EXPORT ; Kernel enters here with RSP pointing at SYS_USER_APC_FRAME. There is no ; return address because this is an IRET redirection. Preserve RBX because ; the original user context resumes after SysApcReturn. push rbx lea rbx, [rsp + 8] ; original injected RSP = frame pointer sub rsp, 32 ; shadow space; RSP is already call-aligned mov rcx, [rbx + SYS_USER_APC_FRAME_NormalContext] mov rdx, [rbx + SYS_USER_APC_FRAME_SystemArgument1] mov r8, [rbx + SYS_USER_APC_FRAME_SystemArgument2] mov rax, [rbx + SYS_USER_APC_FRAME_Routine] call rax add rsp, 32 mov rcx, rbx ; SysApcReturn(frame) mov rbx, [rsp] ; restore original user RBX add rsp, 8 mov rax, SYS_APC_RETURN int 40h SysUserApcDispatcher_Failed: jmp SysUserApcDispatcher_Failed SysUserApcDispatcher ENDP ; --------------------------------------------------------------------------- ; Memory and handles ; --------------------------------------------------------------------------- SYSCALL_STUB2 Alloc, SYS_ALLOC SYSCALL_STUB2 Free, SYS_FREE SYSCALL_STUB2 Realloc, SYS_REALLOC SYSCALL_STUB2 CloseHandle, SYS_CLOSE_HANDLE ; --------------------------------------------------------------------------- ; Synchronization objects ; --------------------------------------------------------------------------- SYSCALL_STUB2 MutexCreate, SYS_MUTEX_CREATE SYSCALL_STUB2 MutexAcquire, SYS_MUTEX_ACQUIRE SYSCALL_STUB2 MutexTryAcquire, SYS_MUTEX_TRY_ACQUIRE SYSCALL_STUB2 MutexRelease, SYS_MUTEX_RELEASE SYSCALL_STUB2 SemCreate, SYS_SEM_CREATE SYSCALL_STUB2 SemWait, SYS_SEM_WAIT SYSCALL_STUB2 SemTryWait, SYS_SEM_TRY_WAIT SYSCALL_STUB2 SemSignal, SYS_SEM_SIGNAL SYSCALL_STUB2 EventCreate, SYS_EVENT_CREATE SYSCALL_STUB2 EventSignal, SYS_EVENT_SIGNAL SYSCALL_STUB2 EventClear, SYS_EVENT_CLEAR SYSCALL_STUB2 EventWait, SYS_EVENT_WAIT ; --------------------------------------------------------------------------- ; Queues and named queues ; --------------------------------------------------------------------------- SYSCALL_STUB2 QueueCreate, SYS_QUEUE_CREATE SYSCALL_STUB2 QueueSend, SYS_QUEUE_SEND SYSCALL_STUB2 QueueRecv, SYS_QUEUE_RECV SYSCALL_STUB2 PublishQueue, SYS_PUBLISH_QUEUE SYSCALL_STUB2 OpenNamedQueue, SYS_OPEN_NAMED_QUEUE SYSCALL_STUB2 QueueDuplicate, SYS_QUEUE_DUPLICATE SYSCALL_STUB2 NamedQueueOwnerPid, SYS_NAMED_QUEUE_OWNER_PID ; --------------------------------------------------------------------------- ; Files, directories, and current directory ; --------------------------------------------------------------------------- SYSCALL_STUB2 OpenFile, SYS_OPEN_FILE SYSCALL_STUB2 CreateFile, SYS_CREATE_FILE SYSCALL_STUB2 ReadFile, SYS_READ_FILE SYSCALL_STUB2 WriteFile, SYS_WRITE_FILE SYSCALL_STUB2 ReadFileAsync, SYS_READ_FILE_ASYNC SYSCALL_STUB2 WriteFileAsync, SYS_WRITE_FILE_ASYNC SYSCALL_STUB2 CancelIo, SYS_CANCEL_IO SYSCALL_STUB2 SeekFile, SYS_SEEK_FILE SYSCALL_STUB2 GetFilePos, SYS_GET_FILE_POS SYSCALL_STUB2 GetFileSize, SYS_GET_FILE_SIZE SYSCALL_STUB2 TruncateFile, SYS_TRUNCATE_FILE SYSCALL_STUB2 DeleteFile, SYS_DELETE_FILE SYSCALL_STUB2 RenameFile, SYS_RENAME_FILE SYSCALL_STUB2 OpenDir, SYS_OPEN_DIR SYSCALL_STUB2 ReadDir, SYS_READ_DIR SYSCALL_STUB2 CreateDir, SYS_CREATE_DIR SYSCALL_STUB2 RemoveDir, SYS_REMOVE_DIR SYSCALL_STUB2 SetCwd, SYS_SET_CWD SYSCALL_STUB2 GetCwd, SYS_GET_CWD ; --------------------------------------------------------------------------- ; Console and graphics ; --------------------------------------------------------------------------- SYSCALL_STUB2 WriteConsole, SYS_WRITE_CONSOLE SYSCALL_STUB6 ScreenBlit, SYS_SCREEN_BLIT SYSCALL_STUB2 ScreenClear, SYS_SCREEN_CLEAR SYSCALL_STUB2 ScreenGetSize, SYS_SCREEN_GET_SIZE SYSCALL_STUB6 ScreenPutChar, SYS_SCREEN_PUT_CHAR ; --------------------------------------------------------------------------- ; Input ; --------------------------------------------------------------------------- SYSCALL_STUB2 KbPoll, SYS_KB_POLL SYSCALL_STUB2 KbIsKeyDown, SYS_KB_IS_KEY_DOWN SYSCALL_STUB2 KbReadChar, SYS_KB_READ_CHAR SYSCALL_STUB2 KbReadScancode, SYS_KB_READ_SCANCODE SYSCALL_STUB2 KbGetModifiers, SYS_KB_GET_MODIFIERS SYSCALL_STUB2 MousePoll, SYS_MOUSE_POLL SYSCALL_STUB2 MouseRead, SYS_MOUSE_READ SYSCALL_STUB2 MouseGetPos, SYS_MOUSE_GET_POS ; --------------------------------------------------------------------------- ; Time and debug ; --------------------------------------------------------------------------- SYSCALL_STUB2 GetTick, SYS_GET_TICK SYSCALL_STUB2 DebugPrint, SYS_DEBUG_PRINT SYSCALL_STUB2 QueryTrapFrame, SYS_QUERY_TRAP_FRAME SYSCALL_STUB6 CatchAllDebugBucket, SYS_CATCHALLDEBUGBUCKET END