2016-03-11 2 views
0

J'essaie d'utiliser Intel Pin pour étudier l'activité de la mémoire d'un exécutable. Je veux modifier l'exemple de pinatrace à partir du kit Pin. J'ai essayé d'utiliser les paramètres IARG_MEMORYWRITE_SIZE/IARG_MEMORYREAD_SIZE. Voici le code source.Utilisation du paramètre IARG_MEMORYWRITE_SIZE et IARG_MEMORYREAD_SIZE dans Intel Pin

#include <stdio.h> 
#include <chrono> 
#include "pin.H" 
#include <string> 
using std::chrono::nanoseconds; 

FILE * trace; 
auto start=std::chrono::high_resolution_clock::now(); 

std::string buffer; 
// Print a memory read record 
VOID RecordMemRead(VOID * ip, VOID * addr,VOID * size) 
{ 
    auto elapsed = (std::chrono::high_resolution_clock::now()) - start; 
    nanoseconds ns= std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed); 

//sprintf(buffer,trace,"%p: R %p Time,ns %lld \n", ip, addr,ns); 

    //std::string fout = fout + std::to_string("%p: R %p Time,ns %lld \n", ip, addr,ns); 

    fprintf(trace,"%p: R,bytes %p Size,bytes %lld \n", ip, addr,size); 
} 

// Print a memory write record 
VOID RecordMemWrite(VOID * ip, VOID * addr, VOID * size) 
{ 
    auto elapsed = (std::chrono::high_resolution_clock::now()) - start; 
    nanoseconds ns= std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed); 

    fprintf(trace,"%p: W,bytes %p Size,bytes %lld \n", ip, addr,size); 
} 

// Is called for every instruction and instruments reads and writes 
VOID Instruction(INS ins, VOID *v) 
{ 
    // Instruments memory accesses using a predicated call, i.e. 
    // the instrumentation is called iff the instruction will actually be executed. 
    // 
    // On the IA-32 and Intel(R) 64 architectures conditional moves and REP 
    // prefixed instructions appear as predicated instructions in Pin. 
    UINT32 memOperands = INS_MemoryOperandCount(ins); 

    // Iterate over each memory operand of the instruction. 
    for (UINT32 memOp = 0; memOp < memOperands; memOp++) 
    { 
     if (INS_MemoryOperandIsRead(ins, memOp)) 
     { 
      INS_InsertCall(
      //INS_InsertIfCall(
      ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead, 
       IARG_INST_PTR, 
       IARG_MEMORYOP_EA, 
       IARG_MEMORYREAD_SIZE, memOp, 
       IARG_END); 
     } 
     // Note that in some architectures a single memory operand can be 
     // both read and written (for instance incl (%eax) on IA-32) 
     // In that case we instrument it once for read and once for write. 
     //IARG_MEMORYREAD_SIZE Type: UINT32. Size in bytes of memory read. 
     //IARG_MEMORYOP_EA 
     //IARG_MEMORYWRITE_SIZE  Type: UINT32. Size in bytes of memory write. 
     if (INS_MemoryOperandIsWritten(ins, memOp)) 
     { 
      INS_InsertCall(
      //INS_InsertPredicatedCall(
       ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, 
       IARG_INST_PTR, 
       IARG_MEMORYOP_EA, 
       IARG_MEMORYWRITE_SIZE, memOp, 
       IARG_END); 
     } 
    } 
} 

VOID Fini(INT32 code, VOID *v) 
{ 
    fprintf(trace, "#eof\n"); 
    fclose(trace); 
} 

/* ===================================================================== */ 
/* Print Help Message             */ 
/* ===================================================================== */ 

INT32 Usage() 
{ 
    PIN_ERROR("This Pintool prints a trace of memory addresses\n" 
       + KNOB_BASE::StringKnobSummary() + "\n"); 
    return -1; 
} 

/* ===================================================================== */ 
/* Main                 */ 
/* ===================================================================== */ 


int main(int argc, char *argv[]) 
{ 
    if (PIN_Init(argc, argv)) return Usage(); 

    trace = fopen("pinatrace2.out", "w"); 

    start = std::chrono::high_resolution_clock::now(); 

    INS_AddInstrumentFunction(Instruction, 0); 
    PIN_AddFiniFunction(Fini, 0); 

    // Never returns 
    PIN_StartProgram(); 

    return 0; 
} 

Après la compilation, j'essaie de l'exécuter, mais en recevant cette erreur. Si je supprime ces arguments et édite les fonctions RecordMemWrite/RecordMemRead - tout fonctionne parfaitement.

>..\..\..\..\ia32\bin\pin.exe -t MyPinTool -- cmd /C dir 
A: Source\pin\vm\iarglist.cpp: LEVEL_VM::IARGLIST_CLASS::AddArgumentsAndParams: 330: IARG_INVALID seen 
NO STACK TRACE AVAILABLE 
Detach Service Count: 1 
Pin 2.14 
Copyright (c) 2003-2015, Intel Corporation. All rights reserved. 
@CHARM-VERSION: $Rev: 71293 $ 
@CHARM-BUILDER: BUILDER 
@CHARM-COMPILER: MS-cl 1700 
@CHARM-TARGET: ia32 
@CHARM-CFLAGS: __OPTIMIZE__=__OPTIMIZE__ __NO_INLINE__=__NO_INLINE__ 

Est-ce que quelqu'un a une idée de ce que je fais mal?

Répondre

2

Vous avez fait une erreur avec les opérandes IARG_.

  • IARG_MEMORYOP_EA nécessitent un argument supplémentaire
  • IARG_MEMORYREAD_SIZE et IARG_MEMORYWRITE_SIZE faire ne nécessitent un argument supplémentaire

d'Intel PIN documentation:

IARG_MEMORYOP_EA Type: ADDRINT. Adresse effective d'une mémoire op (l'index op de la mémoire est l'argument suivant); uniquement valide à IPOINT_BEFORE

Pour l'IARG ci-dessus, il est clairement indiqué que "memory op index" est l'argument suivant.

IARG_MEMORYREAD_SIZE Type: UINT32. Taille en octets de mémoire lue IARG_MEMORYWRITE_SIZE Type: UINT32. Taille en octets de la mémoire d'écriture.

La documentation n'indique pas que quelque chose est nécessaire après ARG_MEMORYxxx_SIZE (cela indique simplement ce que vous recevez dans votre rappel).

Code fixe (la même chose pour l'autre appel):

 INS_InsertCall(
     //INS_InsertIfCall(
     ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead, 
      IARG_INST_PTR, 
      IARG_MEMORYOP_EA, memop, // memory op index required 
      IARG_MEMORYREAD_SIZE, // no arg 
      IARG_END); 
+0

Merci. Cela a très bien fonctionné. – aGGeRReS