【问题标题】:My stack frames are different from the legacy one我的堆栈框架与旧版不同
【发布时间】:2016-07-10 20:01:44
【问题描述】:

堆栈帧的外观如下:

(high memory addresses)
    -function arguments
    -return address
    -saved frame pointer
    -local variables
(low memory addresses)

问题是为什么我的堆栈帧看起来像这样:

(high memory addresses)
    -return address
    -saved frame pointer
    -local variables
    -function arguments
(low memory addresses)

我在 gdb 中调试时注意到了这一点。 我用 C 编写代码并在 Kali Linux x86_64(intel core i7)上使用 gcc 5.4.0 编译。

C 代码:

void test_function(int a, int b, int c, int d) {
    int flag;
    char buffer[10];
    flag = 31337;
    buffer[0] = 'A';
}

int main() {
    test_function(1, 2, 3, 4);
    return 0;
}

main中rbp的值:

0x7fffffffe260

test_functtion调用地址后的汇编指令:

0x00000000004004e1

在 test_function 框架中对 rsp 执行 x 命令的结果:

0x7fffffffe240: 0x00000004  0x00000003  0x00000002  0x00000001
0x7fffffffe250: 0x00400441  0x00000000  0x004003b0  0x00007a69
0x7fffffffe260: 0xffffe270  0x00007fff  0x004004e1  0x00000000
0x7fffffffe270: 0x004004f0  0x00000000  0xf7a575f0  0x00007fff

【问题讨论】:

  • 因为堆栈向下增长
  • 我知道,但如果你把它颠倒过来,它甚至不对应。
  • “堆栈帧的外观如下:”。你从哪里得到的?
  • 每次我在谷歌上输入堆栈框架图,这是我唯一得到的东西,我读了一本名为“黑客:剥削的艺术”的书,它是同一张图(那个人写这本书也是用gcc)。
  • 我认为您可能误解了某些信息。首先,正如已经指出的那样,您在第一张图中的地址是颠倒的。其次,请向我们展示您用来制作第二张图的代码和 gdb 输出(或其他信息)。

标签: c gcc stack gdb


【解决方案1】:

看起来堆栈帧的规范在 x86 和 x86_64 之间发生了显着变化。对于 x86 堆栈帧 (Intel386 Processor Supplement),您是正确的。然而,x86_64 规范 (AMD64 Architecture Support Supplement) 在寄存器中传递整数参数(第 3.2.3 段)。下面的项目#2:

  1. 如果类是 MEMORY,则在堆栈上传递参数。

  2. 如果类是 INTEGER,则使用序列 rdi、%rsi、%rdx、%rcx、%r8 和 %r9 的下一个可用寄存器 13。

  3. 如果类是 SSE,则使用下一个可用向量寄存器,寄存器按从 %xmm0 到 %xmm7 的顺序获取。

  4. 如果类是 SSEUP,则八字节在最后使用的向量寄存器的下一个可用八字节块中传递。

  5. 如果类是 X87、X87UP 或 COMPLEX_X87,则在内存中传递。

堆栈帧现在看起来像这样:

如果查看堆栈帧,main 中的返回地址是 8[%rbp] 或 0x004005be,并且参数在正确的寄存器中:

(gdb) x/32 $rbp
0x7fffffffe040: 0xffffe050  0x00007fff  0x004005be  0x00000000
0x7fffffffe050: 0x00000000  0x00000000  0xf7a36f45  0x00007fff
0x7fffffffe060: 0x00000000  0x00000000  0xffffe138  0x00007fff
0x7fffffffe070: 0x00000000  0x00000001  0x004005a1  0x00000000
0x7fffffffe080: 0x00000000  0x00000000  0xdf5e7534  0x8acdbc8c
0x7fffffffe090: 0x00400470  0x00000000  0xffffe130  0x00007fff
0x7fffffffe0a0: 0x00000000  0x00000000  0x00000000  0x00000000
0x7fffffffe0b0: 0x1f9e7534  0x75324373  0x02a47534  0x753253ca
(gdb) info registers 
rax            0x4005a1 4195745
rbx            0x0  0
rcx            0x4  4
rdx            0x3  3
rsi            0x2  2
rdi            0x1  1
....

【讨论】:

  • 感谢您的回答
猜你喜欢
  • 2016-12-20
  • 2013-01-30
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
  • 2014-06-23
相关资源
最近更新 更多