我正在计算反汇编代码中汇编指令的数量(add、sub、jmp 等)。我还必须考虑可能导致循环/跳转的情况,这些情况需要我重复计算一组指令。因此,我必须记录寄存器的值,这样当我遇到像“jne”这样的情况时,我就知道代码是否跳转了,或者我是否可以继续解析反汇编代码。
我目前对寄存器的初始值感到困惑,例如(edx、eax、rbp、rsp 等)。我使用 objdump 转储所有汇编代码,我可以在反汇编的 <main>
中看到它函数,第一行汇编代码为:
push rbp
mov rbp, rsp
sub rsp, 0xdb0
我不知道 rbp 在哪里初始化。当我为“rbp”执行控制 F 时,我看到首先弹出的是“rex.WRX push rbp”指令。这会将 rbp 初始化为 0 吗?
我也对汇编代码从哪里开始感到困惑。我本来以为是从<main>
开始的,但我也看到了其他功能,例如 <start>
和 <init>
.
如有任何说明,我们将不胜感激!
最佳答案
Objdump 只会为您提供可执行文件的静态反汇编。要获取程序的运行时跟踪,您可以使用 Intel Pin 等工具.在管脚分布的ManualExample文件夹中有一个itrace.so工具,您可以简单地使用它来获取程序的运行时跟踪。
Path-to-pin-folder/pin -t pin-tool-name-with-path -- binary-to-instrument
Pin框架还可以让你记录不同寄存器的内容和程序变量的内容和地址。参见 PIN manual有关示例以及如何编写自己的工具。您可以随时修改现有示例的内容以根据您的需要进行修改。要编写全新的引脚工具,您应该使用 MyPinTool 目录中的引脚工具模板。
“在函数开始时推送 rbp 和其他指令”。在程序执行期间调用一系列函数。每个函数共享寄存器和堆栈。每个函数都将一部分堆栈用于其局部变量。当一个函数释放堆栈位置时,其他后续函数可以自由使用。释放内存很简单,修改栈顶(rbp)值。使用堆栈可确保同一组内存位置可由许多函数的局部变量使用,从而减少内存需求。
main() 是在程序执行期间调用的第一个用户编写 函数。一组不属于原始程序的附加函数,__start()、__fini 等也作为可执行程序的一部分存在,通常不由用户定义强>.它们是特定于操作系统的,由编译器添加。其中一些在用户程序执行之前调用,一些在用户程序执行之后调用,用于初始化和内务处理。
关于assembly - 如何确定英特尔 x86 汇编代码中使用的初始寄存器值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63212680/