> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/JoasASantos/SysWhispers4/llms.txt
> Use this file to discover all available pages before exploring further.

# Updating Syscall Tables

> How to update syscall numbers from j00ru's repository for new Windows builds

## 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.

<Note>
  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.
</Note>

***

## Why Update Tables?

### When Syscall Numbers Change

Microsoft occasionally changes syscall numbers between builds:

```c theme={null}
// Windows 11 22H2 (build 22621)
NtCreateThreadEx = 0xC6

// Windows 11 23H2 (build 22631)
NtCreateThreadEx = 0xC7  // ← Changed!
```

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)

```bash theme={null}
cd SysWhispers4
python scripts/update_syscall_table.py
```

**Output:**

```
  [~] Fetching: https://raw.githubusercontent.com/j00ru/windows-syscalls/master/x64/csv/nt.csv
  [+] Written 183 functions (x64) → data/syscalls_nt_x64.json
  [+] Syscall table update complete.
```

### Update Both x64 and x86

```bash theme={null}
python scripts/update_syscall_table.py --arch x64,x86
```

**Output:**

```
  [~] Fetching: https://raw.githubusercontent.com/j00ru/windows-syscalls/master/x64/csv/nt.csv
  [+] Written 183 functions (x64) → data/syscalls_nt_x64.json
  [~] Fetching: https://raw.githubusercontent.com/j00ru/windows-syscalls/master/x86/csv/nt.csv
  [+] Written 231 functions (x86) → data/syscalls_nt_x86.json
  [+] Syscall table update complete.
```

***

## Command-Line Options

### Architecture Selection

```bash theme={null}
# x64 only (default)
python scripts/update_syscall_table.py --arch x64

# x86 only
python scripts/update_syscall_table.py --arch x86

# Both
python scripts/update_syscall_table.py --arch x64,x86
```

### Custom Output Path

```bash theme={null}
# Write to custom location instead of data/
python scripts/update_syscall_table.py --out custom_syscalls.json
```

### Filter Specific Functions

```bash theme={null}
# Only update specific functions (useful for testing)
python scripts/update_syscall_table.py \
    --functions NtAllocateVirtualMemory,NtCreateThreadEx,NtWriteVirtualMemory
```

***

## Script Internals

### Data Source

The script fetches CSV files from [j00ru/windows-syscalls](https://github.com/j00ru/windows-syscalls):

```python theme={null}
CSV_URLS = {
    "x64": "https://raw.githubusercontent.com/j00ru/windows-syscalls/master/x64/csv/nt.csv",
    "x86": "https://raw.githubusercontent.com/j00ru/windows-syscalls/master/x86/csv/nt.csv",
}
```

j00ru's repository is the **authoritative source** for Windows syscall research, maintained since Windows NT 3.1.

### CSV Format (j00ru)

**Example x64 CSV header:**

```csv theme={null}
Function Name,Windows 7 (SP1),Windows 10 (1507),Windows 10 (1903),Windows 11 and Server (11 24H2),...
NtAllocateVirtualMemory,24,24,24,24,...
NtCreateThreadEx,166,189,199,198,...
```

Each row = NT function, each column = Windows build.

### Parsing Logic

```python theme={null}
def parse_joru_csv(csv_text: str) -> dict:
    reader = csv.reader(io.StringIO(csv_text))
    rows = list(reader)
    header = rows[0]  # Column headers = Windows versions
    
    result = {
        "_comment": "NT syscall numbers — generated by SysWhispers4",
        "_source": "https://github.com/j00ru/windows-syscalls",
        "_windows_builds": {},
    }
    
    # Map human-readable version strings to build keys
    for col in range(1, len(header)):
        version_str = header[col]  # e.g., "Windows 11 and Server (11 24H2)"
        build_key, display_label = parse_version(version_str)  # → ("26100", "Windows 11 24H2")
        result["_windows_builds"][build_key] = display_label
    
    # Parse function rows
    for row in rows[1:]:
        func_name = row[0]
        if not func_name.startswith("Nt"):
            continue  # Skip non-NT functions
        
        func_entry = {}
        for col, build_key in enumerate(build_keys, start=1):
            ssn_str = row[col].strip()
            if ssn_str and ssn_str not in ("", "n/a", "-"):
                ssn = int(ssn_str, 16) if ssn_str.startswith("0x") else int(ssn_str)
                func_entry[build_key] = ssn
        
        result[func_name] = func_entry
    
    return result
```

### Version Mapping

The script maps j00ru's human-readable column headers to short build keys:

```python theme={null}
VER_MAP = {
    "Windows 7 (SP1)": ("7_sp1", "Windows 7 SP1"),
    "Windows 10 (1507)": ("10240", "Windows 10 1507 (build 10240)"),
    "Windows 10 (1903)": ("18362", "Windows 10 1903 (build 18362)"),
    "Windows 11 and Server (11 24H2)": ("26100", "Windows 11 24H2 (build 26100)"),
    "Windows 11 and Server (Server 2025)": ("26100_srv", "Windows Server 2025 (build 26100)"),
    # ... full list in source
}
```

**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

```json theme={null}
{
  "_comment": "NT syscall numbers — generated by SysWhispers4/scripts/update_syscall_table.py",
  "_source": "https://github.com/j00ru/windows-syscalls",
  "_format": "FunctionName -> { build_key -> decimal_ssn }",
  "_windows_builds": {
    "7_sp1": "Windows 7 SP1",
    "10240": "Windows 10 1507 (build 10240)",
    "18362": "Windows 10 1903 (build 18362)",
    "22000": "Windows 11 21H2 (build 22000)",
    "26100": "Windows 11 24H2 (build 26100)",
    "26100_srv": "Windows Server 2025 (build 26100)"
  },
  "NtAllocateVirtualMemory": {
    "7_sp1": 24,
    "10240": 24,
    "18362": 24,
    "22000": 24,
    "26100": 24
  },
  "NtCreateThreadEx": {
    "7_sp1": 166,
    "10240": 189,
    "18362": 199,
    "22000": 197,
    "26100": 198
  },
  ...
}
```

### Metadata Keys

| Key               | Purpose                                  |
| ----------------- | ---------------------------------------- |
| `_comment`        | Describes file origin                    |
| `_source`         | Link to j00ru's repository               |
| `_format`         | Explains data structure                  |
| `_windows_builds` | Maps build keys to human-readable labels |

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

***

## How SysWhispers4 Uses the Table

### Static Resolution (`--resolve static`)

```python theme={null}
# In generator.py
def gen_ssn_table(self):
    build_key = self.get_target_build_key()  # e.g., "22000" for Win11 21H2
    ssn_table = load_syscall_table(self.arch)  # Load data/syscalls_nt_x64.json
    
    code = "DWORD SW4_SsnTable[] = {\n"
    for func in self.functions:
        if func.name in ssn_table and build_key in ssn_table[func.name]:
            ssn = ssn_table[func.name][build_key]
            code += f"    {ssn},  // {func.name}\n"
        else:
            code += f"    0xFFFFFFFF,  // {func.name} (unavailable)\n"
    code += "};\n"
    return code
```

**Generated code:**

```c theme={null}
DWORD SW4_SsnTable[] = {
    24,   // NtAllocateVirtualMemory
    198,  // NtCreateThreadEx
    58,   // NtWriteVirtualMemory
    // ...
};
```

### Runtime Build Detection

To support multiple Windows versions with one binary, use dynamic resolution instead:

```bash theme={null}
# Instead of static:
python syswhispers.py --preset common --resolve static

# Use FreshyCalls (works on any version):
python syswhispers.py --preset common --resolve freshycalls
```

**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:

```bash theme={null}
# Visit j00ru's repo
https://github.com/j00ru/windows-syscalls

# Look for new CSV columns
https://github.com/j00ru/windows-syscalls/blob/master/x64/csv/nt.csv
```

**Step 2:** Run the update script

```bash theme={null}
cd SysWhispers4
python scripts/update_syscall_table.py --arch x64,x86
```

**Step 3:** Verify new build in output

```bash theme={null}
# Check data/syscalls_nt_x64.json
cat data/syscalls_nt_x64.json | jq '._windows_builds'

# Should show new entry:
{
  ...
  "26200": "Windows 11 25H2 (build 26200)"
}
```

**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`:

```python theme={null}
VER_MAP = {
    # ... existing entries
    "Windows 11 and Server (11 25H2)": ("26200", "Windows 11 25H2 (build 26200)"),
}
```

**Step 5:** Test generation

```bash theme={null}
python syswhispers.py --preset common --resolve static

# Verify generated code
grep -A 5 "SW4_SsnTable" SW4Syscalls.c
```

**Step 6:** Commit changes

```bash theme={null}
git add data/syscalls_nt_x64.json data/syscalls_nt_x86.json
git commit -m "Update syscall tables for Windows 11 25H2 (build 26200)"
```

***

## Troubleshooting

### Script Fails to Fetch CSV

**Error:**

```
[!] Failed to fetch https://raw.githubusercontent.com/...: URLError
```

**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:**

```
Unknown version string: "Windows 12 (Beta)"
```

**Solution:**
Add to `VER_MAP` in `update_syscall_table.py`:

```python theme={null}
VER_MAP = {
    # ...
    "Windows 12 (Beta)": ("27000", "Windows 12 Beta (build 27000)"),
}
```

### SSN Mismatch After Update

**Symptom:** Binary crashes with `STATUS_INVALID_SYSTEM_SERVICE` after regenerating stubs.

**Diagnosis:**

```bash theme={null}
# Check what build number the system reports
powershell "[System.Environment]::OSVersion.Version"

# Example output: 10.0.26100.0
# Build number = 26100

# Verify SSN table has entry for 26100
cat data/syscalls_nt_x64.json | jq '.NtAllocateVirtualMemory["26100"]'
```

**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

```
kd> u ntdll!NtAllocateVirtualMemory L5
ntdll!NtAllocateVirtualMemory:
00007ffe`12345678 4c8bd1          mov     r10,rcx
00007ffe`1234567b b818000000      mov     eax,18h     ← SSN = 0x18 (24 decimal)
00007ffe`12345680 f604250803fe7f01 test byte ptr [SharedUserData+0x308],1
00007ffe`12345688 7503            jne     ntdll!NtAllocateVirtualMemory+0x15
00007ffe`1234568a 0f05            syscall
```

**Extract for all functions:**

```
kd> .foreach (func {!for_each_function ntdll Nt*}) { u ntdll!${func} L3; .echo ${func} }
```

### Manual JSON Entry

```json theme={null}
{
  "NtAllocateVirtualMemory": {
    "26100": 24,   // ← Manually add new build
    "22000": 24,
    "18362": 24
  }
}
```

**When to use:**

* j00ru hasn't updated yet
* Testing on preview/insider builds
* Custom Windows builds

***

## Best Practices

### 1. Use Dynamic Resolution for Production

```bash theme={null}
# Instead of brittle static tables:
python syswhispers.py --preset common --resolve static

# Use version-agnostic methods:
python syswhispers.py --preset common --resolve freshycalls  # or recycled, from_disk
```

**Why:**

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

### 2. Update Tables Before Engagements

```bash theme={null}
# Before red team operation, ensure tables are current:
python scripts/update_syscall_table.py --arch x64,x86
```

### 3. Version Control Your Tables

```bash theme={null}
# Track changes to syscall numbers over time
git log -p data/syscalls_nt_x64.json

# See when NtCreateThreadEx changed:
git log -p -S "NtCreateThreadEx" data/syscalls_nt_x64.json
```

### 4. Automate Updates (CI/CD)

```yaml theme={null}
# GitHub Actions example
name: Update Syscall Tables
on:
  schedule:
    - cron: '0 0 * * 0'  # Weekly

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
      - run: python scripts/update_syscall_table.py --arch x64,x86
      - uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "chore: update syscall tables"
```

***

## Table Coverage

### Current Coverage (Default Tables)

| OS                 | Builds Included                         |
| ------------------ | --------------------------------------- |
| **Windows 7**      | SP1 (7601)                              |
| **Windows 8**      | 8.0 (9200), 8.1 (9600)                  |
| **Windows 10**     | 1507 (10240) → 22H2 (19045) — 14 builds |
| **Windows 11**     | 21H2 (22000) → 24H2 (26100) — 4 builds  |
| **Windows Server** | 2022 (20348), 2025 (26100)              |

### x86-Specific (Legacy Coverage)

| OS                            | Builds Included               |
| ----------------------------- | ----------------------------- |
| **Windows NT**                | 3.1, 3.5, 3.51, 4.0 (SP0-SP6) |
| **Windows 2000**              | SP0-SP4                       |
| **Windows XP**                | SP0-SP3                       |
| **Windows Server 2003**       | RTM, SP1, SP2, R2, R2 SP2     |
| **Windows Vista**             | RTM, SP1, SP2                 |
| All modern builds same as x64 |                               |

***

## 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:**
   ```python theme={null}
   # In update_syscall_table.py
   import ssl
   context = ssl.create_default_context()
   context.check_hostname = True
   context.verify_mode = ssl.CERT_REQUIRED
   ```

2. **Manual verification:**
   ```bash theme={null}
   # After update, spot-check a few known SSNs
   # NtAllocateVirtualMemory on Win11 22H2 should be 24 (0x18)
   cat data/syscalls_nt_x64.json | jq '.NtAllocateVirtualMemory["22621"]'
   ```

3. **Use local copy:**
   ```bash theme={null}
   # Clone j00ru's repo locally
   git clone https://github.com/j00ru/windows-syscalls

   # Modify script to read from local CSV
   python scripts/update_syscall_table.py --local-csv windows-syscalls/x64/csv/nt.csv
   ```

***

## 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:

```bash theme={null}
git checkout -b update-syscall-tables
python scripts/update_syscall_table.py --arch x64,x86
git add data/syscalls_nt_*.json
git commit -m "Update syscall tables for Windows 11 25H2"
git push origin update-syscall-tables
# Open PR on GitHub
```

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

The JSON will omit that build:

```json theme={null}
{
  "NtAllocateVirtualMemoryEx": {
    "19041": 118,  // Added in Win10 2004
    "22000": 119,
    // No entries for Win7, Win8 (function didn't exist)
  }
}
```

Generated code handles this:

```c theme={null}
if (build_key in table) {
    ssn = table[func_name][build_key];
} else {
    ssn = 0xFFFFFFFF;  // Marker for unavailable
}
```

***

## Next Steps

* [Project Structure](/advanced/project-structure) - Understand the codebase
* [Recommended Configurations](/advanced/recommended-configs) - See usage examples
* [j00ru's Windows Syscalls Repository](https://github.com/j00ru/windows-syscalls) - Upstream data source
