1. 类似于valgrind,pin也是一个用于编写动态分析程序的框架。Pin由Intel维护,因而貌似更加强大。Pin支持的Linux二进制,包括IA-32,Intel-64,Itanium等处理器;支持的windows二进制,包括IA-32和Intel64;支持的MacOS二进制,包括IA-32。Pin采取的思路是“运行时instrumentation”,而不是静态地重写二进制代码,这样,Pin可以处理一个正在运行的进程。
Pin的特色是提供了大量地API,而且文档比较详细。
2. 一个完整的例子
#include <iostream>
#include <fstream>
#include "pin.H"
// The running count of instructions is kept here
// make it static to help the compiler optimize docount
static UINT64 icount = 0;
// This function is called before every instruction is executed
VOID docount() { icount++; }
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
// Insert a call to docount before every instruction, no arguments are passed
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
}
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
"o", "inscount.out", "specify output file name");
// This function is called when the application exits
VOID Fini(INT32 code, VOID *v)
{
// Write to a file since cout and cerr maybe closed by the application
ofstream OutFile;
OutFile.open(KnobOutputFile.Value().c_str());
OutFile.setf(ios::showbase);
OutFile << "Count " << icount << endl;
OutFile.close();
}
/* ===================================================================== */
/* Print Help Message */
/* ===================================================================== */
INT32 Usage()
{
cerr << "This tool counts the number of dynamic instructions executed" << endl;
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
/* ===================================================================== */
/* Main */
/* ===================================================================== */
/* argc, argv are the entire command line: p in -t <toolname> -- ... */
/* ===================================================================== */
int main(int argc, char * argv[])
{
// Initialize pin
if (PIN_Init(argc, argv)) return Usage();
// Register Instruction to be called to instrument instructions
INS_AddInstrumentFunction(Instruction, 0);
// Register Fini to be called when the application exits
PIN_AddFiniFunction(Fini, 0);
// Start the program, never returns
PIN_StartProgram();
return 0;
}
3. 其它
3.1 例子的说明
该例子实现了一个统计执行的指令数目的功能。可以看出,一个Pin工具主要包括4个部分:
- 初始化Pin环境:PIN_Init
- 设置用于Instrument的回调函数:INS_AddInstrumentFunction添加一个回调函数,该回调函数的执行时机是每执行一条指令
- 应用结束前工作,与PIN_Init对应:PIN_AddFiniFunction
- 启动Instrument过程
3.2 其它函数
函数名 | 执行时机 | 回调函数原型 | 常用函数 |
INS_AddInstrumentFunction | 每执行一条新指令 | (INS, void *) | INS_InsertCall |
TRACE_AddInstrumentFunction | 每执行一个新trace(基本块) | (TRACE, void *) | BBL_InsertCall |
RTN_AddInstrumentFunction | 每执行一个新函数 | (RTN, void *) | RTN_InsertCall |
IMG_AddInstrumentFunction | 每加载一个新映像 | (IMG, void *) | |
IMG_AddUnloadFunction | 每卸载一个映像 |
参考:
1. http://www.pintool.org