【发布时间】:2012-08-27 10:06:15
【问题描述】:
我向大家问好。我有一个 C 程序,基本上是为测试缓冲区溢出而编写的。
#include<stdio.h>
void display()
{
char buff[8];
gets(buff);
puts(buff);
}
main()
{
display();
return(0);
}
现在我使用 GDB 分解显示和主要部分。代码:-
函数 main 的汇编代码转储:
0x080484ae <+0>: push %ebp # saving ebp to stack
0x080484af <+1>: mov %esp,%ebp # saving esp in ebp
0x080484b1 <+3>: call 0x8048474 <display> # calling display function
0x080484b6 <+8>: mov $0x0,%eax # move 0 into eax , but WHY ????
0x080484bb <+13>: pop %ebp # remove ebp from stack
0x080484bc <+14>: ret # return
汇编程序转储结束。
函数显示的汇编代码转储:
0x08048474 <+0>: push %ebp #saves ebp to stack
0x08048475 <+1>: mov %esp,%ebp # saves esp to ebp
0x08048477 <+3>: sub $0x10,%esp # making 16 bytes space in stack
0x0804847a <+6>: mov %gs:0x14,%eax # what does it mean ????
0x08048480 <+12>: mov %eax,-0x4(%ebp) # move eax contents to 4 bytes lower in stack
0x08048483 <+15>: xor %eax,%eax # xor eax with itself (but WHY??)
0x08048485 <+17>: lea -0xc(%ebp),%eax #Load effective address of 12 bytes
lower placed value ( WHY???? )
0x08048488 <+20>: mov %eax,(%esp) #make esp point to the address inside of eax
0x0804848b <+23>: call 0x8048374 <gets@plt> # calling get, what is "@plt" ????
0x08048490 <+28>: lea -0xc(%ebp),%eax # LEA of 12 bytes lower to eax
0x08048493 <+31>: mov %eax,(%esp) # make esp point to eax contained address
0x08048496 <+34>: call 0x80483a4 <puts@plt> # again what is "@plt" ????
0x0804849b <+39>: mov -0x4(%ebp),%eax # move (ebp - 4) location's contents to eax
0x0804849e <+42>: xor %gs:0x14,%eax # # again what is this ????
0x080484a5 <+49>: je 0x80484ac <display+56> # Not known to me
0x080484a7 <+51>: call 0x8048394 <__stack_chk_fail@plt> # not known to me
0x080484ac <+56>: leave # a new instruction, not known to me
0x080484ad <+57>: ret # return to MAIN's next instruction
汇编程序转储结束。
所以伙计们,你们应该考虑一下我的功课。剩下的所有代码我都知道,除了几行。我已经包括了一个很大的“为什么????”以及每行前面的 cmets 中的更多问题。对我来说第一个障碍是“mov %gs:0x14,%eax”指令,我不能在这个指令之后制作流程图。有人请解释我,这几条指令是什么意思,在程序中做什么?谢谢...
【问题讨论】:
-
在main中你返回0,这就是
mov $0x0,%eax的原因。 -
xor %eax,%eax是一种清除 %eax 的高效方法,因为异或相同的值总是产生 0。 -
gs:0x14的操作看起来像 stack canary。xor %eax, %eax只是将eax设置为0的一种方式。lea -0xc(%ebp), %eax将你的buff的地址加载到eax中,因此可以将其传递给gets/puts。 -
非常感谢 Qiau 和 DCoder... :-)
-
PLT 是过程链接表。
gets和puts位于动态库中,链接程序时不知道其地址。所以,以后每次加载程序的时候,它需要的动态库也会被加载。无论是在那个时候还是以后,当你第一次从动态库中调用一个函数时,它的地址就会被解析,并放入 GOT(全局偏移表)中。当您调用gets@plt时,它会间接跳转到相应 GOT 条目所指向的条目(或解析该地址的例程,如果仍未解析)。