Windows下使用二进制插装工具Pin

Pin是Intel公司提供的一个程序插装工具,支持IA-32,Intel(R) 64和IA64架构上的Linux和Windows可执行程序。

Pin允许一个工具在可执行程序的任何地方插入任意代码(用C或C++编写)。这些代码在程序运行的时候动态添加(修改内存映像)。这也使得可以将Pin附加到进程上。

插装粒度

指令级插桩(instruction instrumentatio),通过函数INS_AddInstrumentFunctio实现。

轨迹级插装(trace instrumentation),通过函数TRACE_AddInstrumentFunction实现。(貌似就是基本块插装)

镜像级插装(image instrumentation),使用IMG_AddInstrumentFunction函数,由于其依赖于符号信息去确定函数边界,因此必须在调用PIN_Init之前调用PIN_InitSymbols。

函数级的插装(routine instrumentation),使用RTN_AddInstrumentFunction函数。函数级插装比镜像级插装更有效,因为只有镜像中的一小部分函数被执行。

Pin与Pintool

Pin只是一个插装的平台或框架,执行具体的插装任务要通过定义Pintool来实现。目录source\tools\下定义了非常多的Pin工具,下面列举一些例子。

打开Visual Studio 命令行界面,进入目录source\tools\ManualExamples。

编译目录下的所有例子

$ cd source\tools\ManualExamples
$ ..\nmake tools

编译和运行一个具体例子(如inscount0)

$ cd source\tools\ManualExamples
$ ..\nmake inscount0.test

编译一个具体例子但不运行(如inscount0)

$ cd source\tools\ManualExamples
$ ..\nmake inscount0.dll

(注:这里的nmake指souce\tools\ nmake.bat,调用的是当前目录下的Nmakefile文件,即source\tools\ManualExamples\Nmakefile。打开Nmakefile文件,可以发现并不是每一个.cpp文件都有对应的.dll文件,可能要自己添加。)

简单指令计数(指令级插装)

源码:source/tools/ManualExamples/inscount0.cpp

功能:对应用程序执行的指令计数,展示怎么写分析函数

测试命令如下:

cd source\tools\ManualExamples
pin -t obj-ia32\inscount0.dll -- cmd /C dir

输出:

type inscount0.out
Count 4565876

Pin的用法为:pin [Pin Args] [-t <ToolDLL> [Tool Args]] -- <App EXE> [App args]

这里没有Pin Args,Tool DLL为obj-ia32\inscount0.dll,要计数的应用程序为cmd,cmd的参数为 /C dir,也可指定其他可执行程序,参数不是必须的。默认输出结果保存到inscount0.out,也可用-o filepath指定。

后面的Pintool不一定可以指定保存路径,只有实现了函数KnobOutputFile才可以,不过可以很容易添加。

指令地址追踪(指令级插装)

源码:source/tools/ManualExamples/itrace.cpp

功能:打印每条执行指令的地址,展示怎么向分析函数传递参数

测试命令如下:

pin -t obj-ia32\itrace.dll -- cmd /C dir

输出:itrace.out

内存引用追踪(指令级插装)

源码:source/tools/ManualExamples/pinatrace.cpp

功能:只追踪内存操作指令

测试命令如下:

pin -t obj-ia32\pinatrace.dll -- cmd /C dir

输出:pinatrace.out

检测镜像的加载和卸载(镜像级插装)

源码:source/tools/ManualExamples/imageload.cpp

功能:检测镜像文件的加载和卸载(Windows下主要为dll文件)

测试命令如下:

pin -t obj-ia32\imageload.dll -- cmd /C dir

输出:imageload.out

更有效的指令计数(Trace级插装)

源码:source/tools/ManualExamples/inscount1.cpp

功能:同inscount0,但不是在每一指令执行前插入调用,而是对每一基本块(BBL)

测试命令如下:

pin -t obj-ia32\inscount1.dll -- cmd /C dir

输出:inscount1.out

过程指令计数(函数级插装)

源码:source/tools/ManualExamples/proccount.cpp

功能:统计每一函数被调用的次数,及这一函数内执行的指令数

测试命令如下:

pin -t obj-ia32\proccount.dll -- cmd /C dir

输出:proccount.out

使用 PIN_SafeCopy()

源码:source/tools/ManualExamples/safecopy.cpp

功能:将指定数目字节从内存一个地址复制到另一地址(推荐用这个API来读写应用程序的内存)

测试命令如下:

pin -t obj-ia32\safecopy.dll -- ..\Tests\obj-ia32\cp-pin.exe Nmakefile obj-ia32\safecopy.dll.Nmakefile.copy

也可以在visual studio命令提示符窗口中切换到source/tools/ManualExamples/,然后输入:

..\nmake safecopy.test

输出:safecopy.out

指令顺序

源码:source/tools/ManualExamples/invocation.cpp

功能: 以3种不同的方式插装返回指令

测试命令如下:

pin -t obj-ia32\invocation.dll -- cmd /C dir

输出:invocation.out

发现函数参数的值

源码:source/tools/ManualExamples/malloctrace.cpp

功能: 打印函数malloc()和free()及malloc()返回值的输入参数

测试命令如下:

pin -t obj-ia32\ malloctrace.dll -- ..\Tests\obj-ia32\cp-pin.exe Nmakefile obj-ia32\ malloctrace.dll.Nmakefile.copy

输出:malloctrace.out

在Windows下通过名称查找函数

源码:source/tools/ManualExamples/w_malloctrace.cpp

功能: 通过符号表获得函数名为RtlAllocateHeap的地址,进一步获得其参数和返回值

测试命令如下:

pin -t obj-ia32\ w_malloctrace.dll -- ..\Tests\obj-ia32\cp-pin.exe Nmakefile obj-ia32\ w_malloctrace.dll.Nmakefile.copy

输出:w_malloctrace.out

对线程级应用插装

源码:source/tools/ManualExamples/malloc_mt.cpp

功能:展示对线程的插装

测试命令如下:

pin -t obj-ia32\malloc_mt.dll -- cmd /C dir

输出:malloc_mt.out

注:给的例子thread_lin不能在Windows编译,但是cmd /C dir貌似不是多线程的,不够典型。Windows下会有死锁的情况,解决的方法见buffer-win.cpp。

使用TLS

源码:source/tools/ManualExamples/inscount_tls.cpp

功能:展示使用线程本地存储(tls),创建特定于线程的数据

测试命令如下:

pin -t obj-ia32\inscount_tls.dll -- cmd /C dir

输出:inscount_tls.out

注:同样thread_lin不能在Windows编译,改用cmd /C dir。 

使用Fast Buffering APIs

源码:source/tools/ManualExamples/buffer-lin_tls.cpp

功能:打印所有访问内存指令的PC(程序计数器)值和这个指令的有效访问地址

测试命令如下:

pin -t obj-ia32\buffer-lin_tls.dll -- cmd /C dir

输出:buffer-lin_tls.out

注:同样thread_lin不能在Windows编译,改用cmd /C dir。如果你的分析函数只是存储参数到缓冲区,可以用Fast Buffering APIs来代替。

发现镜像的静态特性

源码:source/tools/ManualExamples/staticcount.cpp

功能:不用插装发现镜像的静态特性,这里仍然是统计镜像文件的指令数(未运行)

测试命令如下:

pin -t obj-ia32\staticcount.dll -- cmd /C dir

输出:dos显示

从应用程序分离Pin

源码:source/tools/ManualExamples/detach.cpp

功能:从应用程序分离Pin,不再执行插装代码,使其以原始速度运行

测试命令如下:

pin -t obj-ia32\detach.dll -- cmd /C dir

输出:dos显示

在Probe Mode下替换函数

对子进程插装

在forks之前或之后插装

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值