Assembly 从地址获取上一条指令的开头

Assembly 从地址获取上一条指令的开头,assembly,x86,Assembly,X86,我们在缓冲区中,查看x86操作码标记当前指针 68 0F 00 6A 90 | 00 找到下一条指令的起始点很容易,因为电流的大小是可以确定的。但是你怎么能准确地猜出上一个故事的开头呢 68 0F 00 6A 90-5字节总计,结束于| 0F 00 6A 90-总共4个字节,结束于| 00 6A 90-3个字节总计,结束于| 6A 90-总共2个字节,结束于| 90-总共1个字节,结束于| 显然,这不是一个实际的例子,但它说明了这个问题。这与其说是一个问题,不如说是一个好奇,但现代的反汇编程序

我们在缓冲区中,查看x86操作码标记当前指针

68 0F 00 6A 90 | 00
找到下一条指令的起始点很容易,因为电流的大小是可以确定的。但是你怎么能准确地猜出上一个故事的开头呢

68 0F 00 6A 90
-5字节总计,结束于|

0F 00 6A 90
-总共4个字节,结束于|

00 6A 90
-3个字节总计,结束于|

6A 90
-总共2个字节,结束于|

90
-总共1个字节,结束于|


显然,这不是一个实际的例子,但它说明了这个问题。这与其说是一个问题,不如说是一个好奇,但现代的反汇编程序如何准确地猜测呢?它们是否使用调用/跳转引用存储点,并找到与当前指令结束的最近标签最近的地址?

对于这样的可变长度指令集,您无法准确地线性分解。您必须从一个入口点开始,尽可能遵循所有代码路径,当然,如果反汇编程序就是这样做的话,它很容易出错(强制一个条件,然后使用一个条件分支,它将只采用一条路径,并将数据保留在未使用的路径中,该路径会导致以下指令解码出错)。更糟糕的是,如果您只是尝试从入口点开始线性执行,而不检查数据(例如,编译器将轮询数据放在反汇编程序视为指令数据的无条件分支或返回之后)


你不可能真正准确地倒退,除非你沿着代码路径,用一个分支将你带到那里,或者在它前面的某个地方执行它。

谢谢,我是这样想的。你知道像奥利这样的程序是如何进入内存中的一个随机点,并且运行得很好的吗?或者它最终会成功吗?不,我不知道,但我没有检查某些文件格式是否会留下信息,比如gnu objdump是如何做到这一点的?编译器生成的代码将非常干净且易于反汇编,需要尝试使工具出错,以查看它们的实际性能。虽然如果使用的是原始二进制文件,而不是包含大量调试信息的格式,跳转表或函数指针也可能会使它们出错。为调试而编译应该是添加信息来帮助处理这类事情,也可以用它做一些实验……如果你仔细想想,真的没有其他方法,处理器显然可以找到自己的方法,因为它正在完全执行每一条指令。反汇编程序可以尝试这样做,但它仍然可能无法工作,因为某些路径依赖于用户输入。因此,如果没有来自文件格式的帮助,并且不能通过每个代码路径执行代码,那么还有什么可能呢?您所能做的最好的事情就是进行足够的解码,以了解每条指令的长度,并遵循所有可能的分支,假设每条条件的路径都被采用。