ღ Miranda

IE10对象的内存布局及创建

前言

在利用uaf漏洞时,为了达到任意内存读写,需要在内存中喷射布局js的对象,这里我研究几个主要的对象在内存中的布局以及创建过程。

环境

系统: win7 32bit SP1
浏览器: IE10

Array

下面的脚本喷射了很多的array对象,附加后运行:

喷射完后可以使用vmmap查看内存状态,可以看到喷射的大块的内存,随意选择一个地址,查看地址内容:

0x21c600040x1010是数组长度0x1000加上数组头长度0x1021c60014处的两个0x400可能就是数组长度0x1000/4,但我们设置的0x111却变成了0x223,这次我们改变脚本中的一些参数再次调试:

这次得到的结果:

这次的结果证实了判断,而且数字存储的方式是原数*2+1,那如果数字溢出的话会怎么样呢,再次修改脚本:

得到结果如下:

可以看到,对于溢出的数,Array采用JavascriptNumber对象的方式存储,而-2则直接存储。Array这样存储的主要目的就是为了区分地址和数据。

21c6000421c60014两处地址下写入断点,看看数组是如何被创建的:

先断在了中,这时21c60004已经被写入了数组的长度0x1250,跳出这个函数:

再跳出一次:

继续单步可以看到设置21c60014的过程,最后一句把我们创建的数组的地址放到了[esi+14h],这里是一个对象:

在全部喷射完后再次查看这里的地址,

这里可以明显的看到一个对象的大小是0x20,存储了数组的大小和地址等信息。

LargeHeapBlock

测试脚本:

windbg中搜索与largeheapblock有关的函数可以搜索到很多,这里选择两个看上去和内存分配有关的下断点:

这里开启堆页调试,在AddLargeHeapBlock断下后到函数返回后:

可以看到AddLargeHeapBlock分配了0x54大小的空间,是一个LargeHeapBlock对象。然后我们关闭堆页,在返回后的地址下断点:

得到了一系列分配的地址,间隔为0x60就是对象大小加上头大小,这些内存如下:

每个对象偏移0x24处的地址指向前一个对象。

ArrayBuffer & Int32Array

ArrayBuffer表示数据的原始缓冲区,能够申请指定大小的内存,但无法直接读取或写入,需要将其传递到类型化数组创建数据化数组,Int32Array就是一种,比如:

我们来喷射一些Int32Array对象:

喷射完后,内存中的对象:

搜索大小为0x1000的堆,能够搜索到很多:

确实是我们喷射的数据,在堆的头信息处下写入断点,看看这个堆是怎么创建的:

通过栈回溯发现堆由malloc创建,上层是由jscript9!Js::JavascriptArrayBuffer::Create调用的,在上层由jscript9!Js::TypedArray<int>::NewInstance调用,那么在TypedArray<int>::NewInstance下断点就可以看Int32Array的创建过程。

这次只创建一个对象:

断下:

搜索和jscript9!Js::TypedArray<int>有关的函数可以找到一个jscript9!Js::TypedArray<int>::Creat,看起来是创建对象的函数,下断点:

单步可以跟到分配内存的地方:

TypedArray<int>对象大小为0x24,返回后的对象已经设置好了:

TypedArray<int>对象尾部的两个地址分别是存放Int32Array数据的缓冲区和ArrayBuffer对象:

缓冲区的堆头已经设置好了,继续运行后就填入了数据:

总结一下:

发表评论

电子邮件地址不会被公开。