最近在看《黑客攻防技术宝典:系统篇》,在分析书中一些例子时,又对原来c中一些知识点有了新的认识。
0x01 环境
OS:Debian3r4
GCC:gcc version 3.3.5 (Debian 1:3.3.5-13)
GDB:GNU gdb 6.3-debian
编译命令:gcc -g victim.c -o victim
gdb调试命令:gdb --args ./victim "AAAAA"
0x02 源码
//victim.c
#include <stdio.h>
void func(char *str)
{
int a=0;
printf("%p\n",&str);
printf("%s\n", str);
}
int main(int argc, char *argv[])
{
char little_array[512];
//if (argc > 1)
//strcpy(little_array,argv[1]);//-----------------------1
//printf("%s,%s,%s,%s\n", argv[2],argv[3],argv[4],argv[5]);//----------------------2
//func(argv[3]);//---------------------3
}
gdb反编译源码
yerx@debian:~$ gdb --args ./victim "AAAAA"
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disassemble main
Dump of assembler code for function main:
0x080483b9 <main+0>: push %ebp
0x080483ba <main+1>: mov %esp,%ebp
0x080483bc <main+3>: sub $0x208,%esp
0x080483c2 <main+9>: and $0xfffffff0,%esp
0x080483c5 <main+12>: mov $0x0,%eax
0x080483ca <main+17>: sub %eax,%esp
0x080483cc <main+19>: leave
0x080483cd <main+20>: ret
End of assembler dump.
(gdb)
0x03 知识点
-
数组变量分配的空间大小
从上面的汇编代码中可以看出这里分配的空间为520(0x208)个字节大小,而不是512个字节。为什么会出现这种情况。
《深入理解计算机系统》该书中第三章3.7.4中有如下说明:
为什么GCC分配从不使用的空间
GCC为caller参数的代码在栈上分配了24个字节,但是只使用了其中16个。我们会看到很多这样明显浪费的列子。GCC坚持一个x86编程的指导方针,也就是一个函数使用的所有站空间必须是16字节的整数倍。包括保存%ebp值的4个字节和返回值的4个字节,caller一共使用了32个字节。采用这个规则是为了保证访问数据的严格对齐。设置0x08048427为断点,run运行程序后
查看ebp是0xbffffb48,esp:0xbffff930 ,此时栈中还没有保存返回指令地址。
所以整个main栈就是0xbffffb4c-0xbffff930 + 0x4 = 0x220。
整个main函数的栈有544个字节,刚好是16的倍数。 -
main函数的argv参数
main函数的argc参数表示参数数量,argv表示实际参数字符串数组,argv不只是含有输入的参数,还包括环境变量的字符串。(gdb) disassemble main Dump of assembler code for function main: 0x080483b9 <main+0>: push %ebp 0x080483ba <main+1>: mov %esp,%ebp 0x080483bc <main+3>: sub $0x28,%esp 0x080483bf <main+6>: and $0xfffffff0,%esp 0x080483c2 <main+9>: mov $0x0,%eax 0x080483c7 <main+14>: sub %eax,%esp 0x080483c9 <main+16>: leave 0x080483ca <main+17>: ret End of assembler dump. (gdb) b *0x080483b9 Breakpoint 1 at 0x80483b9: file victim.c, line 10. (gdb) run Starting program: /home/yerx/victim AAAAAAAA Breakpoint 1, main (argc=134513593, argv=0x2) at victim.c:10 10 { (gdb) i r esp esp 0xbffffb4c 0xbffffb4c (gdb) x/20x 0xbffffb50 0xbffffb50: 0x00000002 0xbffffba4 0xbffffbb0 0x080482c0 0xbffffb60: 0x00000000 0x4000bcd0 0x4014bdb4 0x40016ca0 0xbffffb70: 0x00000002 0x080482c0 0x00000000 0x080482e1 0xbffffb80: 0x080483b9 0x00000002 0xbffffba4 0x080483d0 0xbffffb90: 0x08048430 0x4000c380 0xbffffb9c 0x00000000 (gdb) x/20x 0xbffffb54 0xbffffb54: 0xbffffba4 0xbffffbb0 0x080482c0 0x00000000 0xbffffb64: 0x4000bcd0 0x4014bdb4 0x40016ca0 0x00000002 0xbffffb74: 0x080482c0 0x00000000 0x080482e1 0x080483b9 0xbffffb84: 0x00000002 0xbffffba4 0x080483d0 0x08048430 0xbffffb94: 0x4000c380 0xbffffb9c 0x00000000 0x00000002 (gdb) x/20x 0xbffffba4 0xbffffba4: 0xbffffc86 0xbffffc98 0x00000000 0xbffffca1 0xbffffbb4: 0xbffffcb1 0xbffffcbc 0xbffffcc6 0xbffffefb 0xbffffbc4: 0xbfffff0a 0xbfffff15 0xbfffff21 0xbfffff5b 0xbffffbd4: 0xbfffff67 0xbfffff76 0xbfffff81 0xbfffff8a 0xbffffbe4: 0xbfffff92 0xbfffffa7 0xbfffffb7 0xbfffffd2 (gdb) x/ws 0xbffffc86 0xbffffc86: "/home/yerx/victim" (gdb) x/20ws 0xbffffc86 0xbffffc86: "/home/yerx/victim" 0xbffffc98: "AAAAAAAA" 0xbffffca1: "SHELL=/bin/bash" 0xbffffcb1: "TERM=xterm" 0xbffffcbc: "USER=yerx" 0xbffffcc6: "LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01"... 0xbffffd8e: ";31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.ti"... 0xbffffe56: "ff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:" 0xbffffefb: "SUDO_USER=root" 0xbfffff0a: "SUDO_UID=0" 0xbfffff15: "COLUMNS=121" 0xbfffff21: "PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games" 0xbfffff5b: "_=/bin/bash" 0xbfffff67: "PWD=/home/yerx" 0xbfffff76: "LANG=zh_CN" 0xbfffff81: "LINES=46" 0xbfffff8a: "SHLVL=2" 0xbfffff92: "SUDO_COMMAND=/bin/su" 0xbfffffa7: "HOME=/home/yerx" 0xbfffffb7: "LANGUAGE=zh_CN:zh:en_US:en" (gdb)