Last active
November 25, 2021 21:53
-
-
Save HoShiMin/9c9d2b89f3efae342631598d0d5c8ed7 to your computer and use it in GitHub Desktop.
Syscalls caller for NativeAPI functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; \ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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