加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

Windows和Linux的内存结构区别

发布时间:2020-01-24 12:06:59 所属栏目:资源 来源:Asc0t6e's Blog
导读:windows 的内存结构分布 首先是内存结构分布图, windows 的内存默认是从 0x80000000 位置开始的 栈的增长方向是从高地址到低地址递增的,用下面一个例子来解释 例子一: esp 是栈指针 ,是 cpu 机制决定的, push 、 pop 指令会自动调整 esp 的值; ebp 只
  windows 的内存结构分布  首先是内存结构分布图, windows 的内存默认是从 0x80000000 位置开始的Windows和Linux的内存结构区别  栈的增长方向是从高地址到低地址递增的,用下面一个例子来解释  例子一:  esp 是栈指针 ,是 cpu 机制决定的, push 、 pop 指令会自动调整 esp 的值;  ebp 只是存取某时刻的 esp , 这个时刻就是进入一个函数内后, cpu 会将 esp 的值赋给 ebp ,此时就可以通过 ebp 对栈进行操作,比如获取函数参数,局部变量等,实际上使用 esp 也可以;  假设执行 print 函数之前 esp=Q  整个的流程图如下,要执行函数之前把 p2 和 p1 压入栈中,栈向低地址递增( Q-4h ),接着把函数地址放入栈中,然后把 ebp 的值放入栈中保存Windows和Linux的内存结构区别  例子二:  EBP 是当前函数的存取指针,即存储或者读取数时的指针基地址; ESP 就是当前函数的栈顶指针。每一次发生函数的调用(主函数调用子函数)时,在被调用函数初始时,都会把当前函数(主函数)的 EBP 压栈,以便从子函数返回到主函数时可以获取 EBP 。  下面是按调用约定 __stdcall 调用函数 test(int p1,int p2) 的汇编代码  原来 ESP 就是一直指向栈顶的指针,而 EBP 只是存取某时刻的栈顶指针,以方便对栈的操作,如获取函数参数、局部变量等。  堆分为堆块和堆表  (1)引用大佬的图Windows和Linux的内存结构区别  (2)堆表  为了合理地组织堆区中的空闲堆块,提出了堆表的概念。堆表的数据结构决定了整个堆区的组织方式,一般位于堆区的起始位置,用于索引堆区中空闲堆块的重要信息,包括堆块的位置、大小、状态(空闲或占用)。  (3)堆块  传统内存统计单位往往是以字节位标准,但处于性能的考虑,堆内存按照大小不同组成不同的块,以堆块为单位进行标识。一个堆块包括两个部分: header 部分和 data 部分。 header 是一个堆块头部的几个字节,用来标识这个堆块自身的信息。 data 是用来在最终分配给用户使用的数据区。  1)堆块分配  堆块的分配可以分为三类, Lookaside 分配、普通 Freelist 分配以及 0 号 Freelist(free[0]) 分配。  Lookaside 分配:寻找到大小匹配的空闲堆块 -> 修改状态为占用 -> 从堆表中解链 -> 给程序返回一个指向堆块的指针  普通 Freelist 分配:寻找最优的空闲堆块 -> 若失败,寻找次优空闲堆块分配  0 号 Freelist 分配:从 free[0] 反向寻找最后一个堆块(最大的堆块) -> 若满足要求,再正向搜索最小的满足要求的空闲堆块。  堆块分配中的“找零钱”现象:当在 Freelist 中无法找到刚好合适的堆块时,此时会分配一个稍微大一点的空闲堆块给程序使用,其过程是首先在这个大块中分配出大小刚好等于请求堆块大小的堆块给程序,然后剩下的部分修改堆块的 header 信息,重新链入到 Freelist 合适的位置。这种方法节约了内存的使用,不会造成大量的内存浪费。  由于 Lookaside 只有在精确匹配时才会分配,因此不存在“找零钱”现象。  2)堆块释放  堆块的释放主要是将堆块修改为空闲状态,然后将堆块链入相应的堆表。所有的释放块都链入堆表的末尾,分配的时候也会首先从堆表末尾分配。  3)堆块合并  为了减少内存中的内存碎片,合理有效地利用内存,堆管理系统还需要进行堆块合并操作。  当两个空闲堆块彼此相邻的时候就会进行堆块合并操作。其过程大致为:  将两个块从 Freelist 中解链 -> 合并堆块 -> 调整合并后堆块的 header 信息 -> 将合并后的堆块放入 Freelist 合适的位置  (4)堆上的漏洞  1)堆溢出漏洞  堆溢出与栈溢出在本质上是相通的,都是精心构造特制的数据去覆盖正常数据,覆盖到某个特定位置后跳转到自己的shellcode的地址去执行shellcode。  但从技术层面来讲,堆溢出比栈溢出难度更大。而且现在基本很少有软件存在典型的栈溢出漏洞,相反由于堆的复杂性,很多软件仍然存在诸多的堆溢出漏洞。  2)UAF 漏洞  Use After Free(UAF),释放后重引用漏洞, 一块内存已经被释放后,在程序中仍然存在对该块内存的引用,并且在一定情况下可能使用内存中的数据。  由于这块原本已经被释放不应该再使用的内存被程序中的其他地方进行了使用,因此该块内存中的数据是不可信的。这种方式甚至会造成内存崩溃或者任意代码执行。此类型的漏洞在浏览器中比较常见。  UAF漏洞比较有名的是CVE-2013-1347 Microsoft IE CGenericElementUAF漏洞,该漏洞被用在了当时著名的“水坑”事件中,影响巨大。  3)Double Free 漏洞  双重释放漏洞,主要是由于对同一块内存进行二次重复释放。在释放过程中,邻近的已释放的堆块存在合并动作,这会导致原有的堆header信息发生改变,同时前向指针和后向指针也会发生改变,随后再对其中的地址进行引用,就会导致访问异常,最终导致程序崩溃或者任意代码执行。  从另外一个角度来说,由于发生了对释放后的堆块内存的引用,因此Double Free漏洞也是UAF漏洞的一个子集。  双重释放漏洞比较经典的是CVE-2014-1767,该漏洞位于Windows AFD.sys文件中。  在2014年的Pwn2Own上,Siberas团队使用该漏洞进行内核提权,绕过了Windows 8.1平台上的IE11沙箱,并在随后获得了Pwnie Awards的“最佳提权漏洞奖”。该漏洞通杀Windows系统,影响较大。  linux 的内存结构分布  首先依旧是先放个内存结构图Windows和Linux的内存结构区别  栈地址也是依旧是高地址到低地址递增,但是栈的整体地址是可以向高地址增加的,不像 windows 一样 ebp 直接就在最高地址了  堆(待更新)

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读