Debugging “如何识别部件”;调用;内存中的指令? 如何在一个进程的可执行内存中区分汇编的“调用”指令(E8[Adv])的操作码与其他E8字节(例如,在另一个指令的中间)的操作码?(最好是从C语言的角度)

Debugging “如何识别部件”;调用;内存中的指令? 如何在一个进程的可执行内存中区分汇编的“调用”指令(E8[Adv])的操作码与其他E8字节(例如,在另一个指令的中间)的操作码?(最好是从C语言的角度),debugging,assembly,x86,disassembly,low-level,Debugging,Assembly,X86,Disassembly,Low Level,验证E8字节后的四个字节是否为有效地址是否足够,然后验证该区域(即调用函数的开始)是否以与操作码“push ebp”和“mov ebp,esp”对应的字节开始(大多数函数使用此序言)?还是有更好的选择,比如检查从入口点到出口点的每个操作码 顺便说一句,我对这个话题几乎没有经验,所以任何信息都非常感谢 谢谢大家! 正确的解释从一个已知为指令开始的地址开始 (这个答案当然适用于指令长度可变的处理器,比如英特尔的x86架构。) 当处理器解释指令时,它总是在特定位置开始解释,因为: 它是之前解释的指令

验证E8字节后的四个字节是否为有效地址是否足够,然后验证该区域(即调用函数的开始)是否以与操作码“push ebp”和“mov ebp,esp”对应的字节开始(大多数函数使用此序言)?还是有更好的选择,比如检查从入口点到出口点的每个操作码

顺便说一句,我对这个话题几乎没有经验,所以任何信息都非常感谢


谢谢大家!

正确的解释从一个已知为指令开始的地址开始

(这个答案当然适用于指令长度可变的处理器,比如英特尔的x86架构。)

当处理器解释指令时,它总是在特定位置开始解释,因为:

  • 它是之前解释的指令之后的下一个位置
  • 它是跳转指令的目标(包括从陷阱和其他特殊指令返回)
  • 它是处理器初始化时的初始起始位置,或
  • 它是用于控制系统的中断表或其他特殊数据结构中的地址
所有这些都是已知的指令起始位置,因为它们是这样设计的:我们编写软件,这些位置就是我们放置指令的位置

解释指令时,处理器遵循有关指令编码的规则。它查看第一个字节,该字节中的位指示接下来的几个字节是当前指令的操作码、修饰符还是操作数。然后它相应地解释下一个字节。因此,指令的第一个字节中的E816的解释将不同于其他地方的E816字节

反汇编程序在用户要求的地方启动。通常,这是由程序中的标签(如函数名)或其他信息(如当前程序计数器的值或堆栈上的返回地址)给出的地址。这些地址都是指令的起始地址,因此反汇编程序以与处理器相同的方式解释字节

有时人们可能不容易获得关于特定区域中指令在哪里开始的信息,并且可能告诉反汇编程序在区域中间的任意地址开始拆解。在这种情况下,前几条反汇编指令可能是错误的,因为反汇编程序正在解释从通常不是指令开始的位置开始的字节。(一个常见的例子是,一个人正在调试并知道当前程序计数器,但希望在不从当前例程开始的情况下回顾最近十几条指令。在这种情况下,他可能会告诉反汇编程序开始从当前程序计数器反汇编100字节。)然而,经常发生的情况是,基本上是偶然的,一条错误解释的指令恰好在正确指令开始的地方结束。然后,反汇编程序将正确地反汇编该指令,并将其与正确的指令序列同步,剩余的反汇编将正确进行。只要大多数指令都很短,且指令长度变化很大,则极有可能在少数指令中发生这种情况


根据您在指令流中开始执行的位置,您可以使用指令编码并创建一个字节序列,该序列表示两个不同的指令流,因此一个指令流的操作码字节是另一个指令流的修饰符/操作数字节,反之亦然。这不是在正常编程中完成的,但表明指令字节的解释取决于起始位置。

对于可变长度指令集(如x86)和许多其他指令集,您必须从已知的良好入口点开始,并按执行顺序进行反汇编,而不一定是线性的

无法保证这会起作用,因为通常情况下,使反汇编程序跳闸并导致其失败是微不足道的

举个简单的例子,有很多方法可以做到这一点

set flag
blah
blah
jump if flag to hello
put the first opcode byte but not the rest of the instruction here as data
hello:
real stuff here
我倾向于跟踪每条指令的第一个字节的位置,然后跟踪哪些字节是指令的附加字节,以便在沿着路径或分支运行时,可以检查每条指令,首先查看我是否已经到达该路径,然后查看第一个字节是否落在非第一个字节的顶部。这可能是完全有效的手工编写的代码,使汇编程序出错,也可能是您在其他地方出错的其他原因

除非编译器被设计为或被告知,否则它不会生成有反汇编问题的代码(执行顺序不是线性的)。但是如果你回头说反汇编经典的视频游戏ROM,你可能会发现这些反汇编问题,然后必须做更多的工作,主要是代码分析,以确定哪一条执行路径是正确的


固定长度的指令集,具有已知的对齐方式,您可以从几乎任何地方进行线性反汇编,您必须容忍未知指令,因为当您点击数据部分时,您将看到很多未知指令,但您可以选择不处理执行顺序的捷径。

回答得很好。以下是处理器从何处获取指令第一个字节位置的列表的更多项目:a)来自VMCS的主机RIP或来宾RIP字段;b) 从中断描述符表;c) 从SIPI中的矢量号中提取。@prl:Tha