Pin学习1
什么是插桩(Instrumentation)?
向程序注入额外的代码来收集程序运行时的状态。
插桩(Instrumentation)的方法:
-
源代码插桩(source instrumentation)
——对源码进行操作 -
二进制插桩(Binary instrumentation)
——运行时直接注入
为何使用动态指令注入?
- 不需要重新编译或重新链接
- 在运行时检测代码
- 处理动态生成的代码
- 附加到运行的进程中
Pin工具的有点
- 简单易用
- 使用动态指令插入方式
—— 不需要修改源代码、重新编译、重新连接
- 多平台支持
- 支持X86、X86_64、Itanium、Xscale
- 支持Linux、Windows、MacOS
- 鲁棒性
- 支持现实常见应用: 数据库、浏览器
- 支持多线程程序
- 支持信号(signals)
- 高效
- 适用编辑器优化(Applies compiler optimizations on instrumentation code)
Pin使用方式
1 | // 加载和注入一个程序 |
Pin注入的API
- 架构无关的基础API:
- 提供确定的基础功能的API
- Control-flow changes
- Memory accesses
- 提供确定的基础功能的API
- 基于特定架构的API:
- 如基于IA32的段寄存器信息
- 基于调用(call-based)的API:
- 桩程序(Instrumentation routines)
- 分析程序(Analysis routines)
桩程序和分析程序的区别
桩和分析都是从ATOM工具发展来的概念。(搜索关键字 ATOM analysis Instrumentation )
ATOM,即Analysis Tools with OM, http://atominstrument.com/products-services-overview/ http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-TN-44.pdf
桩程序(instrumentation routines)定义了在哪里插桩;
- 如在指令前 :
在指令第一次执行时插桩
分析程序(analysis routines)定义当桩启动时执行哪些操作。 - 如 增量计数器:
在每一次指令执行时发生
Pintool举例1——指令计数
1 | sub $0xff, %edx |
输出指令数
1 | $ /bin/ls |
Pintool举例2——指令跟踪
1 | // 传递ip参数到分析程序中 |
输出轨迹
1 | $ pin -t itrace -- /bin/ls |
ManualExamples/itrace.cpp
1 | #include <stdio.h> |
分析程序的参数举例:
- IARG_INST_PTR
- 指令指针值(program counter)
- IARG_UINT32
- 整型值
- IARG_REG_VALUE
- 指定寄存器的值
- IARG_BRANCH_TARGET_ADDR
- 分支桩的目标地址
- IARG_MEMORY_READ_EA
- 内存读取的有效地址
一个指令的桩的位置
-
前置(IPOINT_BEFORE)
-
后置
- Fall-through edge(IPOINT_AFTER)
- Taken edge (IPOINT_TAKEN_BRANCH)
注: 红色代表 IPOINT_BEFORE, 绿色代表 IPOINT_AFTER,黑色代表 IPOINT_TAKEN_BRANCH。
来源
http://www.cs.du.edu/~dconnors/courses/comp3361/notes/PinTutorial
参考
http://terenceli.github.io/技术/2014/01/02/intro-to-pin
http://huirong.github.io/2015/12/30/Intel-Pin-introduction/#参考文献