Commit 32e0451f by 文周繁

feat: e9patch使用说明

parent b65e0142
# E9Patch代码说明与使用说明
# E9Patch代码说明与使用说明
## 1.关于e9patch的简要说明
e9patch可以通过`-M`选项,指定需要patch的指令。通过`-P`项,指定运行到patch指令时执行的操作。
```
./e9tool -M 'jmp' -P 'entry()@count' input-binary -o output-binary
./e9tool -M 'call and target=&malloc' -P 'entry()@count' input-binary -o output-binary
```
或者指令匹配也可进行使用自定义代码
```
./e9tool -M 'plugin(e9afl).match() ' -P 'call entry(random)@state-tracer' xx-1 -o xx-2
```
## 2.代码说明
可以在e9patch的框架下开发汇编指令匹配代码来确定二进制程序的插桩点位
### 指令匹配代码
覆盖率插桩匹配代码:`./e9patch/examples/plugins/e9AFLPlugin.cpp`
状态插桩匹配代码:`./e9patch/examples/plugins/funcMatch.cpp`
### 指令插桩代码
所有的插桩函数都`./e9patch/examplesafl-rt-bk-2.c`中集成
afl-rt-bk-2.c更多也起到**一个中间件的**作用,对于覆盖率插桩的代码,由于操作比较简单在这个代码里面直接集成,就是代码中的entry函数
```c
void entry(uint32_t curr_loc)
{
uint32_t prev_loc = 0;
asm ("mov %%fs:0x4c,%0" : "=r"(prev_loc));
uint16_t idx = prev_loc ^ curr_loc;
AREA_BASE[idx]++;
asm ("mov %0,%%fs:0x4c" : : "r"(curr_loc >> 1));
}
```
对于状态推断插桩,则具体的插桩功能函数集成在动态链接库`state-tracer-log.so`中,afl-rt-bk-2.c负责对链接库进行加载,并在对应匹配的插桩指令,调用动态链接库中的导出函数(afl-rt-bk-2.c中的state_tracer函数)。
此外,afl-rt-bk-2.c还在初始化(afl-rt-bk-2.c中的init函数)时,完成afl-forkserver的启动。
**插桩函数在每次更新后需要利用e9patch中的e9compile重新编译**
```c
./e9compile.sh ./examples/afl-rt-bk-2.c -I ./examples/ -I ./src/e9patch/
```
afl-rt-bk-2.c中的配置文件说明
```c
#define FORKSRV_FD 198
#define AREA_BASE ((uint8_t *)0x2A0000)
#define AREA_SIZE ((size_t)1 << 16)
#define LibPath "/home/echo/e9patch/afl-llvm-state-tracer/state-tracer-log.so" // 状态推断函数库
#define LOG_FILE1 "/home/echo/e9patch/symfunc.log" // 匹配的所有关键插桩函数,自动生成不用更改
#define VAR_FILE "/home/echo/e9patch/live555-VarInfo.log" // ghidra脚本输出的栈内存插桩点信息
#define RUNTIME_LOG "/tmp/e9afl.log" // 运行过程写入的log路径
#define nullptr NULL
#define ENABLE_RUN_LOG // 开启log
```
在进行状态推断插桩时,需要配置如下信息:
```c
#define VAR_FILE "/home/echo/e9patch/live555-VarInfo.log"
```
**注:**每次需要利用ghidra脚本生成相应程序的插桩点位信息
## 3.使用说明
### 代码覆盖率插桩
搭配AFLNet使用
```bash
./e9tool -M 'plugin(e9AFLPlugin).match()' -P 'entry(random)@afl-rt-bk-2' ./e9-test/tinydtls-e9patch/tests/dtls-server -o ./e9-test/tinydtls-e9patch/tests/dtls-server-e9-0902-2
```
通过e9AFLPlugin代码中的match函数确定所有基本块的插桩点位
在所有的插桩点位插入afl-rt中的entry函数,每次调用时
输出信息如下
```bash
-----------------------------------------------
mode = Linux ELF executable
input_binary = ./e9-test/tinydtls-e9patch/tests/dtls-server
output_binary = ./e9-test/tinydtls-e9patch/tests/dtls-server-e9-0421
num_patched = 1464 / 1464 (100.00%)
num_patched_B1 = 1312 / 1464 (89.62%)
num_patched_B2 = 124 / 1464 (8.47%)
num_patched_T1 = 27 / 1464 (1.84%)
num_patched_T2 = 0 / 1464 (0.00%)
num_patched_T3 = 1 / 1464 (0.07%)
num_virtual_mappings = 144
num_physical_mappings = 68 (47.22%)
num_virtual_bytes = 589824
num_physical_bytes = 278528 (47.22%)
input_file_size = 96848
output_file_size = 434173 (448.30%)
time_elapsed = 40ms
memory_used = 4984KB
----------------------------------------------
```
输出的二进制程序可直接作为aflnet的输入,进行测试
```bash
/home/ubuntu/aflnet/afl-fuzz -d -i /home/ubuntu/experiments/in-dtls -o out-tinydtls-e9-aflnet -N udp://127.0.0.1/20220 -P DTLS12 -m none -D 10000 -q 3 -s 3 -E -K -W 30 ./dtls-server-e9-0902-2
```
### 覆盖率插桩+状态推断插桩
```bash
./e9tool -M 'plugin(e9AFLPlugin).match()' -P 'entry(random)@afl-rt-bk-2' \
-M 'plugin(funcMatch).match()' -P 'state_tracer(state,asm,size,offset)@afl-rt-bk-2' \
./e9-test/dnsmasq/src/dnsmasq -o ./e9-test/dnsmasq/src/dnsmasq-e9-0715
```
输出信息如下
```bash
-----------------------------------------------
mode = Linux ELF executable
input_binary = ./e9-test/dnsmasq/src/dnsmasq
output_binary = ./e9-test/dnsmasq/src/dnsmasq-e9-0711
num_patched = 9263 / 9263 (100.00%)
num_patched_B1 = 8338 / 9263 (90.01%)
num_patched_B2 = 658 / 9263 (7.10%)
num_patched_T1 = 230 / 9263 (2.48%)
num_patched_T2 = 22 / 9263 (0.24%)
num_patched_T3 = 15 / 9263 (0.16%)
num_virtual_mappings = 723
num_physical_mappings = 256 (35.41%)
num_virtual_bytes = 2961408
num_physical_bytes = 1048576 (35.41%)
input_file_size = 349264
output_file_size = 1645345 (471.09%)
time_elapsed = 444ms
memory_used = 11604KB
-----------------------------------------------
```
输出的二进制文件可直接交给stateAFL进行测试
```bash
/home/ubuntu/stateafl/afl-fuzz -d -i /home/ubuntu/experiments/in-dns-replay -o out-dnsmasq-stateafl-0918 -N udp://127.0.0.1/5353 -P DNS -t 5000 -m none -D 10000 -q 3 -s 3 -E -K ./dnsmasq-e9-0715
```
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment