安装过程笔记
项目地址:https://github.com/panda-re/panda
查看官方安装文档:https://github.com/panda-re/panda/blob/dev/panda/docs/build_ubuntu.md
编译过程中遇到的最大的一个问题:
在GitHub中搜这个offset/i_t.h,看到一个issue,:
项目地址:https://github.com/panda-re/libosi
安装教程如下:
编译成功:
python接口安装
记得一定要创建一个build文件夹,在这个文件夹下build;
然后 ../build.sh –python即可完成python接口的安装;(之前要根据报错和文档安装一些相关依赖)
../build.sh --python #双横线,文字显示不出来。。。 |
使用方法
首先编写如下启动脚本:
#!/bin/bash
/home/qym/panda/x86_64-softmmu/panda-system-x86_64
-m 2048
-kernel bzImage
-initrd rootfs.cpio
-append “console=ttyS0 nokaslr”
-nographic
-monitor telnet:127.0.0.1:5555,server,nowait
其中panda-system-x86_64是我们前面编译PANDA得到的工具,此时这个终端进入到如下状态:
然后在另一个终端启动qemu monitor:
telnet 127.0.0.1 5555
进入到qemu monitor中界面如下:
在qemu monitor中输入如下内容开始监测:
begin_record test_record
在虚拟机终端中执行操作即可:
在qemu monitor中输入如下内容停止监测:
end_record
快照回放
经过上述操作得到如下两个文件:
其中test_record-rr-nondet.log中存储的是 非确定性(nondeterministic)输入,即虚拟机在运行时遇到的所有 不可预测事件,例如:用户输入(键盘/鼠标)、网络数据包、设备中断、定时器事件,在 回放时,PANDA 会按照这个日志文件重新提供这些输入,从而保证整个执行轨迹与原始运行完全一致。
test_record-rr-snp是 快照(snapshot),记录了:
- 虚拟机的完整 CPU、内存、设备状态
- 所有寄存器和内存布局
它用于 回放的起点。在回放时,PANDA 先恢复快照,然后从 test_record-rr-nondet.log
提供输入,确保每次回放都从相同的初始状态开始,并按照相同的路径执行。
接下来使用如下命令进行回放:
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 -m 2048 -replay test_record
这里要注意-m参数给的内存要和启动时给的内存保持一致,否则会报错。
回放效果图如下所示:
污点分析
分析一个地址的污点传播:
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 -m 2048 -replay cpy -panda taint2:addr=0x4c0236,size=16,label=1
分析寄存器:
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 -m 2048 -replay cpy -panda taint2:reg=RAX,label=1
添加logfile和llvm参数:
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 -m 2048 -replay cpy -panda taint2:reg=RAX,label=1,logfile=taint.log -panda taint2:llvm=1
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 -m 2048 -replay map -panda taint2:addr=0x12340000,size=160000,label=1,logfile=taint.log -panda taint2:llvm=1 -panda taint2:debug=1 -panda tainted_branch -panda taint2:debug=1 -llvm |
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 -m 2048 -replay map -panda taint2:reg=1,label=1 -panda taint2:pandalog=taint.pandalog |
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 \ |
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 \ |
检查llvm依赖:
/home/qym/panda/x86_64-softmmu/panda-system-x86_64 -help -panda taint2 | grep llvm
taint2插件
https://github.com/panda-re/panda/issues/1392
pandare库使用
在每个基本块执行前加hook,打印其地址:
from pandare import Panda
panda = Panda(arch=”x86_64”, mem=’2048M’)
panda.load_plugin(“taint2”) # 你的插件列表里有 taint2
# 监听基本块执行
@panda.cb_before_block_exec
def log_basic_block(cpu, tb):
rip = panda.arch.get_reg(cpu, ‘rip’) # 读取当前指令地址
print(f“[BLOCK] Executing block at: {rip**:#x**}”)
panda.run_replay(“map”)
获取寄存器的值,得到一个int:
rax = panda.arch.get_reg(cpu, ‘rax’)
几个可能用到的hook:
tainit启动失败
直接启动taint:
得到如下报错:
参考这个issue:https://github.com/panda-re/panda/issues/180
修改代码,在第1000个基本块执行的时候开启taint:
紧接着会得到第二个报错:
加入-llvm参数即可解决问题:
on_insn分析
taint的使用
给物理地址加污点、检查是否有污点:
panda.taint_label_ram(0, 1)
print(panda.taint_check_ram(0x10))
dump当前寄存器状态:
panda.arch.dump_state(cpu)
panda.arch.dump_regs(cpu)
其他一些:
def taint_check_reg(self, reg_num):
panda.virt_to_phys(cpu,vmaddr)
panda.arch._get_reg_val(cpu, idx)
v = panda.virtual_memory_read(cpu, 0xffff888000000000, 8) #返回bytes
panda.virtual_memory_write(cpu, 0xffff888000000000, p64(0xdeadbeef))
physical_memory_read
physical_memory_write
syscalls2
参考
https://github.com/panda-re/panda/blob/dev/panda/python/examples/taint.py