Skip to content

Instantly share code, notes, and snippets.

@IgorYunusov
Forked from HoShiMin/SyscallStub.asm
Created January 21, 2021 11:59
Show Gist options
  • Save IgorYunusov/ea60622901065b3acffef2402f8c657c to your computer and use it in GitHub Desktop.
Save IgorYunusov/ea60622901065b3acffef2402f8c657c 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 to 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