Debugging “如何识别部件”;调用;内存中的指令? 如何在一个进程的可执行内存中区分汇编的“调用”指令(E8[Adv])的操作码与其他E8字节(例如,在另一个指令的中间)的操作码?(最好是从C语言的角度)
验证E8字节后的四个字节是否为有效地址是否足够,然后验证该区域(即调用函数的开始)是否以与操作码“push ebp”和“mov ebp,esp”对应的字节开始(大多数函数使用此序言)?还是有更好的选择,比如检查从入口点到出口点的每个操作码 顺便说一句,我对这个话题几乎没有经验,所以任何信息都非常感谢Debugging “如何识别部件”;调用;内存中的指令? 如何在一个进程的可执行内存中区分汇编的“调用”指令(E8[Adv])的操作码与其他E8字节(例如,在另一个指令的中间)的操作码?(最好是从C语言的角度),debugging,assembly,x86,disassembly,low-level,Debugging,Assembly,X86,Disassembly,Low Level,验证E8字节后的四个字节是否为有效地址是否足够,然后验证该区域(即调用函数的开始)是否以与操作码“push ebp”和“mov ebp,esp”对应的字节开始(大多数函数使用此序言)?还是有更好的选择,比如检查从入口点到出口点的每个操作码 顺便说一句,我对这个话题几乎没有经验,所以任何信息都非常感谢 谢谢大家! 正确的解释从一个已知为指令开始的地址开始 (这个答案当然适用于指令长度可变的处理器,比如英特尔的x86架构。) 当处理器解释指令时,它总是在特定位置开始解释,因为: 它是之前解释的指令
谢谢大家! 正确的解释从一个已知为指令开始的地址开始 (这个答案当然适用于指令长度可变的处理器,比如英特尔的x86架构。) 当处理器解释指令时,它总是在特定位置开始解释,因为:
- 它是之前解释的指令之后的下一个位置
- 它是跳转指令的目标(包括从陷阱和其他特殊指令返回)
- 它是处理器初始化时的初始起始位置,或
- 它是用于控制系统的中断表或其他特殊数据结构中的地址
根据您在指令流中开始执行的位置,您可以使用指令编码并创建一个字节序列,该序列表示两个不同的指令流,因此一个指令流的操作码字节是另一个指令流的修饰符/操作数字节,反之亦然。这不是在正常编程中完成的,但表明指令字节的解释取决于起始位置。对于可变长度指令集(如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