Skip to content

Instantly share code, notes, and snippets.

@HoShiMin
Last active November 25, 2021 21:53
Show Gist options
  • Save HoShiMin/9c9d2b89f3efae342631598d0d5c8ed7 to your computer and use it in GitHub Desktop.
Save HoShiMin/9c9d2b89f3efae342631598d0d5c8ed7 to your computer and use it in GitHub Desktop.
Syscalls caller for NativeAPI functions
#pragma once
/*
Depends on:
- Windows.h
Using example:
#include <Windows.h>
#include "Syscalls.h"
int main()
{
HANDLE hNtdll = GetModuleHandle(TEXT("ntdll.dll"));
PVOID NtAlloc = GetProcAddress(hNtdll, "NtAllocateVirtualMemory");
NTSTATUS Status = 0;
PVOID BaseAddress = NULL;
SIZE_T Size = 4097; // PAGE_SIZE + 1
SyscallWithRet(
Status,
GetSyscallIndex(NtAlloc),
NtCurrentProcess(),
&BaseAddress,
NULL,
&Size,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
);
}
*/
#ifdef _AMD64_
#define TEB_SPARE_OFFSET (720)
#define SYSCALL_INDEX_OFFSET (4)
#else
#define TEB_SPARE_OFFSET (428)
#define SYSCALL_INDEX_OFFSET (1)
#endif
static inline PDWORD GetTebSparePtr()
{
// return &TEB->SpareBytes[0] (unused bytes in PEB reserved for alignment):
#ifdef _AMD64_
return (PDWORD)((PBYTE)__readgsqword(0x30) + TEB_SPARE_OFFSET);
#else
return (PDWORD)((PBYTE)__readfsdword(0x18) + TEB_SPARE_OFFSET);
#endif
}
inline DWORD GetSyscallIndex(LPCVOID Function)
{
return *(const DWORD*)((LPCBYTE)Function + SYSCALL_INDEX_OFFSET);
}
extern "C" NTSTATUS CDECL SyscallStub(...);
#define Syscall(Index, ...) \
{ \
PDWORD SpareBytes = GetTebSparePtr(); \
DWORD Original = *SpareBytes; \
*SpareBytes = Index; \
SyscallStub(__VA_ARGS__); \
*SpareBytes = Original; \
}
#define SyscallWithRet(RetValue, Index, ...) \
{ \
PDWORD SpareBytes = GetTebSparePtr(); \
DWORD Original = *SpareBytes; \
*SpareBytes = Index; \
RetValue = SyscallStub(__VA_ARGS__); \
*SpareBytes = Original; \
}
; You should define the 'AMD64' MASM-preprocessor definition
; at the 'General' MASM properties page in the project properties (for the x64 only).
IFNDEF AMD64
.686P
.XMM
.MODEL FLAT, STDCALL
ENDIF
.CODE
IFDEF AMD64
SyscallStub PROC PUBLIC
mov r10, rcx
mov rax, gs:[30h] ; --+
mov eax, [rax + 720] ; --+--> EAX = *(DWORD*)(&TEB->SpareBytes[0]) // Index
syscall
ret
SyscallStub ENDP
ELSE
SyscallStub PROC C PUBLIC
ASSUME FS:NOTHING
mov eax, fs:[18h] ; --+
mov eax, [eax + 428] ; --+--> EAX = *(DWORD*)(&TEB->SpareBytes[0]) // Index
call dword ptr fs:[0C0h] ; ntdll.KiFastSystemCall on x32 or wow64cpu.X86SwitchTo64BitMode on Wow64
ret
SyscallStub ENDP
ENDIF
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment