关于堆栈状态

时间:2011-10-15 20:21:53

标签: c function gdb stack

我有一个程序,我想了解堆栈在执行期间的状态。我的示例程序很简单,

#include <stdio.h>
 int main(){
   setuid(0);
   system("/bin/bash");
   return 1;
 }

现在当我用gdb调试这个程序时,我得到了setuid()函数的地址,但是当我查看堆栈时,我无法确定其地址。

开始执行main(),

后我的堆栈状态
Ajai@ubuntu:/tmp$ gdb -q mal
Reading symbols from /tmp/mal...done.
(gdb) b 2
Breakpoint 1 at 0x80483fd: file mal.c, line 2.
(gdb) r
Starting program: /tmp/mal 

Breakpoint 1, main () at mal.c:4
4        setuid(0);
(gdb) x/32xw $esp
0xbffff3a0:    0x0015ed35    0x0011ea50    0x0804842b    0x0028bff4
0xbffff3b0:    0x08048420    0x00000000    0xbffff438    0x00145e37
0xbffff3c0:    0x00000001    0xbffff464    0xbffff46c    0x0012e414
0xbffff3d0:    0xffffffff    0x0012cff4    0x08048243    0x00000001
0xbffff3e0:    0xbffff420    0x0011da31    0x0012dad0    0xb7fffb48
0xbffff3f0:    0x00000001    0x0028bff4    0x00000000    0x00000000
0xbffff400:    0xbffff438    0xb68cac87    0x61d0d5f8    0x00000000
0xbffff410:    0x00000000    0x00000000    0x00000001    0x08048340
(gdb) p setuid
$1 = {<text variable, no debug info>} 0x1c8ee0 <setuid>

我看错了堆栈吗?

我还想知道当main()函数开始执行时,setuid()函数调用的地址及其参数和system()函数调用以及它的参数将如何存储在堆栈中。

如果已经提出这样的问题,我很抱歉,但我找不到。

2 个答案:

答案 0 :(得分:4)

你的问题非常不清楚,可能是因为你不了解堆栈和通话是如何工作和互动的。

不知何故,您希望在调用该函数之前在堆栈上找到setuid的地址。但是那个地址根本就不存在(既不是在通话之前,也不是在通话过程中,也不是在通话结束之后)。

如果在setuid本身设置断点,请运行该断点,然后检查堆栈。然后,您将看到main中的地址(不是main本身的地址,而是{C}指令后面的main中的指令,该指令可让您进入setuid第一名)。

  

我假设这是执行即将进入setuid()函数时堆栈的样子(假设我在setuid函数调用时有一个断点)

     

1.call to setuid()

     

2.在setuid()函数调用

之后返回地址      

3. setuid()函数的参数。

正如我所说,你的假设是不正确的:堆栈上有没有“调用setuid”(但2.和3.是正确的)。

答案 1 :(得分:1)

正如ER指出的那样,单步执行装配说明。调用函数的地址通常在函数调用之前放入EAX寄存器。检查一下,或者编译器放入的其他内容。