C语言main函数中argv参数分析

最近在看《黑客攻防技术宝典:系统篇》,在分析书中一些例子时,又对原来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 知识点


  1. 数组变量分配的空间大小

    从上面的汇编代码中可以看出这里分配的空间为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的倍数。

  2. 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)
    
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值