Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
pe-signgen — Universal signature generation for any system function from all Windows Builds using Winbindex | Kitploit
Tools/GitHubGitHub/forentfraps/pe-signgen
Static AnalysisVulnerability AnalysisReverse EngineeringForensicsMalware AnalysisBinary Analysis
GitHubforentfraps/pe-signgen

pe-signgen

Universal signature generation for any system function from all Windows Builds using Winbindex

View Repository
20489 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Website
Share

pe-signgen

Cross-version binary signatures and RVA offsets for Windows PE functions


Overview

pe-signgen is a tool for reverse engineers and security researchers that automatically generates:

  • Binary signatures (byte patterns with wildcards) for unexported and exported functions
  • RVA and file offsets for locating functions directly in binaries
  • Cross-build signatures that work across many Windows versions
  • Multiple output formats optimized for different use cases
  • Support for x64, ARM64, and WoW64 architectures

The core idea is to provide a systematic, robust way to access unexported functions across Windows 10/11 builds. It leverages:

  • Winbindex for Windows build metadata
  • Microsoft's public symbol servers for PDBs
  • Local caching for reproducible, offline-friendly workflows

⚠️ Windows version support pe-signgen supports Windows 10 and Windows 11 only. This is a deliberate design choice: Winbindex does not provide complete data for older versions.


Use Cases

  • Unexported Windows internals Generate signatures for functions like LdrpInitializeTls, RtlpInsertInvertedFunctionTableEntry, etc.

  • Game hacking / anti-cheat research Generate stable signatures that survive game updates

  • Security research Locate security-critical routines across Windows builds

  • Automation Scriptable signature and offset generation for entire sets of internal APIs


Output Formats

pe-signgen provides three distinct output formats for different use cases:

1. JSON Format

Structured data for automation, scripting, and integration with other tools.

pe-signgen --signature ntdll!NtCreateFile -o ntcreatefile.json --output-format json

Output structure:

{
  "dll_name": "ntdll",
  "function_name": "NtCreateFile",
  "architecture": "x64",
  "generated": "2024-12-11T15:30:00.123456",
  "total_builds": 1247,
  "unique_signatures": 3,
  "signature_groups": [
    {
      "matched_symbol": "NtCreateFile",
      "signature": "4C 8B DC 49 89 5B 08 49 89 6B 10 49 89 73 18 ...",
      "length": 48,
      "build_count": 845,
      "versions": [
        { "major": 10240, "minor": 16384, "build": "10240.16384" },
        { "major": 10586, "minor": 0, "build": "10586.0" }
      ]
    }
  ]
}

Notes:

  • major and minor are derived from the build string by splitting at the first .. Example: "10240.16384" → major = 10240, minor = 16384.
  • build is the original build string key used internally.

2. Binary Format (WSIG/WOFF)

Compact, runtime-ready binary formats optimized for embedded systems and low-overhead scanning.

These match the on-disk layout implemented in write_wsig() and write_woff().


WSIG Format (Windows Signature)

Magic: WSO\0 (0x57 0x53 0x4F 0x00) Current Version: 1 Purpose: Store binary signatures with wildcard masks and associated Windows build versions

File Structure (conceptual)
┌─────────────────────────────────────┐
│         Header (36 bytes)           │
├─────────────────────────────────────┤
│      DLL Name (variable)            │
├─────────────────────────────────────┤
│    Function Name (variable)         │
├─────────────────────────────────────┤
│   Signature / Mask / Build blobs    │ ← Arbitrary order, see notes
├─────────────────────────────────────┤ ← Aligned to 4 bytes
│   Groups Table (24 × N bytes)       │
└─────────────────────────────────────┘

Important layout notes (matches write_wsig)

  • After the header, the DLL and function names are written as UTF‑8 bytes.
  • For each signature group, the pattern bytes and mask bytes are written, followed by the build array for that group.
  • These per-group regions are not grouped globally by type: patterns, masks, and build arrays may be interleaved.
  • The builder aligns to 4 bytes before each build array and before the groups table. This can introduce padding.
  • Consumers must always follow the offsets in the header and group entries; do not rely on the conceptual diagram for physical contiguity.
Header Layout (36 bytes)
// Packed as: "<4sIIIIIIII" (little-endian)

typedef struct {
    char     magic[4];   // "WSO\0" (WSIG_MAGIC)
    uint32_t version;    // FORMAT_VERSION (currently 1)
    uint32_t arch;       // Architecture code (1=x64, 2=ARM64, 3=WoW64)
    uint32_t dll_off;    // Offset to DLL name string
    uint32_t dll_len;    // Length of DLL name in bytes
    uint32_t func_off;   // Offset to function name string
    uint32_t func_len;   // Length of function name in bytes
    uint32_t group_count;// Number of signature groups
    uint32_t groups_off; // Offset to groups table
} wsig_header_t; // 36 bytes
Group Entry (24 bytes)

Each signature group represents a unique pattern that applies to one or more Windows builds.

// Packed as: "<IIIIII" (little-endian)

typedef struct {
    uint32_t sig_off;    // Offset to signature pattern bytes
    uint32_t sig_len;    // Length of signature pattern (in bytes)
    uint32_t mask_off;   // Offset to wildcard mask bytes
    uint32_t mask_len;   // Length of wildcard mask (≈ ceil(sig_len/8))
    uint32_t builds_off; // Offset to build version array
    uint32_t build_cnt;  // Number of builds using this signature
} wsig_group_t; // 24 bytes
Build Version Entry (8 bytes)

Each build entry identifies a specific Windows version that uses this signature.

typedef struct {
    uint32_t major; // e.g. 19041
    uint32_t minor; // e.g. 1234
} wsig_build_t; // 8 bytes

major and minor come from splitting the build string ("A.B" → A, B). The original build string is not stored in the binary format; if you need it, keep it externally (it is present in the JSON output).

Wildcard Mask Format

The mask is a bitmask where each bit corresponds to a byte in the signature pattern:

  • Bit = 1: Byte must match exactly (fixed byte)
  • Bit = 0: Byte is wildcarded (ignore this byte during matching)

Example:

Signature: 4C 8B DC 49 89 ?? 08 49
Mask bits: 1  1  1  1  1  0  1  1  (MSB first within each byte)
Mask byte: 0xBF (binary: 10111111)

Mask bytes are stored and interpreted in little-endian bit order within each byte (exactly as used in the C helpers and parse_signature):

uint8_t bit = (mask_bytes[byte_index >> 3] >> (byte_index & 7)) & 1u;
String Storage
  • DLL and function names are stored as UTF‑8, without null terminators.
  • Use *_len to determine the length; do not read past that.
  • There are no alignment requirements for the strings themselves.
  • Additional data regions (build arrays and the groups table) are aligned to 4‑byte boundaries; treat any padding as opaque.

WOFF Format (Windows Offset)

Magic: WOF\0 (0x57 0x4F 0x46 0x00) Current Version: 1 Purpose: Store direct RVA and file offsets for functions across Windows builds

File Structure
┌─────────────────────────────────────┐
│         Header (36 bytes)           │
├─────────────────────────────────────┤
│      DLL Name (variable)            │
├─────────────────────────────────────┤
│    Function Name (variable)         │
├─────────────────────────────────────┤
│ Matched Symbol Names (variable)     │ ← One UTF‑8 string per entry
├─────────────────────────────────────┤ ← Aligned to 4 bytes
│   Entries Table (32 × N bytes)      │
└─────────────────────────────────────┘

Layout details (matches write_woff):

  • After the header placeholder, the DLL and function names are written as UTF‑8 bytes.
  • For each build, the matched symbol name is written as a UTF‑8 string (no terminator). These form a simple string pool.
  • The writer then aligns to 4 bytes and writes the fixed-size entries table.
  • Each entry contains offsets (matched_off, matched_len) pointing into this string pool.
Download Tool