在Kali上使用radare2剖析恶意软件PE — 彻底掌握汇编提取

“即使不执行代码,我们也能读懂其中隐藏的意图。”

静态分析的第一道关卡,我们用radare2来打开。


本文涵盖内容

  • 不执行恶意软件PE文件,安全地提取汇编代码的方法
  • 使用rabin2快速收集PE头、导入表和字符串的侦察技术
  • 使用r2的核心命令(aaa, afl, pdf)进行函数级反汇编
  • 将提取的汇编代码保存为干净的.asm文本文件的批处理(headless)技术
  • 分析师必须遵守的隔离环境和安全规范

为什么选择radare2

初次进行恶意软件分析时,大多数人会想到IDA Pro或Ghidra。两者都很优秀,但它们笨重且以GUI为中心,对于“只想快速查看一个函数”的情况来说,可能有些大材小用。

radare2(简称r2)则恰恰相反。它是一个基于终端的轻量级、快速逆向工程框架,预装在Kali Linux中,无需额外安装即可立即使用。最重要的是,它易于脚本自动化,对于从数十个样本中批量提取特定函数汇编代码的任务非常强大。

核心在于:通过r2进行的反汇编是静态分析。这意味着它绝不会执行恶意软件,而只是将文件内部的机器码翻译成人类可读的汇编代码。这表示分析本身不会有系统感染的风险。


核心概念总结

什么是PE文件

PE(Portable Executable) 是Windows的可执行文件格式。.exe、.dll、.sys都是PE格式,其内部结构包括包含代码的.text节、包含数据的.data节、导入表和入口点地址等。由于大多数恶意软件都以Windows为目标,因此PE分析是分析师的基本功。

反汇编(Disassembly)

编译后的二进制文件中包含人类难以阅读的机器码(machine code)。将其逆向翻译成mov、push、call等汇编指令的过程就是反汇编。radare2通过一行命令即可完成此操作。

radare2工具集

  • r2 — 交互式主控制台。分析和反汇编的核心
  • rabin2 — 用于提取PE/ELF等二进制文件元信息(头、导入表、字符串)的工具
  • r2脚本 — 使用-c选项预先注入命令以自动执行

实践:汇编提取分步命令

第0步 — 隔离环境和样本完整性检查

分析必须在与互联网隔离的虚拟机(可恢复快照)中进行。首先,记录样本的身份和哈希值。

bash

# 检查文件类型 — 验证是否为PE可执行文件
file sample.exe

# 记录哈希 — 用于后续威胁情报(如VirusTotal)查询
sha256sum sample.exe

哈希值是分析报告的标识符,因此最好养成首先记录它的习惯。

第1步 — 使用rabin2进行初步侦察

进入控制台之前,使用rabin2了解整体概况。由于它只读取头部而不执行,因此非常安全。

# 二进制基本信息(架构、位数、编译器、入口点)
rabin2 -I sample.exe

# PE头字段详情
rabin2 -H sample.exe

# 导入函数列表 — 推断恶意行为的关键线索
rabin2 -i sample.exe

# 导出函数(DLL分析时有用)
rabin2 -E sample.exe

# 入口点地址
rabin2 -e sample.exe

# 字符串提取 — 揭示URL、命令、注册表键等
rabin2 -z sample.exe

rabin2 -i 显示的导入表尤为重要。如果看到CreateRemoteThread、VirtualAllocEx、WinHttpOpen等API,可能会怀疑存在代码注入或外部通信。

第2步 — 使用r2加载并自动分析

现在,进入主控制台。-A选项在加载的同时执行完整分析(aaa)。

# -A : 加载后立即执行aaa(自动分析)
r2 -A sample.exe

如果未带-A选项打开,则在控制台内手动运行分析。

[0x00401000]> aaa

aaa(analyze all)是r2的核心分析命令,用于自动识别函数边界、调用关系和字符串引用。对于大型样本,可能需要一些时间,请耐心等待。

第3步 — 检查函数列表

分析完成后,列出已识别的函数。

[0x00401000]> afl

afl(analyze function list)以表格形式显示每个函数的地址、大小和名称。如果只想查看特定名称,可以使用r2内置的grep(~)。

[0x00401000]> afl~main
[0x00401000]> afl~entry

第4步 — 反汇编汇编代码

终于到了核心部分。按函数单位输出汇编代码。

# 反汇编整个入口点函数
[0x00401000]> pdf @ entry0

# 移动到当前位置并打印函数
[0x00401000]> s entry0
[0x00401000]> pdf

# 反汇编特定函数(使用afl中确认的名称)
[0x00401000]> pdf @ sym.malicious_routine

# 从特定地址只打印50条指令
[0x00401000]> pd 50 @ 0x00401230

pdf(print disassembly function)反汇编整个函数,而pd N只反汇编指定数量的指令。记住两者的区别,可以根据情况灵活选择。

第5步 — 在可视化(Visual)模式下查看流程

如果想以图形而不是指令列表的形式查看控制流,请使用可视化模式。

# 可视化反汇编模式(q退出,p切换视图)
[0x00401000]> V

# 函数控制流图
[0x00401000]> VV

VV的图形视图可以一目了然地掌握分支和循环结构,这在理解复杂的脱壳例程时特别有用。

第6步 — 将汇编代码提取到文件(自动化)

分析师真正的武器是自动化。即使不进入控制台,也可以通过-q -c选项注入命令,将结果提取到文本文件中。

# 仅将入口函数保存为纯文本(移除颜色代码)
r2 -q -c "e scr.color=0; aaa; pdf @ entry0" sample.exe > entry0.asm

# 一次性反汇编所有函数 — @@f 表示按函数单位重复执行
r2 -q -c "e scr.color=0; aaa; pdf @@f" sample.exe > all_functions.asm

# 仅函数列表(文本形式)
r2 -q -c "aaa; afl" sample.exe > functions.txt

这里的e scr.color=0是关闭终端颜色代码的设置。如果省略它,文件中会混入^[[31m等ANSI转义字符,使其变得混乱,所以务必添加。@@f是r2的迭代运算符,表示对所有已识别的函数依次执行pdf。

如果需要更易读的输出,请调整附加设置。

# 隐藏左侧流程线和十六进制字节,仅提取纯汇编代码
r2 -q -c "e scr.color=0; e asm.lines=false; e asm.bytes=false; aaa; pdf @@f" sample.exe > clean.asm

这样提取的.asm文件可以直接用作分析数据,例如通过grep搜索特定的API调用,或比较不同变种之间的代码相似性。


⚠️ 注意事项和常见错误

  • 切勿在主机上直接操作。 分析必须在可恢复快照的隔离虚拟机中进行,并切断网络。虽然r2本身不执行样本,但意外双击样本的事故随时可能发生。
  • 打包样本的反汇编可能毫无意义。 如果使用UPX等工具打包,看到的代码可能只是解包存根。如果rabin2 -I结果的熵异常高或节名称类似于UPX0,请首先考虑解包。
  • 不要忘记删除颜色代码。 如果没有e scr.color=0就导出到文件,会混入^[[31m等控制字符。
  • aaa可能无法捕获所有函数。 混淆代码有时会导致自动分析遗漏函数边界。在这种情况下,请在可疑地址手动调用af(定义函数),然后执行pdf。
  • 遵守法律和道德界限。 仅在具有合法权限的样本和环境中进行分析。分析的目的是增强防御和检测能力。

✅ 总结

今天讨论的流程可以总结为一句话:准备隔离环境 → 使用rabin2侦察 → 使用r2 -A分析 → 使用afl识别函数 → 使用pdf提取汇编代码 → 使用-q -c自动保存。

radare2的命令初看起来可能不熟悉,但一旦了解其命令体系分为i(info)、a(analyze)、p(print)、s(seek)四个类别,就会很快上手。随着通过静态分析读取汇编代码的感觉逐渐积累,过渡到动态分析(调试)和行为分析也会变得更加顺利。

推荐的下一步

  • 使用r2的调试器模式(r2 -d)入门动态分析
  • 尝试使用pdc或r2dec插件进行伪C代码反编译
  • 结合Cutter(radare2 GUI)进行图形分析
  • 结合YARA规则编写实现变种检测自动化


Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注