我是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代码中的切换条件。
答案 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是指针表的索引。您需要知道索引并从表中找到跳转地址。