takakhoo/ParseRE_ELF_etc
GitHub: takakhoo/ParseRE_ELF_etc
ParseRE 的 ELF 评估与 ACSAC 2026 论文配套仓库,通过 QEMU 差分追踪对二进制解析器控制流图进行自动化标签标注。
Stars: 0 | Forks: 0
# ParseRE_ELF_etc
嘿 Ben,
这是我用于 ELF 评估和 ACSAC 论文的仓库。我实际运行过的所有内容都在这里,加上修改过的 `main.py` 和论文源码,你可以直接把它们扔进 Overleaf 或使用 tectonic 在本地编译。我觉得把整个东西发给你,而不是发一堆附件更好。
当前的论文 PDF 位于 [`paper/main.pdf`](paper/main.pdf)。共 8 页,远低于 ACSAC 11 页的限制。任何需要你或 Rishav 提供内容的地方,我都在文中留下了斜体标记,方便使用 grep 查找:`grep -rn "\[BEN:\|\[RISHAV:" paper/sections/`。目前文件中共有七个这样的标记。

## 里面有什么
```
ParseRE_ELF_etc/
├── README.md you are here
├── paper/ IEEE LaTeX source + compiled PDF + new figures
│ ├── main.tex
│ ├── main.pdf 8-page draft
│ ├── IEEEtran.cls
│ ├── references.bib
│ ├── figures/ new TikZ figures (pipeline, motivating, ELF layout, ELF CFG)
│ └── sections/ one .tex per section
├── parsere/main.py your main.py with ELF support added
├── harnesses/ json-c, libcurl, libelf C harnesses
├── docker/ Dockerfile + run.sh that runs any of the three evals
├── evaluations/
│ ├── elf/ corpus + scripts + real outputs + per-block manual labeling
│ ├── json/output/ real run, 294 labels
│ ├── url/output/ real run, 211 labels
│ └── hpack/ placeholder for your run
├── images/ real artifacts: CFG PNGs, hexdumps, QEMU traces
├── references/ notes on related work
└── docs/ contributing notes
```
## 我上周实际做了什么
三件事,按顺序如下:
1. **在我的机器上跑通了 ParseRE。** 它需要 Docker,因为 macOS Homebrew 的 QEMU 不提供 `qemu-x86_64` 用户模式。我构建了一个 Docker 镜像,它编译了所有三个 harness(json-c 静态 `.a`,使用 `--without-shared` 从源码编译的 curl,以及使用 `-static` 编译的 libelf),并在容器内运行修补过的 ParseRE。镜像可以通过 `docker/Dockerfile` 复现。
2. **运行并验证了你的 JSON 和 URL 评估。** 一旦解决了静态链接问题(下文详述),两者首次尝试就成功了。JSON 在 6 个产生式中生成了 294 个标签。URL 在 11 个产生式中生成了 211 个标签。多次重复运行的数据完全一致。
3. **端到端构建了 ELF 评估。** 编写了语料库生成器、harness、模板,运行了 ParseRE,并手动标注了输出。在 91.2% 的严格准确率下有 68 个标注块。有趣的发现是 `program_header` 没有获得任何标签,因为 libelf 通过相同的代码路径读取所有 phdr 类型。我将此作为二进制和文本格式之间一个值得写入论文的对比进行了撰写。在当前的草稿中应该是第 IV-E 节。
## 静态链接的教训
这在 URL 评估上耗费了半天时间,我认为这值得在论文中特别提一下,我已经将其添加到了第 IV-C 节。简而言之:我的第一个 URL harness 动态链接了 `libcurl.so`,结果 ParseRE 生成了零个标签。动态链接器启动会在每次输入时运行,主导了所有的 trace,因此唯一性过滤器清除了整个图。解决方法是从源码重建 curl 并使用 `--without-shared`,然后将 harness 链接到静态归档。ELF harness 出于同样的原因使用了 `-static`。我已将此添加到 README 中,以免以后再有人遇到这个问题。
## 当前评估状态
| 格式 | 库 | 状态 | 标签 | 准确率 | 需求 |
|--------|---------|--------|--------|----------|-------|
| URI | curl | 已完成 | 211 | 待定 | Rishav 的标注 SVG |
| URI | Apache APR | 未开始 | -- | -- | Rishav 运行 |
| JSON | json-c | 已完成 | 294 | 待定 | Rishav 的标注 SVG |
| HPACK | nghttp2 | 未开始 | -- | -- | 你来运行 |
| ELF | libelf | 已完成 | 68 | 91.2% | 已经完成 |
## 我需要你帮忙的事情
大致按优先级排列:
1. **HPACK 数据。** 方便的话把它们放到 `evaluations/hpack/output/` 里并附上一个 README,我会进行整合。论文中已经有一个准备好的占位章节可以填入。
2. **帮忙审阅相关工作章节。** 我遵循了我们 5 月 19 日对话中的框架(语法恢复与标签转移,PolyTracker 的 LLVM 依赖路线,Tenet 作为 N=2 的案例)。我引用了 T-Reqs 和 ParDiff 而不是 HTTP Garden,以避免双盲审稿下的身份泄露。如果你觉得我们应该增加或删减任何内容,请告诉我。
3. **作者信息块。** 目前 `main.tex` 中是 `\author{Anonymous}`。我们需要在最终提交定稿时修复此项,但双盲提交必须保持匿名。
4. **Ghidra 脚本。** 你原来仓库中的那个并没有包含在这里。值得检查一下我们 `out.dot` 中的 addr2line 注释是否让该插件变得多余,或者它们是互补的。
## 快速复现
如果你想从头验证其中任何内容:
```
git clone git@github.com:takakhoo/ParseRE_ELF_etc.git
cd ParseRE_ELF_etc/docker
docker build --platform linux/amd64 -t parsere-runner -f Dockerfile .
# 首次构建大约需要 15 分钟,其中大部分时间用于静态编译 curl。
mkdir -p ../elf_out
docker run --platform linux/amd64 --rm -v "$PWD/../elf_out:/output" parsere-runner elf
# 端到端大约需要 10 秒。在浏览器中打开 elf_out/out.svg。
# 然后与已提交的输出进行 diff:
diff <(sort ../elf_out/parsere.out) <(sort ../evaluations/elf/output/parsere.out)
# 应该为空。
```
对于 JSON:使用相同的命令,将 `elf` 替换为 `json`。大约需要 30 秒。
对于 URL:使用相同的命令,将 `elf` 替换为 `url`。因为需要进行 210 万次成对比较,大约需要 8 分钟。
## 如何逐步查看 ELF 相关工作
如果你想按照我的构建顺序阅读所有内容:
1. **`evaluations/elf/scripts/gen_elf_corpus.py`**。固定布局 1048 字节的 ELF 生成器。论文中的布局图(图 3)来源于此。
2. **`harnesses/elf_harness.c`**。108 行代码,读取 stdin,调用 `elf_memory`,遍历 phdrs/shdrs/symtab。`if (shdr.sh_type == SHT_SYMTAB)` 条件分支使得 section_header 标签触发了 68 次。
3. **`parsere/main.py` 第 591 行**。`ELF_PARSE_TREE_TEMPLATE` 的定义。由 `evaluations/elf/scripts/gen_template.py` 生成的字节字面量。三个子项:一个固定的 ELF header,四个 phdr 变体,五个 section 变体。通过笛卡尔积生成 20 个输入。
4. **`evaluations/elf/output/parsere.out`**。实际运行输出。269 行,其中 68 行被标记为 section_header。
5. **`evaluations/elf/output/MANUAL_LABELING.md`**。我按函数整理的 TP/FP 表格。那 5 个假阳性全部位于 `__gelf_getehdr_rdlock` 中,这是一个在 section 遍历期间偶然被调用的 ELF header 验证例程。
## 你的 main.py 中有哪些改动
进行了三处极简的修改,都可以作为一个单独的 PR 向上游提交:
1. 在 `URI_PARSE_TREE_TEMPLATE` 之后添加了 `ELF_PARSE_TREE_TEMPLATE`(大约在第 591 行)。使用语料库生成器生成的字节进行内嵌。
2. 在格式 switch 中添加了 `case "elf":`(大约在第 844 行)。
3. 修复了去重步骤中的一个 `ZeroDivisionError`(第 683 行)。当模板包含一个只有一个备选项的子项时(比如我们的 `elf_header`),该规则会产生零条边,而原始的 `len(e1-e2)/len(e1)` 会引发错误。已将其修改为 `len(e1) > 0 and ...`。
diff 非常小。只要你准备好了,我很乐意随时向 `kenballus/parsere` 提交一个 PR。
## 有用的链接
- 你的上游仓库:[github.com/kenballus/parsere](https://github.com/kenballus/parsere)
- HTTP Garden 论文(用作风格参考):在我们的 `papers/http-garden/` 目录树中
- Tectonic(我用来在本地编译论文的工具):[tectonic-typesetting.github.io](https://tectonic-typesetting.github.io)
- 我们链接的确切库 commit:
- json-c: `89485680314df3b4dfb2aaed14f89d212d57c119`
- curl: `462244447e8ba3a53b1ba9f0ba7baa52d8777daa`
- libelf: Debian bookworm `libelf-dev`
如果有任何不清楚的地方,或者你希望我重新安排其中的任何部分,请告诉我。
Taka
标签:ELF, QEMU, TruffleHog, 二进制分析, 云安全运维, 内联执行, 可配置连接, 学术论文, 差异追踪, 控制流图, 程序分析, 请求拦截, 身份验证强制, 逆向工具