


;-------------------------------------------------------------------------------
;    ______________   ______________    _________________
;   /\   __________\ /\   ________  \  /\   ____   ____  \
;   \ \  \_________/ \ \  \______/\  \ \ \  \__/\  \__/\  \
;    \ \  \           \ \  \     \ \  \ \ \  \ \ \  \ \ \  \
;     \ \  \__________ \ \  \_____\_\  \ \ \  \ \ \  \ \ \  \
;      \ \____________\ \ \_____________\ \ \__\ \ \__\ \ \__\
;       \/____________/  \/_____________/  \/__/  \/__/  \/__/
;
; component object model library for activex-vbscript calling from assembly
; flat assembler 1.6 syntax, x86-win32
;
; version 1b (tested on x86-win32 xp sp2)
;
; asmhack, copyright (c) 2008
; asmhack@live.com
;
; usage:
; just include this library in data-code section
; ...
; call @@StartScriptEngine
; vbscall 'code' (or stdcall @@RunScript,addressofcode)
; ...
; needed imports:
; kernel32.LocalAlloc.LocalFree.MultiByteToWideChar.WideCharToMultiByte
; ole32.CoInitialize.CoCreateInstance.IsEqualGUID
; user32.MessageBox (only if __ENABLE_PARSING_ERROR is enabled)
;-------------------------------------------------------------------------------



;----|Custom Declarations|------------------------------------------------------



__RETURN_VARIABLE_NAME		       equ 'v'
; use only one character, that is supported as a variable name in vbscript
; after the call, eax will have the address, pointer of the buffer, that holds
; RETURN_VARIABLE_NAME's STRING data:
; ...
; vbscall 'RETURN_VARIABLE_NAME = "abc"'
; ***
; vbsfree
; ...
; if RETURN_VARIABLE_NAME's data is not string, use cstr() vbscript function
; to convert the data:
; ...
; vbscall 'RETURN_VARIABLE_NAME = cstr(1+2*3)'
; ***
; vbsfree
; ...
; if you do not use RETURN_VARIABLE_NAME variable in the vbscript
; then you do not have to use vbsfree to free the buffer

__ENABLE_PARSING_ERROR		       equ 1
; display parsing error* messagebox when enabled
; *error in vbscript code



;----|Macros|-------------------------------------------------------------------



  macro vbscall  x
  {	 call	 @f
	 db	 x,$0
  @@:
	 call	 @@RunScript }



  macro stdcall  x,[y]
  {	 reverse
	 push	 y
	 common
	 call	 x }



  macro vbsfree
  {	 push	 [__answer]
	 call	 [LocalFree] }



;----|Declarations|-------------------------------------------------------------



QueryInterface			       equ $0
Addref				       equ $4
Release 			       equ $8
Close				       equ $1c
SetScriptSite			       equ $c
InitNew 			       equ $c
ParseScriptText 		       equ $14
SetScriptState			       equ $14
AddNamedItem			       equ $20
 
CLSCTX_INPROC_SERVER		       equ $1
CLSCTX_INPROC_HANDLER		       equ $2
CLSCTX_LOCAL_SERVER		       equ $4
CLSCTX_INPROC_SERVER16		       equ $8
CLSCTX_REMOTE_SERVER		       equ $10
CLSCTX_INPROC_HANDLER16 	       equ $20
CLSCTX_INPROC_SERVERX86 	       equ $40
CLSCTX_INPROC_HANDLERX86	       equ $80
CLSCTX_ESERVER_HANDLER		       equ $100

E_NOTIMPL			       equ $80004001
E_NOINTERFACE			       equ $80004002
E_INVALIDARG			       equ $80070057
E_OUTOFMEMORY			       equ $8007000E
TYPE_E_ELEMENTNOTFOUND		       equ $8002802B

SCRIPTSTATE_UNINITIALIZED	       equ $0
SCRIPTSTATE_STARTED		       equ $1
SCRIPTSTATE_CONNECTED		       equ $2
SCRIPTSTATE_DISCONNECTED	       equ $3
SCRIPTSTATE_CLOSED		       equ $4
SCRIPTSTATE_INITIALIZED 	       equ $5

SCRIPTITEM_ISVISIBLE		       equ $2
SCRIPTITEM_ISSOURCE		       equ $4
SCRIPTITEM_GLOBALMEMBERS	       equ $8
SCRIPTITEM_ISPERSISTENT 	       equ $40
SCRIPTITEM_CODEONLY		       equ $200
SCRIPTITEM_NOCODE		       equ $400
SCRIPTITEM_ALL_FLAGS		       equ $64e

SCRIPTINFO_IUNKNOWN		       equ $1
SCRIPTINFO_ITYPEINFO		       equ $2
SCRIPTINFO_ALL_FLAGS		       equ $3

DISPATCH_METHOD 		       equ $1
DISPATCH_PROPERTYGET		       equ $2
DISPATCH_PROPERTYPUT		       equ $4
DISPATCH_PROPERTYPUTREF 	       equ $8
DISP_E_BADINDEX 		       equ $8002000B
DISP_E_MEMBERNOTFOUND		       equ $80020003
DISP_E_UNKNOWNNAME		       equ $80020006



;----|data|---------------------------------------------------------------------



  if __ENABLE_PARSING_ERROR = 1
__serr				       db 'parsing error',$0
  end if

__ActiveScriptSiteObject	       dd $0
__hwnd				       dd $0
__answer			       dd $0
__qq				       dd $0
__gg				       dd $0
__ret_var_name			       dw __RETURN_VARIABLE_NAME,$0



;----|guid declarations|--------------------------------------------------------



  struc guid def
  {
   match d1-d2-d3-d4-d5, def
  \{
   .Data1 dd 0x\#d1
   .Data2 dw 0x\#d2
   .Data3 dw 0x\#d3
   .Data4 db 0x\#d4 shr 8,0x\#d4 and 0FFh
   .Data5 db 0x\#d5 shr 40,0x\#d5 shr 32 and 0FFh,0x\#d5 shr 24 and 0FFh,0x\#d5 shr 16 and 0FFh,0x\#d5 shr 8 and 0FFh,0x\#d5 and 0FFh
  \}
  }



;----|Class identifiers|--------------------------------------------------------



CLSID_VBScript			       guid b54f3741-5b07-11cf-a4b0-00aa004a55e8



;----|IActiveScript Interface identifiers|--------------------------------------



IID_IActiveScript		       guid bb1a2ae1-a4f9-11cf-8f20-00805f2cd064
IID_IActiveScriptParse		       guid bb1a2ae2-a4f9-11cf-8f20-00805f2cd064
IID_IActiveScriptSite		       guid d57d7817-e9b7-4a82-8574-01d0f93d6170
IID_IActiveScriptSiteWindow	       guid d10f6761-83e9-11cf-8f20-00805f2cd064
IID_IUnknown			       guid 00000000-0000-0000-0c00-000000000046
IID_IDispatch			       guid 00020400-0000-0000-c000-000000000046



;-------------------------------------------------------------------------------



pIActiveScript			       dd $0
pIActiveScriptParse		       dd $0
pIActiveScriptSite		       dd $0

IActiveScriptSite		       dd IActiveScriptSite_vtable
IActiveScriptSiteWindow 	       dd IActiveScriptSiteWindow_vtable
IDispatch			       dd IDispatch_vtable

IActiveScriptSite_vtable	       dd @@IActiveScriptSite_QueryInterface
				       dd @@IActiveScriptSite_AddRef
				       dd @@IActiveScriptSite_Release
				       dd @@IActiveScriptSite_GetLCID
				       dd @@IActiveScriptSite_GetItemInfo
				       dd @@IActiveScriptSite_GetDocVersionString
				       dd @@IActiveScriptSite_OnScriptTerminate
				       dd @@IActiveScriptSite_OnStateChange
				       dd @@IActiveScriptSite_OnScriptError
				       dd @@IActiveScriptSite_OnEnterScript
				       dd @@IActiveScriptSite_OnLeaveScript
			
IActiveScriptSiteWindow_vtable	       dd @@IActiveScriptSite_QueryInterface
				       dd @@IActiveScriptSite_AddRef
				       dd @@IActiveScriptSite_Release
				       dd @@IActiveScriptSiteWindow_GetWindow
				       dd @@IActiveScriptSiteWindow_EnableModeless

IDispatch_vtable		       dd @@IActiveScriptSite_QueryInterface
				       dd @@IActiveScriptSite_AddRef
				       dd @@IActiveScriptSite_Release
				       dd @@IDispatch_GetTypeInfoCount
				       dd @@IDispatch_GetTypeInfo
				       dd @@IDispatch_GetIDsOfNames
				       dd @@IDispatch_Invoke



;-------------------------------------------------------------------------------



  @@StartScriptEngine:

	 stdcall [CoInitialize],$0
	 stdcall [CoCreateInstance],CLSID_VBScript,$0,CLSCTX_INPROC_SERVER,IID_IActiveScript,pIActiveScript
	 stdcall [LocalAlloc],$0,16
	 mov	 [__ActiveScriptSiteObject],eax
	 mov	 dword[eax+$0],IActiveScriptSite
	 mov	 dword[eax+$4],IActiveScriptSiteWindow
	 mov	 dword[eax+$8],IDispatch
	 mov	 dword[eax+$C],$1
	 push	 pIActiveScriptParse
	 push	 IID_IActiveScriptParse
	 mov	 edx,[pIActiveScript]
	 push	 edx
	 mov	 edx,[edx]
	 call	 dword[edx+QueryInterface]
	 test	 eax,eax
	 js	 @f
	 mov	 edx,IActiveScriptSite
	 mov	 [pIActiveScriptSite],edx
  @@:
	 ret



;-------------------------------------------------------------------------------



  @@RunScript:

	 mov	 eax,[esp+$4]
	 mov	 ebx,eax

	 lea	 eax,[eax-$1]
  @@:
	 lea	 eax,[eax+$1]
	 cmp	 byte[eax],$0
	 jnz	 @b

	 sub	 eax,ebx

	 shl	 eax,$1
	 lea	 eax,[eax+$2]

	 push	 eax
	 stdcall [LocalAlloc],$0,eax
	 pop	 ecx

	 push	 eax
	 stdcall [MultiByteToWideChar],$0,$0,ebx,-$1,eax,ecx
	 pop	 ebx

	 mov	 edx,[pIActiveScriptSite]
	 mov	 edx,[edx]
	 push	 [pIActiveScriptSite]
	 call	 dword[edx+Addref]
		
	 mov	 edx,[pIActiveScript]
	 mov	 edx,[edx]
	 push	 [pIActiveScriptSite]
	 push	 [pIActiveScript]
	 call	 dword[edx+SetScriptSite]
		
	 mov	 edx,[pIActiveScriptParse]
	 mov	 edx,[edx]
	 push	 [pIActiveScriptParse]
	 call	 dword[edx+InitNew]
	    
	 mov	 edx,[pIActiveScript]
	 mov	 edx,[edx]
	 push	 SCRIPTITEM_ISVISIBLE
	 push	 __ret_var_name
	 push	 [pIActiveScript]
	 call	 dword[edx+AddNamedItem]

	 mov	 edx,[pIActiveScriptParse]
	 mov	 edx,[edx]
	 mov	 eax,ebx
	 xor	 ecx,ecx
	 push	 ecx
	 push	 ecx
	 push	 ecx
	 push	 ecx
	 push	 ecx
	 push	 ecx
	 push	 ecx
	 push	 ecx
	 push	 eax
	 push	 [pIActiveScriptParse]
	 call	 dword[edx+ParseScriptText]
				
	 mov	 edx,[pIActiveScript]
	 mov	 edx,[edx]
	 push	 SCRIPTSTATE_CONNECTED
	 push	 [pIActiveScript]
	 call	 dword[edx+SetScriptState]

	 stdcall [LocalFree],ebx
	 mov	 eax,[__answer]
	 ret



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_GetItemInfo:

	 mov	 eax,__ret_var_name
	 mov	 eax,[eax]
	 mov	 edx,[esp+$8]
	 mov	 edx,[edx]
	 cmp	 ax,dx
	 jz	 @f
	 mov	 eax,TYPE_E_ELEMENTNOTFOUND
	 ret	 4*4
  @@:
	 mov	 eax,[esp+$C]
	 cmp	 eax,SCRIPTINFO_IUNKNOWN
	 jz	 @@unk
	 cmp	 eax,SCRIPTINFO_ALL_FLAGS
	 jz	 @@unk
	 cmp	 eax,SCRIPTINFO_ITYPEINFO
	 jz	 @@tnfo
	 mov	 eax,E_INVALIDARG
	 ret	 4*4
  @@unk:
	 mov	 eax,[esp+$10]
	 mov	 edx,IDispatch
	 mov	 [eax],edx
	 mov	 edx,[edx]
	 push	 IDispatch
	 call	 dword[edx+Addref]
  @@tnfo:
	 mov	 eax,[esp+$14]
	 test	 eax,eax
	 jz	 @f
	 and	 dword[eax],$0
  @@:
	 xor	 eax,eax
	 ret	 4*4



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_GetLCID:
	 mov	 eax,E_NOTIMPL
	 ret	 4*2



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_GetDocVersionString:
	 mov	 eax,E_NOTIMPL
	 ret	 4*2



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_OnScriptTerminate:
	 xor	 eax,eax
	 ret	 4*3



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_OnStateChange:
	 xor	 eax,eax
	 ret	 4*2



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_OnScriptError:
  if __ENABLE_PARSING_ERROR = 1
	 stdcall [MessageBox],$0,__serr,$0,$10
  end if
	 xor	 eax,eax
	 ret	 4*2



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_OnEnterScript:
	 xor	 eax,eax
	 ret	 4*1



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_OnLeaveScript:
	 xor	 eax,eax
	 ret	 4*1



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_AddRef:
	 mov	 ecx,[__ActiveScriptSiteObject]
	 inc	 dword[ecx+$C]
	 mov	 eax,[ecx+$C]
	 ret	 4*1



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_Release:
	 mov	 ecx,[__ActiveScriptSiteObject]
	 dec	 dword[ecx+$C]
	 mov	 eax,[ecx+$C]
	 test	 eax,eax
	 jnz	 @f
	 stdcall [LocalFree],ecx
  @@:
	 ret	 4*1



;-------------------------------------------------------------------------------



  @@IActiveScriptSiteWindow_EnableModeless:
	 xor	 eax,eax
	 ret	 4*2



;------------------------------------------------------------------------------



  @@IActiveScriptSiteWindow_GetWindow:
	 mov	 ecx,[esp+$8]
	 mov	 eax,[__hwnd]
	 mov	 [ecx],eax
	 xor	 eax,eax
	 ret	 4*2



;-------------------------------------------------------------------------------



  @@IActiveScriptSite_QueryInterface:
	 mov	 eax,[esp+$8]
	 mov	 [__qq],eax
	 mov	 eax,[esp+$C]
	 mov	 [__gg],eax

	 stdcall [IsEqualGUID],[__qq],IID_IUnknown
	 test	 eax,eax
	 jnz	 @@s_ok_unk

	 stdcall [IsEqualGUID],[__qq],IID_IActiveScriptSite
	 test	 eax,eax
	 jnz	 @@s_ok_unk

	 stdcall [IsEqualGUID],[__qq],IID_IActiveScriptSiteWindow
	 test	 eax,eax
	 jnz	 @@s_ok_acw
		
	 stdcall [IsEqualGUID],[__qq],IID_IDispatch
	 test	 eax,eax
	 jnz	 @@s_ok_dsp
		
	 mov	 eax,E_NOINTERFACE
	 ret	 4*3
  @@s_ok:
	 mov	 edx,[pIActiveScriptSite]
	 mov	 edx,[edx]
	 push	 [pIActiveScriptSite]
	 call	 dword[edx+Addref]
		
	 xor	 eax,eax
	 ret	 4*3
  @@s_ok_unk:
	 mov	 eax,[__ActiveScriptSiteObject]
	 mov	 eax,[eax]
	 mov	 edx,[__gg]
	 mov	 [edx],eax
	 jmp	 @@s_ok
  @@s_ok_acw:
	 mov	 eax,[__ActiveScriptSiteObject]
	 mov	 eax,[eax+$4]
	 mov	 edx,[__gg]
	 mov	 [edx],eax
	 jmp	 @@s_ok
  @@s_ok_dsp:
	 mov	 eax,[__ActiveScriptSiteObject]
	 mov	 eax,[eax+$8]
	 mov	 edx,[__gg]
	 mov	 [edx],eax
	 jmp	 @@s_ok



;-------------------------------------------------------------------------------



  @@IDispatch_GetTypeInfoCount:
	 mov	 eax,[esp+$8]
	 mov	 dword[eax],$0
	 xor	 eax,eax
	 ret	 4*2



;-------------------------------------------------------------------------------



  @@IDispatch_GetTypeInfo:
	 mov	 eax,DISP_E_BADINDEX
	 ret	 4*4



;-------------------------------------------------------------------------------



 @@IDispatch_GetIDsOfNames:
	 xor	 eax,eax
	 ret	 4*6



;-------------------------------------------------------------------------------



  @@IDispatch_Invoke:
	 mov	 eax,[esp+$8]
	 lea	 eax,[eax-$1]
	 jnz	 @@not
		
	 mov	 edx,[esp+$18]
	 mov	 edx,[edx]
	 mov	 edx,[edx+$8]

	 xchg	 ebx,edx
	 stdcall [WideCharToMultiByte],$0,$0,ebx,-$1,$0,$0,$0,$0
	 lea	 eax,[eax+$2]

	 push	 eax
	 stdcall [LocalAlloc],$0,eax

	 mov	 [__answer],eax

	 pop	 ecx
	 stdcall [WideCharToMultiByte],$0,$0,ebx,-$1,eax,ecx,$0,$0

	 xor	 eax,eax
	 ret	 4*9
  @@not:
	 mov	 eax,DISP_E_MEMBERNOTFOUND
	 ret	 4*9



;-------------------------------------------------------------------------------