genericname
genericname

Reputation: 177

Intel pin: getting instruction memory write\read size

I am trying to change a bit the Memory Reference Trace (Instruction Instrumentation) example from the pin documentation.

My goal is to extract from each instruction that access memory also the size of the size of the memory to read\write in bytes.

I looked in the documentation and found that I need to use

IARG_MEMORYREAD_SIZE
IARG_MEMORYWRITE_SIZE

to hold that size.

I couldn't find though in the documentation how to extract this data from the instruction.

here is my code:

for (UINT32 memOp = 0; memOp < memOperands; memOp++)
{
    if (INS_MemoryOperandIsRead(ins, memOp))
    {
        if(INS_hasKnownMemorySize(ins))
        {
            //IARG_MEMORYREAD_SIZE  memReadSize = what to do here?

            INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)MyFuncWhenRead,
                IARG_INST_PTR,
                IARG_MEMORYOP_EA, memOp,
                IARG_END);
        }
    }

    if (INS_MemoryOperandIsWritten(ins, memOp))
    {
        if(INS_hasKnownMemorySize(ins))
        {
            //IARG_MEMORYREAD_SIZE  memWriteSize = what to do here?

            INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)MyFuncWhenWrite,
                IARG_INST_PTR,
                IARG_MEMORYOP_EA, memOp,
                IARG_END);
        }
    }
}

Would appreciate some help solving this. That is, what to write in the line with the comment

        //IARG_MEMORYREAD_SIZE  memReadSize = ???

Thanks!

Upvotes: 2

Views: 1308

Answers (1)

Neitsa
Neitsa

Reputation: 8176

As a quick reminder (this is an important concept in PIN, often overlooked):

Conceptually, instrumentation consists of two components:

  • A mechanism that decides where and what code is inserted: the instrumentation.
  • The code to execute at insertion points: the analysis.

The INS_INSERT(xxx)CALL functions are used in the instrumentation routine (to tell to the analysis routine) when and what code is inserted. So, in your code:

        INS_InsertPredicatedCall(
            ins, IPOINT_BEFORE, (AFUNPTR)MyFuncWhenRead,
            IARG_INST_PTR,
            IARG_MEMORYOP_EA, memOp,
            IARG_END);
  • IPOINT_BEFORE is the when.
    • It tells where the analysis routine is inserted relative to the instrumented code (here, the insertion point is made before the instruction).
  • IARG_INST_PTR, IARG_MEMORYOP_EA are the what.
    • They determine the arguments that are passed to the analysis routine.
    • They are received by the analysis routine in the order they are declared.
  • MyFuncWhenRead is the analysis routine called by the instrumentation.

If you have something that starts with IARG_it is an IARG_TYPE which is has to passed to the INS_Insert(xxx)Call function.

The documentation for IARG_MEMORYREAD_SIZE says:

IARG_MEMORYREAD_SIZE Type: UINT32. Size in bytes of memory read. (...)

The Type tells us what the analysis routine receives.

In your case you have (in this precise order):

  • IARG_INST_PTR: Type: ADDRINT
  • IARG_MEMORYOP_EA: Type: ADDRINT
  • IARG_MEMORYREAD_SIZE: Type: UINT32

Which means your instrumentation function will look like this:

    INS_InsertPredicatedCall(
        ins, IPOINT_BEFORE, (AFUNPTR)MyFuncWhenRead,
        IARG_INST_PTR,
        IARG_MEMORYOP_EA, memOp,
        IARG_MEMORYREAD_SIZE,
        IARG_END);

And your analysis function should look like this:

VOID MyFuncWhenRead(
    ADDRINT ins_ptr, // from IARG_INST_PTR (address of the instruction)
    ADDRINT mem_op_addr, // from IARG_MEMORYOP_EA (address of the memory read)
    UINT32 mem_read_size, // from IARG_MEMORYREAD_SIZE (size of the read)
) 
{ 
    // ...
}

The same logic applies to IARG_MEMORYWRITE_SIZE.

Upvotes: 3

Related Questions