跳跃指令
使用代码移动
在之前的例子里,我们替换了指令,让北极星做出了不同的动作。但是我们需要去掉一些旧的指令来添加新的指令。怎样才能在不用替换大量旧代码的情况下,添加很多行新代码?你就要用到跳跃指令。
我们之前已经见过了跳跃,但是这里有一些新的例子:
从地址4937F7开始,程序会执行四条指令,然后跳跃到497000.跳跃之后,DEC EDX指令被执行费,接下来下面的指令就按顺序执行。
用跳跃命令的CMP
地址 指令 命令
004937F7 MOV EAX,0 ;Store 0 to EAX.
004937FC INC EAX ;Increase EAX by 1.
004937FD CMP EAX,50 ;Compare EAX with 50 (hex).
00493800 JGE 00450DE9 ;If EAX is greater than or equal to 50 (hex), jump to 450DE9.
00493806 PUSH 9955 ;If not, push 9955 onto the stack.
0049380B JMP SHORT 004937FC ;Jump to address 4937FC
上面的代码复杂了很多。大致看一下它做了什么:
代码将0存到EAX中,并增加一。
它检查 EAX是否比50大或者和50(16进制)一样大。就是十进制的 80。
如果EAX比 80(十进制)大或者一样大,代码就会跳到完全不同的地方(地址450DE9)。
如果不是,9955就会被推进堆叠,接下来代码就会稍微向后跳到INC EAX... CMP EAX,50...的循环中。
EAX就像一个从一到 80的计数器。当EAX最终到达 80到时候,代码跳到450DE9。
最终结果:9955被推到堆叠上79次(80次循环时,程序在它推动9955之前就跳到地址450DE9了)。
现在,绝对没有实际目的推动9955那么多次。即使如此,这也是非常好的循环代码的例子:一个东西不停地重复,直到某些情况发生为止。多亏了循环,我们没有必要写PUSH 9955 79次(这将占79行代码)。相对的我们只需要6行ASM代码!
JMP SHORT ?
JMP和JMP SHORT有什么不同?
JMP意味着你可以跳跃很长一段距离,但是JMP SHORT意味着跳跃短距离。JMP SHORT非常棒因为它比JMP占的空间更小。
(JMP SHORT占两个字节,但是一个跳跃根据跳跃的距离占五或六个,我记得很清楚)。
你永远也不要担心输入“JMP SHORT ”,只要输入JMP。如果有必要,OllyDbg会自动把JMP转换成JMP SHORT。这对其他类型的跳跃指令也有效。例如,使用JNE SHORT也有可能。
特别说一下,JMP SHORT最多可以向前跳跃 129字节(从JMP SHORT的开头开始),或者向后跳跃126字节。因为计数不总是那么容易的,所以你可能需要OllyDbg来完成。
下一课:呼叫和返回