反汇编中的跳转指令该怎么理解?
图中是植物大战僵尸的部分反汇编代码,注意关注我写的备注
我不能理解的是,每个跳转指令后面都会跟上一个内存地址,为什么相同的两个 jne 413E45,会编译出两个不同的字节码来?
我所理解的是,JMP0x001,翻译成人类语言,现在立刻无条件去 张三家继续办公
如果用中文写一段伪代码,例子1:
现在立刻无条件去 张三家继续办公 jmp 0x001
现在立刻无条件去 李四家继续办公 jmp 0x002
现在立刻无条件去 张三家继续办公 jmp 0x001
上例中有两行相同的语句,因此对应的汇编代码,应该是一样的才对
再看例子二:
cmp ESI EBX
大于则立刻去 张三家继续办公 jmp 0x001
...
test EAX EBX
大于则立刻去 张三家继续办公 jmp 0x001
上例中同样有两个一样的跳转,虽然各自前一行的比较命令不同,但是他们自身判断及跳转地址一致,应该都是 jmp 0x001 才对
但是很显然,我所理解的和实际反汇编中显示的情况不一样,我需要有人能告诉我这是为什么?
因此而衍生的第二个问题,我通过VirtualAllowEx成功开辟一段内存空间,可读写可执行,在dbg中能看到
于是我在里面写上一段自己的汇编代码,得到其字节码,然后在程序里通过WriteProcessMemory在这个地址写入这些字节码
到此为止,都没问题,但是有两个点出问题了,这两个点都是跳转地址,如下图所示
比如我先在x64DBG里,写上 jge 0x00413E45,假如此时这条汇编代码的字节码是 AABBCC
但是我通过程序写入后,再去看,就变成了 jge 0x00666888,而且每次都不一样,也许下一次是jge 0x00777999
这又是为什么呢?
本帖最后由 longs75 于 2021-11-19 15:34 编辑
转移指令(包括JMP、CALL、RET)都有相对寻址和绝对寻址两种方式,你把相对寻址的概念再仔细研究一下就明白了,指令操作码后边不是地址,是跳转的相对距离。
00401011 | EB 02 | jmp empty32.401015 |
00401013 | EB 02 | jmp empty32.401017 |
00401015 | EB 02 | jmp empty32.401019 |
00401017 | EB 02 | jmp empty32.40101B | 二进制代码表示的是相对本指令的偏移地址而不是绝对地址 不专业点解释的话,从A到B和从C到B是完全不同的距离,你不能因为从A到B需要走1km,就说从C到B也是1km,虽然目的地相同 0D就是 13 , 13个字节。 懂吗?
页:
[1]