我们正在使用gdb调试器来读取汇编函数。
在装配中,我们有以下说明:
mov 0xc(%rsp),%eax
jmpq *0x402390(,%rax,8)
在内存位置*0x402390
,我们的值为0x8e
。在寄存器rax中,我们有这个特定函数的第二个整数输入(可以使用变量y)。
根据我们的分析,我们推断出此函数包含三个变量(x, y, z)
,并且可以分别在内存位置(rsp)
,(rsp + 8)
,(rsp + 12)
找到它们。
我们想知道jmpq *0x402390(,%rax,8)
中发生了什么。
它跳到了(0x8e + rax*8)
的指令吗?如果是这样,我们怎样才能找出该指令的内容?
这是函数phase_3的汇编程序代码的完整转储:
答案 0 :(得分:10)
来自GAS-manual:
表格
的英特尔语法间接内存引用section:[base + index*scale + disp]
被翻译成AT& T语法
section:disp(base, index, scale)
其中base和index是可选的32位基址和索引寄存器, disp是可选的位移和比例,取值1,2, 4和8,乘以索引来计算操作数的地址。
(https://sourceware.org/binutils/docs/as/i386_002dMemory.html#i386_002dMemory)
所以你可以将jmpq *0x402390(,%rax,8)
翻译成INTEL语法:jmp [RAX * 8 + 0x402390]。它是一个间接的"跳。地址[RAX * 8 + 0x402390]是一个地址,它将成为jmp
的目标。下一步是确定在0x402390 + x处可以找到多少个地址,在这种情况下使用它们。
答案 1 :(得分:7)
炸弹实验室吧?
此操作jmpq *0x402390(,%rax,8)
用于直接跳转到存储在
的绝对地址
8 * %rax + 0x402390
如果您在gdb中执行x/16gx 0x402390
(检查以0x402390
开头的十六进制的16个“巨字”),您会发现地址表如下所示:(我有一个不同的实验室,因此没有和你一样)
0x402880: 0x0000000000400fee 0x000000000040102b
0x402890: 0x0000000000400ff5 0x0000000000400ffc
0x4028a0: 0x0000000000401003 0x000000000040100a
0x4028b0: 0x0000000000401011 0x0000000000401018
所有这些地址都指向mov
之后的单个jmpq *0x402390(,%rax,8)
操作
答案 2 :(得分:1)
它跳转到每个条目有8个字节的代码表,有点像switch case语句优化。它有点令人困惑,因为在jmpq之后有一系列7字节序列,而jmpq分支到的代码(从402390开始)没有显示在图像中。