marirs/strix
GitHub: marirs/strix
一款用Rust编写的高性能二进制字符串提取工具,能从PE、ELF、Mach-O和shellcode中提取包括混淆后在内的多种类型字符串。
Stars: 0 | Forks: 0
# strix
[](https://github.com/marirs/strix/actions/workflows/ci.yml)
[](https://github.com/marirs/strix/actions/workflows/release.yml)
[](LICENSE.txt)
[](https://www.rust-lang.org)
[](#install)
从二进制文件中提取混淆字符串。库 + CLI。支持 PE、ELF、Mach-O(包括 fat binaries)和原始 shellcode。静态、栈和解码后的字符串,具有结构化 JSON 输出。
## 零拷贝
静态字符串、Go 字符串和 Rust 字符串通过 `Cow::Borrowed(&str)` 直接借用输入字节。通过 `mmap` 传递文件,对于这些提取器不会发生分配。模拟字符串(解码/栈/紧凑)在定义上无法零拷贝——它们在模拟运行前不存在于文件中。
## 安装
### 预编译二进制文件
从 [Releases](https://github.com/marirs/strix/releases) 下载适合您平台的版本:
| 平台 | 架构 | 归档文件 |
|---------|-----------|--------------------------------------------------|
| Linux | x86_64 | `strix--x86_64-unknown-linux-gnu.tar.gz` |
| Linux | aarch64 | `strix--aarch64-unknown-linux-gnu.tar.gz` |
| macOS | aarch64 | `strix--aarch64-apple-darwin.tar.gz` |
| Windows | x86_64 | `strix--x86_64-pc-windows-msvc.zip` |
每个归档包含一个 `strix`(或 `strix.exe`)二进制文件和 SHA-256 校验和。
### 从源码构建
```
git clone https://github.com/marirs/strix
cd strix
cargo build --release --features unicorn -p strix-cli
# 二进制文件: target/release/strix
```
不启用 `--features unicorn`,您仍然可以提取静态、语言和栈字符串(x86、x86_64 和 AArch64)。`unicorn` 特性添加了用于解码字符串的暴力模拟流水线;它引入了 `unicorn-engine` C 库,并在构建时需要 `cmake` + C 工具链。
AArch64 (ARM64) 的函数发现和栈字符串模式匹配始终启用——bad64 是纯 Rust 反汇编器,因此不添加任何系统依赖。AArch64 二进制文件上的解码字符串提取仍然需要 AArch64 模拟器后端(计划中)。
## CLI 用法
```
# 默认:分组、人类可读输出到 stdout
strix malware.exe
# JSON
strix --json malware.exe
# 缩进 JSON,写入文件
strix --json --pretty -o malware.json malware.exe
# 删除重复项(相同的值 + 类型 + 编码)
strix --dedupe malware.exe
# 过滤掉落在可执行段中的静态字符串
# (消除大多数汇编字节假阳性,如 AWAVAUATSH)
strix --no-code malware.exe
# 删除 CRT / libc / Windows-API 样板代码噪声
# (kernel32.dll, GetProcAddress, "Runtime Error!", ...)
strix --no-library malware.exe
# 删除低熵噪声(AAAAAA, ////////, +++++++)
strix --min-quality 0.4 malware.exe
# 按源函数 VA 分组模拟恢复的字符串
strix --by-function malware.exe
# 组合:典型分析用法
strix --dedupe --no-code --no-library --min-quality 0.4 --by-function malware.exe
# 仅运行特定提取器组
strix --only static malware.exe
strix --only lang malware.exe # Go / Rust runtime strings
strix --only decoded stack malware.exe
# 跳过特定提取器组
strix --no decoded stack malware.exe
# 提高静态字符串最小长度(默认为 4)
strix --min-length 8 malware.exe
# 强制文件格式(跳过自动检测)
strix --format pe malware.exe
strix --format elf binary
strix --format macho /usr/bin/ls
strix --format sc64 shellcode.bin # raw 64-bit shellcode
strix --format sc32 shellcode.bin # raw 32-bit shellcode
# 静默:无节标题、横幅或警告——仅字符串
strix --quiet malware.exe | sort -u
```
运行 `strix --help` 查看完整的标志说明。
### 输出格式
在人类可读模式下(默认),strix 按字符串种类分组:
```
strix: format=pe, size=131072 bytes
arch=x86_64, bits=64
=== static strings (412) ===
0x0000000140001000 Microsoft Visual C++ Runtime Library
0x0000000140001028 Runtime Error!
...
=== decoded strings (7) ===
0x0000000000000000 http://c2.example.com/beacon
0x0000000000000000 kernel32.dll
...
=== stack strings (12) ===
0x0000000140002a30 ntdll.dll
0x0000000140002a48 LdrLoadDll
...
warnings:
- 3 of 14 emulated candidates failed (faulted on unmapped memory ...)
```
`--json` 输出相同数据的机器可读格式。
## 库用法
`strix` 通过此仓库而非 crates.io 分发。
将它作为 git 依赖添加到您的 `Cargo.toml` 中:
```
[dependencies]
strix = { git = "https://github.com/marirs/strix", tag = "v0.1.1", features = ["unicorn"] }
serde_json = "1"
```
使用 `branch = "master"` 代替 `tag` 来跟踪最新的未发布更改,或使用 `rev = ""` 固定到特定提交。
`unicorn` 特性是可选的——如果您只需要静态、语言和栈字符串提取,可以禁用它。禁用它后,构建时不需要 `cmake` 或 C 工具链:
```
[dependencies]
strix = { git = "https://github.com/marirs/strix", tag = "v0.1.1" }
```
### 最小示例
```
use strix::{extract, ExtractOptions};
fn main() -> Result<(), Box> {
let bytes = std::fs::read("malware.exe")?;
let result = extract(&bytes, &ExtractOptions::default())?;
for s in &result.strings {
println!("{:?} {} {}", s.kind, s.encoding, s.value);
}
Ok(())
}
```
### 配置提取
```
use strix::{extract, ExtractOptions, FormatHint, StringKind};
let opts = ExtractOptions {
min_length: 6, // skip short noise
enabled: Some(vec![ // only these kinds
StringKind::StaticAscii,
StringKind::Decoded,
StringKind::Stack,
]),
format_override: Some(FormatHint::Pe),
max_emulation_steps: 20_000, // cap per emulated function
dedupe: true, // drop duplicate (value, kind, encoding)
skip_code_sections: true, // drop static strings in .text / __TEXT,__text
skip_library_strings: true, // drop CRT/libc/Windows-API noise
min_quality: 0.4, // drop AAAAAA, //////, +++++ noise
};
let bytes = std::fs::read("malware.exe")?;
let result = strix::extract(&bytes, &opts)?;
```
### 零拷贝读取
对于大型二进制文件,使用 mmap 映射输入,以便静态字符串切片直接借用映射中的数据,无需分配:
```
use memmap2::Mmap;
let file = std::fs::File::open("malware.exe")?;
let mmap = unsafe { Mmap::map(&file)? };
let result = strix::extract(&mmap, &strix::ExtractOptions::default())?;
// The result borrows from `mmap`. Bind both to names that outlive
// the use, or call `result.into_owned()` to detach.
```
### JSON 输出
```
let json = serde_json::to_string_pretty(&result)?;
std::fs::write("malware.strix.json", json)?;
```
JSON 模式与 CLI 的 `--json` 输出完全匹配:
```
{
"version": "0.1.1",
"input": {
"format": "pe",
"arch": "x86_64",
"bits": 64,
"size": 131072
},
"strings": [
{
"value": "kernel32.dll",
"kind": "decoded",
"encoding": "ascii",
"location": {
"offset": 0,
"address": 4294967296,
"section": "scratch"
}
}
],
"warnings": []
}
```
### 按种类迭代
```
use strix::StringKind;
let decoded: Vec<&str> = result.strings.iter()
.filter(|s| s.kind == StringKind::Decoded)
.map(|s| s.value.as_ref())
.collect();
let stack: Vec<&str> = result.strings.iter()
.filter(|s| s.kind == StringKind::Stack)
.map(|s| s.value.as_ref())
.collect();
```
### 处理来自内存的输入
库不关心字节来自何处——文件、网络、嵌入式资源都可以:
```
let bytes: Vec = fetch_sample_from_some_api()?;
let result = strix::extract(&bytes, &strix::ExtractOptions::default())?;
```
## strix 提取的内容
| 种类 | 来源 |
|---------------|-----------------------------------------------------------|
| `static_ascii` / `static_utf16_le` | 任何节中的可打印字节序列。 |
| `go` | Go 二进制文件中的 UTF-8 字符串(存在 pclntab 时提取函数名)。 |
| `rust` | Rust 二进制文件中的 UTF-8 字符串(存在 `.rustc` 时提取 crate 元数据)。 |
| `stack` | 通过 mov / push / 寄存器-存储模式在栈上构建的字符串。支持 x86、x86_64 和 AArch64。 |
| `decoded` | 由内存解码器例程产生的字符串,通过 Unicorn 支持的暴力模拟恢复,包括导入桩和调用点参数提取。支持 x86、x86_64 和 AArch64。 |
| `tight` | 写入指令位于已发现循环体内的栈字符串。通过 CFG 回边检测与 `stack` 区分。 |
## 性能
模拟流水线(暴力解码模糊测试、调用者模拟和调用点数据流运行)通过 rayon 跨核心并行化。每个工作线程构建自己的 Unicorn 实例;每个工作线程的构建成本在其分配的所有候选者之间摊销。设置 `RAYON_NUM_THREADS=1` 进行确定性单线程运行。
在 Apple Silicon 笔记本上的指示性挂钟时间:
```
$ time target/release/strix tests/fixtures/elf-Linux-ARM64-bash > /dev/null
real 0m0.265s
user 0m0.910s
sys 0m0.138s
```
该次运行中用户时间与实际时间 3.4 倍的比率显示,在模拟过程中大约有三个半核心并行忙碌。
加速比随着启发式标记为高于分数阈值的解码候选者数量而扩展;仅有少量候选者的二进制文件收益很小,因为 rayon 开销占主导。
## 工作区布局
```
crates/
strix-core types, JSON schema, errors, traits
strix-format PE / ELF / Mach-O / shellcode parsing (goblin)
strix-static zero-copy ASCII + UTF-16LE scanning
strix-lang Go and Rust language-specific extraction
strix-emulator Unicorn-backed emulator + iced-x86 + bad64 analyzers
+ x86 and AArch64 stack-string pattern matchers
+ x86 and AArch64 call-site dataflow analyzers
strix umbrella library, ties everything together
strix-cli CLI binary
```
## 许可证
Apache-2.0
标签:CPU仿真, DAST, ELF格式, Mach-O格式, PE格式, Rust语言, shellcode分析, unicorn引擎, 二进制分析, 云安全监控, 云安全运维, 云资产清单, 内存映射, 可视化界面, 字符串提取, 恶意软件分析, 混淆字符串, 结构化输出, 跨平台支持, 逆向工程, 逆向工程工具, 通知系统, 零拷贝, 静态分析