将 IARG_MEMORYREAD_EA 与 PIN_SafeCopy 一起使用

Posted

技术标签:

【中文标题】将 IARG_MEMORYREAD_EA 与 PIN_SafeCopy 一起使用【英文标题】:Using IARG_MEMORYREAD_EA with PIN_SafeCopy 【发布时间】:2015-06-12 14:53:18 【问题描述】:

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()?

【问题讨论】:

【参考方案1】:

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

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

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

对于PIN_SafeCopy,我会将ADDRINT 转换为void*,通过C 风格转换或reinterpet_cast&lt;&gt;:你已经知道它是一个指针,但它的类型错误,这就是为什么转换是为。

【讨论】:

以上是关于将 IARG_MEMORYREAD_EA 与 PIN_SafeCopy 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

rasberry pi 4的相机与opencv集成

公开课预告:多媒体开源PI

SKSpriteNode zrotation M_PI 真气

使用 Fortran 和 CUDA 计算 PI

算法设计与分析——电路布线(动态规划)

Raspberry pi不会使用minicom或python将串行数据发送到arduino