将IARG_MEMORYREAD_EA与PIN_SafeCopy一起使用

Using IARG_MEMORYREAD_EA with PIN_SafeCopy

本文关键字:SafeCopy 一起 PIN IARG MEMORYREAD EA      更新时间:2023-10-16

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_EAADDRINT,尽管我同意PIN_SafeCopy的示例奇怪地使用了ADDRINT*。。。

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

对于DoLoad(),我会用一个ADDRINT来代替ADDRINT*

对于PIN_SafeCopy,我会通过C样式的强制转换或reinterpet_cast<>ADDRINT强制转换为void*:您已经知道它是一个指针,但它的类型不对,这就是强制转换适用的原因。