Internet Explorer(三)[上]——VBScript Scripting Engine初探

简介: OS版本:Windows 7 Service Pack 1•Internet Explorer版本:8.0.7601.17514•vbscript.dll版本:5.8.7601.17514

近来分析Internet Explorer历史漏洞,遂对VBScript脚本解析引擎进行研究,具体环境如下:

OS版本:Windows 7 Service Pack 1Internet Explorer版本:8.0.7601.17514vbscript.dll版本:5.8.7601.17514

0x01 变量

VBScript中仅有一种数据类型——Variant。其结构定义如下:

typedef struct tagVARIANT {  union {    struct {      VARTYPE vt;      WORD    wReserved1;      WORD    wReserved2;      WORD    wReserved3;      union {        LONGLONG     llVal;        LONG         lVal;        BYTE         bVal;        SHORT        iVal;        FLOAT        fltVal;        DOUBLE       dblVal;        VARIANT_BOOL boolVal;        VARIANT_BOOL __OBSOLETE__VARIANT_BOOL;        SCODE        scode;        CY           cyVal;        DATE         date;        BSTR         bstrVal;        IUnknown     *punkVal;        IDispatch    *pdispVal;        SAFEARRAY    *parray;        BYTE         *pbVal;        SHORT        *piVal;        LONG         *plVal;        LONGLONG     *pllVal;        FLOAT        *pfltVal;        DOUBLE       *pdblVal;        VARIANT_BOOL *pboolVal;        VARIANT_BOOL *__OBSOLETE__VARIANT_PBOOL;        SCODE        *pscode;        CY           *pcyVal;        DATE         *pdate;        BSTR         *pbstrVal;        IUnknown     **ppunkVal;        IDispatch    **ppdispVal;        SAFEARRAY    **pparray;        VARIANT      *pvarVal;        PVOID        byref;        CHAR         cVal;        USHORT       uiVal;        ULONG        ulVal;        ULONGLONG    ullVal;        INT          intVal;        UINT         uintVal;        DECIMAL      *pdecVal;        CHAR         *pcVal;        USHORT       *puiVal;        ULONG        *pulVal;        ULONGLONG    *pullVal;        INT          *pintVal;        UINT         *puintVal;        struct {          PVOID       pvRecord;          IRecordInfo *pRecInfo;        } __VARIANT_NAME_4;      } __VARIANT_NAME_3;    } __VARIANT_NAME_2;    DECIMAL decVal;  } __VARIANT_NAME_1;} VARIANT;

其中VARTYPE可参阅[Microsoft Docs——VARIANT Type Constants]https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f。例:

'显式声明Dim Name,Age,Hex,PiName="Ethon"Age=27Hex=&h80000000Pi=3.1415926'隐式声明Hello="ABC123"

赋值对应函数为vbscript!AssignVar,于该函数处设断,查看其参数:

图1

0x400C表示VT_VARIANT

图2

判断pvargSrc—>vt值(具体数值可自行分析,不赘述),若均不满足,执行如下语句:

图3

简单来说,即VariantCopyInd(&pvarDest, pvargSrc)——>copy pvarDest to pvarg

图4

隐式声明变量其pvarg全为零:

图5

0x02 数组

数组存储结构由SAFEARRAY定义:

typedef struct tagSAFEARRAY {  USHORT         cDims;  USHORT         fFeatures;  ULONG          cbElements;  ULONG          cLocks;  PVOID          pvData;  SAFEARRAYBOUND rgsabound[1];} SAFEARRAY;

其中各字段含义可参阅[Microsoft Docs——SAFEARRAY]https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearray ,SAFEARRAYBOUND结构定义如下:

typedef struct tagSAFEARRAYBOUND {  ULONG cElements;  LONG  lLbound;} SAFEARRAYBOUND, *LPSAFEARRAYBOUND;

数组定义及赋值操作:

Dim stu_name(3)stu_name(0)="Alan"stu_name(1)="Susan"stu_name(2)="Lisa"stu_name(3)="Mary"

VBS中数组下标由0开始,数组元素个数为n+1(Dim array_name(n))。另一种定义数组方法:

Dim stu_namestu_name=Array("Alan","Susan","Lisa","Mary")

对应函数为vbscript!MakeArray

图6

传递给函数的参数有二——cDims对应维数,VAR对应n。cDims应介于1-64:

图7

先来看一维数组的创建:

图8

rgsabound结构各字段赋值:

图9

之后则直接调用SafeArrayCreate函数进行创建,各参数含义可参阅[Microsoft Docs——SafeArrayCreate]https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraycreate 。创建完成:

图10

为数组元素赋值则直接将该元素所在内存偏移传递给vbscript!AssignVar

图11


下面来看看二维数组(Dim stu_name(2,3))创建过程:

图12

可以看到数组各维大小于内存中并列存储,之后调用VAR::PvarGetTypeVal逐一读取为rgsaboundcElements字段赋值:

图13

各维大小于内存中由最高维——>最低维存储,故读取时首先计算出v3变量指向最低维大小所在内存偏移,之后递减。创建完成:

图14


Redim语句用于重新定义数组大小:

'定义一维动态数组Dim MyArray()'重新定义该数组大小ReDim MyArray(3) MyArray(0) = "A" MyArray(1) = "B"MyArray(2) = "C"MyArray(3) = "C"

再次调用vbscript!MakeArray过程如下:

图15

而在重新定义时加上Preserve关键字用于保留之前元素:

Dim MyArray()ReDim MyArray(3)MyArray(0) = "A"MyArray(1) = "B"MyArray(2) = "C"MyArray(3) = "D"ReDim Preserve MyArray(5)MyArray(4) = "E"MyArray(5) = "F"

其对应vbscript!RedimPreserveArray函数:

图16

psaboundNew各字段赋值完成后传递给SafeArrayRedim函数:

图17

0x03 可用于调试时函数

IsEmpty(var)对应vbscript!VbsIsEmpty,其第三个参数对应var。一例:

<!doctype html><html lang="en"><head></head><body><script LANGUAGE="VBScript">    dim a    a = &h1234    IsEmpty(a)</script></body></html>

图18

IsObject(var)对应vbscript!VbsIsObject,同样,其第三个参数对应var。一例:

<!doctype html><html lang="en"><head></head><body><script LANGUAGE="VBScript">    dim a    a = &h1234    IsObject(a)</script></body></html>

图19

在调试时可借助这两个函数以确定变量值或内存位置。

0x04 VarType函数

<!doctype html><html lang="en"><head></head> <body><script LANGUAGE="VBScript">    dim a    a = &h1234    VarType(a)</script></body></html>

VarType对应vbscript!VbsVarType,其调用GetVarType函数获取类型值并完成赋值操作:

图20

参数1用于存储类型值,参数2为VarType参数:

图21

GetVarType函数调用PvarGetVarVal——判断类型值是否为0x4A0x0C

图22

之后与0x09进行比较,若不是则直接返回对象进而获取vt值:

图22

VbsVarType函数完成最终赋值给参数1操作:

图23

0x05 LenB函数

<!doctype html><html lang="en"><head></head><body><script LANGUAGE="VBScript">On Error Resume NextDim length,aa=1.12345678901235length=LenB("Hello")length=LenB(a)</script></body></html>

该函数用于返回存储字符串字节大小,其对应vbscript!VbsLenB。参数为字符串时,该函数先是call VAR::BstrGetVal,返回pbstrVal

图24

之后call cbLengthBstr返回长度:

图25

参数为变量时, VAR::BstrGetVal函数调用VAR::PvarConvert,将其内容转换为字符串:

图26

之后再进行计算:

图27

cbLengthBstr函数功能仅是读取字符串存储位置之前4字节内容,该内容为字符串长度:

图28


相关文章
|
Web App开发 JavaScript 关系型数据库
|
4月前
|
人工智能 边缘计算 自然语言处理
|
6月前
|
人工智能 小程序 API
【一步步开发AI运动APP】九、自定义姿态动作识别检测——之关键点追踪
本文介绍了【一步步开发AI运动APP】系列中的关键点追踪技术。此前分享的系列博文助力开发者打造了多种AI健身场景的小程序,而新系列将聚焦性能更优的AI运动APP开发。文章重点讲解了“关键点位变化追踪”能力,适用于动态运动(如跳跃)分析,弥补了静态姿态检测的不足。通过`pose-calc`插件,开发者可设置关键点(如鼻子)、追踪方向(X或Y轴)及变化幅度。示例代码展示了如何在`uni-app`框架中使用`createPointTracker`实现关键点追踪,并结合人体识别结果完成动态分析。具体实现可参考文档与Demo示例。
|
8月前
|
人工智能 文字识别 自然语言处理
1.6K star!这个开源文本提取神器,5分钟搞定PDF/图片/Office文档!
Kreuzberg 是一个基于 Python 的文本提取库,支持从 PDF、图像、Office 文档等 20+ 格式中提取文本内容。采用 MIT 开源协议,具备本地处理、异步架构、智能 OCR 等特性,特别适合需要隐私保护的文档处理场景。
901 1
|
编解码 iOS开发 UED
响应式设计在 iPhone 开发适配中的具体应用
【10月更文挑战第23天】响应式设计在 iPhone 开发适配中扮演着至关重要的角色,它能够帮助我们打造出适应不同屏幕尺寸和用户需求的高质量应用。通过合理运用响应式设计的原则和方法,我们可以在提供良好用户体验的同时,提高开发效率和应用的可维护性。
|
关系型数据库 MySQL
深入理解SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE
深入理解SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE
780 0
|
人工智能 数据中心 云计算
AI网络新生态ALS发起成立,信通院、阿里云、AMD等携手制定互连新标准
9月3日,在2024 ODCC开放数据中心大会上,阿里云联合信通院、AMD等国内外十余家业界伙伴发起AI芯片互连开放生态ALS(ALink System)。
AI网络新生态ALS发起成立,信通院、阿里云、AMD等携手制定互连新标准
|
存储 前端开发 JavaScript
State 状态管理最佳实践
【10月更文挑战第1天】本文深入浅出地介绍了前端开发中的状态管理概念,强调其在构建复杂单页应用(SPA)中的重要性。文章详细阐述了状态管理的核心原则,如单一源真理、状态不可直接修改及状态变更透明,并对比分析了如Redux、Vuex和MobX等常用状态管理库。通过具体代码示例,指出了状态分散和非原子操作等常见问题及其解决方案,为开发者提供了实用指导。
526 2
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的校园失物招领网站的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的校园失物招领网站的详细设计和实现(源码+lw+部署文档+讲解等)
195 0
|
测试技术
如何用RIDE写自动化脚本
本文介绍如何用RIDE写自动化脚本。
343 0