0 debugging x86 assembly low-level disassembly
如何在进程的可执行存储器中区分组装"调用"指令(E8 [地址])与其他E8字节(例如,在另一条指令中间的那个)的操作码?(从C语言的角度来看,最好)
是否足以验证E8字节之后的四个字节是否引用有效地址,然后验证该区域(即被调用函数的开始)是否以对应于操作码"push ebp"和"mov ebp"的字节开头,esp"(大多数功能都使用这个序幕)?或者是否有更好的选择,例如检查从入口点到出口点的每个操作码?
顺便说一句,我对这个主题几乎没有经验,所以任何信息都值得赞赏.
谢谢!
正确的解释从已知为指令开始的地址开始.
(这个答案适用于具有可变长度指令的处理器,当然,例如Intel的x86架构.)
当处理器解释指令时,它总是开始在特定位置进行解释,因为:
所有这些都是已知的指令开始位置,因为它们的设计方式如下:我们编写软件,这些位置是我们放置指令的地方.
在解释指令时,处理器遵循关于指令编码的规则.它查看第一个字节,该字节中的位指示接下来的几个字节是否是当前指令的操作码,修饰符或操作数.然后它相应地解释下一个字节.因此,指令的第一个字节中的E8 16将被解释为与其他地方的E8 16字节不同.
反汇编程序从用户告诉它开始.通常,这是程序中标签给出的地址(例如函数名称)或其他信息,例如当前程序计数器的值或堆栈中找到的返回地址.这些地址都是指令的开始,因此反汇编程序以与处理器相同的方式解释字节.
有时可能无法轻易访问有关特定区域中的指令开始的信息,并且可能只是告诉反汇编程序开始在区域中间的任意地址进行反汇编.在这种情况下,前几个反汇编的指令可能是错误的,因为反汇编程序正在解释从通常不是指令开始的位置开始的字节.(一个常见的例子是,一个是调试并且知道当前的程序计数器,但是想要向后看最近的十几条指令而不从当前例程的开头开始.在这种情况下,可能会告诉反汇编程序开始从当前程序计数器反汇编100个字节.)然而,经常发生的是,基本上是偶然的,错误解释的指令之一恰好在正确指令开始的地方结束.然后,反汇编程序正确地反汇编该指令,并与正确的指令序列同步,剩余的反汇编正确进行.只要大多数指令很短并且指令长度变化很大,很可能在几条指令中发生这种情况.
可以使用指令编码进行播放,并根据您在其中开始执行的位置制作表示两个不同指令流的字节序列,以便一个流的操作码字节是另一个的修饰符/操作数字节,反之亦然.这不是在正常编程中完成的,但表明指令字节的解释取决于起始位置.
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |