IARG_MEMORYREAD_EA的类型在PIN中定义为ADDRINT。我需要获取一条存储在IARG_MEMORYREAD_EA内存位置中的数据。据我了解,从特定地址位置获取数据的最正确方法是使用PIN_SafeCopy函数,其示例用法如下:

ADDRINT DoLoad(REG reg, ADDRINT * addr)
{
    *out << "Emulate loading from addr " << addr << " to " << REG_StringShort(reg) << endl;
    ADDRINT value;
    PIN_SafeCopy(&value, addr, sizeof(ADDRINT));
    return value;
}

当我尝试将IARG_MEMORYREAD_EA直接传递给此函数时,编译器说类型不匹配(ADDRINT * and ADDRINT)。显然他们没有,但是我不确定应该如何使用此功能。

我当前的代码如下:
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessMemIns,
 IARG_CONTEXT,
 IARG_INST_PTR,
 IARG_MEMORYREAD_EA,
 IARG_MEMORYREAD2_EA,
 IARG_MEMORYREAD_SIZE,
 IARG_MEMORYWRITE_EA,
 IARG_MEMORYWRITE_SIZE,
 IARG_BOOL, INS_IsBranchOrCall(ins),
 IARG_BRANCH_TAKEN,
 IARG_UINT32,  INS_Category(ins),
 IARG_UINT32, INS_RegR(ins, 0),
 IARG_UINT32, INS_RegR(ins, 1),
 IARG_UINT32, INS_RegR(ins, 2),
 IARG_UINT32, INS_RegR(ins, 3),
 IARG_UINT32, INS_RegW(ins, 0),
 IARG_UINT32, INS_RegW(ins, 1),
 IARG_UINT32, INS_RegW(ins, 2),
 IARG_UINT32, INS_RegW(ins, 3),
 IARG_END);

而ProcessMemIns是:
VOID ProcessMemIns(
    CONTEXT * context,
    ADDRINT ip,
    ADDRINT raddr, ADDRINT raddr2, UINT32 rlen,
    ADDRINT waddr, UINT32  wlen,
    BOOL    isbranch,
    BOOL    isbranchtaken,
    UINT32  category,
    UINT32  rr0,
    UINT32  rr1,
    UINT32  rr2,
    UINT32  rr3,
    UINT32  rw0,
    UINT32  rw1,
    UINT32  rw2,
    UINT32  rw3)
{ // for memory address and register index, '0' means invalid
  if (pthreadsim->first_instrs < pthreadsim->skip_first)
  {
    pthreadsim->first_instrs++;
    return;
  }
  else if (pthreadsim->first_instrs == pthreadsim->skip_first)
  {
    pthreadsim->first_instrs++;
    pthreadsim->initiate(context);
  }

  /* Log for addresses and data */
  uint64_t data1 = -1, data2 = -1, data3 = -1;
  if (raddr > 0) {
    PIN_SafeCopy(&data1, raddr , sizeof(uint64_t));
    cout << "1A:" << hex << raddr << ",D:" << hex << data1 << endl;
  }
  if (raddr2 > 0) {
    PIN_SafeCopy(&data1, raddr2 , sizeof(uint64_t));
    cout << "2A:" << hex << raddr2 << ",D:" << hex << data2 << endl;
  }
  if (waddr > 0) {
    PIN_SafeCopy(&data1, waddr , sizeof(uint64_t));
    cout << "3A:" << hex << waddr << ",D:" << hex << data3 << endl;
  }

  pthreadsim->process_ins(
    context,
    ip,
    raddr, raddr2, rlen,
    waddr,         wlen,
    isbranch,
    isbranchtaken,
    category,
    rr0, rr1, rr2, rr3,
    rw0, rw1, rw2, rw3);
}

不出所料,我从编译器中收到以下错误消息。 invalid conversion from ‘LEVEL_BASE::ADDRINT {aka long unsigned int}’ to ‘const VOID* {aka const void*}’ [-fpermissive]
是否有更正确的方法将IARG_MEMORYREAD_EA用于PIN_SafeCopy(),还是应该只定义一个指针并将其用于PIN_SafeCopy()?

最佳答案

英特尔PIN文档指出 IARG_MEMORYREAD_EA ADDRINT,尽管我确实同意example PIN_SafeCopy 奇怪地使用了ADDRINT* ...

OTOH,ADDRINT是表示地址的类型,对于IARG_MEMORYREAD_EA,我们知道这是读取的内存的有效地址(因此,在大多数情况下,ADDRINT是有效的指针)。

对于DoLoad(),我将ADDRINT*替换为ADDRINT

对于PIN_SafeCopy,我可以通过C样式强制转换或ADDRINTvoid*强制转换为reinterpet_cast<>:您已经知道它是一个指针,但是类型错误,这就是为什么要强制转换的原因。

10-08 08:10