如何使用 Intel PIN 获取内存操作值?
Posted
技术标签:
【中文标题】如何使用 Intel PIN 获取内存操作值?【英文标题】:How to get memory operation values using Intel PIN? 【发布时间】:2018-06-12 11:56:54 【问题描述】:我正在使用 Intel PIN 修改系统中的内存分配。
我找不到根据内存指令获取实际值的方法。
VOID Instruction(INS ins, VOID *v)
UINT32 memOperands = INS_MemoryOperandCount(ins)
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
if (INS_MemoryOperandIsRead(ins, memOp))
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
if (INS_MemoryOperandIsWritten(ins, memOp))
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
VOID RecordMemRead(VOID * ip, VOID * addr)
if (!Record) return;
printf("%p: R %p\n", ip, addr);
VOID RecordMemWrite(VOID * ip, VOID * addr)
if (!Record) return;
printf("%p: R %p\n", ip, addr);
据我了解,这只打印指令指针和操作数的寄存器地址。那是对的吗?如果是这样,我怎样才能得到这个寄存器的值?
最终,我要做的是拦截所有对静态和堆变量的赋值,并将它们转换为一些过程调用,以将值保存在 Google Bigtable 上。
【问题讨论】:
【参考方案1】:据我了解,这 [...] 打印指令指针
是的,由于IARG_INST_PTR
。
以及操作数的寄存器地址
不,你得到的是操作数的 EA(有效地址),定义为:
Effective Address = Displacement + Base_Reg + Index_Reg * Scale
假设您有以下指令(Intel 语法):
mov eax, [ebx+ecx+0xf]
源操作数(右操作数)的 EA 是 [ebx+ecx+0xf]
的计算地址,如果使用 IARG_MEMORYOP_EA
,则不会得到 EA 的每个组件的值。
由于您只想跟踪堆和静态变量分配,您可能对操作数的“组件”不感兴趣。
最终,我要做的是拦截所有分配给 静态和堆变量并将它们转换为一些过程调用 将值保存在 Google Bigtable 上。
这不是一件容易的事。
您可以使用RTN_xxx
函数来跟踪对内存分配和释放函数的调用(通常是malloc()
和free()
)。我认为有一个 PIN 源附带的示例。
对于 malloc(),您可以追踪返回的指针和分配的大小(例如,将其放在 std::map 上)。每次写入时,检查它是否在您的分配范围内。 对于每个 free(),从映射中删除指针。
对于静态变量,您可以使用 IMG_AddInstrumentFunction
跟踪加载的模块,并查看是否在可执行文件的某个部分中发生了写入。
【讨论】:
以上是关于如何使用 Intel PIN 获取内存操作值?的主要内容,如果未能解决你的问题,请参考以下文章