Qiling框架初探

Setup·

Initialization·

模拟二进制文件
在预加载(初始化期间)状态下,有多个选项可以配置。

Binary emulation·

名称 类型 描述
argv Sequence[str] 一个模拟命令行参数的序列
rootfs str 模拟的文件系统根目录。被模拟的程序访问的所有路径都基于此目录
env (可选) MutableMapping[AnyStr, AnyStr] 一个环境变量字典,供模拟程序使用

Shellcode emulation·

名称 类型 描述
code bytes 要模拟的 shellcode,替代 argv
rootfs (可选) str 参见上表
ostype str 或 QL_OS 设置目标操作系统(不区分大小写):‘Linux’, ‘FreeBSD’, ‘MacOS’, ‘Windows’, ‘UEFI’, ‘DOS’, ‘EVM’ 或 ‘QNX’
archtype str 或 QL_ARCH 设置目标架构(不区分大小写):‘a8086’, ‘x86’, ‘x8664’, ‘ARM’, ‘ARM64’, ‘MIPS’, ‘EVM’, ‘Cortex_M’, ‘RISCV’ 或 ‘RISCV64’
endian (可选) bool 指示架构的字节序(仅对 ARM 和 MIPS 相关)
thumb (可选) bool 指示 ARM thumb 模式(仅对 ARM 相关)

Common Qiling initialization options·

名称 类型 描述
verbose (可选) QL_VERBOSE 设置 Qiling 日志的详细程度(默认:QL_VERBOSE.DEFAULT)。更多细节参见打印部分
profile (可选) str 额外设置的配置文件路径。更多细节参见配置文件部分
console (可选) bool 如果设置为 False,则完全禁用 Qiling 日志,这相当于设置 verbose=QL_VERBOSE.DISABLED
multithread (可选) bool 指示目标是否应作为多线程程序仿真
libcache (可选) bool 指示是否应从缓存加载库。这可以节省库在后续运行时的解析和重定位时间。目前仅适用于 Windows

Setup·

ql=Qiling() 之后和 ql.run() 之前可用的选项:

  • ql.fs_mapper(“tobe_mapped”, “actual_path”)
    将 Qiling 文件或目录映射到实际文件夹,例如:

    1
    ql.fs_mapper('/etc', '/real_etc')
  • ql.debug_stop = False
    默认是 False。遇到缺失的 POSIX syscall 或 API 停止。

  • ql.debugger = None
    远程调试器。请参阅相关文档

  • ql.verbose = 1
    从 1 到 n,请参阅print section获取更多细节。

Execution·

通过调用 ql.run() 来启动二进制执行。但在某些情况下,如部分执行,有 4 个额外选项可以在 ql.run() 中使用,以实现更精细的控制。

1
ql.run(begin, end, timeout, count)

例如:

1
2
3
ql = Qiling()
ql.run(begin = 0xFE, end = 0xFF)
ql.run(begin = 0xAE, end = 0xFF)

这将只允许程序在地址 0xFE 到 0xFF 之间执行。因此,像模糊测试这样的活动不必从头到尾执行整个文件,只需模糊测试目标部分。请查看示例代码。

Qltool·

qltool有四个可用命令:

  1. run:仿真一个程序二进制文件。

  2. code:执行一段shellcode。

  3. qltui:显示qltool的终端用户界面。

  4. examples:显示用法示例。

Emulation·

Run Options·

用于仿真二进制文件的选项:

选项名称 缩写 参数 描述
--filename -f filename 要仿真的二进制文件名
--rootfs dirname 仿真根目录,所有库文件所在的目录
--args 要仿真的程序命令行参数

注意:

  • 如果未指定--filename,最后一个参数将被视为程序二进制文件。

  • 如果未指定--args,所有尾随参数将被视为程序命令行参数。

Code Options·

用于执行shellcode的选项:

选项名称 缩写 参数 描述
--filename -f filename 输入文件名
--input -i hex 输入的十六进制字符串;仅当--format设置为hex时相关
--format asm, hex, bin 指定文件或输入格式:汇编(assembly)、十六进制字符串(hex)或二进制文件(bin)
--arch x86, x8664, arm, arm_thumb, arm64, mips, a8086, evm 目标架构
--endian little, big 目标字节序(默认:little)
--os linux, freebsd, macos, windows, uefi, dos, evm 目标操作系统

注意:

  • --format设置为hex时,qltool首先会在--input中查找数据。如果未指定输入字符串,它会参考在--filename中指定的文件。

Common Options·

这些选项适用于所有命令:

选项名称 缩写 参数 描述
--verbose -v off, default, debug, disasm, dump 设置日志详细级别
--env filename 包含环境字典的Pickle文件路径,或一个评估结果为字典的Python字符串
--gdb -g [server:port] 启用gdb服务器
--qdb 在入口点附加qdb,目前仅支持MIPS和ARM(thumb模式)
--rr 启用qdb记录和重放功能;需要--qdb
--profile filename 指定配置文件
--no-console 不将程序输出发送到stdout
--filter -e regexp 在日志输出上应用过滤正则表达式
--log-file filename 将日志输出到文件
--log-plain 在日志输出中不使用颜色;在将日志输出到文件时有用
--root 启用需要sudo的模式
--debug-stop 在第一个错误时停止仿真;需要将详细级别设置为debug或dump
--multithread -m 以多线程模式执行程序
--timeout microseconds 设置仿真超时时间(以微秒为单位,1000000μs = 1s)
--coverage-file -c filename 代码覆盖率输出文件
--coverage-format drcov, drcov_exact 代码覆盖率文件格式
--json 输出仿真报告为JSON格式

qltui·

qltuiqltool的终端用户界面,提供以下功能:

  • 运行在qltool之上。

  • 通过界面接受runcode命令的数据。

  • 返回一个Argparse Namespace对象给qltool进行执行。

  • 提供交互式报告查看器以及将报告保存为PDF的选项。

Examples·

shellcode·

1
2
3
4
5
6
7
8
9
$ ./qltool code --os linux --arch arm --format hex -f examples/shellcodes/linarm32_tcp_reverse_shell.hex
$ ./qltool code --os linux --arch x86 --format asm -f examples/shellcodes/lin32_execve.asm
```k

### binary file

```shell
$ ./qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello --rootfs examples/rootfs/x8664_linux/
$ ./qltool run -f examples/rootfs/mips32el_linux/bin/mips32el_hello --rootfs examples/rootfs/mips32el_linux

UEFI file·

1
./qltool run -f examples/rootfs/x8664_efi/bin/TcgPlatformSetupPolicy --rootfs examples/rootfs/x8664_efi --env examples/rootfs/x8664_efi/rom2_nvar.pickel

GDB debugger enable·

1
./qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello --gdb 127.0.0.1:9999 --rootfs examples/rootfs/x8664_linux

Binary file and argv·

1
2
./qltool run -f examples/rootfs/x8664_linux/bin/x8664_args --rootfs examples/rootfs/x8664_linux --args test1 test2 test3
./qltool run --rootfs examples/rootfs/x8664_linux examples/rootfs/x8664_linux/bin/x8664_args test1 test2 test3

Binary file and various output format·

1
./qltool run -f examples/rootfs/mips32el_linux/bin/mips32el_hello --rootfs examples/rootfs/mips32el_linux --verbose disasm

Binary file and env·

1
./qltool run -f jexamples/rootfs/x8664_linux/bin/tester --rootfs jexamples/rootfs/x8664_linux --env '{"LD_PRELOAD":"hijack.so"}' --verbose debug

qltui·

1
./qltool qltui