在这个例子中,jmpq命令是做什么的

时间:2014-10-24 07:04:53

标签: assembly terminal gdb att

我们正在使用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的汇编程序代码的完整转储:

Full assembly function

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开始)没有显示在图像中。