Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
pe-signgen — 使用Winbindex为所有Windows版本中的任意系统函数生成通用签名 | Kitploit
工具/GitHubGitHub/forentfraps/pe-signgen
静态分析漏洞分析逆向工程取证分析恶意软件分析二进制分析
GitHubforentfraps/pe-signgen

pe-signgen

使用Winbindex为所有Windows版本中的任意系统函数生成通用签名

查看仓库
20489个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

pe-signgen

跨版本二进制签名和 Windows PE 函数的 RVA 偏移量


概述

pe-signgen 是一款面向逆向工程师和安全研究人员的工具,可自动生成:

  • 未导出和导出函数 的 二进制签名(含通配符的字节模式)
  • 用于直接在二进制文件中定位函数的 RVA 和文件偏移量
  • 可在多种 Windows 版本中工作的 跨构建签名
  • 针对不同用例优化的 多种输出格式
  • 支持 x64、ARM64 和 WoW64 架构

核心思想 是提供一种 系统化、可靠的方式来访问未导出函数,跨越 Windows 10/11 构建版本。它利用:

  • Winbindex 获取 Windows 构建元数据
  • Microsoft 的公共符号服务器获取 PDB
  • 本地缓存,实现可重现且离线友好的工作流程

⚠️ Windows 版本支持 pe-signgen 仅支持 Windows 10 和 Windows 11。 这是一个经过深思熟虑的设计选择:Winbindex 并未为较旧版本提供完整数据。


使用案例

  • 未导出的 Windows 内部函数 为 LdrpInitializeTls、RtlpInsertInvertedFunctionTableEntry 等函数生成签名。

  • 游戏外挂 / 反作弊研究 生成在游戏更新后仍稳定的签名。

  • 安全研究 跨越 Windows 构建版本定位安全关键例程。

  • 自动化 为整组内部 API 提供可脚本化的签名和偏移量生成。


输出格式

pe-signgen 针对不同用例提供三种不同的输出格式:

1. JSON 格式

适用于自动化、脚本编写以及与其他工具集成的结构化数据。```bash pe-signgen --signature ntdll!NtCreateFile -o ntcreatefile.json --output-format json

**输出结构:**```json
{
  "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" }
      ]
    }
  ]
}

注意:

  • major和minor是从构建字符串中通过分割第一个点得到的。 示例:"10240.16384" → major = 10240, minor = 16384。
  • build是内部使用的原始构建字符串键。

2. 二进制格式 (WSIG/WOFF)

紧凑的、运行时就绪的二进制格式,针对嵌入式系统和低开销扫描进行了优化。

这些匹配write_wsig()和write_woff()中实现的磁盘布局。


WSIG 格式(Windows 签名)

魔数: WSO\0 (0x57 0x53 0x4F 0x00) 当前版本: 1 用途: 存储带有通配符掩码和相关Windows构建版本的二进制签名。

文件结构(概念性)```

┌─────────────────────────────────────┐ │ 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) │ └─────────────────────────────────────┘

**重要布局说明(与 `write_wsig` 匹配)**

* 在头部之后,DLL 和函数名称以 UTF‑8 字节形式写入。
* 对于每个签名组,依次写入模式字节和掩码字节,然后是该组的构建数组。
* 这些每组区域**不**按类型全局分组:模式、掩码和构建数组可能交错排列。
* 构建器在每个构建数组之前以及组表之前会进行 **4 字节** 对齐。这可能会引入填充。
* 消费者**始终**必须遵循头部和组条目中的偏移量;**不要**依赖概念图来获得物理连续性。

##### 头部布局(36 字节)```c
// 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
组条目 (24 bytes)

每个签名组表示一个独特的模式,适用于一个或多个Windows构建版本。```c // 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

##### 构建版本条目(8 字节)

每个构建条目标识一个使用此签名的特定 Windows 版本。```c
typedef struct {
    uint32_t major; // e.g. 19041
    uint32_t minor; // e.g. 1234
} wsig_build_t; // 8 bytes

major 和 minor 来自构建字符串的拆分 ("A.B" → A, B)。原始构建字符串不存储在二进制格式中;如果需要,请将其保留在外部(它存在于 JSON 输出中)。

通配符掩码格式

该掩码是一个 位掩码,其中每个位对应签名模式中的一个字节:

  • 位 = 1: 字节必须完全匹配(固定字节)
  • 位 = 0: 字节被通配(匹配时忽略此字节)

示例:``` 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)

掩码字节以**小端位序**在每个字节内存储和解释(与C辅助函数和`parse_signature`中的用法完全相同):```c
uint8_t bit = (mask_bytes[byte_index >> 3] >> (byte_index & 7)) & 1u;
字符串存储
  • DLL 和函数名称以 UTF‑8 格式存储,不带空终止符。
  • 使用 *_len 确定长度;不要读取超过该长度。
  • 字符串本身没有对齐要求。
  • 其他数据区域(构建数组和组表)按 4 字节边界对齐;将任何填充视为不透明。

WOFF 格式(Windows 偏移)

魔数: WOF\0 (0x57 0x4F 0x46 0x00) 当前版本: 1 目的: 存储跨 Windows 构建版本的函数的直接 RVA 和文件偏移

文件结构```

┌─────────────────────────────────────┐ │ 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) │ └─────────────────────────────────────┘

布局细节(与 `write_woff` 匹配):

* 在头部占位符之后,DLL 和函数名称以 UTF‑8 字节写入。
* 对于每个构建,匹配的符号名称以 UTF‑8 字符串写入(无终止符)。这些组成一个简单的字符串池。
* 写入器随后进行 4 字节对齐,并写入固定大小的条目表。
* 每个条目包含指向该字符串池的偏移量(`matched_off`、`matched_len`)。

##### 头部布局(36 字节)```c
// Packed as: "<4sIIIIIIII" (little-endian)

typedef struct {
    char     magic[4];   // "WOF\0" (WOFF_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 entry_cnt;  // Number of offset entries
    uint32_t entries_off;// Offset to entries table
} woff_header_t; // 36 bytes
偏移条目 (32 bytes)

每个条目将一个 Windows 构建版本映射到该构建版本中函数的位置。```c // Packed as: "<IIQQII" (little-endian)

typedef struct { uint32_t major; // Windows major version (e.g., 19041) uint32_t minor; // Windows minor version (e.g., 1234) uint64_t rva; // Relative Virtual Address in the DLL uint64_t file_offset; // Raw file offset in the DLL on disk uint32_t matched_off; // Offset to matched symbol name string uint32_t matched_len; // Length of matched symbol name } woff_entry_t; // 32 bytes

##### 使用说明

* **RVA** 是 DLL 以其首选基址加载时的内存偏移量。
* **文件偏移量** 是磁盘上 PE 文件中的原始位置。
* **匹配的符号** 可能与请求的函数不同(例如,转发的导出)。
  该字符串在字符串池中只存储一次;`matched_off`/`matched_len` 引用它。
* 条目按**构建版本**(先 `major`,后 `minor`)排序,以提高查找效率。

---

#### 架构代码

两种二进制格式使用相同的架构编码(通过 `ARCH_CODE_MAP`):

| 代码 | 架构 | 描述                       |
| ---- | ------------ | ---------------------------- |
| 1    | x64          | 64位 AMD64/Intel64           |
| 2    | ARM64        | 64位 ARM (AArch64)           |
| 3    | WoW64        | 64位 Windows 上的 32位 x86   |

未知的架构字符串内部默认使用 `1` (x64);CLI 将值限制在支持的集合内。

---

### 3. **C 头文件格式**

可直接编译的 C 头文件,包含类型安全的结构体和数据数组。

`pe-signgen` 可以输出两种*类型*的 C 头文件:

* **WSIG 头文件** – 用于签名和掩码数据(来自 `write_wsig_header`)。
* **WOFF 头文件** – 用于直接的 RVA/文件偏移量表(来自 `write_woff_header`)。

`--output-format cheader` 选项选择 C 头文件;结合 `--offsets` 可在 WSIG 和 WOFF 变体之间切换。

#### WSIG C 头文件```bash
pe-signgen --signature ntdll!RtlpInitializeThreadActivationContextStack \
  -o rtlp_init_actx.h --output-format cheader

生成的头部结构(简化,匹配 write_wsig_header):```c /* Auto-generated WSIG header for ntdll ! RtlpInitializeThreadActivationContextStack ! x64. */ #ifndef WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H #define WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H

#include <stdint.h> #include <stddef.h>

下载工具