include word.inc
.data
_WordDocuments dd 0
_WordDocument dd 0
.code
ON_Application_Quit PROC __Inst_Obj:DWORD
invoke MessageBox,0, chr$("ON_Application_Quit"),0,0
RET
ON_Application_Quit ENDP
Start:
New_Word_Application _WordApplication
Word_Application_Visible_Set _WordApplication,TRUE
;Event : Quit
Word_Application_On_Quit _WordApplication,offset ON_Application_Quit
Word_Application_Documents_Get _WordApplication,addr _WordDocuments
Word_Documents_Open _WordDocuments,__String("d:\01.doc"),,,,,,,,,,,,,,,,addr _WordDocument
inkey
__Release _WordApplication
exit
end Start
include WbemScripting.INC
.data
_ISWbemServices dd 0
_SWbemObjectSet dd 0
_ISWbemObject dd 0
_ISWbemPropertySet dd 0
_ISWbemProperty dd 0
_varValue VARIANT <>
.code
Start:
New_WbemScripting_SWbemLocator _SWbemLocator
WbemScripting_SWbemLocator_ConnectServer _SWbemLocator,BSTR$("."),BSTR$("root\cimv2"),0,0,0,0,0,0,addr _ISWbemServices
WbemScripting_SWbemServices_ExecQuery _ISWbemServices,BSTR$("Select * From Win32_ComputerSystem"),BSTR$("WQL"),0,0, addr _SWbemObjectSet
WbemScripting_SWbemObjectSet_ItemIndex _SWbemObjectSet,0,addr _ISWbemObject
WbemScripting_SWbemObject_Properties__Get _ISWbemObject,addr _ISWbemPropertySet
;=========================================== Name
WbemScripting_SWbemPropertySet_Item _ISWbemPropertySet,BSTR$("Name"),0,addr _ISWbemProperty
WbemScripting_SWbemProperty_Value_Get _ISWbemProperty,addr _varValue
invoke crt_wprintf,cfm$("\n Computer name :%s"),_varValue.bstrVal
;=========================================== NumberOfProcessors
WbemScripting_SWbemPropertySet_Item _ISWbemPropertySet,BSTR$("NumberOfProcessors"),0,addr _ISWbemProperty
WbemScripting_SWbemProperty_Value_Get _ISWbemProperty,addr _varValue
invoke crt_wprintf,cfm$("\n Nb Processors :%d "),_varValue.lVal
;=========================================== Workgroup
WbemScripting_SWbemPropertySet_Item _ISWbemPropertySet,BSTR$("Workgroup"),0,addr _ISWbemProperty
WbemScripting_SWbemProperty_Value_Get _ISWbemProperty,addr _varValue
invoke crt_wprintf,cfm$("\n Workgroup :%s "),_varValue.bstrVal
;=========================================== BootupState
WbemScripting_SWbemPropertySet_Item _ISWbemPropertySet,BSTR$("BootupState"),0,addr _ISWbemProperty
WbemScripting_SWbemProperty_Value_Get _ISWbemProperty,addr _varValue
invoke crt_wprintf,cfm$("\n BootupState :%s "),_varValue.bstrVal
;=========================================== DNSHostName
WbemScripting_SWbemPropertySet_Item _ISWbemPropertySet,BSTR$("DNSHostName"),0,addr _ISWbemProperty
WbemScripting_SWbemProperty_Value_Get _ISWbemProperty,addr _varValue
invoke crt_wprintf,cfm$("\n DNSHostName :%s "),_varValue.bstrVal
invoke crt_wprintf,cfm$("\n \n ")
inkey
exit
end Start
include System.Windows.Forms.inc
.code
On_Click PROC _sender:VARIANT, _e:DWORD
LOCAL vt_e:VARIANT
mov vt_e.vt,VT_DISPATCH; VT_UNKNOWN
m2m vt_e.punkVal,_e
invoke MessageBox,0,BSTR$("On_Click"),0,0
RET
On_Click ENDP
start:
invoke __InitCLR
.if eax
New_System_Windows_Forms_Form Form1
System_Windows_Forms_Form_Text_Set Form1,__String("My First Form")
System_Windows_Forms_Button_SetBounds Form1,__Integer(640),__Integer(480),__Integer(640),__Integer(480)
New_System_Windows_Forms_Button Button1
System_Windows_Forms_Button_Text_Set Button1,__String("My First Button")
System_Windows_Forms_Button_SetBounds Button1,__Integer(100),__Integer(100),__Integer(160),__Integer(60)
System_Windows_Forms_Button_On_Click Button1,offset On_Click
__New_Null Controls
System_Windows_Forms_Control_Controls_Get Form1,Controls
System_Windows_Forms_Control_ControlCollection_Add Controls, Button1
System_Windows_Forms_Form_ShowDialog Form1,0
invoke __ReleaseClr
.endif
exit
end start
Public Class MyClass1
Public Function MyFirstFunc(s As String) As System.Windows.Forms.DialogResult
Return System.Windows.Forms.MessageBox.Show("Masm32 Injector:"+s, "Masm32Ref")
End Function
Public Shared Function MySecFunc(s As String) As System.Windows.Forms.DialogResult
Return System.Windows.Forms.MessageBox.Show("Masm32 Injector:"+s, "Masm32Ref")
End Function
End Classclick "Add Ref" and select System.Windows.Forms.dllinclude MyAssembly.inc
start:
invoke __InitCLR
.if eax
__New_Empty _msgRet
;Static function
MyClass1_MySecFunc __String("Hello"),_msgRet
New_MyClass1 _cls1
MyClass1_MyFirstFunc _cls1,__String("Hello"),_msgRet
invoke __ReleaseClr
.endif
inkey
exit
end start
The Word-example directly worked :tThank you qWord Good observation, I've removed masm32rt.inc. I've added what I need only
The file COMHelper.inc does include code/data and also references masm32rt.inc.
I would at least move the code and data into separate asm files, or better supply them via a static library. The reference to masm32rt.inc should be completely removed IMO.
There is some redundant macro code (__New_float/double/short,....) that could be removed by using macros that define other macros (afaics).
regards
Statusline is too narrow in Windows 10
Hi, MABDELOUAHAB,
:bgrin: I think you just conquered the COM/NET Galaxy single-handedly. :bgrin:
:bgrin: MASM assembly language programming will never be the same. :bgrin:
I don't want you to give away all your secrets,...but, I've got a million questions,...:icon_eek:I don't have secrets, "It's science", and I'll answer to 2 million question
include System.Windows.Forms.MessageBox.inc
include masm32rt.inc
.data
msg__ = BSTR$("Hello World")
vString dw VT_BSTR,0,0,0
dd msg__,0
.code
Start:
System_Windows_Forms_MessageBox_Show_14 addr vString,0
inkey
exit
end Start
...
;[Static];System.Windows.Forms.DialogResult Show(System.String, System.String)
System_Windows_Forms_MessageBox_Show_13 MACRO _text ,_caption ,lpvtRetValue
??DEF_System_Windows_Forms_MessageBox
invoke __NetFWHelper_Method,addr __Type_System_Windows_Forms_MessageBox,13,0,lpvtRetValue,2, _text ,_caption
ENDM
;[Static];System.Windows.Forms.DialogResult Show(System.String)
System_Windows_Forms_MessageBox_Show_14 MACRO _text ,lpvtRetValue
??DEF_System_Windows_Forms_MessageBox
invoke __NetFWHelper_Method,addr __Type_System_Windows_Forms_MessageBox,14,0,lpvtRetValue,1, _text
ENDM
...
What about MASM64Ref or even better: HJWASM64Ref ;)It's summer project :lol:
MASM32Ref make for you a MACROs ready for direct use, and it initialise the last CLR automatically for you if you have not done so.
invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,9,BSTR$("mscorlib,"),9
And, everywhere this macro is called, I'm getting the following error when compiling: And, everywhere this macro is called, I'm getting the following error when compiling:
error A2085: instruction or register not accepted in current CPU mode. No clue as to why
__ForEach MyVariable in MyArray
; ....
__ExitFor ; exit __ForEach
; ....
RET ; go to the next
; ....
__Next
MyVariable : pointer to Variant
What processor model are you using ?Yeah, first thing I thought of. I'm using the .486 model directive (the same as MABDELOUAHAB is using in his include files). But, I did change it, and then tried to compile,...and got the same error. I'll have to play around with that macro some and see what happens,...
If the BSTR$ Macro works for everyone else, then the error is on my part ...
MABDELOUAHAB,
Like I said before, I don't understand what the macro does.
BSTR$("mscorlib,")
=
invoke SysAllocString,chr$("mscorlib,")
mov bstrValue,eax
...
invoke SysFreeString,bstrValue
BSTR$("v2.0.50727")
=
.data
dd 10*2
clrV2 dw "v","2",".","0",".","5","0","7","2","7",0
.code
It is just shorthand
BSTR$("mscorlib,")
=
invoke SysAllocString,chr$("mscorlib,")
mov bstrValue,eax
...
invoke SysFreeString,bstrValue
BSTR$ MACRO qstr:vararg
LOCAL arg,qot,q,bstrLbl,bstr_Seg,FrstL,tmpLen,cur_Pos,tmpStr,cur_tPos
cs_Seg catstr @CurSeg
ifidn cs_Seg, <CONST>
bstr_Seg TEXTEQU <.const>
elseifidn cs_Seg, <_BSS>
bstr_Seg TEXTEQU <.data?>
elseifidn cs_Seg, <_DATA>
bstr_Seg TEXTEQU <.data>
elseifidn cs_Seg, <_TEXT>
bstr_Seg TEXTEQU <.code>
endif
; .data
; dd _LenBSTR(qstr)
FrstL = 0
FOR arg,<qstr>
tmpStr equ <>
qot SubStr <arg>,1,1
IFIDNI qot,<!'>
tmpLen = @SizeStr(<arg>)
tmpLen = tmpLen - 2
cur_Pos = 1
cur_tPos = 0
repeat tmpLen
cur_Pos=cur_Pos+1
cur_tPos=cur_tPos+1
ch_unq SubStr <arg>,cur_Pos,1
IF cur_Pos eq 2
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
IF cur_tPos eq 1
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
tmpStr CATSTR tmpStr,<!,">,ch_unq,<!">
ENDIF
ENDIF
IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF
endm
IF tmpLen ne 0
IF cur_tPos ne 0
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
ENDIF
ENDIF
ELSEIFIDNI qot,<!">
tmpLen = @SizeStr(<arg>)
tmpLen = tmpLen - 2
cur_Pos = 1
cur_tPos = 0
repeat tmpLen
cur_Pos=cur_Pos+1
cur_tPos=cur_tPos+1
ch_unq SubStr <arg>,cur_Pos,1
IF (cur_Pos eq 2)
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
IF (cur_tPos eq 1)
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
tmpStr CATSTR tmpStr,<!,">,ch_unq,<!">
ENDIF
ENDIF
IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF
endm
IF tmpLen ne 0
IF cur_tPos ne 0
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
ENDIF
ENDIF
ELSE
IF FrstL eq 0
bstrLbl dw arg
FrstL = 1
ELSE
dw arg
ENDIF
ENDIF
ENDM
IF FrstL eq 0
bstrLbl dw 0
ELSE
dw 0
ENDIF
; bstr_Seg
EXITM <OFFSET bstrLbl>
ENDM
Sure?
BSTR Data Type (https://msdn.microsoft.com/en-us/library/ms221069.aspx)
Length prefix Consists of a four-byte integer.
Data string On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).
.data ; Must be in DATA section
dd _LenBSTR(qstr) ; < ----------- Length prefix
. Consists of a four-byte integer.
. Occurs immediately before the first character of the data string.
. Contains the number of bytes in the following data string.
. Does not include the terminator.
bstrLbl dw tmpStr ; < ----------- Data string
. On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).
. On Apple Power Macintosh, consists of a single-byte string.
. May contain multiple embedded null characters.
DW 0 ;< ----------- Terminator
. Consists of two null characters (0x00).
bstr_Seg; return to the last section
_LenBSTR MACRO qstr:VARARG
LOCAL arg,qot,szT,n,Len__
Len__ = 0
FOR arg,<qstr>
qot SubStr <arg>,1,1
IFIDNI qot,<!'>
n=__checkNDQot(arg)
Len__ = Len__ +@SizeStr(<arg>)-2-n
ELSEIFIDNI qot,<!">
n=__checkN2Qot(arg)
Len__ = Len__ +@SizeStr(<arg>)-2-n
ELSE
Len__ = Len__ +1
ENDIF
ENDM
Len__= Len__ + Len__ ;*2
szT TEXTEQU %Len__;<@CatStr(%co__)>
EXITM< szT >
ENDM
BSTR$ MACRO qstr:vararg
LOCAL arg,qot,q,bstrLbl,FrstL,tmpLen,cur_Pos,tmpStr,cur_tPos,cs_Seg
cs_Seg catstr @CurSeg
; ifidn cs_Seg, <CONST>
; bstr_Seg TEXTEQU <.const>
; elseifidn cs_Seg, <_BSS>
; bstr_Seg TEXTEQU <.data?>
; elseifidn cs_Seg, <_DATA>
; bstr_Seg TEXTEQU <.data>
; elseifidn cs_Seg, <_TEXT>
; bstr_Seg TEXTEQU <.code>
; endif
.data
dd _LenBSTR(qstr)
FrstL = 0
tmpStr equ <>
cur_tPos = 0
FOR arg,<qstr>
qot SubStr <arg>,1,1
IsQot = 0
IFIDNI qot,<!'>
IsQot = 1
ELSEIFIDNI qot,<!">
IsQot = 1
ENDIF
IF IsQot eq 1
tmpLen = @SizeStr(<arg>)
tmpLen = tmpLen - 2
cur_Pos = 1
QuotF = 0
repeat tmpLen
cur_Pos=cur_Pos+1
ch_unq SubStr <arg>,cur_Pos,1
tmpStr2 CATSTR <>
IFIDNI ch_unq,<!">
IF QuotF eq 0
QuotF = 1
ELSE
QuotF = 0
tmpStr2 CATSTR <!022h>
ENDIF
ELSE
tmpStr2 CATSTR <!">,ch_unq,<!">
ENDIF
IF QuotF eq 0
cur_tPos=cur_tPos+1
IF (cur_tPos eq 1)
tmpStr CATSTR tmpStr,tmpStr2
ELSE
tmpStr CATSTR tmpStr,<!,>,tmpStr2
ENDIF
ENDIF
IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF
endm
ELSE
cur_tPos=cur_tPos+1
ch_unq SubStr <arg>,1
IF (cur_tPos eq 1)
tmpStr CATSTR tmpStr,ch_unq
ELSE
tmpStr CATSTR tmpStr,<!,>,ch_unq
ENDIF
IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF
ENDIF
ENDM
IF FrstL eq 0
IF cur_tPos eq 0
bstrLbl dw 0
else
bstrLbl dw tmpStr,0
ENDIF
ELSE
IF cur_tPos eq 0
dw 0
ELSE
dw tmpStr,0
ENDIF
ENDIF
;bstr_Seg
ifidn cs_Seg, <CONST>
.const
elseifidn cs_Seg, <_BSS>
.data?
elseifidn cs_Seg, <_TEXT>
.code
endif
EXITM <OFFSET bstrLbl>
ENDM
Sure?
BSTR Data Type (https://msdn.microsoft.com/en-us/library/ms221069.aspx)
Length prefix Consists of a four-byte integer.
Data string On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).
of course JOCHENQuote.data ; Must be in DATA section
dd _LenBSTR(qstr) ; < ----------- Length prefix
. Consists of a four-byte integer.
. Occurs immediately before the first character of the data string.
. Contains the number of bytes in the following data string.
. Does not include the terminator.
bstrLbl dw tmpStr ; < ----------- Data string
. On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).
Yep, dw tmpStr makes sense. But SysAllocString,chr$("mscorlib,") (see "shorthand" above) will not give you what you wantjj2007 why not:SysAllocString (https://msdn.microsoft.com/en-us/library/windows/desktop/ms221458(v=vs.85).aspx)
Return value
If successful, returns the string. If psz is a zero-length string, returns a zero-length BSTR. If psz is NULL or insufficient memory exists, returns NULL.
Remarks
You can free strings created with SysAllocString using SysFreeString.
jj2007 why not:SysAllocString (https://msdn.microsoft.com/en-us/library/windows/desktop/ms221458(v=vs.85).aspx)
BSTR SysAllocString(
OLECHAR FAR* sz
);
It is just shorthand
BSTR$("mscorlib,")
=
invoke SysAllocString,chr$("mscorlib,")
include \masm32\include\masm32rt.inc
.code
start:
invoke SysAllocString,chr$("mscorlib,")
int 3
exit
end start
__UNICODE__ equ 1because:
A BSTR (Basic string or binary string) is a string data type that is used by COM, Automation, and Interop functions. Use the BSTR data type in all interfaces that will be accessed from script.relaunch Olly and see what you get 8)
__UNICODE__ equ 1
include \masm32\include\masm32rt.inc
.code
start:
invoke SysAllocString,chr$("mscorlib,")
int 3
exit
end start
Jochen, Don't forget that the third line in ComHelper.inc isQuote__UNICODE__ equ 1
.IF !hMsCorEE
invoke LoadLibrary,BSTR$("mscoree")
MOV hMsCorEE ,EAX
.ENDIF
invoke LoadLibrary, ADDR szMSCore ; Modified from original
; If the LoadLibrary function fails, the return value is NULL.
mov hMsCorEE, eax
.IF eax==NULL ; Modified from original (Added this Log File notification if LoadLibrary fails.)
invoke LogEntry, ADDR szFAILLoadLib
RET
.ENDIF .IF !hMsCorEEOR
invoke LoadLibraryW,BSTR$("mscoree")
MOV hMsCorEE ,EAX
.ENDIF
.IF !hMsCorEE
invoke LoadLibrary,chr$("mscoree")
MOV hMsCorEE ,EAX
.ENDIF
__Private_GetRuntimeHost4 PROC
.IF !Curr_CLRRuntimeInfo
.IF !Curr_CLRMetaHost
invoke CLRCreateInstance,addr CLSID_CLRMetaHost,addr IID_ICLRMetaHost,addr Curr_CLRMetaHost
.ENDIF
.IF Curr_CLRMetaHost
MOV Curr_CLRRuntimeInfo,0
PUSH 0
PUSH offset CallBackFunction_GetLastVersionInstaled
CALL __ForEachInstalledRuntimes
.ENDIF
.ENDIF
.IF Curr_CLRRuntimeInfo
PUSH OFFSET Curr_CLRRuntimeHost
PUSH OFFSET IID_ICLRRuntimeHost
PUSH OFFSET CLSID_CLRRuntimeHost
MOV EDX , Curr_CLRRuntimeInfo
PUSH EDX
MOV EDX ,[EDX]
CALL DWORD PTR [EDX+36]
.IF !EAX
MOV EDX, Curr_CLRRuntimeHost
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+12]
PUSH OFFSET Curr_CorRuntimeHost
PUSH OFFSET IID_ICorRuntimeHost
PUSH OFFSET CLSID_CorRuntimeHost
MOV EDX , Curr_CLRRuntimeInfo
PUSH EDX
MOV EDX ,[EDX]
CALL DWORD PTR [EDX+36]
.IF !eax
MOV EAX,TRUE
.ELSE
MOV EAX,FALSE
.ENDIF
.ELSE
MOV EAX,FALSE
.ENDIF
.ELSE
MOV EAX,FALSE
.ENDIF
ret
__Private_GetRuntimeHost4 endp
So,...here is the question: After loading the Common Language Runtime (CLR) version 4, and calling ICLRRuntimeHost:Start (which succeeds), you have a block of code that calls ICLRRuntimeInfo:GetInterface (https://msdn.microsoft.com/en-us/library/dd233135(v=vs.110).aspx) (using the ICLRRuntimeInfo interface pointer for version 4) to obtain an ICorRuntimeHost (https://msdn.microsoft.com/en-us/library/ms164320(v=vs.110).aspx) interface pointer. Why ??? The documentation for the ICorRuntimeHost interface states that: "In the .NET Framework version 2.0, this interface is superseded by ICLRRuntimeHost." I'm just wondering if this is necessary.Yes it is necessary, we must obtain an ICorRuntimeHost interface pointer to get the DefaultDomain
.IF _rv(__InitCLR)
LEA ECX,Asm__s ; Asm__s is defined as a LOCAL variable
PUSH ECX
.IF IAppDom ; IAppDom is a parameter of __ForEachAssemblyInIAppDomain, which in this case is zero.
MOV EDX, IAppDom
.ELSE
MOV EDX, IDefaultDomain
.ENDIF
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+228]
What I'd like to know is how you determined the vtable order of the AppDomain (https://msdn.microsoft.com/en-us/library/system.appdomain(v=vs.110).aspx) object,...(or, is it the _AppDomain Interface (https://msdn.microsoft.com/en-us/library/system._appdomain(v=vs.110).aspx) ???) It's not in mscoree.h.the vtable order of the AppDomain object? There is no way to know this ( vtable order of the AppDomain object not equal vtable order of the _AppDomain interface)
That doesn't make sense.is _AppDomain interface not AppDomain object :biggrin: from mscorlib.tlb
How did you figure out what method was located at:
DWORD PTR [EDX+228] ???
// TLBimports.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#import "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb" raw_interfaces_only
#import "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscoree.tlb" raw_interfaces_only
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
Marshaling Object to Interface
When an object is exposed to COM as an interface, that interface is the class interface for the managed type Object (the _Object interface). This interface is typed as an IDispatch (UnmanagedType.IDispatch) or an IUnknown (UnmanagedType.IUnknown) in the resulting type library. COM clients can dynamically invoke the members of the managed class or any members implemented by its derived classes through the _Object interface. The client can also call QueryInterface to obtain any other interface explicitly implemented by the managed type.
The classes in the System.Reflection namespace, together with System::Type, enable you to obtain information about loaded assemblies and the types defined within them, such as classes, interfaces, and value types. You can also use reflection to create type instances at run time, and to invoke and access them
...Here's the trick . You've got all interfaces defined. Convert them to MASM includes and you'll become extremly dangerous coder,...I'm already the undisputed champion 'most annoying coder in the MASM Forum',...so, yes,...the yellow brick road to world domination extends out on my horizon. :bgrin: Thanks for the tip,...but, I don't have Visual Studio on my computer anymore,...but, I think I can figure out how to do it in MASM, if necessary,...
; (from procedure, CallBackFunction_GetMsCorLibAssembly)
.IF __Asm ; __Asm is a pointer to the data returned in SAFEARRAY (returned from _APPDomain:GetAssemblies).
LEA ECX,__lpstrname
PUSH ECX
MOV EDX, __Asm
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+28] ; What the HECK are we calling here ??? GetType, or, GetName ???
.IF MsCorLib
MOV EDX,BSTR$("System.AppDomain") ; If this block of code were executing the application would crash at the BSTR$ Macro.
LEA ECX,tAppDomain
PUSH ECX
PUSH EDX
MOV EDX, MsCorLib
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+68]
.IF !EAX
LEA ECX,aProperties
PUSH ECX
MOV EDX, tAppDomain
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+308]
.IF !EAX
MOV ECX,aProperties
MOV EDX,[ECX].SAFEARRAY.rgsabound.cElements
MOV ESI,[ECX].SAFEARRAY.pvData
XOR ECX,ECX
MOV CurrentDomainProperty,ECX
SPr__:
CMP ECX,EDX
JE EPr__
PUSH ECX
PUSH EDX
MOV EAX,[ESI]
LEA ECX,__lpstrname
PUSH ECX
MOV EDX, EAX
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+48]
.IF !EAX
invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,-1,BSTR$("CurrentDomain"),13
.IF EAX == CSTR_EQUAL
invoke SysFreeString,__lpstrname
MOV EAX,[ESI]
MOV CurrentDomainProperty,EAX
POP EDX
POP ECX
jmp EPr__
.ENDIF
invoke SysFreeString,__lpstrname
.ENDIF
POP EDX
POP ECX
INC ECX
ADD ESI,4
JMP SPr__
EPr__:
.IF CurrentDomainProperty
LEA ECX,vtDefaultDomain
PUSH ECX
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
MOV EDX, CurrentDomainProperty
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+76]
.IF !EAX
MOV DefaultDomain ,offset vtDefaultDomain
MOV EAX,DefaultDomain
RET
.ELSE
__ExeptionMsg BSTR$("CurrentDomain.GetValue FAIL")
MOV EAX,FALSE
.ENDIF
.ELSE
__ExeptionMsg BSTR$("CurrentDomainProperty FAIL ")
MOV EAX,FALSE
.ENDIF
.ELSE
MOV EAX,FALSE
.ENDIF
.ELSE
MOV EAX,FALSE
.ENDIF
.ENDIF
...So,...I launched ProcessExplorer to see what DLLs were being loaded by the version 4 CLR when calling __GetDefaultDomain, and, weirdly enough, the DLL: mscorlib.ni.dll (https://blogs.msdn.microsoft.com/junfeng/2004/11/11/mscorlib-ni-dll/) is loaded into the process address space.
...And,...so,...finally,...what is supposed to be happening here ???
invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,9,BSTR$("mscorlib,"),9
I changed that by just substituting a BSTR pointer to the Unicode string, "mscorlib.ni.dll" for the string "mscorlib" in the BSTR$ Macro, and changed the number of characters in each string to be compared from 9 to 8. Like this: invoke CompareStringW, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname, 8, bstmscorlibni, 8 ; Modified from original ("mscorlib.ni.dll")
The CompareStringW function now works (returning CSTR_EQUAL) without having to change anything else. And, almost everything else in the .IF MsCorLib block (noted above) works after substituting BSTR strings for the BSTR$ Macro.... The Unicode string that is returned is: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089. So, the reason that CompareStringW was NOT returning CSTR_EQUAL is simple. You wrote this in the original DotNetHelper.inc:What are the first nine letters of :"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Of course, it is "mscorlib,"Code: [Select]invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,9,BSTR$("mscorlib,"),9..
"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"What is the difference between the two strings when we use CompareStringW, is that the 9 letters of the first is "mscorlib," and the 9 letters of the secend is "mscorlib."
"mscorlib.resources"
LEA ECX,__lpstrname
PUSH ECX
MOV EDX, __Asm ; __Asm must be a pointer, but, to what ???
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+28] ; Unknown COM method call. ...from, CallBackFunction_GetMsCorLibAssembly. MOV EDX, MsCorLib
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+68] ; Unknown COM method call.
MOV EDX, tAppDomain
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+308] ; Unknown COM method call. LEA ECX,__lpstrname
PUSH ECX
MOV EDX, EAX
PUSH EDX
MOV EDX,[EDX]
CALL DWORD PTR [EDX+48] ; Unknown COM method call.
...
; struct __declspec(uuid("05f696dc-2b29-3663-ad8b-c4389cf2a713"))
_AppDomain STRUCT
IUnknown <>
METHOD(GetTypeInfoCount , _this:LPVOID, pcTInfo:LPVOID )
METHOD(GetTypeInfo , _this:LPVOID, iTInfo:UINT, lcid:LCID, ppTInfo:LPVOID )
METHOD(GetIDsOfNames , _this:LPVOID, riid:LPVOID, rgszNames:LPOLESTR, cNames:UINT,lcid:LCID, rgDispId:LPVOID )
METHOD(_Invoke , _this:LPVOID, dispIdMember:DWORD, riid:LPVOID,lcid:LCID, wFlags:DWORD, pDispParams:LPVOID, pVarResult:LPVOID, pExcepInfo:LPVOID, puArgErr:LPVOID )
METHOD(get_ToString , _this:LPVOID, pRetVal:BSTR )
METHOD(Equals , _this:LPVOID, other:VARIANT, pRetVal:VARIANT_BOOL )
METHOD(GetHashCode , _this:LPVOID, pRetVal:LPVOID )
METHOD(GetType , _this:LPVOID, pRetVal: ptr _Type )
METHOD(InitializeLifetimeService , _this:LPVOID, pRetVal:VARIANT )
METHOD(GetLifetimeService , _this:LPVOID, pRetVal:VARIANT )
METHOD(get_Evidence , _this:LPVOID, pRetVal:ptr _Evidence )
METHOD(add_DomainUnload , _this:LPVOID, value:ptr _EventHandler )
METHOD(remove_DomainUnload , _this:LPVOID, value:ptr _EventHandler )
METHOD(add_AssemblyLoad , _this:LPVOID, value:ptr _AssemblyLoadEventHandler )
METHOD(remove_AssemblyLoad , _this:LPVOID, value:ptr _AssemblyLoadEventHandler )
METHOD(add_ProcessExit , _this:LPVOID, value:ptr _EventHandler )
METHOD(remove_ProcessExit , _this:LPVOID, value:ptr _EventHandler )
METHOD(add_TypeResolve , _this:LPVOID, value:ptr _ResolveEventHandler )
METHOD(remove_TypeResolve , _this:LPVOID, value:ptr _ResolveEventHandler )
METHOD(add_ResourceResolve , _this:LPVOID, value:ptr _ResolveEventHandler )
METHOD(remove_ResourceResolve , _this:LPVOID, value:ptr _ResolveEventHandler )
METHOD(add_AssemblyResolve , _this:LPVOID, value:ptr _ResolveEventHandler )
METHOD(remove_AssemblyResolve , _this:LPVOID, value:ptr _ResolveEventHandler )
METHOD(add_UnhandledException , _this:LPVOID, value:ptr _UnhandledExceptionEventHandler )
METHOD(remove_UnhandledException , _this:LPVOID, value:ptr _UnhandledExceptionEventHandler )
METHOD(DefineDynamicAssembly , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_2 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR , pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_3 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , Evidence:ptr _Evidence , pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_4 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_5 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, Evidence:ptr _Evidence , pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_6 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_7 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , Evidence:ptr _Evidence , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_8 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, Evidence:ptr _Evidence , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder )
METHOD(DefineDynamicAssembly_9 , _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, Evidence:ptr _Evidence , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, IsSynchronized:VARIANT_BOOL , pRetVal:ptr _AssemblyBuilder )
METHOD(CreateInstance , _this:LPVOID, AssemblyName:BSTR, typeName:BSTR ,pRetVal:ptr _ObjectHandle )
METHOD(CreateInstanceFrom , _this:LPVOID, assemblyFile:BSTR, typeName:BSTR ,pRetVal:ptr _ObjectHandle )
METHOD(CreateInstance_2 , _this:LPVOID, AssemblyName:BSTR, typeName:BSTR , activationAttributes:SAFEARRAY,pRetVal:ptr _ObjectHandle )
METHOD(CreateInstanceFrom_2 , _this:LPVOID, assemblyFile:BSTR, typeName:BSTR , activationAttributes:SAFEARRAY,pRetVal:ptr _ObjectHandle )
METHOD(CreateInstance_3 , _this:LPVOID, AssemblyName:BSTR, typeName:BSTR , ignoreCase:VARIANT_BOOL, bindingAttr:BindingFlags , Binder:ptr _Binder , args:SAFEARRAY , culture:ptr _CultureInfo, activationAttributes:SAFEARRAY,securityAttributes:ptr _Evidence ,pRetVal:ptr _ObjectHandle )
METHOD(CreateInstanceFrom_3 , _this:LPVOID, assemblyFile:BSTR, typeName:BSTR , ignoreCase:VARIANT_BOOL, bindingAttr:BindingFlags , Binder:ptr _Binder , args:SAFEARRAY , culture:ptr _CultureInfo, activationAttributes:SAFEARRAY,securityAttributes:ptr _Evidence ,pRetVal:ptr _ObjectHandle )
METHOD(Load , _this:LPVOID, assemblyRef:ptr _AssemblyName, pRetVal:ptr _Assembly )
METHOD(Load_2 , _this:LPVOID, assemblyString:BSTR, pRetVal:ptr _Assembly )
METHOD(Load_3 , _this:LPVOID, rawAssembly:SAFEARRAY , pRetVal:ptr _Assembly )
METHOD(Load_4 , _this:LPVOID, rawAssembly:SAFEARRAY , rawSymbolStore:SAFEARRAY , pRetVal:ptr _Assembly )
METHOD(Load_5 , _this:LPVOID, rawAssembly:SAFEARRAY , rawSymbolStore:SAFEARRAY , securityEvidence:ptr _Evidence , pRetVal:ptr _Assembly )
METHOD(Load_6 , _this:LPVOID, assemblyRef:ptr _AssemblyName, assemblySecurity:ptr _Evidence , pRetVal:ptr _Assembly )
METHOD(Load_7 , _this:LPVOID, assemblyString:BSTR, assemblySecurity:ptr _Evidence , pRetVal:ptr _Assembly )
METHOD(ExecuteAssembly , _this:LPVOID, assemblyFile:BSTR, assemblySecurity:ptr _Evidence , pRetVal:LPVOID )
METHOD(ExecuteAssembly_2 , _this:LPVOID, assemblyFile:BSTR, pRetVal:LPVOID )
METHOD(ExecuteAssembly_3 , _this:LPVOID, assemblyFile:BSTR, assemblySecurity:ptr _Evidence , args:SAFEARRAY , pRetVal:LPVOID )
METHOD(get_FriendlyName , _this:LPVOID, pRetVal:BSTR )
METHOD(get_BaseDirectory , _this:LPVOID, pRetVal:BSTR )
METHOD(get_RelativeSearchPath , _this:LPVOID, pRetVal:BSTR )
METHOD(get_ShadowCopyFiles , _this:LPVOID, pRetVal:VARIANT_BOOL )
METHOD(GetAssemblies , _this:LPVOID, pRetVal:SAFEARRAY )
METHOD(AppendPrivatePath , _this:LPVOID, Path:BSTR )
METHOD(ClearPrivatePath , _this:LPVOID)
METHOD(SetShadowCopyPath , _this:LPVOID, s:BSTR )
METHOD(ClearShadowCopyPath , _this:LPVOID)
METHOD(SetCachePath , _this:LPVOID, s:BSTR )
METHOD(SetData , _this:LPVOID, _name:BSTR, data:VARIANT )
METHOD(GetData , _this:LPVOID, _name:BSTR, pRetVal:VARIANT)
METHOD(SetAppDomainPolicy , _this:LPVOID, domainPolicy:ptr _PolicyLevel )
METHOD(SetThreadPrincipal , _this:LPVOID, principal:ptr IPrincipal )
METHOD(SetPrincipalPolicy , _this:LPVOID, policy:PrincipalPolicy )
METHOD(DoCallBack , _this:LPVOID, theDelegate:ptr _CrossAppDomainDelegate )
METHOD(get_DynamicDirectory , _this:LPVOID, pRetVal:BSTR )
_AppDomain ENDS
....