Skip to main content

Overview

SysWhispers4 includes syscall tables for Windows 7 through Windows 11 24H2. When Microsoft releases new Windows builds, syscall numbers can change. This guide shows how to update the tables using the included update_syscall_table.py script.
This is only necessary if you’re using --resolve static (embedded syscall numbers). Dynamic methods like FreshyCalls, Halo’s Gate, etc. automatically adapt to any Windows version.

Why Update Tables?

When Syscall Numbers Change

Microsoft occasionally changes syscall numbers between builds:
If your embedded table has the wrong number, the syscall will:
  • Call the wrong kernel function (undefined behavior)
  • Trigger an invalid syscall exception
  • Return STATUS_INVALID_SYSTEM_SERVICE

New Windows Builds

Recent builds not in the default table:
  • Windows 11 25H2 (build 26200) - Released Q2 2026
  • Windows Server 2025 (build 26100) - Released late 2024
  • Future builds (use the update script to stay current)

Quick Start

Update x64 Table (Default)

Output:

Update Both x64 and x86

Output:

Command-Line Options

Architecture Selection

Custom Output Path

Filter Specific Functions


Script Internals

Data Source

The script fetches CSV files from j00ru/windows-syscalls:
j00ru’s repository is the authoritative source for Windows syscall research, maintained since Windows NT 3.1.

CSV Format (j00ru)

Example x64 CSV header:
Each row = NT function, each column = Windows build.

Parsing Logic

Version Mapping

The script maps j00ru’s human-readable column headers to short build keys:
Why use build numbers instead of version names?
  • Consistent across x64/x86
  • Unambiguous (“22H2” exists for both Win10 and Win11)
  • Easier to match against RtlGetVersion() output

Output Format

JSON Structure

Metadata Keys

Metadata keys are ignored during generation (filtered by key.startswith("_") check).

How SysWhispers4 Uses the Table

Static Resolution (--resolve static)

Generated code:

Runtime Build Detection

To support multiple Windows versions with one binary, use dynamic resolution instead:
Why: FreshyCalls sorts exports by virtual address — the sorted index is the syscall number. Works on:
  • Windows 7 → 11 (any build)
  • Future versions (no table update needed)

Workflow: Updating for New Windows Release

Scenario: Windows 11 25H2 Just Released

Step 1: Wait for j00ru to update his repository j00ru typically updates within 1-2 weeks of a new build release. Check:
Step 2: Run the update script
Step 3: Verify new build in output
Step 4: Update version mapping (if needed) If the script doesn’t recognize the new build name, add it to VER_MAP in update_syscall_table.py:
Step 5: Test generation
Step 6: Commit changes

Troubleshooting

Script Fails to Fetch CSV

Error:
Solutions:
  1. Check internet connection
  2. Verify j00ru’s repo is accessible (not moved/deleted)
  3. Check firewall/proxy settings
  4. Use --out to write to accessible location

Unknown Build in CSV

Warning:
Solution: Add to VER_MAP in update_syscall_table.py:

SSN Mismatch After Update

Symptom: Binary crashes with STATUS_INVALID_SYSTEM_SERVICE after regenerating stubs. Diagnosis:
Fix:
  • If missing, run update_syscall_table.py again
  • If present, verify you’re using the correct build key in generator logic

Alternative: Manual Table Creation

Use WinDbg to Extract SSNs

Extract for all functions:

Manual JSON Entry

When to use:
  • j00ru hasn’t updated yet
  • Testing on preview/insider builds
  • Custom Windows builds

Best Practices

1. Use Dynamic Resolution for Production

Why:
  • Works on any Windows version (past, present, future)
  • No table updates needed
  • More resilient against hooks

2. Update Tables Before Engagements

3. Version Control Your Tables

4. Automate Updates (CI/CD)


Table Coverage

Current Coverage (Default Tables)

x86-Specific (Legacy Coverage)


Security Considerations

Trust in j00ru’s Data

The update script trusts data from j00ru’s GitHub repository. Risks:
  • GitHub account compromise
  • Man-in-the-middle attack (if not using HTTPS)
  • Malicious data injection
Mitigations:
  1. Verify SSL certificate:
  2. Manual verification:
  3. Use local copy:

FAQ

Do I need to update tables for dynamic resolution methods?

No. FreshyCalls, Halo’s Gate, Tartarus’ Gate, RecycledGate, etc. automatically determine SSNs at runtime. Tables are only needed for --resolve static.

How often does Microsoft change syscall numbers?

Rarely within a major version. Typically only between major releases (Win10 → Win11) or significant feature updates. Example stability:
  • NtAllocateVirtualMemory = 24 (0x18) on every Windows 10 build (1507-22H2)
  • NtCreateThreadEx varies: 189 (1507) → 199 (1903) → 197 (Win11 21H2)

Can I contribute updated tables back to SysWhispers4?

Yes! Submit a PR with updated JSON files:

What if a function doesn’t exist on an older Windows version?

The JSON will omit that build:
Generated code handles this:

Next Steps