【问题标题】:how to interpret stack memory from gdb如何从 gdb 解释堆栈内存
【发布时间】:2018-09-22 04:45:31
【问题描述】:

对 assemly 相当陌生,在使用 gdb 时无法理解如何解释堆栈内存。我了解 bt 和 info frame 显示的内容。 x/10x 显示从当前堆栈指针开始的前 10 个值,但您如何解释它?第一列是堆栈级别,我假设这意味着堆栈框架?并且在第一列之后有 32 位,每个十六进制值是什么意思?

(gdb) bt
#0  zzz () at zzz.c:96
#1  0xf7d39cba in yyy (arg=arg@entry=0x0) at yyy.c:542
#2  0xf7d3a4f6 in yyyinit () at yyy.c:590
#3  0x0804ac0c in gnninit () at gnn.c:374
#4  main (argc=1, argv=0xffffd5e4) at gnn.c:389

(gdb) info frame
Stack level 0, frame at 0xffeac770:
eip = 0x8049047 in main (goo.c:291); saved eip 0xf7f1fea1
source language c.
Arglist at 0xffeac768, args: argc=1, argv=0xffffd5e4
Locals at 0xffeac768, Previous frame's sp is 0xffeac770
Saved registers:
ebx at 0xffeac75c, ebp at 0xffeac768, esi at 0xffeac760, edi at 0xffeac764, 
eip at 0xffeac76c

(gdb) x/10x $sp
0xffeac63c: 0xf7d39cba  0xf7d3c0d8  0xf7d3c21b  0x00000001
0xffeac64c: 0xf78d133f  0xffeac6f4  0xf7a14450  0xffeac678
0xffeac65c: 0x00000000  0xf7d3790e

【问题讨论】:

    标签: assembly memory x86 stack


    【解决方案1】:
    (gdb) x/10x $sp
    0xffeac63c: 0xf7d39cba  0xf7d3c0d8  0xf7d3c21b  0x00000001
    0xffeac64c: 0xf78d133f  0xffeac6f4  0xf7a14450  0xffeac678
    0xffeac65c: 0x00000000  0xf7d3790e
    

    第一列是后面第一个字节的内存地址。

    其他四列是存储在内存中的四个 32 位值。

    即第一行表示在地址 0xffeac63c 内存包含字节值 0xba,在地址 0xffeac63d 有值 0x9c 等。直到地址 0xffeac64b 存储值 0x00(英特尔是小端,所以 dword 0xf7d39cba 存储在内存为字节ba 9c d3 f7)。

    这些值是什么意思......好吧,0xf7d39cba0xf7d39cba,一个 32 位值。内存内容没有任何意义,除非您通过使用它们的代码赋予这些值一些意义。

    即如果下一条要执行的指令是ret 并且esp 指向0xf7d39cba,则该值用作返回地址。

    如果下一条指令是pop eax,那么该值将被提取到寄存器eax,并用于代码进一步处理eax中的值...

    【讨论】:

    • 我发现类似于print *(void **) $esp @ 10 的内容对于在编写Different Ubuntu versions binary execution differences 时让gdb 用符号名称注释堆栈上的指针很有用。
    • 你从 0xf7d39cba 这个词中得到 0xba 了吗?
    • @cloudiebro 是的,0xf7d39cba 作为四个字节存储在内存中ba 9c d3 f7(按照从最低有效字节到最高有效字节的顺序,因为英特尔是“小端”机器)。
    • 而内存可以通过单字节寻址,即存储在计算机内存中的每个字节值(8位)都有自己的地址(物理内存地址),通常由操作系统虚拟化并转换为进程地址空间,但是在 32 位模式下,无论哪种方式,内存地址(虚拟或物理)都是 32 位值,因此以 32 位值打印堆栈内容的方式通常比单字节转储更方便。但是在十六进制格式中,您可以轻松读取单独的字节(每个十六进制数字正好是 4 位 => 两位数字是单字节)。
    • 我对 0xba 是一个字节有点困惑,我认为你的回答有误,你说 0xffeac63d 时是指 0xffeac63c 吗?
    猜你喜欢
    • 2016-07-25
    • 2017-01-17
    • 1970-01-01
    • 2012-09-17
    • 2018-11-29
    • 2019-10-16
    • 2013-09-10
    • 2011-07-20
    • 2011-12-12
    相关资源
    最近更新 更多