Использование IARG_MEMORYREAD_EA с PIN_SafeCopy

Тип IARG_MEMORYREAD_EA определяется как ADDRINT в PIN-коде. Мне нужно получить часть данных, хранящихся в ячейке памяти 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()?


person agy    schedule 07.04.2015    source источник


Ответы (1)


В документации Intel PIN указано, что — это ADDRINT, хотя я согласен с тем, что пример с PIN_SafeCopy странно использует ADDRINT*...

OTOH, ADDRINT — это тип, представляющий адрес, а в случае IARG_MEMORYREAD_EA мы знаем, что это эффективный адрес чтения памяти (поэтому в подавляющем большинстве случаев ADDRINT является допустимым указателем).

Для DoLoad() я бы заменил ADDRINT* только на ADDRINT.

Для PIN_SafeCopy я бы преобразовал ADDRINT в void* либо с помощью приведения в стиле C, либо reinterpet_cast<>: вы уже знаете, что это указатель, но он неправильного типа, и именно поэтому приведение предназначено для.

person Neitsa    schedule 08.04.2015