flat assembler
Message board for the users of flat assembler.
Index
> Windows > How to implement virtual function table in a DLL |
Author |
|
mns 11 Apr 2023, 17:32
I am trying to understand how Vtable is created in a DLL
I have made the following example code so far, Code: format PE GUI 4.0 DLL entry startDLL include 'WIN32A.inc' ;include 'rcWin32p16.inc' struct MYINTERFACE QueryInterface dd ? AddRef dd ? Release dd ? GetMsgBox dd ? GetErrorMsgBox dd ? ends ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.data' data readable writeable ;======================================================================================================== myMSGBOXHead db 'Error MSGBOX Heading',0 myError db 'This is a error',0 mytext db 'This is a test text',0 myInterface MYINTERFACE ;====================================================================================================== ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.code' code readable executable ;====================================================================================================== ;----------------------------------Entry point-------------------------------------------------------- proc startDLL hInstance,Reason,Reserved mov eax,TRUE ret endp ;---------------------------------------------------------------------------------------------------------- proc myInterfaceFunc call mydecoderVTBL mov eax,mydecoderVTBL ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- mydecoderVTBL: mov dword[myInterface],myInterface_QueryInterface mov dword[myInterface+4],myInterface_AddRef mov dword[myInterface+8],myInterface_Release mov dword[myInterface+12],myInterface_GetMsgBox mov dword[myInterface+16],myInterface_GetErrorMsgBox ret ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- myInterface_QueryInterface: ;code here ret ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- myInterface_AddRef: ;code here ret ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- myInterface_Release: ;code here ret ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- myInterface_GetErrorMsgBox: lea eax,[myError] lea edx,[myMSGBOXHead] invoke MessageBox, 0,eax,edx, MB_OK ret ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- myInterface_GetMsgBox: lea eax,[mytext] lea edx,[myMSGBOXHead] invoke MessageBox, 0,eax,edx, MB_OK ret ;---------------------------------------------------------------------------------------------------------- ;========================================================================================================== ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.idata' import data readable ;======================================================================================================= library kernel32,'kernel32.dll',\ user32,'USER32.DLL' include 'api/kernel32.inc' include 'api/USER32.inc' ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.edata' export data readable ;======================================================================================================= export 'dlltest2.dll',\ myInterfaceFunc,'myInterfaceFunc' ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.reloc' fixups data readable discardable ;======================================================================================================= if $=$$ dd 0,8 ; if there are no fixups, generate dummy entry end if ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Several things I cannot understand, 1). How vtable is created when loading the DLL (Is my way in the code correct ?) 2). What address in this code(if this has specified CLSID) CoCreateInstance function will return and How it does that Please could someone help ?
Last edited by mns on 12 Apr 2023, 07:29; edited 1 time in total |
|||||||||||
11 Apr 2023, 17:32 |
|
mns 12 Apr 2023, 09:01
Thank you ProMiNick for the kind answer. But still I am not clear. You mean,
To implement DllGetClassObject function(and export it), Where, DllGetClassObject function is, Code: proc DllGetClassObject rclsid,riid,ppv ;newIClassFactory IClassFactory ;check rclsid = my class rclsid ;if yes, cominvk newIClassFactory,CreateInstance,[riid],[ppv] ret endp Is this correct? (now I am more confused ) |
|||
12 Apr 2023, 09:01 |
|
ProMiNick 12 Apr 2023, 11:58
Is this correct? - no.
COM technology request IClassFactory via exported from DLL function DllGetClassObject. than outside of library (and internaly in libraries that realise COM from OS side) executed method CreateInstance of IClassFactory requested previously. that method is able to build thour custom interface. But without COM technology thou could import whatever thou want no matter function, or string, or some structure or interface. And in that not COM interface thou don`t needed in QueryInterface,AddRef & Release. Just export address of interface and use it in executable that know that. |
|||
12 Apr 2023, 11:58 |
|
mns 13 Apr 2023, 04:12
I am trying to learn how vtable is created in loading a DLL. So far I get, DllGetClassObject function is the key for that. Could you please tell me (in simple terms) what should I do in DllGetClassObject function for that? (may be step wise).
|
|||
13 Apr 2023, 04:12 |
|
ProMiNick 13 Apr 2023, 05:45
Code: DllGetClassObject: procedure(rclsid,riid,ppv) ; returned requested ClassFactory!!! not COMobject itself push ebx mov ebx, [ppv] test ebx, ebx jz .ret_E_POINTER xor eax, eax mov [ebx], eax precmpGUID ; search ClassFactory corresponded to rclsid cld cmpGUID [rclsid],lpCLSID_QuickRegister postcmpGUID jnz .ret_CLASS_E_CLASSNOTAVAILABLE comcall QRClassFactory_COMobject,IUnknown,QueryInterface,[riid],ebx jmp .locret .ret_E_POINTER: mov eax, E_POINTER jmp .locret .ret_CLASS_E_CLASSNOTAVAILABLE: mov eax, CLASS_E_CLASSNOTAVAILABLE .locret: pop ebx ret endp Every COM object has its own CLSID, in thour DLL could be one IClassFactory for every COM object or one IClassFactory for whole DLL. DllGetClassObject firstly starts from checking args that ppv is valid pointer. Than goes comparisons of requested rclsid with CLSIDS of COM objects described in DLL, and selected IClassFactory(selected COM object that realize IClassFactory interface, not IClassFactory interface) according to that comparison or returned CLASS_E_CLASSNOTAVAILABLE if CLSID not implemented in DLL. If detected COM object realized IClassFactory interface matched to requested CLSID, than executed its method QueryInterface. That method mostly increase DLL_used counter. Code: DllCanUnloadNow: procedure() xor eax,eax cmp eax,[ServerLockCount] jz .locret inc eax .locret: ret endp For checking if DLL could be unloaded is another export that checks DLL_used counter (ServerLockCount) and if it is zero say yes - DLL could be unloaded, otherwise it says no. By the way all QueryInterface of other COM objects realized in DLL increase that counter, they do that increase via subcall of another interface method AddRef, but before that each QueryInterface checks matching of requested IID to ones that interface accept. for example COM object that realize IClassFactory interface accept IID only as IID_IClassFactory or as IID_IUnknown Code: QRClassFactory@QueryInterface: procedure(Self,riid,ppvObject) push ebx mov ebx, [ppvObject] test ebx, ebx jz .ret_E_POINTER xor eax, eax mov [ebx], eax precmpGUID cld cmpGUID [riid],lpIID_IUnknown je .cmp_done cmpGUID [riid],lpIID_IClassFactory .cmp_done: postcmpGUID jnz .ret_E_NOINTERFACE mov eax, [Self] mov [ebx], eax comcall eax, IClassFactory, AddRef xor eax, eax jmp .locret .ret_E_POINTER: mov eax, E_POINTER jmp .locret .ret_E_NOINTERFACE: mov eax, E_NOINTERFACE .locret: pop ebx ret endp |
|||
13 Apr 2023, 05:45 |
|
mns 13 Apr 2023, 06:55
Thank you very much ProMiNick
So to call "comcall QRClassFactory_COMobject,IUnknown,QueryInterface,[riid],ebx" in DllGetClassObject, do we have to create QRClassFactory_COMobject(I mean the object it self to call QueryInterface) ? may be in the out side DllGetClassObject function?\ |
|||
13 Apr 2023, 06:55 |
|
ProMiNick 13 Apr 2023, 07:32
Yes, object realised IClassFactory interface must be created in design time.
that one is example of object created in design time Code: myClassFactory dd myClassFactory_QueryInterface,myClassFactory_AddRef,myClassFactory_Release,myClassFactory_CreateInstance that is simplest structure of object, but it could be Code: myClassFactory dd ...,myClassFactory_vtbl,... myClassFactory_vtbl dd myClassFactory_QueryInterface,myClassFactory_AddRef,myClassFactory_Release,myClassFactory_CreateInstance Code: myClassFactory dd ...,myClassFactory_Intf_Tbl,... myClassFactory_Intf_Tbl dd ...,myClassFactory_Intf1_vtbl,... myClassFactory_Intf1_vtbl dd myClassFactory_QueryInterface,myClassFactory_AddRef,myClassFactory_Release,myClassFactory_CreateInstance complexity of COM object and its structure could be any kind thou want, but with the only one requirement to COM object structure: any its method should be able to walk via current object structure and find other methods (implementation of every method should know current COM object structure) Because assembler have no ability to hide methods or fields - that requirement is always passed in assembly, moreover in assembly it accesible even with static addresses in contrary to requirement of series of indirect accesses via object fields for HLL languages. and COM object itself in case of HLL are always on heap, in assembly if object must be single instance - we are free to locate it in glodal memory of data section, and we could initialize it in design time like ClassFactory. |
|||
13 Apr 2023, 07:32 |
|
mns 13 Apr 2023, 09:23
Let us say I do this in data section
section '.data' data readable myClassFactory dd myClassFactory_QueryInterface,myClassFactory_AddRef,myClassFactory_Release,myClassFactory_CreateInstance and Implement each method in code section section '.code' code readable executable myClassFactory_QueryInterface: ;code here ret ;---------------------------------------------------------------------------------------------------------- myClassFactory_AddRef: ;code here ret ;---------------------------------------------------------------------------------------------------------- myClassFactory_Release: ;code here ret ;---------------------------------------------------------------------------------------------------------- myClassFactory_CreateInstance : ;code here ret How can I initialize the myClassFactory object to use QueryInterface method in the DllGetClassObject function? (if I being foolish here please bare with me) |
|||
13 Apr 2023, 09:23 |
|
ProMiNick 13 Apr 2023, 10:01
for DllGetClassObject all thou described is enought. will be returned COM object myClassFactory.
|
|||
13 Apr 2023, 10:01 |
|
mns 13 Apr 2023, 10:32
And call to
comcall myClassFactory_object, myClassFactory ,myClassFactory_CreateInstance,pUnkOuter,riid,ppvObject" (in DllGetClassObject function) should return address of myClass in ppvObject? |
|||
13 Apr 2023, 10:32 |
|
ProMiNick 13 Apr 2023, 11:30
yes.
when thou call CoCreateInstance then OS enumerated calls to DllGetClassObject of all registered DLLs(registered as COM server). If DllGetClassObject succesfuly returns ClassFactory, then OS runs its method CreateInstance, result of such call is COM oject. After that ClassFactory is released and created COM object returned to code called CoCreateInstance. |
|||
13 Apr 2023, 11:30 |
|
mns 13 Apr 2023, 13:07
Thank you very much ProMiNick now I understand.
|
|||
13 Apr 2023, 13:07 |
|
ProMiNick 13 Apr 2023, 13:21
"Thank" not grabbed to wallet. joke. As a payment I accept couple more of examples (in addition to mine 2s) of COM DLL published for that community (I`m ready to continue help on that way).
|
|||
13 Apr 2023, 13:21 |
|
mns 14 Apr 2023, 11:29
Thanks. I will try. And for the first one, below shows my completed code(except
DllRegisterServer and DllUnregisterServer implementations). Hope there will be no errors Code: format PE GUI 4.0 DLL entry startDLL include 'WIN32A.inc' ;include 'rcWin32p16.inc' struct GUID Data1 dd ? Data2 dw ? Data3 dw ? Data4 db 8 dup(?) ends ;objects struct MYINTERFACEFactory QueryInterface dd ? AddRef dd ? Release dd ? CreateInstance dd ? LockServer dd ? ends struct MYINTERFACE QueryInterface dd ? AddRef dd ? Release dd ? GetMsgBox dd ? GetErrorMsgBox dd ? ends ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.data' data readable writeable ;======================================================================================================== myMSGBOXHead db 'Error MSGBOX Heading',0 myError db 'This is a error',0 mytext db 'This is a test text',0 modulename db 1024 dup(?) CLSID_myInterfaceFactory GUID 0x4519ebca,0x1469,0x4fab,<0x88,0x48,0x5e,0xaf,0x4b,0xfb,0xbe,0x39> IID_myInterfaceFactory GUID 0xe1828e00,0xfa2d,0x41b5,<0x8c,0xf9,0x7d,0x22,0xd9,0x4c,0x56,0x38> IID_myInterface GUID 0x7218f11d,0x86ef,0x4344,<0x8e,0x96,0x60,0x31,0x94,0x21,0xf6,0xc6> IID_IUnknown GUID 0x00000000,0x0000,0x0000,<0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46> IID_IClassFactory GUID 0x00000001,0x0000,0x0000,<0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46> myInterfaceFactory MYINTERFACEFactory myIntrfcFtry_QueryInterface,myIntrfcFtry_AddRef,myIntrfcFtry_Release,myIntrfcFtry_CreateInstance,myIntrfcFtry_LockServer myInterface MYINTERFACE myInterface_QueryInterface,myInterface_AddRef,myInterface_Release,myInterface_GetMsgBox,myInterface_GetErrorMsgBox align 4 MyObjCount dd 0 DllHinst dd 0 ;MyIntrfaceCount dd 0 ;====================================================================================================== ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.code' code readable executable ;====================================================================================================== ;----------------------------------Entry point-------------------------------------------------------- proc startDLL hInstance,Reason,Reserved push [hInstance] pop [DllHinst] mov eax,TRUE ret endp ;---------------------DllGetClassObject------------------------------------------------------------------ proc DllGetClassObject stdcall uses ebx esi edi,rclsid,riid,ppv cmp [ppv],0 je .emptyPointer mov edi,[ppv] mov dword[edi],0 stdcall compareGUIDs,CLSID_myInterfaceFactory,[rclsid] cmp eax,0 jne .classNotAvailable stdcall myIntrfcFtry_QueryInterface,[riid],[ppv] xor eax,eax ret .emptyPointer: mov eax,0x80004003 ;E_POINTER ret .classNotAvailable: mov eax,80040154h ; CLASS_E_CLASSNOTAVAILABLE ret endp ;---------------------DllCanUnloadNow------------------------------------------------------------------ proc DllCanUnloadNow stdcall uses ebx esi edi xor eax,eax cmp [MyObjCount],0 jne .canntUnload ret .canntUnload: mov eax,1 ;S_FALSE ret endp ;---------------------DllRegisterServer------------------------------------------------------------------ proc DllRegisterServer stdcall uses ebx esi edi ;invoke GetModuleFileName,[DllHinst],modulename,1024 ret endp ;---------------------DllUnregisterServer------------------------------------------------------------------ proc DllUnregisterServer stdcall uses ebx esi edi ret endp ;--------------Methods of myInterfaceFactory------------------------------------------------------------------ ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_QueryInterface stdcall uses ebx esi edi,riid,ppv cmp [ppv],0 je .emptyPointer mov edi,[ppv] mov dword[edi],0 stdcall compareGUIDs,IID_IUnknown,[riid] cmp eax,0 je .validIntrfc stdcall compareGUIDs,IID_IClassFactory,[riid] cmp eax,0 jne .noInterface .validIntrfc: mov eax,myInterfaceFactory mov [ppv],eax stdcall myIntrfcFtry_AddRef xor eax,eax ret .emptyPointer: mov eax,0x80004003 ;E_POINTER ret .noInterface: mov eax,0x80004002;E_NOINTERFACE ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_AddRef stdcall uses ebx esi edi ;inc [MyObjCount] invoke InterlockedIncrement,MyObjCount mov eax,[MyObjCount] ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_Release stdcall uses ebx esi edi cmp [MyObjCount],0 je .delObjct invoke InterlockedDecrement,MyObjCount cmp [MyObjCount],0 jne .returnRelease .delObjct: ;***need to delete the object here*** .returnRelease: ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_CreateInstance stdcall uses ebx esi edi,pUnkOuter,riid,ppvObject cmp [pUnkOuter],0 jne .nonAggregation cmp [ppvObject],0 je .emptyPointer mov edi,[ppvObject] mov dword[edi],0 stdcall myInterface_QueryInterface,[riid],[ppvObject]; ret .emptyPointer: mov eax,0x80004003 ;E_POINTER ret .nonAggregation: mov eax,0x80040110;CLASS_E_NOAGGREGATION; ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_LockServer stdcall uses ebx esi edi,fLock cmp [fLock],0 je .freeLk invoke InterlockedIncrement,MyObjCount xor eax,eax ret .freeLk: invoke InterlockedDecrement,MyObjCount xor eax,eax ret endp ;---------------------------------------------------------------------------------------------------------- ;--------------Methods of myInterface------------------------------------------------------------ ;---------------------------------------------------------------------------------------------------------- proc myInterface_QueryInterface stdcall uses ebx esi edi,riid,ppv cmp [ppv],0 je .emptyPointer mov edi,[ppv] mov dword[edi],0 stdcall compareGUIDs,IID_myInterface,[riid] cmp eax,0 jne .noInterface .validIntrfc: mov eax,myInterface mov [ppv],eax stdcall myInterface_AddRef xor eax,eax ret .emptyPointer: mov eax,0x80004003 ;E_POINTER ret .noInterface: mov eax,0x80004002;E_NOINTERFACE ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_AddRef stdcall uses ebx esi edi ;inc [MyObjCount] invoke InterlockedIncrement,MyObjCount mov eax,[MyObjCount] ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_Release stdcall uses ebx esi edi cmp [MyObjCount],0 je .delObjct invoke InterlockedDecrement,MyObjCount cmp [MyObjCount],0 jne .returnRelease .delObjct: ;***need to delete the object here*** .returnRelease: ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_GetErrorMsgBox stdcall uses ebx esi edi lea eax,[myError] lea edx,[myMSGBOXHead] invoke MessageBox, 0,eax,edx, MB_OK ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_GetMsgBox stdcall uses ebx esi edi lea eax,[mytext] lea edx,[myMSGBOXHead] invoke MessageBox, 0,eax,edx, MB_OK ret endp ;---------------------------------------------------------------------------------------------------------- ;--------------------------compareGUIDs------------------------------------------------------------------ proc compareGUIDs stdcall uses ebx esi edi,localGUID,outsideGUID mov edi,[localGUID] mov esi,[outsideGUID] cld cmpsd jne .notIdentical cmpsw jne .notIdentical cmpsw jne .notIdentical mov ecx,8 repe cmpsb jne .notIdentical mov eax,0 ret .notIdentical: mov eax,1 ret endp ;========================================================================================================== ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.idata' import data readable ;======================================================================================================= library kernel32,'kernel32.dll',\ user32,'USER32.DLL' include 'api/kernel32.inc' include 'api/USER32.inc' ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.edata' export data readable ;======================================================================================================= export 'dlltest2.dll',\ DllGetClassObject,'DllGetClassObject',\ DllCanUnloadNow,'DllCanUnloadNow',\ DllRegisterServer,'DllRegisterServer',\ DllUnregisterServer,'DllUnregisterServer' ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.reloc' fixups data readable discardable ;======================================================================================================= if $=$$ dd 0,8 ; if there are no fixups, generate dummy entry end if ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|||||||||||
14 Apr 2023, 11:29 |
|
mns 25 Apr 2023, 10:58
This is the corrected example dll and testing program
This is the DLL Code: format PE GUI 4.0 DLL entry startDLL include 'WIN32AX.inc' ;include 'custmFnc/win32Strfunc.inc' struct GUID Data1 dd ? Data2 dw ? Data3 dw ? Data4 db 8 dup(?) ends ;objects struct IclassFactory QueryInterface dd ? AddRef dd ? Release dd ? CreateInstance dd ? LockServer dd ? ends struct MYINTERFACE QueryInterface dd ? AddRef dd ? Release dd ? GetMsgBox dd ? GetErrorMsgBox dd ? ends ;struct IclassFactoryObj ; IclassFactory_vtbl IclassFactory ;ends struct MYINTERFACEObj MYINTERFACE_vtbl dd ? Refcounter dd ? ends ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.data' data readable writeable ;======================================================================================================== myMSGBOXHead db 'MSGBOX Heading',0 myError db 'This is the error text',0 mytext db 'This is the text',0 myInterfaceFactoryGUID_regText db 'Software\\Classes\\CLSID\\{4519ebca-1469-4fab-8848-5eaf4bfbbe39}',0 CLSIDRegkeyText db 'Software\\Classes\\CLSID',0 MyIntfcGUIDText db '{4519ebca-1469-4fab-8848-5eaf4bfbbe39}',0 InprocServer32Text db 'InprocServer32',0 ThreadingModelText db 'ThreadingModel',0 bothText db 'both',0 DLLRegError db 'Failed to register IExample.DLL as a COM component.',0 modulename db 1024 dup(?) CLSID_myInterface GUID 0x4519ebca,0x1469,0x4fab,<0x88,0x48,0x5e,0xaf,0x4b,0xfb,0xbe,0x39> ;IID_myInterfaceFactory GUID 0xe1828e00,0xfa2d,0x41b5,<0x8c,0xf9,0x7d,0x22,0xd9,0x4c,0x56,0x38> IID_myInterface GUID 0x7218f11d,0x86ef,0x4344,<0x8e,0x96,0x60,0x31,0x94,0x21,0xf6,0xc6> IID_IUnknown GUID 0x00000000,0x0000,0x0000,<0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46> IID_IClassFactory GUID 0x00000001,0x0000,0x0000,<0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46> align 4 ;myClassFactoryObj IclassFactoryObj myClassFactory IclassFactory myIntrfcFtry_QueryInterface,myIntrfcFtry_AddRef,myIntrfcFtry_Release,myIntrfcFtry_CreateInstance,myIntrfcFtry_LockServer myInterface MYINTERFACE myInterface_QueryInterface,myInterface_AddRef,myInterface_Release,myInterface_GetMsgBox,myInterface_GetErrorMsgBox myInterfaceObj dd myInterface dd 0 ;count myClassFactoryObj dd myClassFactory lockCount dd 0 MyObjCount dd 0 DllHinst dd 0 hKey dd 0 hKey2 dd 0 disposition dd 0 ;MyIntrfaceCount dd 0 ;====================================================================================================== ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.code' code readable executable ;====================================================================================================== ;----------------------------------Entry point-------------------------------------------------------- proc startDLL hInstance,Reason,Reserved push [hInstance] pop [DllHinst] mov eax,TRUE ret endp ;---------------------DllGetClassObject------------------------------------------------------------------ proc DllGetClassObject stdcall uses ebx esi edi,rclsid,riid,ppv cmp [ppv],0 je .emptyPointer mov edi,[ppv] mov dword[edi],0 stdcall compareGUIDs,CLSID_myInterface,[rclsid] cmp eax,0 jne .classNotAvailable stdcall myIntrfcFtry_QueryInterface,myClassFactoryObj,[riid],[ppv] jmp .ret_DllGetClassObject .emptyPointer: mov eax,0x80004003 ;E_POINTER jmp .ret_DllGetClassObject .classNotAvailable: mov eax,80040154h ; CLASS_E_CLASSNOTAVAILABLE .ret_DllGetClassObject: ret endp ;---------------------DllCanUnloadNow------------------------------------------------------------------ proc DllCanUnloadNow stdcall uses ebx esi edi xor eax,eax cmp [MyObjCount],0 jne .canntUnload ret .canntUnload: mov eax,1 ;S_FALSE ret endp ;--------------Methods of IclassFactory------------------------------------------------------------------ ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_QueryInterface stdcall uses ebx esi edi,ClassObjAddress,riid,ppv ;invoke MessageBox, 0,'myIntrfcFtry_QueryInterface',0, MB_OK cmp [ppv],0 je .emptyPointer mov edi,[ppv] mov dword[edi],0 stdcall compareGUIDs,IID_IUnknown,[riid] cmp eax,0 je .validIntrfc stdcall compareGUIDs,IID_IClassFactory,[riid] cmp eax,0 jne .noInterface .validIntrfc: mov eax,myClassFactoryObj mov dword[edi],eax stdcall myIntrfcFtry_AddRef,eax;[ClassObjAddress] xor eax,eax ret .emptyPointer: mov eax,0x80004003 ;E_POINTER ret .noInterface: mov eax,0x80004002;E_NOINTERFACE ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_AddRef stdcall uses ebx esi edi,ClassObjAddress ;invoke MessageBox, 0,'myIntrfcFtry_AddRef',0, MB_OK invoke InterlockedIncrement,MyObjCount; mov eax,1 ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_Release stdcall uses ebx esi edi,ClassObjAddress ;invoke MessageBox, 0,'myIntrfcFtry_Release',0, MB_OK invoke InterlockedDecrement,MyObjCount; mov eax,[MyObjCount] ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_CreateInstance stdcall uses ebx esi edi,ClassObjAddress,pUnkOuter,riid,ppvObject ;invoke MessageBox, 0,'myIntrfcFtry_CreateInstance',0, MB_OK ;stdcall GUIDToStrng,CLSID_myInterfaceFactory,1 cmp [pUnkOuter],0 jne .nonAggregation cmp [ppvObject],0 je .emptyPointer mov edi,[ppvObject] mov dword[edi],0 mov [myInterfaceObj+4],1 stdcall myInterface_QueryInterface,myInterfaceObj,[riid],[ppvObject]; cmp eax,0 jne .failed mov edi,myInterfaceObj add edi,4 ;stdcall ValueToHxDcmlStrng,edi,1 stdcall myInterface_Release,myInterfaceObj ;invoke MessageBox, 0,'finish release',0, MB_OK xor eax,eax ret .failed: ;stdcall myInterface_Release,myInterfaceObj invoke InterlockedDecrement,MyObjCount; mov eax,0x80004005 ret .emptyPointer: mov eax,0x80004003 ;E_POINTER ret .nonAggregation: mov eax,0x80040110;CLASS_E_NOAGGREGATION; ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myIntrfcFtry_LockServer stdcall uses ebx esi edi,fLock ;invoke MessageBox, 0,'myIntrfcFtry_LockServer',0, MB_OK cmp [fLock],0 je .freeLk invoke InterlockedIncrement,lockCount xor eax,eax ret .freeLk: invoke InterlockedDecrement,lockCount xor eax,eax ret endp ;---------------------------------------------------------------------------------------------------------- ;--------------Methods of myInterface------------------------------------------------------------ ;---------------------------------------------------------------------------------------------------------- proc myInterface_QueryInterface stdcall uses ebx esi edi,IntrfcObjAddress,riid,ppv ;invoke MessageBox, 0,'QueryInterface',0, MB_OK cmp [ppv],0 je .emptyPointer mov edi,[ppv] mov dword[edi],0 stdcall compareGUIDs,IID_IUnknown,[riid] cmp eax,0 je .validIntrfc stdcall compareGUIDs,IID_myInterface,[riid] cmp eax,0 jne .noInterface .validIntrfc: mov eax,myInterfaceObj mov dword[edi],eax stdcall myInterface_AddRef,eax xor eax,eax jmp .ret__QueryInterface .emptyPointer: mov eax,0x80004003 ;E_POINTER jmp .ret__QueryInterface .noInterface: mov eax,0x80004002;E_NOINTERFACE .ret__QueryInterface: ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_AddRef stdcall uses ebx esi edi,IntrfcObjAddress ;inc [MyObjCount] ;invoke MessageBox, 0,'AddRef',0, MB_OK mov edi,dword[IntrfcObjAddress] add edi,4 invoke InterlockedIncrement,edi mov eax,dword[edi] ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_Release stdcall uses ebx esi edi,IntrfcObjAddress ;invoke MessageBox, 0,'Release',0, MB_OK mov edi,dword[IntrfcObjAddress] add edi,4 ;stdcall ValueToHxDcmlStrng,edi,1 invoke InterlockedDecrement,edi cmp dword[edi],0 jne .returnRelease .delObjct: ;***need to delete the object here if object was allocated memory from heap*** invoke InterlockedDecrement,MyObjCount; .returnRelease: mov eax,dword[edi] ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_GetErrorMsgBox stdcall uses ebx esi edi,IntrfcObjAddress ;invoke MessageBox, 0,'GetErrorMsgBox',0, MB_OK lea eax,[myError] lea edx,[myMSGBOXHead] invoke MessageBox, 0,eax,edx, MB_OK ret endp ;---------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- proc myInterface_GetMsgBox stdcall uses ebx esi edi,IntrfcObjAddress ;invoke MessageBox, 0,'GetMsgBox',0, MB_OK lea eax,[mytext] lea edx,[myMSGBOXHead] invoke MessageBox, 0,eax,edx, MB_OK ret endp ;---------------------------------------------------------------------------------------------------------- ;--------------------------compareGUIDs------------------------------------------------------------------ proc compareGUIDs stdcall uses ebx esi edi,localGUID,outsideGUID mov edi,[localGUID] mov esi,[outsideGUID] cld cmpsd jne .notIdentical cmpsw jne .notIdentical cmpsw jne .notIdentical mov ecx,8 repe cmpsb jne .notIdentical mov eax,0 ret .notIdentical: mov eax,1 ret endp ;========================================================================================================== ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.idata' import data readable ;======================================================================================================= library kernel32,'kernel32.dll',\ user32,'USER32.DLL',\ ADVAPI32,'ADVAPI32.DLL' include 'api/advapi32.inc' include 'api/kernel32.inc' include 'api/USER32.inc' ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.edata' export data readable ;======================================================================================================= export 'dlltest2.dll',\ DllGetClassObject,'DllGetClassObject',\ DllCanUnloadNow,'DllCanUnloadNow' ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.reloc' fixups data readable discardable ;======================================================================================================= if $=$$ dd 0,8 ; if there are no fixups, generate dummy entry end if ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ This is the test programme Code: format PE GUI 4.0 entry start include 'WIN32AX.inc' include 'testREGRc.inc' ;include 'DxInclds/objbase.inc' ;include 'custmFnc/win32Strfunc.inc' struct GUID Data1 dd ? Data2 dw ? Data3 dw ? Data4 db 8 dup(?) ends interface IclassFactory,\ QueryInterface,\ AddRef,\ Release,\ CreateInstance,\ LockServer interface MYINTERFACE,\ QueryInterface,\ AddRef,\ Release,\ GetMsgBox,\ GetErrorMsgBox ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.data' data readable ;======================================================================================================== CLSCTX_INPROC_SERVER = 0x1 COINIT_APARTMENTTHREADED = 0x2 COINIT_DISABLE_OLE1DDE = 0x4 MenuName = IDR_MAINMENU ClassName db 'MNSwndClass',0 AppName db 'window Ideal',0 ButtonClassName db 'BUTTON',0 ButtonText1 db 'Get ErrorTX',0 ButtonText2 db 'Get TX',0 ;------------------error texts--------------------------------------- ErrTxt1 db 'Registering window class Failed',0 ErrTxt2 db 'Fail to create a window using MNSwndClass',0 ErrTxt3 db 'Error in the message loop of the window',0 ErrTxt4 db 'COM library could not initialized',0 ErrTxt5 db 'Myclass Factory object could not created',0 ErrMsgBoxCaption db 'Program Error',0 WindowProcErrTxt1 db 'Error in creation of Child control',0 WindowProcErrTxt2 db 'cocreate failed',0 ;WindowProcErrTxt3 db 'Creat process failed',0 ;WindowProcErrTxt4 db 'Error reading',0 DLLRegError db 'Error in creation Registry Entries',0 myMSGBOXHead db 'RegCreate',0 myInterfaceFactoryGUID_regText db 'Software\\Classes\\CLSID\\{4519ebca-1469-4fab-8848-5eaf4bfbbe39}',0 CLSIDRegkeyText db 'Software\\Classes\\CLSID',0 MyIntfcGUIDText db '{4519ebca-1469-4fab-8848-5eaf4bfbbe39}',0 InprocServer32Text db 'InprocServer32',0 ThreadingModelText db 'ThreadingModel',0 bothText db 'both',0 dllName db 'dlltest3.DLL',0 CLSID_myInterface GUID 0x4519ebca,0x1469,0x4fab,<0x88,0x48,0x5e,0xaf,0x4b,0xfb,0xbe,0x39> IID_IClassFactory GUID 0x00000001,0x0000,0x0000,<0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46> IID_myInterface GUID 0x7218f11d,0x86ef,0x4344,<0x8e,0x96,0x60,0x31,0x94,0x21,0xf6,0xc6> ;CLSID_myInterfaceFactory_string db '4519ebca-1469-4fab-8848-5eaf4bfbbe39',0 ;IID_myInterfaceFactory_string db 'e1828e00-fa2d-41b5-8cf9-7d22d94c5638',0 ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.?data' data readable writeable ;======================================================================================================== myFactoryObj IclassFactory myIntrFcObj MYINTERFACE msg MSG wc WNDCLASSEX cmdLine dd ? hInst dd ? hwnd dd ? ;hEdit dd ? hwndButton1 dd 0 hwndButton2 dd 0 hwndButton3 dd 0 hwndButton4 dd 0 DllHinst dd 0 hKey dd 0 hKey2 dd 0 disposition dd 0 modulename db 1024 dup(?) ;////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////////////////////////// section '.code' code readable executable ;===================================================================================================== start: invoke GetModuleHandle,0 mov [hInst],eax invoke GetCommandLine mov [cmdLine],eax stdcall WinMain,[hInst],NULL,[cmdLine],SW_SHOWDEFAULT stdcall DllUnregisterServer invoke ExitProcess,eax ;-----------------------WinMain Procedure------------------------------------------------------------- proc WinMain hInstance:DWORD,hPrvinstance:DWORD,commandLine:DWORD,cmdshow:DWORD ;stdcall GUIDToStrng,CLSID_myInterfaceFactory,1 stdcall DllRegisterServer invoke CoInitializeEx,NULL,COINIT_APARTMENTTHREADED + COINIT_DISABLE_OLE1DDE cmp eax,0 jne err4 invoke CoCreateInstance,CLSID_myInterface,0,CLSCTX_INPROC_SERVER,IID_myInterface,myIntrFcObj ;invoke CoGetClassObject,CLSID_myInterface, CLSCTX_INPROC_SERVER, 0, IID_IClassFactory,myFactoryObj; cmp eax,0 jne err5 ;cominvk myFactoryObj,CreateInstance,0, IID_myInterface, myIntrFcObj ;cmp eax,0 ;jne err5 ;invoke MessageBox, 0,'success',ErrMsgBoxCaption, MB_OK ;----declare window struct---------------------------- push [hInst] pop [wc.hInstance] mov [wc.cbSize], sizeof.WNDCLASSEX mov [wc.style], CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc],WindowProc xor eax,eax mov [wc.cbClsExtra],eax mov [wc.cbWndExtra],eax mov [wc.hbrBackground], COLOR_APPWORKSPACE mov [wc.lpszMenuName], MenuName mov [wc.lpszClassName],ClassName invoke LoadIcon, NULL, IDI_APPLICATION mov [wc.hIcon], eax mov [wc.hIconSm], eax invoke LoadCursor, NULL, IDC_ARROW mov [wc.hCursor], eax ;----Registering window class---------- invoke RegisterClassEx, wc or eax,eax jz err1;end_loop ;----Create a window------------------- invoke CreateWindowEx,WS_EX_CLIENTEDGE,ClassName,AppName,WS_VISIBLE+WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX,CW_USEDEFAULT,CW_USEDEFAULT,200,300,0,0,[wc.hInstance],0 mov [hwnd],eax or eax,eax jz err2;end_loop ;-----Show window---------------------- invoke ShowWindow, [hwnd],[cmdshow] ;-----Update window--------------------- invoke UpdateWindow, [hwnd] ;-----message loop---------------------- msg_loop: invoke GetMessage,msg,NULL,0,0 cmp eax,0 je end_loop jb err3 invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop ;-------------Errors-------------------------------------------- err1: invoke MessageBox, 0,ErrTxt1,ErrMsgBoxCaption, MB_OK jmp end_loop err2: invoke MessageBox, 0,ErrTxt2,ErrMsgBoxCaption, MB_OK jmp end_loop err3: invoke MessageBox, 0,ErrTxt3,ErrMsgBoxCaption, MB_OK jmp end_loop err4: invoke MessageBox, 0,ErrTxt4,ErrMsgBoxCaption, MB_OK jmp end_loop err5: ;stdcall ValueToHxDcmlStrng,eax,1 invoke MessageBox, 0,ErrTxt5,ErrMsgBoxCaption, MB_OK ;jmp end_loop ;--------------------------------------------------------------- end_loop: stdcall CleanALL invoke CoUninitialize mov eax,[msg.wParam] ret endp ;---------------------------------------------------------------------------------------------------------- ;------------------------------------window procedure------------------------------------------------------ proc WindowProc hwnds,umsg:DWORD,wParam:DWORD,iParam:DWORD push ebx esi edi cmp [umsg],WM_DESTROY je wmdestroy cmp [umsg],WM_COMMAND je commands cmp [umsg],WM_CREATE je cerate defwndproc: invoke DefWindowProc,[hwnds],[umsg],[wParam],[iParam] jmp finish commands: cmp [iParam],0 jne .otherCommands mov eax,[wParam] cmp ax,IDM_EXIT je wmdestroy cmp ax,IDM_HELP je .helpMSG jmp finish .helpMSG: jmp finish .otherCommands: cmp [wParam], BN_CLICKED shl 16 +IDB_BUTTON1 je GeterrTxt ;DllRegisterServer cmp [wParam], BN_CLICKED shl 16 +IDB_BUTTON2 je GetTextD ;DllUnregisterServer jmp finish GeterrTxt: cominvk myIntrFcObj,GetErrorMsgBox jmp finish GetTextD: cominvk myIntrFcObj,GetMsgBox jmp finish cerate: invoke CreateWindowEx,0,ButtonClassName,ButtonText1,WS_CHILD + WS_VISIBLE + BS_DEFPUSHBUTTON,50,50,100,40,[hwnds],IDB_BUTTON1,[hInst],0 cmp eax,0 je WindowProc_error1 mov [hwndButton1],eax invoke CreateWindowEx,0,ButtonClassName,ButtonText2,WS_CHILD + WS_VISIBLE + BS_DEFPUSHBUTTON,50,150,100,40,[hwnds],IDB_BUTTON2,[hInst],0 cmp eax,0 je WindowProc_error1 mov [hwndButton2],eax jmp finish ;-------------Errors------------------------------- WindowProc_error1: invoke MessageBox, 0,WindowProcErrTxt1,ErrMsgBoxCaption, MB_OK jmp finish WindowProc_error2: invoke MessageBox, 0,WindowProcErrTxt2,ErrMsgBoxCaption, MB_OK jmp finish ;WindowProc_error3: ;invoke MessageBox, 0,WindowProcErrTxt3,ErrMsgBoxCaption, MB_OK ;jmp finish ;WindowProc_error4: ;invoke MessageBox, 0,WindowProcErrTxt4,ErrMsgBoxCaption, MB_OK ;jmp commands.terminateProcess ;-------------------------------------------------- wmdestroy: invoke PostQuitMessage,0 xor eax,eax finish: pop edi esi ebx ret endp ;--------------------------------------------------------------------------------------------------------- ;---------------------DllRegisterServer------------------------------------------------------------------ proc DllRegisterServer stdcall uses ebx esi edi ;1).Create a subkey whose name is the ascii string that represents our object's GUID ;so invoke RegCreateKeyEx,HKEY_LOCAL_MACHINE, myInterfaceFactoryGUID_regText, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, hKey, disposition cmp eax,0 jne .err1 ;2).Create an "InprocServer32" key whose default value is the path of this DLL invoke RegCreateKeyEx,[hKey],InprocServer32Text, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0,hKey2, disposition cmp eax,0 jne .err2 invoke GetModuleFileName,[DllHinst],modulename,1024 cmp eax,0 je .err3 mov ecx,12 sub eax,10 mov edi,modulename add edi,eax dec edi add eax,ecx mov esi,dllName cld rep movsb invoke RegSetValueEx,[hKey2], 0, 0, REG_SZ, modulename, eax cmp eax,0 jne .err3 ;3).Create a "ThreadingModel" value set to the string "both" invoke RegSetValueEx,[hKey2], ThreadingModelText, 0, REG_SZ,bothText,5 cmp eax,0 jne .err3 invoke RegCloseKey,[hKey2] invoke RegCloseKey,[hKey] invoke MessageBox,0, 'DLL registered- OK',0, MB_OK; ret .err3: invoke RegDeleteKey,[hKey2],InprocServer32Text invoke RegCloseKey,[hKey2] .err2: invoke RegDeleteKey,[hKey],myInterfaceFactoryGUID_regText invoke RegCloseKey,[hKey] .err1: invoke MessageBox,0, DLLRegError,myMSGBOXHead, MB_OK+MB_ICONEXCLAMATION; ret endp ;---------------------CleanALL------------------------------------------------------------------ proc CleanALL stdcall uses ebx esi edi cmp [myIntrFcObj],0 je @f cominvk myIntrFcObj, Release mov [myIntrFcObj],0 @@: xor eax,eax ret endp ;--------------------------------------------------------------------------------------------------------- ;---------------------DllUnregisterServer------------------------------------------------------------------ proc DllUnregisterServer stdcall uses ebx esi edi invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,CLSIDRegkeyText, 0, KEY_WRITE,hKey cmp eax,0 jne .retDLLUnreg invoke RegOpenKeyEx,[hKey], MyIntfcGUIDText, 0, KEY_ALL_ACCESS,hKey2 cmp eax,0 jne .closeKey invoke RegDeleteKey,[hKey2],InprocServer32Text invoke RegCloseKey,[hKey2] invoke RegDeleteKey,[hKey],MyIntfcGUIDText .closeKey: invoke RegCloseKey,[hKey] .retDLLUnreg: invoke MessageBox,0, 'DLL Un-registered -OK',0, MB_OK; xor eax,eax ret endp ;========================================================================================================== ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;////////////////////////////////////////////////////////// ;////////////////////////////////////////////////////////////////////////////////////////////////////// section '.idata' import data readable ;======================================================================================================= library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ comctl32,'comctl32.dll',\ ADVAPI32,'ADVAPI32.DLL',\ Ole32,'ole32.dll' include 'api/advapi32.inc' include 'api/comctl32.inc' include 'api/kernel32.inc' include 'api/USER32.inc' ;include 'DxInclds/Api/ole32.inc' import Ole32,\ CoInitializeEx,'CoInitializeEx',\ CoCreateInstance,'CoCreateInstance',\ CoUninitialize,'CoUninitialize' ;======================================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ If anything wrong please post a reply
|
|||||||||||
25 Apr 2023, 10:58 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.