Как получить значение, которое написано инструкцией магазина в Pin?

В настоящее время я использую Pin, и я хочу получить значение, которое пишет инструкция магазина. Проблема, с которой я столкнулась, заключается в том, что даже если я могу вставить обратный вызов перед записью (используя IPOINT_BEFORE) и получить значение из адреса памяти, который будет записан, это, очевидно, неверно, поскольку в письме нет произошло еще. Я не могу использовать IARG_MEMORYWRITE_EA и IPOINT_AFTER в качестве аргументов вместе.

Мне удалось заставить его работать, когда есть инструкция загрузки, так как значение уже находится в памяти. Код для этого ниже.

void Read(THREADID tid, ADDRINT addr, ADDRINT inst){

 PIN_GetLock(&globalLock, 1);

 ADDRINT * addr_ptr = (ADDRINT*)addr;
 ADDRINT value;
 PIN_SafeCopy(&value, addr_ptr, sizeof(ADDRINT));

 fprintf(stderr,"Read: ADDR, VAL: %lx, %lu\n", addr, value);

 .
 .
 .

 PIN_ReleaseLock(&globalLock);
}

VOID instrumentTrace(TRACE trace, VOID *v)
{

 for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
 for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { 
 if(INS_IsMemoryRead(ins)) {
 INS_InsertCall(ins, 
 IPOINT_BEFORE, 
 (AFUNPTR)Read, 
 IARG_THREAD_ID,
 IARG_MEMORYREAD_EA,
 IARG_INST_PTR,
 IARG_END);
 } else if(INS_IsMemoryWrite(ins)) {
 INS_InsertCall(ins, 
 IPOINT_BEFORE, 
 (AFUNPTR)Write, 
 IARG_THREAD_ID,//thread id
 IARG_MEMORYWRITE_EA,//address being accessed
 IARG_INST_PTR,//instruction address of write
 IARG_END);
 }
 }
 }
}

Как я могу захватить значение, которое команда сохранения записывает в память?

1 ответ

Думаю, мне удалось сделать то, что я пытался. Способ, которым я получаю значения, состоит в том, что каждый раз, когда в программе есть хранилище, я сохраняю адрес памяти, на который он будет писать. Затем я обрабатываю каждую инструкцию и вызываю функцию WriteData, которая по существу получает данные из адреса памяти, который я ранее сохранял, как и с помощью Reads.

Это код для получения значения инструкции загрузки.

void Read(THREADID tid, ADDRINT addr, ADDRINT inst){

 PIN_GetLock(&globalLock, 1);

 ADDRINT * addr_ptr = (ADDRINT*)addr;
 ADDRINT value;
 PIN_SafeCopy(&value, addr_ptr, sizeof(ADDRINT));

 fprintf(stderr,"Read: ADDR, VAL: %lx, %lx\n", addr, value); 
 ... 
 PIN_ReleaseLock(&globalLock);
}

Это код для захвата адреса инструкции магазина.

void Write(THREADID tid, ADDRINT addr, ADDRINT inst ){ 

 PIN_GetLock(&globalLock, 1); 

 writeaddr = addr;
 writecount++; 
 ... 
 PIN_ReleaseLock(&globalLock);
}

Это код для получения данных из адреса предыдущего магазина.

void WriteData(){ 

 PIN_GetLock(&globalLock, 1);

 //Reading from memory 
 if (writecount > 0){

 ADDRINT * addr_ptr = (ADDRINT*)writeaddr;
 ADDRINT value;
 PIN_SafeCopy(&value, addr_ptr, sizeof(ADDRINT));

 fprintf(stderr,"Write: ADDR, Value: %lx, %lx\n", writeaddr, value); 

 writecount--;
 }

 PIN_ReleaseLock(&globalLock);

}

Но остается небольшая проблема. Ниже приведены данные из микрообнаружения, которые я использую, и после этого распечатки в терминале.

for (i = 0; i < MAX; i++) {
 a[i] = i;
 }

 for (i = 0; i < MAX; i++) {
 a[i] = a[i] + 1;
 b[i] = a[i];
 }

MAX - 5.

Write: ADDR, Value: 601078, 6f
Read: ADDR, VAL: 7ffd0560de10, 40051b
Write: ADDR, Value: 601080, 0
Write: ADDR, Value: 601084, 1
Write: ADDR, Value: 601088, 2
Write: ADDR, Value: 60108c, 3
Write: ADDR, Value: 601090, 4
Read: ADDR, VAL: 601080, 100000000
Write: ADDR, Value: 601080, 100000001
Write: ADDR, Value: 601060, 1
Read: ADDR, VAL: 601084, 200000001
Write: ADDR, Value: 601084, 200000002
Write: ADDR, Value: 601064, 2
Read: ADDR, VAL: 601088, 300000002
Write: ADDR, Value: 601088, 300000003
Write: ADDR, Value: 601068, 3
Read: ADDR, VAL: 60108c, 400000003
Write: ADDR, Value: 60108c, 400000004
Write: ADDR, Value: 60106c, 4
Read: ADDR, VAL: 601090, 4
Write: ADDR, Value: 601090, 5
Write: ADDR, Value: 601070, 5

Из того, что мы видим в терминале, кажется, что первые записи в [i] происходят так, как ожидалось. Но тогда, когда программа читает одни и те же адреса вместо получения 1,2 и т.д., Она получает 100000001 и так далее. Он правильно увеличивает их на 1. Но когда придет время, чтобы сохранить их в b [i], значения снова верны. Поэтому мне интересно, почему я сталкиваюсь с этим поведением с данными, которые я получаю от чтения.

licensed under cc by-sa 3.0 with attribution.