0x0 论文信息

0x0 复现环境

  • Window
  • Ubuntu18.04(in WSL)

由于环境依赖问题,本人复现时会在Windows和WSL之间切换,涉及到IDA Pro的部分使用Windows,其他部分使用WSL

  • IDA Pro 7.3 For Windows
  • capstone 3.0.5
  • Python 3.8.16
  • Python 2.7.13

0x01 数据获取

训练所需的数据作者均整理到了Google云盘,并可通过gdrive_download.py脚本下载。

python gdrive_download.py --binaries --features --results

旧版本的代码中的gdown版本不兼容,需要安装gdown==4.6.4,最新版本已解决此问题

0x02 数据集处理

数据集处理的步骤包括:

  1. 编译:改变配置,基于源码,编译生成不同指令集架构、优化选项、编译器类型、编译器版本的二进制Binary
  2. 生成IDB:通过IDA Pro,基于Binary生成IDB
  3. 生成代码图数据:通过IDA Pro的扩展插件,基于IDB生成Flow图、ACFG汇编代码和ACFG特征
  4. 数据筛选清洗:
  5. 生成函数对:根据实验组中的编译优化、指令集等异同,组合生成用于训练的函数对
  6. 数据集拆分:拆分得到训练、验证、测试集

0x02.1 编译

参看代码的 Binaries/Compilation scripts/README.md 部分,本文不详细介绍。

0x02.2 生成IDB

配置IDA Pro

首先需要解决IDA Pro的安装问题。作者建议使用IDA Pro 7.3版本进行实验,但由于IDA Pro 7.3 for linux的资源很难找,所以本人在复现的时候使用了Windows版本的IDA Pro,代码可以完美运行。

在此之前需要设置环境变量指定IDA pro的位置。

# 在powershell下设置环境变量
$env:IDA_PATH='D:\IDA 7.3\ida64.exe'

或者也可以通过WSL调用宿主机的IDA pro

export IDA_PATH=/mnt/d/IDA\ 7.3/ida64.exe

运行生成IDB

环境配置完成后,可通过运行IDA_scripts/generate_idbs.py生成IDB

python3 generate_idbs.py 

其中--db1 --db2 --dbvuln参数可以任意组合。

成功运行结果:

image

代码解析:

# 第72行
def export_idb(input_path, output_path):
    """运行IDA Pro并导出IDB"""
    try:
        print("Export IDB for {}".format(input_path))
        ida_output = str(subprocess.check_output([
            IDA_PATH,
            "-L{}".format(LOG_PATH),  # name of the log file. "Append mode"
            "-a-",  # enables auto analysis
            "-B",  # batch mode. IDA will generate .IDB and .ASM files
            "-o{}".format(output_path),
            input_path
        ]))
$ ida64.exe -L debug.log -a- -B -obinaryfile.idb  /path/to/binaryfile

0x02.3 生成代码图数据

通过IDA Pro的扩展插件,基于IDB生成Flow图、ACFG汇编代码和ACFG特征。

安装capstone插件

本步骤需要在IDA pro的python环境中安装运行capstone 3.0.4。但由于ida pro 7.3的Linux版本不好找,因此使用在WSL中调用宿主机的IDA Pro 7.3的方式来运行,这就需要在IDA Pro 7.3的python2.7环境中安装capstone包。作者使用的是Linux环境,安装三方包更容易。

因此本人选择在window下需要额外安装python 2.7 x64,并在该环境中安装capstone。

首先尝试使用pip安装,但由于编译问题导致编译失败。(Windows下,涉及C代码的pypi扩展包编译安装是个大坑)

image

从项目主页找到了适用于Windows的预编译包,由于3.0.4版本未放出预编译包,因此使用了3.0.5版本。

链接:https://github.com/capstone-engine/capstone/releases/tag/3.0.5

下载其中的msi包,运行,选择python2.7的安装目录即可安装。

安装成功后在ida python中成功import capstone。

image

生成Flow图

IDA_scripts\IDA_flowchart下执行:

#powershell

$env:IDA_PATH='D:\IDA 7.3\ida64.exe'

python .\cli_flowchart.py -i ..\..\IDBs\Dataset-1\ -o flowchart_Dataset-1.csv

运行成功截图:

image

如在WSL下运行,需要处理依赖路径转换的问题。

生成ACFG汇编代码

本步骤可以对选定的函数生成ACFG。包括函数中涉及的基本块、汇编指令、控制流图的边结构等。

运行方式: 在IDA_Script/IDA_acfg_disam下运行cli_acfg_disam.py

示例(poweshell):

$env:IDA_PATH='D:\IDA 7.3\ida64.exe'
python cli_acfg_disasm.py -j  ../../DBs/Dataset-Vulnerability/features/selected_Dataset-Vulnerability.json -o acfg_disam_Dataset-Vulnerability2
// 示例文件: ACFG_arm32-clang-3.5-O0_afalg.so_acfg_disasm.json
	{
	    "IDBs/Dataset-1/openssl/arm32-clang-3.5-O0_afalg.so.i64": {
	        "arch": "arm-32",
	        "0x215c": { // 函数地址
	            "elapsed_time": 0.0019881725311279297,
	            "nodes": [  // 控制流图节点,即每个基本块的编号
	                8640, 8584, 8652, 8588, 8660, 8620, 8540
	            ],
	            "edges": [ //控制流图的边
	                [ 8620, 8640 ], [ 8588, 8620 ], [ 8584, 8620 ], [ 8620, 8652 ],
	                // ...
	            ],
	            "basic_blocks": { //每个基本块的详细信息
	                "8640": { //基本块编号
	                    "bb_len": 12, //基本块长度
	                    "bb_mnems": [ "movw", "str", "b" ], //基本块中的指令(简化版)
	                    "bb_norm": [ "movw_r0,_0x0", "str_r0,_[fp-4]", "b_himm" ], //基本块中的指令(标准版)
	                    "bb_disasm": [ "movw r0, #0", "str r0, [fp, #-4]", "b #0x21d4" ], //基本块中的指令(反汇编)
	                    "b64_bytes": "AAAA4wQAC+UBAADq", //基本块的字节码
	                    "bb_heads": [ 8640, 8644, 8648 ] //基本块的头部
	                },
	                "8584": {/* ...*/ } //,
	                // ...
	            }
	        }
	    }
}

生成ACFG特征

0x02.4 数据筛选清洗

0x02.5 生成函数对

根据实验组中的编译优化、指令集等异同,组合生成用于训练的函数对。

0x02.6

  1. 数据集拆分:拆分得到训练、验证、测试集

0x03 复现Asm2Vec & Doc2vec实验

Asm2vec和Doc2vec实现由两个模块构成。第一个模块以ACFG逆向数据为输入,并输出所选函数的随机路径。然后,这些随机路径作为机器学习第二部分的输入。

  • 待补充


欢迎在ISSUE参与本博客讨论: m2kar/m2kar.github.io#19