HWSyscalls Documentation

repository·master·Indexed 20 days ago

https://github.com/dec0ne/hwsyscalls

A C++ library for executing indirect syscalls using hardware breakpoints and Vectored Exception Handlers (VEH) to bypass EDR/AV detections. It creates a synthetic trampoline in kernel32 and utilizes HalosGate to locate syscall numbers and addresses, ensuring the stack remains unwindable.

Tokens
876
Snippets
2
Records
4
Agent score
23%

What's inside HWSyscalls

  1. How HWSyscalls works

    master

    HWSyscalls is a method for executing indirect syscalls designed to bypass EDR/AV detections that look for direct access to ntdll.

    Unlike standard indirect syscalls that jump directly to ntdll, HWSyscalls uses three components to create a synthetic trampoline in kernel32:

    1. Hardware Breakpoints (HWBP) and Vectored Exception Handler (VEH): Used to control the execution flow.
    2. HalosGate: Used to locate syscall numbers (SSNs) and addresses.
    3. Synthetic Trampoline: Created in kernel32 using hardware breakpoints to ensure the execution flow appears legitimate.

    The implementation includes stack manipulation magic to ensure the stack remains unwindable. When a syscall is triggered, it hits a hardware breakpoint in an NTAPI function, creates a new stack frame, and sets the return address to a gadget (e.g., ADD RSP, 68; RET) found in kernel32 or kernelbase. This allows the stack to unwind naturally through kernel32 on the way back from ntdll.

  2. Setup and compilation requirements

    master

    To compile HWSyscalls, ensure you meet the following requirements:

    • IDE: Visual Studio 2019 or newer.
    • Architecture: x64 environments only.
    • Optimization: Must be compiled without optimization.

    To disable optimization in Visual Studio: Go to Project Settings -> C/C++ -> Optimization -> Set Optimization to Disabled (/Od).

  3. Use HWSyscalls in your C++ project

    master

    To integrate HWSyscalls, include HWSyscalls.h and follow this lifecycle:

    1. Call InitHWSyscalls() to find required gadgets and initialize the exception handler.
    2. Use PrepareSyscall to obtain a function pointer for the desired NTAPI function by passing its name as a string.
    3. Cast the returned pointer to the appropriate NTAPI function type and execute it.
    4. Call DeinitHWSyscalls() at the end of the program to remove the exception handler.
    #include "HWSyscalls.h"
    
    typedef NTSTATUS(WINAPI* NtOpenProcess_t)(
    	OUT          PHANDLE            ProcessHandle,
    	IN           ACCESS_MASK        DesiredAccess,
    	IN           POBJECT_ATTRIBUTES ObjectAttributes,
    	IN OPTIONAL  PCLIENT_ID         ClientId);
    
    void main() {
    
        // Initialize the exception handler and find the required gadgets.
        if (!InitHWSyscalls())
            return;
        
        // ...
    
        // Execute your function!
        NtOpenProcess_t pNtOpenProcess = (NtOpenProcess_t)PrepareSyscall((char*)("NtOpenProcess"));
        NTSTATUS status = pNtOpenProcess(&targetHandle, PROCESS_ALL_ACCESS, &object, &clientID);
    
        // ...
    
        // Removing the exception handler.
        DeinitHWSyscalls();
    }
  4. Configure HWSyscalls debug verbosity

    master

    You can enable or disable debug output by modifying the HWSYSCALLS_DEBUG macro within HWSyscalls.h.

    • 0: Debugging disabled.
    • 1: Debugging enabled.
    #define HWSYSCALLS_DEBUG 0 // 0 disable, 1 enable