mahmoudimus/ida-sigmaker
GitHub: mahmoudimus/ida-sigmaker
一个为 IDA Pro 设计的签名制作插件,通过生成和搜索二进制模式签名来应对二进制更新导致的地址变化问题。
Stars: 187 | Forks: 13
# IDA Pro 9.0+ 签名制作插件
[](https://github.com/mahmoudimus/ida-sigmaker/actions/workflows/python.yml)
## 目录
- [安装](#installation)
- [快速安装](#quick-install)
- [从发布版本安装](#from-releases)
- [需要找到你的插件目录?](#need-to-find-your-plugin-directory)
- [我的默认用户目录在哪里,是什么?](#where-and-what-is-my-default-user-directory)
- [SIMD 加速](#simd-speedups)
- [要求](#requirements)
- [什么是“sigmaker”?](#what-is-a-sigmaker)
- [使用方法](#usage)
- [查找 XREF](#finding-xrefs)
- [签名搜索](#signature-searching)
- [签名配置](#signature-configuration)
- [性能](#performance)
- [基准测试](#benchmarks)
- [工作原理](#how-it-works)
- [将 SigMaker 用作库](#using-sigmaker-as-a-library)
- [稳定性契约](#stability-contract)
- [致谢](#acknowledgements)
- [开发与发布](#development--releases)
- [贡献](#contributing)
- [联系方式](#contact)
## 安装
### 快速安装
- 将 [`src/sigmaker/__init__.py`](./src/sigmaker/__init__.py) 复制到插件目录的 /plugins/ 文件夹中!
- 将其重命名为 `sigmaker.py`
- *可选*,如果你想要 `SIMD` 加速,只需运行 `pip install sigmaker`
- 重启 IDA Pro。
### 从发布版本安装
- 从 [Releases 页面](https://github.com/mahmoudimus/ida-sigmaker/releases) 下载最新的、已重命名的 `sigmaker.py` 发布版本
- 将其复制到你的 IDA Pro 插件目录
- *可选*,如果你想要 `SIMD` 加速,只需运行 `pip install sigmaker`
- 重启 IDA Pro
就这样!
### 需要找到你的插件目录?
从 IDA 的 Python 控制台运行以下命令来查找其插件目录:
```
import idaapi, os; print(os.path.join(idaapi.get_user_idadir(), "plugins"))
```
### 我的默认用户目录在哪里,是什么?
用户目录是 IDA 存储部分全局设置的位置,可用于一些额外的自定义。
默认位置:
- 在 Windows 上:`%APPDATA%/Hex-Rays/IDA Pro`
- 在 Linux 和 Mac 上:`$HOME/.idapro`
## SIMD 加速
如果你刚刚按照上面的步骤安装并运行了 `pip install sigmaker`,那么根据你的系统和架构(即 Windows (x64)、Linux (x64)、Mac (x64)、Mac (ARM/Silicon)),插件会安装合适的 wheel 包,并在它们可用时自动使用。你无需做其他任何事情。插件设计为会显示是否安装了 SIMD 加速的状态。它们显示在插件的右上角菜单栏中:
### SIMD 已启用

### 无 SIMD 加速

## 要求
- IDA Pro 9.0+
- IDA Python
- Python 3.10+
## 什么是“sigmaker”?
Sigmaker 代表“签名制作器”。它使用户能够创建独特的二进制模式签名,即使在二进制文件更新后,这些签名也能识别二进制文件中的特定地址或例程。
在恶意软件分析或二进制逆向工程中,一个常见的挑战是定位重要的地址,例如函数或全局变量。然而,当二进制文件更新时,如果地址发生变化,之前用于识别这些位置的所有努力都可能付诸东流。
为了保留这项工作,逆向工程师利用了这样一个事实:大多数程序在更新之间不会发生剧烈变化。虽然一些函数或数据可能被修改,但二进制文件的大部分保持不变。最常见的情况是,先前识别的地址只是被重新定位。这正是 `sigmaker` 的用武之地。
Sigmaker 允许你创建独特的模式来跟踪程序的重要部分,使你的分析更能适应更新。通过为特定的函数、数据引用或其他关键位置生成签名,你可以快速在二进制文件的新版本中重新定位这些点,从而在未来逆向工程任务中节省时间和精力。
## 使用方法
在反汇编视图中,选择你想要为其生成签名的行,然后按
**CTRL+ALT+S**:

*或者* *右键点击* 并选择 *SigMaker*:

生成的签名将被打印到输出控制台,**同时也会被复制到剪贴板**:

| 签名类型 | 示例预览 |
| --- | ----------- |
| IDA Signature | `E8 ? ? ? ? 45 33 F6 66 44 89 34 33` |
| x64Dbg Signature | `E8 ?? ?? ?? ?? 45 33 F6 66 44 89 34 33` |
| C 字节数组签名 + 字符串掩码 | `\xE8\x00\x00\x00\x00\x45\x33\xF6\x66\x44\x89\x34\x33 x????xxxxxxxx` |
| C 原始字节签名 + 位掩码 | `0xE8, 0x00, 0x00, 0x00, 0x00, 0x45, 0x33, 0xF6, 0x66, 0x44, 0x89, 0x34, 0x33 0b1111111100001` |
### 查找 XREF
也支持通过数据或代码的交叉引用生成代码签名,并查找最短签名:

### 签名搜索
搜索签名支持所有已生成的格式:

它还支持通配符半字节搜索:

只需输入包含你签名的任何字符串,它会自动尝试判断使用的是哪种签名格式:

目前支持所有可以生成的输出格式。
匹配你签名的结果将与包含它的函数名一起打印到控制台:

如果匹配的地址不是函数名或没有函数名,它会回退到只打印地址:

### 签名配置
`sigmaker` 还支持可配置的通配符操作数,用于创建独特的签名:

还有各种选项可以通过 `Other options` 按钮进行配置:

## 性能
SigMaker 的“为当前函数查找最短唯一签名”搜索经过了高度优化。在一个真实的 16 MB 模块上,一次最坏情况的函数搜索曾经需要 **462 秒(7.7 分钟)**。四项优化的叠加将最繁重的搜索时间降低到几十秒,典型搜索则接近瞬时。一位用户[报告](https://github.com/mahmoudimus/ida-sigmaker/issues/27#issuecomment-4577775008)称,进度等待框现在对于 26 字节的签名“几乎不会显示出来”。
完整的推导,包括匹配集的数学计算、计数排序索引、选择性证明以及该方法的新颖之处,都记录在 **[ALGORITHM.md](./ALGORITHM.md)** 中。
### 基准测试
在 Apple Silicon 上通过原生 idalib 对 16 MB 模块中最大的函数(8486 字节)进行测量。效果在四个阶段中是累积的:
| 优化 | 效果 | PR |
| --- | --- | --- |
| 阶段 1:种子然后细化候选优化 | 函数搜索速度提升约 13 倍 | [#33](https://github.com/mahmoudimus/ida-sigmaker/pull/33) |
| 阶段 2:2 字节桶位置索引 | 在大型数据库上额外提升约 2.48 倍,随着数据库增长优势扩大 | [#35](https://github.com/mahmoudimus/ida-sigmaker/pull/35) |
| 阶段 3:动态种子选择(1 或 2 字节) | 每锚点的种子扫描从 206 次减少到 2 次 | [#36](https://github.com/mahmoudimus/ida-sigmaker/pull/36) |
| 阶段 4:Cython 原地细化 | 每字节细化从约 14 秒降至约 0.28 秒(约 50 倍);函数总时间从约 24 秒降至约 15.6 秒 | [#36](https://github.com/mahmoudimus/ida-sigmaker/pull/36) |
每次优化前后,签名输出都是字节级相同的。测试套件会将每个快速路径与暴力破解预言机进行交叉检查,并在整个测试二进制文件上比较生成的签名。
### 工作原理
简要介绍(数学细节见 [ALGORITHM.md](./ALGORITHM.md)):
- **种子然后细化。** 数据库的匹配集只会随着签名增长而缩小,因此 SigMaker 不是为每个候选长度重新扫描整个数据库,而是扫描一次以生成一个候选集,然后随着每个字节的追加在原地过滤该集。
- **一次索引数据库。** 对每一对相邻字节的计数排序索引允许从模式中*最稀少*的精确连续部分提取种子,时间与该连续部分的频率成正比,而不是与数据库大小成正比。该索引同时免费服务于 1 字节和 2 字节的连续部分,因此总是选择最具选择性的锚点。
- **将热循环推入 C。** 通过可选的 `pip install sigmaker` SIMD wheel,索引构建和每字节的细化作为 `nogil` C 代码在类型化缓冲区上运行,且每次调用零分配,原始字节扫描使用 AVX2/NEON/SSE2。如果没有该 wheel,纯 Python 的回退方案也能产生完全相同的结果。
## 将 SigMaker 用作库
除了 IDA 插件外,`sigmaker` 也被其他工具(例如,批量签名生成流程)直接导入为 Python 库。核心类型可在任何 IDAPython 或 idalib 环境中使用:
```
import sigmaker
cfg = sigmaker.SigMakerConfig(
output_format=sigmaker.SignatureType.IDA,
wildcard_operands=True,
continue_outside_of_function=False,
wildcard_optimized=True,
ask_longer_signature=False,
)
result = sigmaker.SignatureMaker().make_signature(ea, cfg)
print(f"{result.signature:ida}") # IDA-style string
print(len(result.signature)) # byte length
# 交叉引用:
xrefs = sigmaker.XrefFinder().find_xrefs(ea, cfg)
for gen in xrefs.signatures:
print(str(gen.address), f"{gen.signature:ida}")
```
### 稳定性契约
如果你嵌入 `sigmaker`,你可以依赖以下约定。这些约定被视为契约,并在公共接口的任何更改前进行检查:
1. **仅追加配置。** `SigMakerConfig` 的字段永远不会被重新排序或删除。新行为作为具有安全默认值的新字段引入,因此现有的构造方式继续有效。
2. **稳定的公共名称。** 这些名称及其记录的属性不会被重命名或移除:`SignatureMaker`、`SigMakerConfig`、`SignatureType` (`IDA`, `x64Dbg`, `Mask`, `BitMask`)、`XrefFinder`、`GeneratedSignature` (`signature`, `address`, `status`, `match_count`)、`XrefGeneratedSignature` (`signatures`)、`Match` (`__str__` 返回十六进制地址)、`Signature` (`__len__`, `__format__`)、`GenerationPolicy`、`GenerationStatus`。
3. **稳定的方法签名。** `SignatureMaker.make_signature(ea, cfg, end=None, *, progress_reporter=None, policy=GenerationPolicy.strict())`、`XrefFinder.find_xrefs(ea, cfg)`、`XrefFinder.count_code_xrefs_to(ea)` 和 `XrefFinder.iter_code_xrefs_to(ea)`。
4. **稳定的格式规范。** `f"{sig:ida}"`、`f"{sig:x64dbg}"`、`f"{sig:mask}"` 和 `f"{sig:bitmask}"` 保持输出其当前的确切格式。
5. **默认值字节相同。** 生产默认值在各优化间保持不变:一个没有启用新标志的脚本将获得与之前版本字节相同的签名。
## 致谢
## 开发与发布
## 联系方式
在 x 上 ping 我 [@mahmoudimus](https://x.com/mahmoudimus) 或者你可以通过 [mahmoudimus.com](https://mahmoudimus.com) 上的任何地址联系我。
[](https://github.com/mahmoudimus/ida-sigmaker/actions/workflows/python.yml)
## 目录
- [安装](#installation)
- [快速安装](#quick-install)
- [从发布版本安装](#from-releases)
- [需要找到你的插件目录?](#need-to-find-your-plugin-directory)
- [我的默认用户目录在哪里,是什么?](#where-and-what-is-my-default-user-directory)
- [SIMD 加速](#simd-speedups)
- [要求](#requirements)
- [什么是“sigmaker”?](#what-is-a-sigmaker)
- [使用方法](#usage)
- [查找 XREF](#finding-xrefs)
- [签名搜索](#signature-searching)
- [签名配置](#signature-configuration)
- [性能](#performance)
- [基准测试](#benchmarks)
- [工作原理](#how-it-works)
- [将 SigMaker 用作库](#using-sigmaker-as-a-library)
- [稳定性契约](#stability-contract)
- [致谢](#acknowledgements)
- [开发与发布](#development--releases)
- [贡献](#contributing)
- [联系方式](#contact)
## 安装
### 快速安装
- 将 [`src/sigmaker/__init__.py`](./src/sigmaker/__init__.py) 复制到插件目录的 /plugins/ 文件夹中!
- 将其重命名为 `sigmaker.py`
- *可选*,如果你想要 `SIMD` 加速,只需运行 `pip install sigmaker`
- 重启 IDA Pro。
### 从发布版本安装
- 从 [Releases 页面](https://github.com/mahmoudimus/ida-sigmaker/releases) 下载最新的、已重命名的 `sigmaker.py` 发布版本
- 将其复制到你的 IDA Pro 插件目录
- *可选*,如果你想要 `SIMD` 加速,只需运行 `pip install sigmaker`
- 重启 IDA Pro
就这样!
### 需要找到你的插件目录?
从 IDA 的 Python 控制台运行以下命令来查找其插件目录:
```
import idaapi, os; print(os.path.join(idaapi.get_user_idadir(), "plugins"))
```
### 我的默认用户目录在哪里,是什么?
用户目录是 IDA 存储部分全局设置的位置,可用于一些额外的自定义。
默认位置:
- 在 Windows 上:`%APPDATA%/Hex-Rays/IDA Pro`
- 在 Linux 和 Mac 上:`$HOME/.idapro`
## SIMD 加速
如果你刚刚按照上面的步骤安装并运行了 `pip install sigmaker`,那么根据你的系统和架构(即 Windows (x64)、Linux (x64)、Mac (x64)、Mac (ARM/Silicon)),插件会安装合适的 wheel 包,并在它们可用时自动使用。你无需做其他任何事情。插件设计为会显示是否安装了 SIMD 加速的状态。它们显示在插件的右上角菜单栏中:
### SIMD 已启用

### 无 SIMD 加速

## 要求
- IDA Pro 9.0+
- IDA Python
- Python 3.10+
## 什么是“sigmaker”?
Sigmaker 代表“签名制作器”。它使用户能够创建独特的二进制模式签名,即使在二进制文件更新后,这些签名也能识别二进制文件中的特定地址或例程。
在恶意软件分析或二进制逆向工程中,一个常见的挑战是定位重要的地址,例如函数或全局变量。然而,当二进制文件更新时,如果地址发生变化,之前用于识别这些位置的所有努力都可能付诸东流。
为了保留这项工作,逆向工程师利用了这样一个事实:大多数程序在更新之间不会发生剧烈变化。虽然一些函数或数据可能被修改,但二进制文件的大部分保持不变。最常见的情况是,先前识别的地址只是被重新定位。这正是 `sigmaker` 的用武之地。
Sigmaker 允许你创建独特的模式来跟踪程序的重要部分,使你的分析更能适应更新。通过为特定的函数、数据引用或其他关键位置生成签名,你可以快速在二进制文件的新版本中重新定位这些点,从而在未来逆向工程任务中节省时间和精力。
## 使用方法
在反汇编视图中,选择你想要为其生成签名的行,然后按
**CTRL+ALT+S**:

*或者* *右键点击* 并选择 *SigMaker*:

生成的签名将被打印到输出控制台,**同时也会被复制到剪贴板**:

| 签名类型 | 示例预览 |
| --- | ----------- |
| IDA Signature | `E8 ? ? ? ? 45 33 F6 66 44 89 34 33` |
| x64Dbg Signature | `E8 ?? ?? ?? ?? 45 33 F6 66 44 89 34 33` |
| C 字节数组签名 + 字符串掩码 | `\xE8\x00\x00\x00\x00\x45\x33\xF6\x66\x44\x89\x34\x33 x????xxxxxxxx` |
| C 原始字节签名 + 位掩码 | `0xE8, 0x00, 0x00, 0x00, 0x00, 0x45, 0x33, 0xF6, 0x66, 0x44, 0x89, 0x34, 0x33 0b1111111100001` |
### 查找 XREF
也支持通过数据或代码的交叉引用生成代码签名,并查找最短签名:

### 签名搜索
搜索签名支持所有已生成的格式:

它还支持通配符半字节搜索:

只需输入包含你签名的任何字符串,它会自动尝试判断使用的是哪种签名格式:

目前支持所有可以生成的输出格式。
匹配你签名的结果将与包含它的函数名一起打印到控制台:

如果匹配的地址不是函数名或没有函数名,它会回退到只打印地址:

### 签名配置
`sigmaker` 还支持可配置的通配符操作数,用于创建独特的签名:

还有各种选项可以通过 `Other options` 按钮进行配置:

## 性能
SigMaker 的“为当前函数查找最短唯一签名”搜索经过了高度优化。在一个真实的 16 MB 模块上,一次最坏情况的函数搜索曾经需要 **462 秒(7.7 分钟)**。四项优化的叠加将最繁重的搜索时间降低到几十秒,典型搜索则接近瞬时。一位用户[报告](https://github.com/mahmoudimus/ida-sigmaker/issues/27#issuecomment-4577775008)称,进度等待框现在对于 26 字节的签名“几乎不会显示出来”。
完整的推导,包括匹配集的数学计算、计数排序索引、选择性证明以及该方法的新颖之处,都记录在 **[ALGORITHM.md](./ALGORITHM.md)** 中。
### 基准测试
在 Apple Silicon 上通过原生 idalib 对 16 MB 模块中最大的函数(8486 字节)进行测量。效果在四个阶段中是累积的:
| 优化 | 效果 | PR |
| --- | --- | --- |
| 阶段 1:种子然后细化候选优化 | 函数搜索速度提升约 13 倍 | [#33](https://github.com/mahmoudimus/ida-sigmaker/pull/33) |
| 阶段 2:2 字节桶位置索引 | 在大型数据库上额外提升约 2.48 倍,随着数据库增长优势扩大 | [#35](https://github.com/mahmoudimus/ida-sigmaker/pull/35) |
| 阶段 3:动态种子选择(1 或 2 字节) | 每锚点的种子扫描从 206 次减少到 2 次 | [#36](https://github.com/mahmoudimus/ida-sigmaker/pull/36) |
| 阶段 4:Cython 原地细化 | 每字节细化从约 14 秒降至约 0.28 秒(约 50 倍);函数总时间从约 24 秒降至约 15.6 秒 | [#36](https://github.com/mahmoudimus/ida-sigmaker/pull/36) |
每次优化前后,签名输出都是字节级相同的。测试套件会将每个快速路径与暴力破解预言机进行交叉检查,并在整个测试二进制文件上比较生成的签名。
### 工作原理
简要介绍(数学细节见 [ALGORITHM.md](./ALGORITHM.md)):
- **种子然后细化。** 数据库的匹配集只会随着签名增长而缩小,因此 SigMaker 不是为每个候选长度重新扫描整个数据库,而是扫描一次以生成一个候选集,然后随着每个字节的追加在原地过滤该集。
- **一次索引数据库。** 对每一对相邻字节的计数排序索引允许从模式中*最稀少*的精确连续部分提取种子,时间与该连续部分的频率成正比,而不是与数据库大小成正比。该索引同时免费服务于 1 字节和 2 字节的连续部分,因此总是选择最具选择性的锚点。
- **将热循环推入 C。** 通过可选的 `pip install sigmaker` SIMD wheel,索引构建和每字节的细化作为 `nogil` C 代码在类型化缓冲区上运行,且每次调用零分配,原始字节扫描使用 AVX2/NEON/SSE2。如果没有该 wheel,纯 Python 的回退方案也能产生完全相同的结果。
## 将 SigMaker 用作库
除了 IDA 插件外,`sigmaker` 也被其他工具(例如,批量签名生成流程)直接导入为 Python 库。核心类型可在任何 IDAPython 或 idalib 环境中使用:
```
import sigmaker
cfg = sigmaker.SigMakerConfig(
output_format=sigmaker.SignatureType.IDA,
wildcard_operands=True,
continue_outside_of_function=False,
wildcard_optimized=True,
ask_longer_signature=False,
)
result = sigmaker.SignatureMaker().make_signature(ea, cfg)
print(f"{result.signature:ida}") # IDA-style string
print(len(result.signature)) # byte length
# 交叉引用:
xrefs = sigmaker.XrefFinder().find_xrefs(ea, cfg)
for gen in xrefs.signatures:
print(str(gen.address), f"{gen.signature:ida}")
```
### 稳定性契约
如果你嵌入 `sigmaker`,你可以依赖以下约定。这些约定被视为契约,并在公共接口的任何更改前进行检查:
1. **仅追加配置。** `SigMakerConfig` 的字段永远不会被重新排序或删除。新行为作为具有安全默认值的新字段引入,因此现有的构造方式继续有效。
2. **稳定的公共名称。** 这些名称及其记录的属性不会被重命名或移除:`SignatureMaker`、`SigMakerConfig`、`SignatureType` (`IDA`, `x64Dbg`, `Mask`, `BitMask`)、`XrefFinder`、`GeneratedSignature` (`signature`, `address`, `status`, `match_count`)、`XrefGeneratedSignature` (`signatures`)、`Match` (`__str__` 返回十六进制地址)、`Signature` (`__len__`, `__format__`)、`GenerationPolicy`、`GenerationStatus`。
3. **稳定的方法签名。** `SignatureMaker.make_signature(ea, cfg, end=None, *, progress_reporter=None, policy=GenerationPolicy.strict())`、`XrefFinder.find_xrefs(ea, cfg)`、`XrefFinder.count_code_xrefs_to(ea)` 和 `XrefFinder.iter_code_xrefs_to(ea)`。
4. **稳定的格式规范。** `f"{sig:ida}"`、`f"{sig:x64dbg}"`、`f"{sig:mask}"` 和 `f"{sig:bitmask}"` 保持输出其当前的确切格式。
5. **默认值字节相同。** 生产默认值在各优化间保持不变:一个没有启用新标志的脚本将获得与之前版本字节相同的签名。
## 致谢
## 开发与发布
## 联系方式
在 x 上 ping 我 [@mahmoudimus](https://x.com/mahmoudimus) 或者你可以通过 [mahmoudimus.com](https://mahmoudimus.com) 上的任何地址联系我。标签:DAST, IDA Pro插件, IDA签名工具, nibbles, SIMD优化, 二进制分析, 云安全运维, 云资产清单, 代码分析, 凭证管理, 右键菜单集成, 性能加速, 恶意软件分析, 恶意软件签名, 情报收集, 操作数模式, 漏洞研究, 签名制作插件, 签名生成, 跨平台兼容, 逆向工具, 逆向工程, 通配符匹配, 零依赖