我有一个程序,我想了解堆栈在执行期间的状态。我的示例程序很简单,
#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()函数调用以及它的参数将如何存储在堆栈中。
如果已经提出这样的问题,我很抱歉,但我找不到。
答案 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寄存器。检查一下,或者编译器放入的其他内容。