簡體   English   中英

如何獲取 Pin 中存儲指令寫入的值?

[英]How do I get the value that is written by a store instruction in 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);
      }
    }
  }
}

如何獲取存儲指令寫入內存的值?

我想我設法做到了我想做的。 我獲取值的方式是,每次在程序中存在存儲時,我都會保存它將寫入的內存地址。 然后我檢測每一條指令並調用 WriteData 函數,它本質上從我之前保存的內存地址中獲取數據,就像讀取一樣。

這是獲取加載指令值的代碼。

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];
  }

最大值為 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

從我們在終端中看到的情況來看,似乎第一個寫入 a[i] 的內容按預期發生。 但是,當程序讀取相同的地址而不是獲取 1,2 等時,它會獲取 100000001 等等。 它正確地將它們加 1。但是當需要將它們存儲到 b[i] 時,這些值又是正確的。 所以我想知道為什么我從讀取中獲得的數據會遇到這種行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM