前言
对于用户程序来说, 堆栈区间 是一个很重要的组成部分, 这部分核心用于支持 函数调用, 参数暂存, 局部变量的存储 等等
我们这里 就来看一下 这块空间 的初始化的相关情况
这里会结合 内核进行调试, 以及 内存中的数据进行分析
堆栈空间的初始化
stack_base, stack_top 的初始化 方式如下
如果开启了 ASLR, 会随机减去一部分页面, 以及一部分随机的页内偏移, 这里讨论关闭 ASLR 的场景
stack_base, stack_top 的初始化, exec.bprm_mm_init 中初始化 stack 对应的 vma 为 0x7fffffffc000 - 0x7ffffffff000
初始化 bprm.p 为 0x7fffffffeff8
setup_arg_pages 中重新初始化 stack_top 基于 STACK_TOP 随机减去 n 个页面,arch_align_stack 随机减去一部分页内偏移,以后作为 bprm.p, mm.start_stack, mprotect_fixed 根据调整之后的 stack 信息,调整上面初始化的 vma 的区间信息
create_elf_tables 中开始初始化 环境变量,参数 等等信息,然后这里会更新 sp
rlimit_stack 默认值为 8m,一般来说大于 132kb + 8k,然后 计算出来的 stack_base 为 vma->vm_start - 132kb, stack_top 为 vma->vm_end
对于栈顶的一部分数据的填充, 处理 大致如下
bprm->p 在 bprm_mm_init 中初始化为 vma->vm_end - 8
然后在 do_execveat_common 中拷贝 文件名,环境变量列表,参数列表到 bprm->p,更新 bprm->p,之后为走 setup_arg_pages 的流程
create_elf_tables 基于 bprm->p 先拷贝 kbase_platform x86_64 上面是 x86_64
然后拷贝 十六个字节的随机字节序列
然后 bprm->p 给 argv, env 预留空间,十六字节对齐
从 bprm->p 开始填充 argc, argv 相关,先填充一字节 argc,再填充所有的 argv, 最后填充一个 \0,
然后开始填充 env 列表,最后填充一个 \0
最后开始填充 elf_info 相关记录信息
exec.bprm_mm_init 中的初始化, 初始化在 用户空间的顶部
拷贝可执行文件名称, 以及 环境变量, 以及参数, 并记录相关地址信息
exec.setup_arg_pages 的 stack_top 参数为 binfmt_elf.randomize_stack_top 中随机减去 [0, 0x7ff) 页
exec.setup_arg_pages 中以 随机减去 [0, 0x7ff) 页作为 stack_top, 然后 arch_align_stack 中减去随机页内偏移, 作为 stack_stop, 更新 bprm->p
更新 stack_base 为 vma->vma_start - 132kb
如果关闭了 ASLR, 这里的处理, bprm->p, stack_top 没有变化
binfmt_elf.create_elf_tables 中为调用 可执行文件的 entry 做准备
拷贝 platform 的字符串标记,
binfmt_elf.create_elf_tables 拷贝 十六字节 的随机字节序列
封装 elf 的信息, 以便于后面记录信息到 堆栈的内存中
binfmt_elf.create_elf_tables 计算 argc, argv, env 所需要的空间, 然后从 低地址开始依次填充指针数据
binfmt_elf.create_elf_tables 拷贝 elf_info 的相关数据
一个用户堆栈信息的实例分析
这个是 关闭 ANLR, 执行 Test01Sum 之后 在 main 中打了一个断点
真是的堆栈数据信息, 这里也添加了相关的备注
再结合 上面的 代码调试信息, 在理一下 ?
内容比较多, 需要足够的耐心, 但是 收货也会不小
140737488343040 - 140737488351232
140737488351224 为 vm_end 减去了 sizeof(void*) 之后的结果[bprm_mm_init]
140737488350704 为 复制 文件名, 环境变量列表, 参数列表 copy_strings 之后的偏移[do_execveat_common]
140737488350064 为 复制 kbase_platform, random_16bytes, argc, argv, env, elf_info 之后的偏移, 作为程序的起始 stack_top
#0 main (argc=1, argv=0x7fffffffe578) at Test01Sum.c:10
(gdb) x /200gx 0x7fffffffe470
0x7fffffffe470: 0x00007fffffffe578 0x0000000100400430 // main_locals | argv, argc, si, di,
0x7fffffffe480: 0x00000002ffffe570 0x0000000500000003 // main_locals | x, nop, z, y
0x7fffffffe490: 0x0000000000400570 0x00007ffff7a2d840 // main-bp | rbp, main'sReturnAddress
0x7fffffffe4a0: 0x0000000000000000 0x00007fffffffe578 // libc_start_main-sp | libc_start_main_locals
0x7fffffffe4b0: 0x0000000100000000 0x0000000000400526 // libc_start_main_locals
0x7fffffffe4c0: 0x0000000000000000 0x3f5247d05df02bae // libc_start_main_locals
0x7fffffffe4d0: 0x0000000000400430 0x00007fffffffe570 // libc_start_main_locals
0x7fffffffe4e0: 0x0000000000000000 0x0000000000000000 // libc_start_main_locals
0x7fffffffe4f0: 0xc0adb8af9e502bae 0xc0ada815f8e02bae // libc_start_main_locals
0x7fffffffe500: 0x0000000000000000 0x0000000000000000 // libc_start_main_locals
0x7fffffffe510: 0x0000000000000000 0x0000000000000000 // libc_start_main_locals
0x7fffffffe520: 0x0000000000000000 0x0000000000000000 // libc_start_main_locals
0x7fffffffe530: 0x0000000000000000 0x0000000000000000 // rbx, rbp
0x7fffffffe540: 0x0000000000400430 0x00007fffffffe570 // r12, r13
0x7fffffffe550: 0x0000000000000000 0x0000000000400459 // r14, libc_start_main_locals'sReturnAddress
0x7fffffffe560: 0x00007fffffffe568 0x000000000000001c // _start | rsp, rax
0x7fffffffe570: 0x0000000000000001 0x00007fffffffe7a7 // argc, argv[0]
0x7fffffffe580: 0x0000000000000000 0x00007fffffffe7d6 // padding0, env[0]
0x7fffffffe590: 0x00007fffffffe7e8 0x00007fffffffe7f8
0x7fffffffe5a0: 0x00007fffffffe803 0x00007fffffffe825
0x7fffffffe5b0: 0x00007fffffffe838 0x00007fffffffe842
0x7fffffffe5c0: 0x00007fffffffedca 0x00007fffffffedd6
0x7fffffffe5d0: 0x00007fffffffee52 0x00007fffffffee66
0x7fffffffe5e0: 0x00007fffffffee89 0x00007fffffffeeb2
0x7fffffffe5f0: 0x00007fffffffeed4 0x00007fffffffeee5
0x7fffffffe600: 0x00007fffffffeeee 0x00007fffffffeef9
0x7fffffffe610: 0x00007fffffffef01 0x00007fffffffef11
0x7fffffffe620: 0x00007fffffffef1e 0x00007fffffffef54
0x7fffffffe630: 0x00007fffffffef74 0x00007fffffffef8b
0x7fffffffe640: 0x00007fffffffefa7 0x0000000000000000 // env[n], padding0
0x7fffffffe650: 0x0000000000000021 0x00007ffff7ffa000 // padding for
0x7fffffffe660: 0x0000000000000010 0x000000000f8bfbff // elf_info[0]
0x7fffffffe670: 0x0000000000000006 0x0000000000001000
0x7fffffffe680: 0x0000000000000011 0x0000000000000064
0x7fffffffe690: 0x0000000000000003 0x0000000000400040
0x7fffffffe6a0: 0x0000000000000004 0x0000000000000038
0x7fffffffe6b0: 0x0000000000000005 0x0000000000000009
0x7fffffffe6c0: 0x0000000000000007 0x00007ffff7dd7000
0x7fffffffe6d0: 0x0000000000000008 0x0000000000000000
0x7fffffffe6e0: 0x0000000000000009 0x0000000000400430
0x7fffffffe6f0: 0x000000000000000b 0x0000000000000000
0x7fffffffe700: 0x000000000000000c 0x0000000000000000
0x7fffffffe710: 0x000000000000000d 0x0000000000000000
0x7fffffffe720: 0x000000000000000e 0x0000000000000000
0x7fffffffe730: 0x0000000000000017 0x0000000000000000
0x7fffffffe740: 0x0000000000000019 0x00007fffffffe789
0x7fffffffe750: 0x000000000000001f 0x00007fffffffefc9
0x7fffffffe760: 0x000000000000000f 0x00007fffffffe799
0x7fffffffe770: 0x0000000000000000 0x0000000000000000
0x7fffffffe780: 0x0000000000000000 0xdce629015e086600 // random_8bytes
0x7fffffffe790: 0xd71fa923a82b88cd 0x0034365f36387815 // random_8bytes, x86_64
0x7fffffffe7a0: 0x2f00000000000000 0x6e696c2f746f6f72 // argvValues
0x7fffffffe7b0: 0x78756e696c2f7875 0x34312e30312e342d
0x7fffffffe7c0: 0x2f736567616d692f 0x747365542f6b6162
0x7fffffffe7d0: 0x4458006d75533130 0x4f49535345535f47 // envValues
0x7fffffffe7e0: 0x0033373d44495f4e 0x622f3d4c4c454853
0x7fffffffe7f0: 0x00687361622f6e69 0x6574783d4d524554
0x7fffffffe800: 0x435f485353006d72 0x39313d544e45494c
0x7fffffffe810: 0x32322e3836312e32 0x3637373520312e30
0x7fffffffe820: 0x4853530032322030 0x65642f3d5954545f
0x7fffffffe830: 0x00332f7374702f76 0x6f6f723d52455355
0x7fffffffe840: 0x4c4f435f534c0074 0x303d73723d53524f
0x7fffffffe850: 0x333b31303d69643a 0x3b31303d6e6c3a34
0x7fffffffe860: 0x30303d686d3a3633 0x333b30343d69703a
0x7fffffffe870: 0x3b31303d6f733a33 0x31303d6f643a3533
0x7fffffffe880: 0x343d64623a35333b 0x3a31303b33333b30
0x7fffffffe890: 0x33333b30343d6463 0x343d726f3a31303b
0x7fffffffe8a0: 0x3a31303b31333b30 0x75733a30303d696d
0x7fffffffe8b0: 0x733a31343b37333d 0x3a33343b30333d67
0x7fffffffe8c0: 0x31343b30333d6163 0x343b30333d77743a
0x7fffffffe8d0: 0x3b34333d776f3a32 0x37333d74733a3234
0x7fffffffe8e0: 0x303d78653a34343b 0x742e2a3a32333b31
0x7fffffffe8f0: 0x31333b31303d7261 0x303d7a67742e2a3a
0x7fffffffe900: 0x612e2a3a31333b31 0x31333b31303d6372
0x7fffffffe910: 0x303d6a72612e2a3a 0x742e2a3a31333b31
0x7fffffffe920: 0x31333b31303d7a61 0x303d61686c2e2a3a
0x7fffffffe930: 0x6c2e2a3a31333b31 0x31333b31303d347a
0x7fffffffe940: 0x303d687a6c2e2a3a 0x6c2e2a3a31333b31
0x7fffffffe950: 0x333b31303d616d7a 0x3d7a6c742e2a3a31
0x7fffffffe960: 0x2e2a3a31333b3130 0x333b31303d7a7874
0x7fffffffe970: 0x3d6f7a742e2a3a31 0x2e2a3a31333b3130
0x7fffffffe980: 0x333b31303d7a3774 0x3d70697a2e2a3a31
0x7fffffffe990: 0x2e2a3a31333b3130 0x3a31333b31303d7a
0x7fffffffe9a0: 0x333b31303d5a2e2a 0x303d7a642e2a3a31
0x7fffffffe9b0: 0x672e2a3a31333b31 0x3a31333b31303d7a
0x7fffffffe9c0: 0x31303d7a726c2e2a 0x7a6c2e2a3a31333b
0x7fffffffe9d0: 0x2a3a31333b31303d 0x3b31303d6f7a6c2e
0x7fffffffe9e0: 0x3d7a782e2a3a3133 0x2e2a3a31333b3130
0x7fffffffe9f0: 0x333b31303d327a62 0x303d7a622e2a3a31
0x7fffffffea00: 0x742e2a3a31333b31 0x31333b31303d7a62
0x7fffffffea10: 0x3d327a62742e2a3a 0x2e2a3a31333b3130
0x7fffffffea20: 0x31333b31303d7a74 0x303d6265642e2a3a
0x7fffffffea30: 0x722e2a3a31333b31 0x31333b31303d6d70
0x7fffffffea40: 0x303d72616a2e2a3a 0x772e2a3a31333b31
0x7fffffffea50: 0x31333b31303d7261 0x303d7261652e2a3a
0x7fffffffea60: 0x732e2a3a31333b31 0x31333b31303d7261
0x7fffffffea70: 0x303d7261722e2a3a 0x612e2a3a31333b31
0x7fffffffea80: 0x31333b31303d7a6c 0x303d6563612e2a3a
0x7fffffffea90: 0x7a2e2a3a31333b31 0x31333b31303d6f6f
0x7fffffffeaa0: 0x3d6f6970632e2a3a 0x2e2a3a31333b3130
0x7fffffffeab0: 0x31333b31303d7a37 0x31303d7a722e2a3a
0x7fffffffeac0: 0x61632e2a3a31333b 0x3a31333b31303d62
0x7fffffffead0: 0x31303d67706a2e2a 0x706a2e2a3a35333b
0x7fffffffeae0: 0x35333b31303d6765 0x303d6669672e2a3a
0x7fffffffeaf0: 0x622e2a3a35333b31 0x35333b31303d706d
0x7fffffffeb00: 0x303d6d62702e2a3a 0x702e2a3a35333b31
0x7fffffffeb10: 0x35333b31303d6d67 0x303d6d70702e2a3a
0x7fffffffeb20: 0x742e2a3a35333b31 0x35333b31303d6167
0x7fffffffeb30: 0x303d6d62782e2a3a 0x782e2a3a35333b31
0x7fffffffeb40: 0x35333b31303d6d70 0x303d6669742e2a3a
0x7fffffffeb50: 0x742e2a3a35333b31 0x333b31303d666669
0x7fffffffeb60: 0x3d676e702e2a3a35 0x2e2a3a35333b3130
0x7fffffffeb70: 0x333b31303d677673 0x7a6776732e2a3a35
0x7fffffffeb80: 0x2a3a35333b31303d 0x3b31303d676e6d2e
0x7fffffffeb90: 0x7863702e2a3a3533 0x2a3a35333b31303d
0x7fffffffeba0: 0x3b31303d766f6d2e 0x67706d2e2a3a3533
0x7fffffffebb0: 0x2a3a35333b31303d 0x31303d6765706d2e
0x7fffffffebc0: 0x326d2e2a3a35333b 0x3a35333b31303d76
0x7fffffffebd0: 0x31303d766b6d2e2a 0x65772e2a3a35333b
0x7fffffffebe0: 0x35333b31303d6d62 0x303d6d676f2e2a3a
0x7fffffffebf0: 0x6d2e2a3a35333b31 0x35333b31303d3470
0x7fffffffec00: 0x303d76346d2e2a3a 0x6d2e2a3a35333b31
0x7fffffffec10: 0x333b31303d763470 0x3d626f762e2a3a35
0x7fffffffec20: 0x2e2a3a35333b3130 0x35333b31303d7471
0x7fffffffec30: 0x303d76756e2e2a3a 0x772e2a3a35333b31
0x7fffffffec40: 0x35333b31303d766d 0x303d6673612e2a3a
0x7fffffffec50: 0x722e2a3a35333b31 0x3a35333b31303d6d
0x7fffffffec60: 0x303d62766d722e2a 0x662e2a3a35333b31
0x7fffffffec70: 0x35333b31303d636c 0x303d6976612e2a3a
0x7fffffffec80: 0x662e2a3a35333b31 0x35333b31303d696c
0x7fffffffec90: 0x303d766c662e2a3a 0x672e2a3a35333b31
0x7fffffffeca0: 0x3a35333b31303d6c 0x3b31303d6c642e2a
0x7fffffffecb0: 0x6663782e2a3a3533 0x2a3a35333b31303d
0x7fffffffecc0: 0x3b31303d6477782e 0x7675792e2a3a3533
0x7fffffffecd0: 0x2a3a35333b31303d 0x3b31303d6d67632e
0x7fffffffece0: 0x666d652e2a3a3533 0x2a3a35333b31303d
0x7fffffffecf0: 0x3b31303d76676f2e 0x78676f2e2a3a3533
0x7fffffffed00: 0x2a3a35333b31303d 0x3b30303d6361612e
0x7fffffffed10: 0x3d75612e2a3a3633 0x2e2a3a36333b3030
0x7fffffffed20: 0x3b30303d63616c66 0x61346d2e2a3a3633
0x7fffffffed30: 0x2a3a36333b30303d 0x3b30303d64696d2e
0x7fffffffed40: 0x64696d2e2a3a3633 0x3a36333b30303d69
0x7fffffffed50: 0x30303d616b6d2e2a 0x706d2e2a3a36333b
0x7fffffffed60: 0x3a36333b30303d33 0x30303d63706d2e2a
0x7fffffffed70: 0x676f2e2a3a36333b 0x3a36333b30303d67
0x7fffffffed80: 0x3b30303d61722e2a 0x7661772e2a3a3633
0x7fffffffed90: 0x2a3a36333b30303d 0x3b30303d61676f2e
0x7fffffffeda0: 0x75706f2e2a3a3633 0x3a36333b30303d73
0x7fffffffedb0: 0x30303d7870732e2a 0x73782e2a3a36333b
0x7fffffffedc0: 0x36333b30303d6670 0x4e4d554c4f43003a
0x7fffffffedd0: 0x4150003037323d53 0x2f7273752f3d4854
0x7fffffffede0: 0x62732f6c61636f6c 0x2f7273752f3a6e69
0x7fffffffedf0: 0x69622f6c61636f6c 0x732f7273752f3a6e
0x7fffffffee00: 0x7273752f3a6e6962 0x62732f3a6e69622f
0x7fffffffee10: 0x3a6e69622f3a6e69 0x6d61672f7273752f
0x7fffffffee20: 0x2f7273752f3a7365 0x61672f6c61636f6c
0x7fffffffee30: 0x6f6f722f3a73656d 0x2f78756e696c2f74
0x7fffffffee40: 0x322e30312d626467 0x6e69622f6e69622f
0x7fffffffee50: 0x2f3d4c49414d003a 0x6c69616d2f726176
0x7fffffffee60: 0x3d5f00746f6f722f 0x696c2f746f6f722f
0x7fffffffee70: 0x2d6264672f78756e 0x6e69622f322e3031
0x7fffffffee80: 0x6264672f6e69622f 0x6f722f3d44575000
0x7fffffffee90: 0x78756e696c2f746f 0x342d78756e696c2f
0x7fffffffeea0: 0x692f34312e30312e 0x61622f736567616d
0x7fffffffeeb0: 0x4f485f424447006b 0x746f6f722f3d454d
0x7fffffffeec0: 0x672f78756e696c2f 0x2f322e30312d6264
0x7fffffffeed0: 0x474e414c006e6962 0x552e53555f6e653d
0x7fffffffeee0: 0x4e494c00382d4654 0x4f480039353d5345
0x7fffffffeef0: 0x746f6f722f3d454d 0x313d4c564c485300
0x7fffffffef00: 0x474155474e414c00 0x3a53555f6e653d45
0x7fffffffef10: 0x454d414e474f4c00 0x535300746f6f723d
0x7fffffffef20: 0x43454e4e4f435f48 0x3239313d4e4f4954
0x7fffffffef30: 0x3032322e3836312e 0x303637373520312e
0x7fffffffef40: 0x3836312e32393120 0x3033312e3032322e
0x7fffffffef50: 0x5353454c00323220 0x2f207c3d4e45504f
0x7fffffffef60: 0x2f6e69622f727375 0x657069707373656c
0x7fffffffef70: 0x5053494400732520 0x61636f6c3d59414c
0x7fffffffef80: 0x33313a74736f686c 0x525f47445800302e
0x7fffffffef90: 0x445f454d49544e55 0x2f6e75722f3d5249
0x7fffffffefa0: 0x4c00302f72657375 0x45534f4c43535345
0x7fffffffefb0: 0x69622f7273752f3d 0x69707373656c2f6e
0x7fffffffefc0: 0x7325207325206570 0x6c2f746f6f722f00
0x7fffffffefd0: 0x6e696c2f78756e69 0x2e30312e342d7875
0x7fffffffefe0: 0x6567616d692f3431 0x65542f6b61622f73 // fileName
0x7fffffffeff0: 0x006d755331307473 0x0000000000000000
0x7ffffffff000: Cannot access memory at address 0x7ffffffff000
# 环境变量列表
// argv list
7fffffffe7a7 -> /root/linux/linux-4.10.14/images/bak/Test01Sum
// env list
7fffffffe7d6 -> XDG_SESSION_ID=73
7fffffffe7e8 -> SHELL=/bin/bash
7fffffffe7f8 -> TERM=xterm
7fffffffe803 -> SSH_CLIENT=192.168.220.1 57760 22
7fffffffe825 -> SSH_TTY=/dev/pts/3
7fffffffe838 -> USER=root
7fffffffe842 -> LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=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:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt
7fffffffedca -> COLUMNS=270
7fffffffedd6 -> PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/root/linux/gdb-10.2/bin/bin:
7fffffffee52 -> MAIL=/var/mail/root
7fffffffee66 -> _=/root/linux/gdb-10.2/bin/bin/gdb
7fffffffee89 -> PWD=/root/linux/linux-4.10.14/images/bak
7fffffffeeb2 -> GDB_HOME=/root/linux/gdb-10.2/bin
7fffffffeed4 -> LANG=en_US.UTF-8
7fffffffeee5 -> LINES=59
7fffffffeeee -> HOME=/root
7fffffffeef9 -> SHLVL=1
7fffffffef01 -> LANGUAGE=en_US:
7fffffffef11 -> LOGNAME=root
7fffffffef1e -> SSH_CONNECTION=192.168.220.1 57760 192.168.220.130 22
7fffffffef54 -> LESSOPEN=| /usr/bin/lesspipe %s
7fffffffef74 -> DISPLAY=localhost:13.0
7fffffffef8b -> XDG_RUNTIME_DIR=/run/user/0
7fffffffefa7 -> LESSCLOSE=/usr/bin/lesspipe %s %s
// fileName
7fffffffefc9 -> /root/linux/linux-4.10.14/images/bak/Test01Sum
完