pin示例程序详解

计数程序inscount0

#include <iostream>
#include <fstream>
#include "pin.H"

ofstream OutFile;

// 计数执行的指令
// static不在栈中,可以方便计数
static UINT64 icount = 0;

// 当每个指令执行前被执行,来技术指令的个数
VOID docount() { icount++; }

// 遇到新指令时执行这个函数
VOID Instruction(INS ins, VOID *v)
{
    // 在每一个指令前植入一个指向docount的调用,不传参
    //第一个参数:操作的指令;第二个参数:调用方式,此处为指令前调用,即无条件调用;
    //第三个参数:指向调用的函数的指针;第四个参数:决定传入参数的类型,不传参,所以空缺,一定以IARG_END结尾
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
}
//KNOB_MODE_WRITEONCE表示:每次调用完成输出结果都是重写
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
    "o", "inscount.out", "specify output file name");

// 退出时输出计数值
VOID Fini(INT32 code, VOID *v)
{
    // Write to a file since cout and cerr maybe closed by the application
    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: pin -t <toolname> -- ...    */
/* ===================================================================== */

int main(int argc, char * argv[])
{
    // 初始化pin
    if (PIN_Init(argc, argv)) return Usage();

    OutFile.open(KnobOutputFile.Value().c_str());

    // 注册插桩函数
    INS_AddInstrumentFunction(Instruction, 0);

    // 注册退出函数
    PIN_AddFiniFunction(Fini, 0);

    // 开始执行
    PIN_StartProgram();

    return 0;
}

小结:

这个程序给出了一般pintool的基本框架: 在main函数中首先调用PIN_Init初始化
之后就可以使用INS_AddInstrumentFunction注册一个插桩函数,在原始程序的每条指令被执行前,都会进入Instruction这个函数中,其第2个参数为一个额外传递给Instruction的参数,即对应VOID
*v这个参数,这里没有使用。而Instruction接受的第一个参数为INS结构,用来表示一条指令。 最后又注册了一个程序退出时的函数Fini,接着就可以使用PIN_StartProgram启动程序了。

此处参考http://brieflyx.me/2017/binary-analysis/intel-pin-intro/
这是一个最简单的插桩函数了,我理解起来也用了一段时间。主要是对每一个函数的作用的理解,并且查阅了一些资料。接下来要看更复杂的函数了。

猜你喜欢

转载自blog.csdn.net/shadothew/article/details/81514895