动态二进制插桩工具Pin和pintools

Pin简介

Intel官方文档 Pin,概述,下载,手册等都有

Pin是intel开发的一个动态二进制插桩工具,提供了丰富的API,支持windows、linux、macos,适用于 IA-32、x86-64 和 MIC 指令集架构。

动态二进制插桩(Dynamic Binary Instrumentation,DBI)的含义:不需要源代码,可以在二进制可执行文件文件的任意位置插入任意的代码 (C/C++ 编写),可以将代码动态地添加到正在执行地可执行文件中。目前的DBI平台有Pin、DynamoRIO、Valgrind等。

基于Pin提供的API开发(c,c++,asm)的工具为pintools。Pin最初是计算机体系结构分析工具,但其灵活的API和活跃的社区(称为“ Pinheads ”)创建了一组用于安全、仿真和并行程序分析的多样化工具。

Pin的功能:可以用自己的函数替换程序中的函数,并且在自己的函数中调用被替换的函数;可以在指令中插入对检测函数的调用,使得在执行指令时执行检测函数,同时可以给检测函数传递参数(寄存器值、指令读写的内存地址、寄存器上下文);可以随时attach和detach进程,即可以自定义在程序中需要插桩和检测的部分;可以追踪函数调用以及syscall,检测/改变参数;可以配合调试器(如gdb)使用,实现调试器的一些拓展功能;跟踪应用程序子线程;拦截signal信号;检测进程树等。

Pintool使用

先看readme,介绍了pintools的编译和基本使用

readme演示的是opcodemix,它可以用来分析程序包含的不同指令组合的数目,比如可以比较两款编译器编译生成的文件的指令组合的差异

1
2
3
4
5
6
7
8
9
10
11
This example applies to a 64-bit application. For a 32-bit application please use "obj-ia32"
instead of "obj-intel64" and add "TARGET=ia32" to the make command.

To build and run a sample tool on Linux*:

cd source/tools/SimpleExamples
make obj-intel64/opcodemix.so
../../../pin -t obj-intel64/opcodemix.so -- /bin/ls

This will instrument and run /bin/ls, the output for this tool is in
opcodemix.out.

下载Pin

编译ManualExamples下的所有Pintool(64位),编译生成的文件会放在obj-intel64目录中

1
2
$ cd source/tools/ManualExamples
$ make all TARGET=intel64

使用编译好的工具,我们需要.so文件-t指明要使用的pintool,–后面是要插桩运行的程序

1
../../../pin -t obj-intel64/inscount0.so -- /bin/ls

这里使用的是inscount0,可以统计运行的指令数量,结果保存在运行时所在目录下的inscount.out文件,inscount0、incount1、inscount2的区别在于后者对运行效率进行了优化。

Pintool架构

windows和linux下Pin的大致架构都是如下

  • 供 pintool 调用的API库。Linux下是instrumentation api 库,windows中是PIN.LIB;
  • VM:即 virtual machine,它的功能主要是插桩并执行程序,过程类似于即时编译,只是编译变成了插桩。大致流程是:先对部分代码进行插桩,放到code cache中运行,运行时需要跳转到未插桩的代码时再对相应代码进行插桩并放入code cache。linux中包含了 emulation unit 用来处理系统调用,JIT 编译器负责编译和插桩,每次取一个 trace 编译后送到 code cache 中;windows原理相同,主要功能集中在PINVM.DLL,执行过程大概是启动pin.exe以debugger的模式,附加要分析程序的进程 -> 注入pinvm.dll->注入pintool的dll->开始运行。
  • code cache:用来存储插桩后的代码,真正执行的是 code cache 中的代码,原目标插桩文件中的代码不会执行。

linux下的架构

来源

1

windows下的架构

来源

2

编写自己的Pintools

阅读不同版本Pin对应的用户手册,其中有详细的API及示例,如Pin 3.28 User Guide

[V4ler1an的博客],主要是官方文档的相关内容的整理总结,博主是看雪二进制漏洞板块小版主。

intel sde

官方下载及文档

sde基于pin和xed,sde在pin插桩分析的基础上多了仿真的功能,可以在特定指令集架构上运行给定程序并捕获各种性能详细信息,可以供开发人员提前熟悉和探索即将推出的新指令集,为在软件中使用新指令集做准备。

Intel X86 Encoder Decoder (XED) 是一个软件库,用于编码和解码 X86(IA32 和 Intel64)指令。解码器采用 1-15 字节的序列以及机器模式信息,并生成描述操作码、操作数和标志的数据结构。编码器采用类似的数据结构并生成 1 到 15 个字节的序列。反汇编本质上是对数据结构的打印。

即XED可以对x86/64代码进行反汇编以及将汇编转化为机器码,可执行程序xed可以反汇编PE和ELF可执行文件。

sde基本使用

中括号表示可选参数

1
path-to-kit/sde [sde args] -- user-application [app args]

用sde运行cmd或shell可以使所有在cmd/shell中运行的程序都在sde的控制之下,sde可以收集并分析所有该命令行中的内容。

例如:

1
sde -icount -- /bin/sh
1
2
3
4
5
6
7
8
9
#查看帮助
-help
#查看更多更详细的帮助,可查看支持仿真的cpu和指令集以及其对应的命令行参数id,可查看分析工具更详细的参数
-help-long
#查看运行到的不同函数中不同指令的数量统计,输出在文件中
-mix
#统计运行的指令数量,有终端输出和文件输出
-icount
#更多功能及参数请看文档

Pin in CTF

因为Pin能够直接对可执行程序动态插桩进行信息收集,所以求解部分ctf题有奇效。

主要用于程序复杂(如复杂的vm逆向以及混淆题)但是对flag(input)的检测是逐位的情况下,每一位的对错都会导致执行流的改变,执行时间或执行指令数量相差巨大,这样就能进行侧信道逐位爆破。

[ctf-wiki]intel pin上有两道例题

2023香山杯nesting

一道vm题,但这里可以不用ida分析

程序运行后会让你输入flag并检测flag是否正确

1
Input your flag:

用sde来统计程序运行到的指令数量,结果会在命令行以ICOUNT: 3421916的形式输出,这也方便爆破脚本的编写

1
sde -icount -- ./nesting

可以发现每多输入一位,总指令数都会增加20万左右

flag的前4位必定是”flag”,分别输入”1111”,”f111”,”fl11”,”fla1”,”flag”可以发现在位数相同的情况下,flag每正确一位总指令数会增加55000左右,说明flag是逐位check的,并且不同结果的执行流长度相差较大,可以通过这一点来爆破flag

爆破脚本,来自Re神

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from pwn import*

def run(str):
p = process(['sde64','-icount','--','./nesting'])
p.recvuntil('Input your flag:')
p.sendline(str)
p.recvuntil('ICOUNT:')
icount = int(p.recvline())
p.close()
return icount

table = '0123456789abcdef-}'
#table = string.printable
flag = 'flag{'

while True:
t1 = run(flag+'#')
ok = 0
for ch in table:
t2 = run(flag+ch)
if(t2-t1>50000):
flag = flag + ch
ok = 1
print(flag)
break
if(ok==0):
print('result : '+flag)
exit()
#flag{2c7c093b-f648-11ed-a716-701ab8caaafe

参考资料

Intel官方文档 Pin

[csdn]Pin介绍,翻译了用户手册的一部分

[ctf-wiki]intel pin

V4ler1an的博客

Intel sde官方文档&&下载


动态二进制插桩工具Pin和pintools
https://lkliki.github.io/2023/10/13/动态二进制插桩pin和pintools/
作者
0P1N
发布于
2023年10月13日
许可协议