我正在尝试使用插装工具DynamoRIO进行指令跟踪。我发现他们的站点上已经有一个指令跟踪的示例:x86.c。但是,我不明白为什么他们在instr函数中使用这么多的操作。我试图用另一种简单的方式重写这个函数:
instrument_instr(void *drcontext, instrlist_t *ilist, instr_t *where)
{
app_pc pc;
per_thread_t *data;
data = drmgr_get_tls_field(drcontext, tls_index);
pc = instr_get_app_pc(where);
fprintf(data->logf, PIFX",%s\n",
(ptr_uint_t)pc, decode_opcode_name(instr_get_opcode(where)));
}
我发现这个简单的方法似乎也很好,只是它的输出比官方的样本少。
我不知道为什么我的方法日志较少,因为我不知道为什么正式的示例代码会执行如此琐碎的操作。有人熟悉DynamoRIO的API吗?(特别是drmgr_register_bb_instrumentation_event
函数)。我不明白他们为什么要这样使用回调函数)
发布于 2022-05-30 12:41:09
函数instrument_instr
是在DynamoRIO转换基本块时调用的,而不是在执行基本块时调用的。由于基本块通常只转换一次,但多次执行,因此您的输出与示例工具的输出不同。
DynamoRIO内部工作机制的一个过于简化的视图是:DynamoRIO在执行目标应用程序之前转换它们的基本块。这使用户(您)能够执行任意更改,并使DynamoRIO能够在执行基本块后恢复控制。转换后的块被写到所谓的代码缓存中,在那里它们将被执行.DynamoRIO仔细重写地址,这样跳转和偏移仍然有效。代码缓存的目的是速度:已经转换过的基本块不需要再次转换,因此它们留在代码缓存中;从程序的其他地方跳到原始的基本块被自动替换为跳转到代码缓存中的转换的基本块。
为了显示完整的执行跟踪,必须更改基本块,以便它们输出它们包含的所有指令;然后,在执行基本块时自动获得输出。如果你想要高效地做这件事,这可不是件小事。这就是为什么示例工具包含大量代码的原因。
我建议阅读一些教程幻灯片集,例如2017年2月DynamoRIO教程(PDF)。
https://stackoverflow.com/questions/40637520
复制相似问题