zoukankan      html  css  js  c++  java
  • binary hacks读数笔记(堆、栈 VMA的分布)

    一、首先看一个简单的程序:

       #include<stdlib.h>
       
       int main()
       {
              while(1)
               {
                      sleep(1000);
              }
              return 0;
     }
    

    gcc -static SectionMapping.c -o SectionMapping.elf
    /usr/bin/ld: cannot find -lc

    yum install glibc-static 

    查看一下静态链接之后,SectionMapping.elf的段分布情况

    readelf -S SectionMapping.elf

    There are 34 section headers, starting at offset 0xd0aa0:
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .note.ABI-tag     NOTE             0000000000400190  00000190
           0000000000000020  0000000000000000   A       0     0     4
      [ 2] .note.gnu.build-i NOTE             00000000004001b0  000001b0
           0000000000000024  0000000000000000   A       0     0     4
      [ 3] .rela.plt         RELA             00000000004001d8  000001d8
           0000000000000108  0000000000000018  AI       0    25     8
      [ 4] .init             PROGBITS         00000000004002e0  000002e0
           000000000000001a  0000000000000000  AX       0     0     4
      [ 5] .plt              PROGBITS         0000000000400300  00000300
           00000000000000b0  0000000000000000  AX       0     0     16
      [ 6] .text             PROGBITS         00000000004003b0  000003b0
           0000000000091916  0000000000000000  AX       0     0     16
      [ 7] __libc_thread_fre PROGBITS         0000000000491cd0  00091cd0
           00000000000000b2  0000000000000000  AX       0     0     16
      [ 8] __libc_freeres_fn PROGBITS         0000000000491d90  00091d90
           0000000000001aef  0000000000000000  AX       0     0     16
      [ 9] .fini             PROGBITS         0000000000493880  00093880
           0000000000000009  0000000000000000  AX       0     0     4
      [10] .rodata           PROGBITS         00000000004938a0  000938a0
           00000000000196f8  0000000000000000   A       0     0     32
      [11] .stapsdt.base     PROGBITS         00000000004acf98  000acf98
           0000000000000001  0000000000000000   A       0     0     1
      [12] __libc_thread_sub PROGBITS         00000000004acfa0  000acfa0
           0000000000000008  0000000000000000   A       0     0     8
      [13] __libc_subfreeres PROGBITS         00000000004acfa8  000acfa8
           0000000000000050  0000000000000000   A       0     0     8
      [14] __libc_IO_vtables PROGBITS         00000000004ad000  000ad000
           00000000000006a8  0000000000000000   A       0     0     32
      [15] __libc_atexit     PROGBITS         00000000004ad6a8  000ad6a8
           0000000000000008  0000000000000000   A       0     0     8
      [16] .eh_frame         PROGBITS         00000000004ad6b0  000ad6b0
           000000000000e234  0000000000000000   A       0     0     8
      [17] .gcc_except_table PROGBITS         00000000004bb8e4  000bb8e4
           0000000000000105  0000000000000000   A       0     0     1
      [18] .tdata            PROGBITS         00000000006bbeb0  000bbeb0
           0000000000000020  0000000000000000 WAT       0     0     16
      [19] .tbss             NOBITS           00000000006bbed0  000bbed0
           0000000000000038  0000000000000000 WAT       0     0     16
      [20] .init_array       INIT_ARRAY       00000000006bbed0  000bbed0
           0000000000000010  0000000000000008  WA       0     0     8
      [21] .fini_array       FINI_ARRAY       00000000006bbee0  000bbee0
           0000000000000010  0000000000000008  WA       0     0     8
      [22] .jcr              PROGBITS         00000000006bbef0  000bbef0
           0000000000000008  0000000000000000  WA       0     0     8
      [23] .data.rel.ro      PROGBITS         00000000006bbf00  000bbf00
           00000000000000e4  0000000000000000  WA       0     0     32
      [24] .got              PROGBITS         00000000006bbfe8  000bbfe8
           0000000000000008  0000000000000008  WA       0     0     8
      [25] .got.plt          PROGBITS         00000000006bc000  000bc000
           0000000000000070  0000000000000008  WA       0     0     8
      [26] .data             PROGBITS         00000000006bc080  000bc080
           0000000000001690  0000000000000000  WA       0     0     32
      [27] .bss              NOBITS           00000000006bd720  000bd710
           0000000000002158  0000000000000000  WA       0     0     32
      [28] __libc_freeres_pt NOBITS           00000000006bf878  000bd710
           0000000000000030  0000000000000000  WA       0     0     8
      [29] .comment          PROGBITS         0000000000000000  000bd710
           000000000000002d  0000000000000001  MS       0     0     1
      [30] .note.stapsdt     NOTE             0000000000000000  000bd740
           0000000000000f88  0000000000000000           0     0     4
      [31] .symtab           SYMTAB           0000000000000000  000be6c8
           000000000000b9e8  0000000000000018          32   815     8
      [32] .strtab           STRTAB           0000000000000000  000ca0b0
           0000000000006870  0000000000000000           0     0     1
      [33] .shstrtab         STRTAB           0000000000000000  000d0920
           000000000000017b  0000000000000000           0     0     1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      l (large), p (processor specific)
    

     可执行文件中共有33个段。

    readelf -l SectionMapping.elf: 查看elf文件的Segment 即程序头。它描述ELF文件该如何被映射到进程的虚拟地址空间

    Elf file type is EXEC (Executable file)
    Entry point 0x400ecd
    There are 6 program headers, starting at offset 64
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                     0x00000000000bb9e9 0x00000000000bb9e9  R E    200000
      LOAD           0x00000000000bbeb0 0x00000000006bbeb0 0x00000000006bbeb0
                     0x0000000000001860 0x00000000000039f8  RW     200000
      NOTE           0x0000000000000190 0x0000000000400190 0x0000000000400190
                     0x0000000000000044 0x0000000000000044  R      4
      TLS            0x00000000000bbeb0 0x00000000006bbeb0 0x00000000006bbeb0
                     0x0000000000000020 0x0000000000000058  R      10
      GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x0000000000000000 0x0000000000000000  RW     10
      GNU_RELRO      0x00000000000bbeb0 0x00000000006bbeb0 0x00000000006bbeb0
                     0x0000000000000150 0x0000000000000150  R      1
    
     Section to Segment mapping:
      Segment Sections...
       00     .note.ABI-tag .note.gnu.build-id .rela.plt .init .plt .text __libc_thread_freeres_fn __libc_freeres_fn .fini .rodata .stapsdt.base __libc_thread_subfreeres __libc_subfreeres __libc_IO_vtables __libc_atexit .eh_frame .gcc_except_table 
       01     .tdata .init_array .fini_array .jcr .data.rel.ro .got .got.plt .data .bss __libc_freeres_ptrs 
       02     .note.ABI-tag .note.gnu.build-id 
       03     .tdata .tbss 
       04     
       05     .tdata .init_array .fini_array .jcr .data.rel.ro .got 
    

      

    二、堆和栈

    在操作系统中,VMA除了被用来映射可执行文件中的各个"segment"以外,他还可以有其他作用。操作系统通过使用VMA来管理进程的地址空间。程序执行时,要用到栈和堆,事实上,它们也是以VMA的形式存在。一般情况,一个进程中的栈和堆分别都有一个对应的VMA。在Linux中可以由/proc查看:

    ./SectionMapping.elf &
    [1] 59117
    [root@tlinux /]# cat /proc/59117/maps

    00400000-004bc000 r-xp 00000000 08:05 4456                               /SectionMapping.elf
    006bb000-006be000 rw-p 000bb000 08:05 4456                               /SectionMapping.elf
    006be000-006c0000 rw-p 00000000 00:00 0 
    017e1000-01804000 rw-p 00000000 00:00 0                                  [heap]
    7ffc12ce6000-7ffc12d07000 rw-p 00000000 00:00 0                          [stack]
    7ffc12db7000-7ffc12db9000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

    输出中:第一列是VMA地址范围,第二列是VMA权限,“p”表示私有,“s”表示共享。第三列是偏移。表示VMA对应的Segment在映像文件中的偏移。第四列是映像文件的主设备号与次设备号。第五列表示文件结点。

  • 相关阅读:
    vr这么火我来看看there.js
    简明现代魔法博客图书馆之php学习记录
    ecshop学习记录
    mysql学习笔记
    linux服务器自动备份mysql数据库
    thinkphp分页及分页样式
    php手册学习(2)
    非常不错的ajax原理总结
    最全的HTTP头部信息分析
    利用curl并发来提高页面访问速度
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/10740921.html
Copyright © 2011-2022 走看看