翻译《The Old New Thing》 - Advantages of knowing your x86 machine code

Advantages of knowing your x86 machine code - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20041111-00/?p=37333

Raymond Chen  2004年11月11日


了解你的x86机器代码的优势

简要

        这篇文章介绍了一些在调试汇编语言时可能会用到的x86机器代码技巧。作者列举了几种单字节操作码,如NOP、INT 3、JZ/JNZ等,它们可以用来临时修改或跳过代码,以及如何撤销这些修改。此外,还提到了如何将条件跳转转换为无条件跳转,或者将跳转转换为永不执行的跳转。文章还讨论了如何安全地覆盖函数调用,以及如何避免栈损坏的问题。作者强调,使用单字节补丁比完全擦除代码更可取,因为它们更容易撤销,从而在调试过程中提供了更大的灵活性。

正文

        当你下次需要在汇编语言环境下进行调试(这对于一些开发者来说,是他们**唯一的**调试手段)时,以下是一些你可能会考虑尝试的机器代码技巧:

90

        是一个单字节的无操作(NOP)指令。如果你需要临时替换代码,而不想深入思考,只需简单地用90来覆盖它。撤销这个操作时,只需重新覆盖上原始的代码字节。

CC

        是一个单字节的中断3(INT 3)指令,它能够触发进入调试器。

74/75

        是零跳转(JZ)和非零跳转(JNZ)的指令码。如果你希望改变一个条件测试的逻辑,可以通过互换这两个指令码来实现。其他有用的指令码对包括72/73(小于跳转/不小于跳转)、76/77(小于等于跳转/大于跳转)、7C/7D(小于跳转/大于等于跳转)以及7E/7F(小于等于跳转/大于跳转)。你无需记住这些指令码的具体数值,只需了解改变最低位可以改变测试的逻辑。要恢复原状,再次改变该位即可。

EB

        是无条件的短跳转指令。如果你想将条件跳转改为无条件跳转,可以将74(例如)更改为EB。撤销这个更改,你需要记得原来的字节是什么。

00

        如果你希望将条件短跳转改为一个永不执行的跳转,可以将第二个字节设置为零。例如,将“74 1C”更改为“74 00”。这样,尽管跳转指令还在,但它实际上只会跳到下一条指令,从而不会产生任何效果。要恢复原状,你需要记住原来的跳转偏移量。

B8/E8

        是将立即数移入EAX寄存器(MOV EAX,immed32)和调用(CALL)指令的操作码。我通常使用它们来修改函数调用。如果我不希望调用某个函数,我会选择将E8更改为B8,而不是简单地用90覆盖它。恢复原状时,只需将B8改回E8。

        需要注意的是,这种方法仅适用于不需要栈参数的函数;否则,你的栈可能会损坏。一种更通用的方法是使用`83 C4 XX 90 90`(将ESP增加XX字节;无操作;无操作),其中XX代表你需要弹出的字节数。我个人不太记得这些指令的机器代码,因此我更倾向于修改CALL指令,使其指向函数末尾的“RETD”。

        相比于完全用90覆盖代码,我更倾向于使用这些单字节的补丁,因为如果你意识到需要恢复到修改前的代码状态,它们更容易撤销。

  • 34
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0x0007

可不可奖励我吃只毛嘴鸡 馋😋

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值