Short-circuiting the Windows API for direct syscall execution.
This is a Zig library designed for direct syscall execution by dynamically resolving System Service Numbers (SSNs) and executing syscalls through legitimate memory instructions.
Read the technical deep dive on the implementation here.
- Hell's Gate: Dynamic SSN resolution by parsing DLL Export Address Table.
- TartarusGate: Neighboring syscall analysis to recover SSNs when a target function is hooked.
- Hell's Hall: Indirect syscall execution by searching for clean syscall; ret gadgets in DLL memory to bypass instruction-level monitoring.
- Comptime Stealth: CRC32 Hashing for both function names and module names at compile-time with a user-configurable seed. No sensitive strings remain in the binary.
- Dynamic Module Lookup: Find any already-loaded Windows DLL (ntdll.dll, kernel32.dll, etc.) by walking the PEB loader list, identified by hash rather than plaintext name.
Add zcircuit to your build.zig.zon:
zig fetch --save git+https://github.com/Hiroki6/zcircuitThen in your build.zig:
const zcircuit = b.dependency("zcircuit", .{});
exe.root_module.addImport("zcircuit", zcircuit.module("zcircuit"));const std = @import("std");
const zc = @import("zcircuit");
pub fn main() !void {
// Initialize with custom seed for compile-time string hashing
// Specify the already-loaded DLL to look up (ntdll.dll, kernel32.dll, etc.)
const MyCircuit = zc.Zcircuit(.{ .seed = 0xABCD1234 });
var circuit = try MyCircuit.init("ntdll.dll");
// Execute syscall directly in one line
const status = circuit.syscall("NtAllocateVirtualMemory", .{
process_handle,
&base_addr,
0,
&size,
0x3000, // MEM_COMMIT | MEM_RESERVE
0x04, // PAGE_READWRITE
});
if (status == std.os.windows.NTSTATUS.SUCCESS) {
std.debug.print("[+] Memory allocated at: 0x{x}\n", .{base_addr});
}
}Use this when you need more control or want to reuse the same syscall:
// Resolve syscall by name with custom options
const nt_allocate = circuit.getSyscall("NtAllocateVirtualMemory", .{
.search_neighbor = true, // Enable TartarusGate
.indirect_syscall = true, // Enable Hell's Hall
}) orelse return;
// Call multiple times without re-resolving
const status1 = nt_allocate.call(.{...});
const status2 = nt_allocate.call(.{...});For a complete example, see the example directory.
> inject_shellcode.exe
[+] Resolved NtAllocateVirtualMemory -> SSN: 0x18, Base: 0x7FFE4410D9A2
[+] Memory allocated at: 0x26afad10000
[+] Resolved NtProtectVirtualMemory -> SSN: 0x50, Base: 0x7FFE4410E0A2
[+] Memory protected!
[+] Resolved NtCreateThreadEx -> SSN: 0xC2, Base: 0x7FFE4410EED2
[+] Thread created!
[+] Resolved NtWaitForSingleObject -> SSN: 0x04, Base: 0x7FFE4410D722This project is a Zig implementation and refinement of several pioneering research techniques.
- Hell's Gate: The original technique for dynamic SSN extraction.
- TartarusGate: Improved SSN recovery via neighboring stubs.
- Hell's Hall: Indirect syscall instruction searching.
- Bananaphone: A major inspiration for the API design.
This tool is for educational purposes and authorized security auditing only. The author is not responsible for any misuse of this software.
