在 Intel Pin 中使用 IARG_MEMORYWRITE_SIZE 和 IARG_MEMORYREAD_SIZE 参数

Using IARG_MEMORYWRITE_SIZE and IARG_MEMORYREAD_SIZE parameter in Intel Pin

我正在尝试使用 Intel Pin 来调查可执行文件的内存 activity。我想修改 Pin 工具包中的 pinatrace 示例。我尝试使用 IARG_MEMORYWRITE_SIZE/IARG_MEMORYREAD_SIZE 参数。这是源代码。

#include <stdio.h>
#include <chrono>
#include "pin.H"
#include <string> 
using std::chrono::nanoseconds;

FILE * trace;
auto start=std::chrono::high_resolution_clock::now();

std::string buffer;
// Print a memory read record
VOID RecordMemRead(VOID * ip, VOID * addr,VOID * size)
{
    auto elapsed = (std::chrono::high_resolution_clock::now()) - start;
    nanoseconds ns= std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed);

//sprintf(buffer,trace,"%p: R %p Time,ns %lld \n", ip, addr,ns);

    //std::string fout = fout + std::to_string("%p: R %p Time,ns %lld \n", ip, addr,ns);

    fprintf(trace,"%p: R,bytes %p Size,bytes %lld \n", ip, addr,size);
}

// Print a memory write record
VOID RecordMemWrite(VOID * ip, VOID * addr, VOID * size)
{
    auto elapsed = (std::chrono::high_resolution_clock::now()) - start;
    nanoseconds ns= std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed);

    fprintf(trace,"%p: W,bytes %p Size,bytes %lld \n", ip, addr,size);
}

// Is called for every instruction and instruments reads and writes
VOID Instruction(INS ins, VOID *v)
{
    // Instruments memory accesses using a predicated call, i.e.
    // the instrumentation is called iff the instruction will actually be executed.
    //
    // On the IA-32 and Intel(R) 64 architectures conditional moves and REP 
    // prefixed instructions appear as predicated instructions in Pin.
    UINT32 memOperands = INS_MemoryOperandCount(ins);

    // Iterate over each memory operand of the instruction.
    for (UINT32 memOp = 0; memOp < memOperands; memOp++)
    {
        if (INS_MemoryOperandIsRead(ins, memOp))
        {
            INS_InsertCall(
            //INS_InsertIfCall(
            ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
                IARG_INST_PTR,
                IARG_MEMORYOP_EA,
                IARG_MEMORYREAD_SIZE, memOp,
                IARG_END);
        }
        // Note that in some architectures a single memory operand can be 
        // both read and written (for instance incl (%eax) on IA-32)
        // In that case we instrument it once for read and once for write.
        //IARG_MEMORYREAD_SIZE  Type: UINT32. Size in bytes of memory read.
        //IARG_MEMORYOP_EA
        //IARG_MEMORYWRITE_SIZE     Type: UINT32. Size in bytes of memory write. 
        if (INS_MemoryOperandIsWritten(ins, memOp))
        {
            INS_InsertCall(
           //INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
                IARG_INST_PTR,
                IARG_MEMORYOP_EA,
                IARG_MEMORYWRITE_SIZE, memOp,
                IARG_END);
        }
    }
}

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

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */

INT32 Usage()
{
    PIN_ERROR( "This Pintool prints a trace of memory addresses\n" 
              + KNOB_BASE::StringKnobSummary() + "\n");
    return -1;
}

/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */


int main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv)) return Usage();

    trace = fopen("pinatrace2.out", "w");

    start = std::chrono::high_resolution_clock::now();

    INS_AddInstrumentFunction(Instruction, 0);
    PIN_AddFiniFunction(Fini, 0);

    // Never returns
    PIN_StartProgram();

    return 0;
}

编译后我试图 运行 它,但收到此错误。如果我删除此参数并编辑 RecordMemWrite/RecordMemRead 函数 - 一切正常。

>..\..\..\..\ia32\bin\pin.exe -t MyPinTool -- cmd /C dir
A: Source\pin\vm\iarglist.cpp: LEVEL_VM::IARGLIST_CLASS::AddArgumentsAndParams: 330: IARG_INVALID seen
NO STACK TRACE AVAILABLE
Detach Service Count: 1
Pin 2.14
Copyright (c) 2003-2015, Intel Corporation. All rights reserved.
@CHARM-VERSION: $Rev: 71293 $
@CHARM-BUILDER: BUILDER
@CHARM-COMPILER: MS-cl 1700
@CHARM-TARGET: ia32
@CHARM-CFLAGS:  __OPTIMIZE__=__OPTIMIZE__  __NO_INLINE__=__NO_INLINE__

有人知道我做错了什么吗?

您的 IARG_ 个操作数有误。

  • IARG_MEMORYOP_EA 需要一个额外的参数
  • IARG_MEMORYREAD_SIZEIARG_MEMORYWRITE_SIZE 不需要 需要额外的参数

来自英特尔 PIN documentation

IARG_MEMORYOP_EA Type: ADDRINT. Effective address of a memory op (memory op index is next arg); only valid at IPOINT_BEFORE

对于上面的IARG,明确指出"memory op index"是下一个参数。

IARG_MEMORYREAD_SIZE Type: UINT32. Size in bytes of memory read IARG_MEMORYWRITE_SIZE Type: UINT32. Size in bytes of memory write.

文档没有说明在 ARG_MEMORYxxx_SIZE 之后需要什么(它只是表明您在回调中收到了什么)。

固定代码(对另一个调用执行相同的操作):

        INS_InsertCall(
        //INS_InsertIfCall(
        ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
            IARG_INST_PTR,
            IARG_MEMORYOP_EA, memop, // memory op index required
            IARG_MEMORYREAD_SIZE, // no arg
            IARG_END);