你不会了解 发表于 2021-11-19 15:17

反汇编中的跳转指令该怎么理解?



图中是植物大战僵尸的部分反汇编代码,注意关注我写的备注

我不能理解的是,每个跳转指令后面都会跟上一个内存地址,为什么相同的两个 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:32

本帖最后由 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                                    |

lies2014 发表于 2021-11-19 15:34

二进制代码表示的是相对本指令的偏移地址而不是绝对地址

搜索曾经的回忆 发表于 2021-11-19 16:01

不专业点解释的话,从A到B和从C到B是完全不同的距离,你不能因为从A到B需要走1km,就说从C到B也是1km,虽然目的地相同

悲伤逆流01 发表于 2021-11-19 18:27

0D就是 13 , 13个字节。 懂吗?
页: [1]
查看完整版本: 反汇编中的跳转指令该怎么理解?