Тип IARG_MEMORYREAD_EA определяется как 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 ()?
В документации Intel PIN указано, что IARG_MEMORYREAD_EA
является ADDRINT
хотя я согласен, что пример с PIN_SafeCopy
странно использует ADDRINT*
…
ОТО, ADDRINT
это тип, который представляет адрес и в случае IARG_MEMORYREAD_EA
мы знаем, что это эффективный адрес чтения из памяти (поэтому в подавляющем большинстве случаев ADDRINT является допустимым указателем).
За DoLoad()
Я бы заменил ADDRINT*
просто ADDRINT
,
За PIN_SafeCopy
Я бы бросил ADDRINT
в void*
либо с помощью броска в стиле C, либо reinterpet_cast<>
: вы уже знаете, что это указатель, но он неправильного типа, и поэтому приведение для.