Reverse Engineering Asked by aGGeRReS on June 25, 2021
I am using Intel Pin in order trace memory activity of an executable on Windows. What I have found, that most of the memory operands (Read or Write) operates with 2 or 4 bytes. So I decided to modify original Pin’s pinatrace example, in order to see which Assembly opcodes produces which memory activity.
VOID Instruction(INS ins, VOID *v)
{
UINT32 memOperands = INS_MemoryOperandCount(ins);
fprintf(trace,"n[%s]n",(INS_Disassemble(ins)).c_str());
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
{
.....
What it basically does (I hope), is just writes disassembled opcode BEFORE the memory operands it produces. But then I looked in the file (W is for write, R is for read):
[test edx, 0x800000]
[jnz 0x77708557]
[mov dword ptr [ebp-0x4], edi]
[test dl, 0x1]
[jnz 0x77703136] RWWRWW
[lea edi, ptr [ebx+0xcc]]
[push dword ptr [edi]]
[call 0x77702520] RWW
[mov edi, edi]
[push ebp]
[mov ebp, esp]
[mov eax, dword ptr [ebp+0x8]]
[mov ecx, dword ptr fs:[0x18]]
[lea edx, ptr [eax+0x4]]
[lock btr dword ptr [edx], 0x0]
[jnb 0x777041dc]
[mov ecx, dword ptr [ecx+0x24]]
[mov dword ptr [eax+0xc], ecx]
[mov dword ptr [eax+0x8], 0x1]
[mov eax, 0x1]
[pop ebp]
[ret 0x4] WRRRWRWWRR
As we can see, opcodes that are supposed to work with memory (e.g. mov) do not produce memory operands. While memory traces are connected as blocks after ret/call/jnz etc.
Question: What kind of memory operands does Intel Pin trace? Is it about calls to virtual memory/RAM/CPU registers? Could it be possible, that memory activity goes in blocks due to CPU’s pipeline?
So, finally I came up with the solution that works how I want and results seem to be valid according to this reference of instruction tables
fprintf(trace,"n[%s]n",(INS_Disassemble(ins)).c_str()); //(INS_Disassemble(ins)).c_str()
fflush(trace);
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
{
if (INS_MemoryOperandIsRead(ins, memOp))
{
fprintf(trace,"R");
icount++;
}
if (INS_MemoryOperandIsWritten(ins, memOp))
{
fprintf(trace,"W");
icount++;
}
}
And it produces the following output:
[mov eax, dword ptr [ebp+0x10]]
R
[mov byte ptr [ebx+0x2], 0x0]
W
[mov byte ptr [ebx+0x7], 0x0]
W
I cannot be sure that it is the true sequence of executable under analysis because I do output in the instrumentation phase, but the code can probably be modified it the way to write opcode inside another INS_InsertPredicatedCall, so it will be recorded when it will be executed.
Correct answer by aGGeRReS on June 25, 2021
If you want to limit your print-out to just memory read/write instructions, your fprintf()
needs to be inside the if (INS_MemoryOperandIsRead(ins, memOp)) { ... }
block and inside the if (INS_MemoryOperandIsWritten(ins, memOp)) { ... }
block (and you'll need to include some logic to not print the same instruction more than once).
For example:
// 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);
BOOL printed = FALSE;
// Iterate over each memory operand of the instruction.
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
{
if (INS_MemoryOperandIsRead(ins, memOp))
{
if (!printed)
{
fprintf(trace,"n[%s]n",(INS_Disassemble(ins)).c_str());
printed = TRUE;
}
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
IARG_INST_PTR,
IARG_MEMORYOP_EA, 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.
if (INS_MemoryOperandIsWritten(ins, memOp))
{
if (!printed)
{
fprintf(trace,"n[%s]n",(INS_Disassemble(ins)).c_str());
printed = TRUE;
}
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
}
}
}
Answered by Jason Geffner on June 25, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP