Linux命令行参数在栈中的分布

来源:互联网 发布:轩辕剑修罗进阶数据 编辑:程序博客网 时间:2024/05/16 14:49


Linux命令行参数在栈中的分布

                                                                                                                                  lxg@2015-03-18

  • Linux命令行参数在栈中的分布

    1:分布示意图

    上图是linux32ELF程序加载之后,命令行参数在stack中的分布示意图。

    从上面来看argvenvp)参数的组织有点像一个链表一样,首先是char *argv[]这个指向指针的数组,然后通过argv[0]找到第一个命令行参数的指针(地址),最后再根据指针找到真正的参数字符串。envp也是类似。

  • 通过gdb查看Linux命令行参数在栈中的分布

    上文中通过图例的形式描述了命令行参数在栈中的分布情况,下面将通过gdb来近一步的查看真实运行环境中的情况。

/**

 *

 * Author:      liuxingen@nsfocus.com

 *

 * Created Time: Mon 16 Mar 2015 10:08:26 PM GMT-8

 *

 * FileName:    hello.c

 *

 * Description: 

 *

 **/

 

#include <stdio.h>

int main(int argc,char*argv[],char*envp[]){

     printf("Hello,world!\n");

}

 

Hello.c

.file  “hello.c”

.section   .rodata

.LC0:

.string“Hello,world!”

.text

.globl main

.type  main, @function

main:

pushl  %ebp

movl   %esp, %ebp

andl   $-16, %esp

subl   $16, %esp

movl   $.LC0,(%esp)

call   puts

leave

ret

.size  main, .-main

.ident “GCC: (Gentoo 4.4.5 p1.3, pie-0.4.5) 4.4.5”

.section   .note.GNU-stack,””,@progbits

 

Hello.s

        上面是一个简单的输出”Hello,world!”的程序,hello.s” gcc -Shello.c”的结果,通过” gcc hello.s -o hello -gstabs”生成可执行文件hello

 

liuxingen@remoter ~/station/asm $ gdb -q hello

Reading symbols from hello...done.

(gdb) b main

Breakpoint 1 at 0x80483e7: file hello.s, line 11.

(gdb) run 1 2 3 4

Starting program: /home/liuxingen/station/asm/hello 1 2 3 4

 

Breakpoint 1, main () at hello.s:11

11             andl$-16, %esp

(gdb) l

6      .globl main

7               .type        main, @function

8      main:

9               pushl        %ebp

10             movl         %esp, %ebp

11             andl$-16, %esp

12             subl $16, %esp

13             movl         $.LC0, (%esp)

14             call  puts

15             leave

(gdb) x/5aw $esp

0xbffff608:       0xbffff688        0xb7e8fcc6 <__libc_start_main+230>  0x5  0xbffff6b4

0xbffff618:       0xbffff6cc

        这是gdb的部分输出,跟图1有一点不相同的地方,堆栈指针esp目前不是指向main的返回值,因为这是我们b main的时候其实断点是设在了第11行,在第9行已经把ebp入栈了。除了第一个0xbffff688输出以外,其它的4个输出分别对应了”main返回值”argc””char **argv””char **envp”

(gdb) x/6wa 0xbffff6b4

0xbffff6b4:       0xbffff828        0xbffff84a        0xbffff850        0xbffff857

0xbffff6c4:       0xbffff85d        0x0

(gdb) x/s 0xbffff828

0xbffff828:       "/home/liuxingen/station/asm/hello"

(gdb) x/s 0xbffff84a

0xbffff84a:       "first"

(gdb) x/s 0xbffff850

0xbffff850:       "second"

(gdb) x/s 0xbffff857

0xbffff857:       "third"

(gdb) x/s 0xbffff85d

0xbffff85d:       "fourth"

        上面是argv[]数组的输出,argv[]后面紧接着就是一个NULL

(gdb) x/3wa 0xbffff6cc

0xbffff6cc:       0xbffff864        0xbffff930        0xbffff940

(gdb) x/s 0xbffff864

0xbffff864:       "MANPATH=/usr/local/share/man:/usr/share/man:/usr/share/binutils-data/i686-pc-linux-gnu/2.21.1/man:/usr/share/gcc-data/i686-pc-linux-gnu/4.4.5/man:/usr/share/postgresql/man/:/usr/share/postgresql-9.0/m"...

(gdb) x/s 0xbffff930

0xbffff930:       "SHELL=/bin/bash"

(gdb) x/s 0xbffff940

0xbffff940:       "TERM=xterm"

        上面是envp[]数组的部分输出。

(gdb) x/s 0xbffffffc

0xbffffffc:""

(gdb) x/s 0xbffffff6

0xbffffff6:         "hello"

        上面是栈底的最后两个数据,一个是NULL,一个是程序的名称。Linux32位系统中栈底的位置固定为0xc0000000

0 0
原创粉丝点击