2018 10 18 pwn的学习0x7 保护和堆

什么是relro保护?
relro 是一种用于加强对 binary 数据段的保护的技术。relro 分为 partial relro 和 full relro
设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。
    Partial RELRO
        现在gcc 默认编译就是 partial relro(很久以前可能需要加上选项 gcc -Wl,-z,relro)
        some sections(.init_array .fini_array .jcr .dynamic .got) are marked as read-only after they have been initialized by the dynamic loader
        一些节区(.init_array .fini_array .jcr .dynamic .got)在被动态加载程序初始化后被标记为只读
        non-PLT GOT is read-only (.got)
        GOT is still writeable (.got.plt)

    Full RELRO
        拥有 Partial RELRO 的所有特性
        lazy resolution 是被禁止的,所有导入的符号都在 startup time 被解析
        bonus: the entire GOT is also (re)mapped as read-only or the .got.plt section is completely initialized with the final addresses of the target functions (Merge .got and .got.plt to one section .got). Moreover,since lazy resolution is not enabled, the GOT[1] and GOT[2] entries are not initialized.
        GOT[0] is a the address of the module’s DYNAMIC section. GOT[1] is the virtual load address of the link_map, GOT[2] is the address for the runtime resolver function
        编译时需要加上选项 gcc -Wl,-z,relro,-z,now

        
FOrity    
    fortify 技术是 gcc 在编译源码的时候会判断程序哪些buffer会存在 可能的溢出,在 buffer 大小已知的情况下,GCC 会把 strcpy,memcpy 这类函数自动替换成相应的 __strcpy_chk(dst, src, dstlen)等函数。GCC 在碰到以下四种情况的时候会采取不同的行为

堆的学习
1,堆:提供动态分配的内存,允许程序申请大小未知的内存,一样的是低地址向高地址方向进行增长
2,堆管理器:管理堆的程序
    堆管理器的位置:位于用户程序和内核中间
    管理器做些什么?
    1响内核一般都会预先分配很大的一块连续的内存,然后让堆管理器通过某种算法管理这块内存。
    只有当出现了堆空间不足的情况,堆管理器才会再次与操作系统进行交互应用户的申请内存的请求,向操作系统申请内存,返回给用户程序
    
    2管理用户所释放的内存。一般来说,用户释放的内存并不是直接返还给操作系统的,而是由堆管理器进行管理。
    这些释放的内存可以来响应用户新申请的内存的请求
3,现在的堆分配和回收是什么软件进行的呢?
    目前 Linux 标准发行版中使用的堆分配器是 glibc 中的堆分配器:ptmalloc2。
    ptmalloc2 主要是通过 malloc/free 函数来分配和释放内存块。

Linux分配内存的核心思想:
    只有当真正访问一个地址的时候,系统才会建立虚拟页面与物理页面的映射关系。
    所以虽然操作系统已经给程序分配了很大的一块内存,但是这块内存其实只是虚拟内存。
    只有当用户使用到相应的内存时,系统才会真正分配物理页面给用户使用。
什么是ptmalloc
    GNU C库(glibc)的malloc库包含一些管理应用程序地址空间中已分配内存的函数。 glibc malloc派生自ptmalloc(pthreads malloc),源自dlmalloc
什么是无符号数:
    无符号数是针对二进制来讲的,无符号数的表数范围是非负数。unsigned修饰
    https://blog.csdn.net/u010765526/article/details/73613815
什么是realloc函数:
    realloc函数用于修改一个原先已经分配的内存块的大小,动态内存调整
    https://www.cnblogs.com/tangshiguang/p/6735402.html
    
内存分配背后的系统调用 
    在前面提到的函数中,无论是 malloc 函数还是 free 函数,我们动态申请和释放内存时,都经常会使用,但是它们并不是真正与系统交互的函数。
    这些函数背后的系统调用主要是 (s)brk 函数以及 mmap, munmap 函数
    brk函数分配内存空间大小的时候受到aslr的影响
        不开启 ASLR 保护时,start_brk 以及 brk 会指向 data/bss 段的结尾。
        开启 ASLR 保护时,start_brk 以及 brk 也会指向同一位置,只是这个位置是在 data/bss 段结尾后的随机偏移处。
    malloc 会使用 mmap 来创建独立的匿名映射段。匿名映射的目的主要是可以申请以 0 填充的内存,并且这块内存仅被调用进程所使用。
多线程支持
    在 glibc 的 ptmalloc 实现中,比较好的一点就是支持了多线程的快速访问。在新的实现中,所有的线程共享多个堆。

什么是VDSO?
    vsyscall和vDSO是用于加速某些系统调用的两种机制。
   【vsyscall的局限】分配的内存较小;只允许4个系统调用;Vsyscall页面在每个进程中是静态分配了相同的地址;
   【vDSO】提供和vsyscall相同的功能,同时解决了其局限。vDSO是动态分配的,地址是随机的;可以提供超过4个系统调用;vDSO是glibc库提供的功能

什么是munmp
   函数说明 munmap()用来取消参数start所指的映射内存起始地址,参数length则是欲取消的内存大小。
   当进程结束或利用exec相关函数来执行其他程序时,映射内存会自动解除,但关闭对应的文件描述符时不会解除映射。
什么是glibc
    glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。
    glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。

malloc_chunk
    chunk的定义是malloc申请的内存,在ptmalloc内部当中用malloc_chunk结构体进行表示,chunk free之后会被加入到相应的空闲管理列表中
    chunk的数据结构:
        struct malloc_chunk {

  INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  这里的前一 chunk 指的是较低地址的 chunk 。*/
  INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */

  struct malloc_chunk* fd;         /* double links -- used only if free. */
  struct malloc_chunk* bk;             chunk 处于分配状态时,从 fd 字段开始是用户的数据。chunk 空闲时,会被添加到对应的空闲管理链表中,其字段的含义如下
                                     fd 指向下一个(非物理相邻)空闲的 chunk
                                     bk 指向上一个(非物理相邻)空闲的 chunk

  /* Only used for large blocks: pointer to next larger size.  */
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
};

你可能感兴趣的:(pwn)