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类

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_VALUERTN的返回值

分析函数的参数
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);
这样可以更轻松地模拟更改控制流的指令。

dump所有nop指令的地址及汇编指令反汇编

VOID dump_ins(UINT64 insAddr, std::string insDis) {
	printf("%lx\t%s\n", insAddr, insDis.c_str());
}
if (INS_IsNop(ins)) {
		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)dump_ins, IARG_ADDRINT,
			INS_Address(ins), IARG_PTR, new string(INS_Disassemble(ins)),
			IARG_END);
	}

一个C++程序执行完毕大概是12亿左右条指令。

跟踪“CALL 0”和“JMP 0”指令

VOID CALL_reg(ADDRINT ip, ADDRINT op, THREADID threadid)
{
        PIN_GetLock(&lock, threadid+1);
        log_info (ip, "CALL", op);
        PIN_ReleaseLock(&lock);
}

VOID CALL_mem(ADDRINT ip, ADDRINT *op_addr, unsigned int op_size, THREADID threadid)
{
        PIN_GetLock(&lock, threadid+1);
        ADDRINT op;
        PIN_SafeCopy(&op, op_addr, op_size);
        log_info (ip, "CALL", op);
        PIN_ReleaseLock(&lock);
};

...

// this function executed only during startup, so no need to optimize anything here:
VOID Instrument_all(INS ins, VOID* v)
{
        // CALL reg
        // N.B.: this doesn't work: if ((INS_Mnemonic(ins) == "CALL") && (INS_OperandIsReg(ins, 0)))
        if (INS_IsCall(ins) && (INS_OperandIsReg(ins, 0)))
        {
                INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        AFUNPTR(CALL_reg),
                        IARG_INST_PTR,
                        IARG_REG_VALUE, REG(INS_OperandReg(ins, 0)),
                        IARG_THREAD_ID,
                        IARG_END);
        }

        // CALL mem
        if (INS_IsCall(ins) && INS_OperandIsMemory(ins, 0))
        {
                INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        AFUNPTR(CALL_mem),
                        IARG_INST_PTR,
                        IARG_MEMORYREAD_EA,
                        IARG_MEMORYREAD_SIZE,
                        IARG_THREAD_ID,
                        IARG_END);
        }

官方提供Pintool及其作用

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

参考链接

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摔不死的笨鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值