使用 IARG_MEMORYREAD_EA 和 PIN_SafeCopy

Using IARG_MEMORYREAD_EA with PIN_SafeCopy

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 is an ADDRINT, although I do agree that the example with PIN_SafeCopy 奇怪地使用 ADDRINT*...

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

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

对于 PIN_SafeCopy,我将 ADDRINT 转换为 void*,通过 C 风格转换或 reinterpet_cast<>:您已经知道它是一个指针,但它是类型错误,这就是为什么要进行演员表的原因。