This guide will walk you through creating your first program using syscalls-cpp. You’ll learn how to initialize a syscall manager and invoke system calls directly.
This single header provides access to all syscall management functionality.
2
Create a syscall manager
Instantiate a syscall::Manager with your chosen policies:
int main() { // Create a manager with section-based allocation and direct syscalls syscall::Manager< syscall::policies::allocator::section, syscall::policies::generator::direct > syscallManager;
The Manager template takes two required parameters:
Allocation Policy: How memory for stubs is allocated
Stub Generation Policy: How syscall instructions are generated
An optional third parameter specifies parsing policies (defaults to directory with signature fallback).
3
Initialize the manager
Before invoking syscalls, initialize the manager to parse system call numbers:
if (!syscallManager.initialize()) { std::cerr << "initialization failed!\n"; return 1; }
By default, initialize() parses ntdll.dll. You can parse additional modules:
Always use nullptr instead of NULL when invoking syscalls on x64.The NULL macro is often defined as 0 (a 32-bit int). Passing it to a syscall expecting a 64-bit pointer can corrupt the stack, causing argument misalignment and crashes.nullptr is type-safe and guarantees the correct 64-bit null pointer representation.
// ❌ Bad - may crash on x64manager.invoke<NTSTATUS>( SYSCALL_ID("NtClose"), NULL // Dangerous!);// ✅ Good - type-safemanager.invoke<NTSTATUS>( SYSCALL_ID("NtClose"), nullptr // Safe);