这块内存已被释放
通过调用CSpanElement::CreateElement函数创建span元素
函数内部通过HeapAlloc申请长度为0x28大小内存空间
查找插入位置,这里查找到了body元素
CTreeNode元素
下面开始分析CElement,CTreeNode的释放情况.
当去掉f0.offsetParent=null,两者都会被释放.
当加上f0.offsetParent=null,CTreeNode不会被释放,CElement会被释放,同时CTreeNode对象依然保存着CElement对象的地址,导致后面CollectGarbage调用时引用到了这个地址的函数,造成了漏洞的发生.所以问题的关键就在于为什么CTreeNode元素没有被释放.
TreeNode
CElement
对比一下f0.offsetParent=null去除与未去除状态下的堆栈情况
为了明白CTreeNode没有被释放的原因,要弄清楚f0.offsetParent=null在内存中做了什么,通过搜索offsetParent,可以找到对应函数CElement::GetOffsetParentHelper,对GetOffsetParentHelper执行前后的CTreeNode进行一个对比,看看修改了哪些值.
+8,+C位置发送了变化.
对比着IE5的源码看一下这两个值.
+4+8位置是CElement对象地址和父节点CTreeNode对象地址,后面4个字节是一些标志位,+C位置是定义CharFormat的值,这个值的作用暂时不知道,对这个值下读断点调一下.
1 | // Class Data |
sxe ld:mshtml
bp mshtml+17d715 “ln eax;g”
bp mshtml!CElement::CElement+0x1e “.echo ‘===CElement===’;dd esi l(28/4);g “
bp mshtml+fb0af “.echo ‘===CTreeNode===’;dd eax l13;g”
bp mshtml!CElement::GetOffsetParentHelper
bu jscript!JsAtan2 “.printf "%mu",poi(poi(poi(esp+14)+8)+8);.echo;”
bp mshtml!+92ab8
bp mshtml+8bed9 “.echo ‘===eax+4===’;dd eax+4;g”
ba w4