> 文章列表 > Intel Pin常用基础函数

Intel Pin常用基础函数

Intel Pin常用基础函数

Intel Pin根据颗粒度可以划分为指令级插桩(INS)、基本块级插桩(TRACE)、函数级插桩(RTN)、镜像级插桩(IMG)。

基础函数

PIN_InitSymbols函数
用于初始化程序的符号表,对于RTN和IMG两个颗粒度的插桩分析时这个函数不可缺少。

Fini函数

PIN_AddFiniFunction(Fini, 0);
VOID Fini(INT32 code, VOID* v)
{fprintf(trace, "#eof\\n");fclose(trace);
}

Usage函数

if (PIN_Init(argc, argv)) return Usage();
INT32 Usage()
{PIN_ERROR("This Pintool prints the IPs of every instruction executed\\n" + KNOB_BASE::StringKnobSummary() + "\\n");return -1;
}

Knob类

KnobOutputFile
KNOB< string > KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "inscount.out", "specify output file name");

分析函数的参数

字段 作用及意义
IARG_INST_PTR 指令的地址
IARG_REG_VALUE 寄存器的值
IARG_CONTEXT
IARG_FUNCARG_ENTRYPOINT_VALUE 传递给RTN的参数,需要额外参数表示RTN的第几个参数,第一个参数从0开始
IARG_FUNCRET_EXITPOINT_VALUE RTN的返回值

分析函数的参数
https://software.intel.com/sites/landingpage/pintool/docs/98650/Pin/doc/html/group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a

插入点的位置

插入点 分析回调 有效性
IPOINT_BEFORE 在插桩对象之前 总是有效
IPOINT_AFTER 在直行边(分支或“规则的”指令) INS_HasFallthrough为真则有效
IPOINT_ANYWHERE 在插桩对象的任何位置 只对TRACE或BBL有效
IPOINT_TAKEN_BRANCH 在分支的转移边 INS_IsBranchOrCall为真则有效

编写Pintool常用的语法

BBL遍历

for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)){BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)docount, IARG_UINT32, BBL_NumIns(bbl), IARG_END);
}

指令类型判断
// 查找将值从内存移动到寄存器的指令
例如:Mov eax,[0x77d154h]

   if ( INS_Opcode (ins) == XED_ICLASS_MOV && INS_IsMemoryRead (ins) && INS_OperandIsReg (ins, 0) && INS_OperandIsMemory (ins, 1))INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoLoad), IARG_UINT32, REG(INS_OperandReg(ins, 0)), IARG_MEMORYREAD_EA,IARG_RETURN_REGS, INS_OperandReg(ins, 0), IARG_END);

首先if语句的判断确定这必须是一条mov寄存器,内存这样的地址。因此IARG_MEMORYREAD_EA获取内存的地址,然后使用IARG_RETURN_REGS指定返回值保存位置,也就是当前指令的第一个寄存器,其中INS_OpeandReg(ins,0)能够获取指令的第0个操作数(也就是寄存器)。

获取malloc函数在IMG中的函数映射地址

RTN mallocRtn = RTN_FindByName(img, MALLOC);

如果在多线程应用程序上运行时,pintool在回调中打开文件,则可能会发生死锁。要解决此问题,请在 main中打开一个文件,并使用线程 ID 标记数据。请参阅 source/tools/ManualExamples/buffer_windows.cpp 作为示例。

修改原始指令
INS_Delete()删除原始指令;
插入直接或间接分支(使用INS_InsertDirectJump和INS_InsertIndirectJump);
这样可以更轻松地模拟更改控制流的指令。

官方提供Pintool及其作用

Malloctrace.cpp 跟踪传递给malloc函数的参数值或返回值
Imageload.cpp 加载模块及image详情
Proccount.cpp 函数过程调用及次数统计

参考链接

https://software.intel.com/sites/landingpage/pintool/docs/98650/Pin/doc/html/index.html#WindowsNotes