如何分析汇编代码中的间接跳转

时间:2018-11-15 19:46:53

标签: assembly x86-64 reverse-engineering att objdump

我是C和汇编代码的初学者,目前正在从事汇编项目。但是,我在使用间接跳转指令时遇到了一些问题。

jmp指令行是:

4006a6: ff 24 c5 50 08 40 00    jmpq   *0x400850(,%rax,8)

当我转到400850时,该行是:

400850: ad                      lods   %ds:(%rsi),%eax
400851: 06                      (bad)  
400852: 40 00 00                add    %al,(%rax)
400855: 00 00                   add    %al,(%rax)
400857: 00 b3 06 40 00 00       add    %dh,0x4006(%rbx)
40085d: 00 00                   add    %al,(%rax)
40085f: 00 bc 06 40 00 00 00    add    %bh,0x40(%rsi,%rax,1)

根据我所学的知识,我应该查看存储在400850 + 8 * rax中的地址,然后跳转到该地址以查看指令并执行特定操作。例如,如果rax = 1,我应该查看存储在400858中的地址,但是找不到400858,并且我也不知道“ ab”之类的值是什么,这是地址吗?

顺便说一句,我相信这种间接跳转代表了C代码中的切换条件。

2 个答案:

答案 0 :(得分:3)

Google.Apis.Admin.Directory.directory_v1.dll是索引到跳转目标表的间接jmpq *0x400850(,%rax,8)。是的,它可能是由jmp语句编译生成的。


您使用的是switch而不是objdump -D,因此输出根据x86-64指令的无意义解码将hexdump分解为多个块,而不是qword地址。

格式为

objdump -s

一行中的字节与指令一起出现。 starting machine code disassembly address hex byte(s) (AT&T syntax) 400850: ad lods %ds:(%rsi),%eax 是操作码为lods的单字节指令,因此0xad处qword的低字节为0x400850

十六进制转储就在那里,但并非每个8字节块都带有编号标签。每个字节都有自己的地址;您只需要从前面标记的地址开始计数,即可找到所需数据的开头。


或按照assembly jmp to a line that doesn't exist中的建议使用0xad来获得每个ELF节的简单十六进制转储,并分成大小一致的块。

或者从GDB内部执行objdump -s命令。

答案 1 :(得分:0)

此地址0x400850是一个指针表,因此类似于: 400850:00000000004006ad 400858:00000000004006b3 400860:00000000004006bc

rax是指针表的索引。您需要知道索引并从表中找到跳转地址。