Page 2 of 2 FirstFirst 12
Results 41 to 48 of 48

Thread: how to call a vb6 standalone exe module function from c/c++ new thread-reg

  1. #41
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,746

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    make a stdcall standard dll function like :
    Code:
    function sum(a as long,b as long) as long
    sum=a+b
    'or dim XML AS XMLHTTP
    end function
    YOU NEED load msvbvm in function like this:

    Code:
    function sum(a as long,b as long) as long
    
    
    'initialize STA and context in threadproc of new thread created using CreateThread API
    
    CreateIExprSrvObj 0&, 4&, 0&
    CoInitialize ByVal 0&
    
    hModule = GetModuleHandle(0) //get module instance of vb6 standard exe in which the dll is loaded
    
    ' Get VBHeader as follows
    
    ' // Get e_lfanew
    GetMem4 ByVal hModule + &H3C, ptr
    ' // Get AddressOfEntryPoint
    GetMem4 ByVal ptr + &H28 + hModule, ptr
    ' // Get VBHeader
    GetMem4 ByVal ptr + hModule + 1, pVBHeader
    
    
    
    
    
    pNewHeader=CreateVBHeaderCopy
    
    If pVBHeader Then
    VBDllGetClassObject hModule , 0& , pNewHeader, aiid, tGuid, 0&
    End If
    
    sum=a+b
    'or dim XML AS XMLHTTP
    end function

  2. #42

    Thread Starter
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    Quote Originally Posted by xiaoyao View Post
    make a stdcall standard dll function like :
    Code:
    function sum(a as long,b as long) as long
    sum=a+b
    'or dim XML AS XMLHTTP
    end function
    YOU NEED load msvbvm in function like this:

    Code:
    function sum(a as long,b as long) as long
    
    
    'initialize STA and context in threadproc of new thread created using CreateThread API
    
    CreateIExprSrvObj 0&, 4&, 0&
    CoInitialize ByVal 0&
    
    hModule = GetModuleHandle(0) //get module instance of vb6 standard exe in which the dll is loaded
    
    ' Get VBHeader as follows
    
    ' // Get e_lfanew
    GetMem4 ByVal hModule + &H3C, ptr
    ' // Get AddressOfEntryPoint
    GetMem4 ByVal ptr + &H28 + hModule, ptr
    ' // Get VBHeader
    GetMem4 ByVal ptr + hModule + 1, pVBHeader
    
    
    
    
    
    pNewHeader=CreateVBHeaderCopy
    
    If pVBHeader Then
    VBDllGetClassObject hModule , 0& , pNewHeader, aiid, tGuid, 0&
    End If
    
    sum=a+b
    'or dim XML AS XMLHTTP
    end function
    Hello Xiaoyao,

    For the above code which is already there in vbcallback1 dll I want an equivalent code in c/c++ like
    1. getting the vbheader structure of the vbstd exe thru its GetModuleHandle(0) and
    2. then creating a copy of the same and calling
    3. calling vbdllgetclassobject

    The above 3 things are crucial for which I request Trick for c/c++ code.

    Thanks

  3. #43
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,746

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    get vbheader,in exe and standard dll,activex dll,activex exe,Compiled into different PE formats, the method of obtaining may be different

  4. #44

    Thread Starter
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    Quote Originally Posted by xiaoyao View Post
    get vbheader,in exe and standard dll,activex dll,activex exe,Compiled into different PE formats, the method of obtaining may be different
    Hello Xiaoyao,

    I understand that but I am trying to implement the method in c/c++.

    Thanks

  5. #45

    Thread Starter
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    Hello Trick,

    In the following code cbdll.cpp of c/c++ dll:

    hMod = LoadLibrary ("shlwapi.dll");
    if (hMod != NULL)
    {
    fSHCreateThread = (BOOL (WINAPI *)( LPTHREAD_START_ROUTINE , VOID *, DWORD , LPTHREAD_START_ROUTINE)) GetProcAddress (hMod, "SHCreateThread");
    fInititialize(0);
    if (!fSHCreateThread((LPTHREAD_START_ROUTINE)ThreadProc, pData, CTF_COINIT_STA, (LPTHREAD_START_ROUTINE)Unmarshal)) {
    pData->pStm->Release();
    GlobalFree(pData);
    hr = E_FAIL;
    }

    return hr;
    }

    when Initialize() exported function of vbcallback1 actx dll is called using fInititialize(0);
    tls is allocated using tlsalloc() and at that index returned by tlsalloc() in the Threadproc(of modMultiThreading2.bas) the pData is stored using tlssetvalue() when we call InitCurrentThreadAndCallFunction exported function using fInitCurrentThreadAndCallFunction in ThreadProc of c/c++ code.

    I can use tlsalloc,tlssetvalue and tlsgetvalue in c/c++ dll.But other tasks left are

    1. How to get vbheader of vbstdexe in our c/c++ code.
    2. Creating a copy of the obtained vbheader.
    3. Calling vbdllgetclassobject using this header.


    Can you provide code in c/c++ dll for the above 1,2 and 3 tasks so that I can implement exported Initialize,Uninitialize and InitCurrentThreadandCallFunction functions using c/c++.

    Thanks.

  6. #46

    Thread Starter
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    Hello Trick,

    DllGetClassObject is used by c/c++ and VBDllGetClassObject is used by vb6 exe.

    But when new thread of c/c++ std dll is used in vb6 std exe, c/c++ dll should use VBDllGetClassObject with copy of vbheader of stdexe as input because it is running in the context of vb6 std exe.
    Can you show me a simple example of the same using c/c++.

    Thanks

  7. #47

    Thread Starter
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    Hello Trick,

    In ModifyVBHeader() of modVBVst2X.bas of vbvst you mentioned the following:

    ' // There is no static vars in this module so we don't touch them

    Can you show me an example where static vars are there and how to handle them.

    How to handle the same case when we use this in c/c++.

    Thanks

  8. #48

    Thread Starter
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: how to call a vb6 standalone exe module function from c/c++ new thread-reg

    Hello Trick,

    Finally I made getting vbheader and obtaining its copy and calling vbdllgetclassobject with this new vbheader copy in new thread for calling
    callback of vb std exe with c/c++ std dll code as follows:


    Code:
    // cdll.cpp : Defines the entry point for the DLL application.
    //
    
    #include "stdafx.h"
    
    #include <Windows.h>
    #include <ole2.h>
    #include <objbase.h>
    
    #include <atlbase.h>
    
    #include <stdio.h>
    
    
    typedef long (__stdcall *pVBDllGetClassObject) (HINSTANCE Unknown1,long Unknown2,PVOID Unknown3_vbheader,REFCLSID, REFIID, LPVOID*);
    pVBDllGetClassObject pv1;
    
    HANDLE vbHandle;
    HANDLE msvbvmvbHandle;
    IDispatch *IDisp=NULL;
    
    
    HINSTANCE hMod;
    
    
    
    
    DWORD d;
    //declare a function pointer to call a funciton
    		  // that returns an int 
    int ( __stdcall *lpVBFunction ) (int,int);
    long glpfnTest;
    
    
    
    typedef long (WINAPI pCreateIExprSrvObj)(long p1_0, long p2_4, long p3_0);
    long (WINAPI *fCreateIExprSrvObj)(long p1_0, long p2_4, long p3_0);
    
    
    
    
    
    struct TThreadData {
    	LPVOID pfn;
    	LONG l1;
    	LONG l2;
    };
    
    
    TThreadData *pData;
    long (WINAPI *pfn1)(long,long);
    
    BOOL WINAPI DllMain(HINSTANCE, DWORD,LPVOID){
    	return TRUE;
    }
    
    
    
    /////////////////////////createvbheadercopy implementation///////////////////////////////////////////////
    
    
    
    int * pVBHeader;
    HANDLE hHeadersHeap;
    
    
    int* CreateVBHeaderCopy(int *vbHeader) 
    {
        int *pHeader;         
        int *pOldProjInfo;    
        int *pProjInfo;       
        int *pObjTable;       
        int *pOldObjTable;    
        int lDifference;     
        int lIndex;          
        int *pNames[4];
        int lModulesCount;   
        int *pDescriptors;    
        int *pOldDesc;        
        int *pVarBlock;       
        int lSizeOfHeaders;  
        int *ptr;
    
         // Get size of all headers
        lSizeOfHeaders = 0x6A + 0x23C + 0x54 + 0xC + 4;
        
        pOldProjInfo=(vbHeader + 0x30);
     
        pOldObjTable= pOldProjInfo + 0x4;
    
        pOldDesc = pOldObjTable + 0x30;
    
        lModulesCount= 3;//*(pOldObjTable + 0x2A);//hardcoded by counting the module count in vbstrd exe (form1,form2,module1) since I unable to get this
    	hHeadersHeap = HeapCreate(0, 0, 65536);
        
        lSizeOfHeaders = lSizeOfHeaders + 0x30 * lModulesCount;
        
         // Allocate memory for header
    
    	
    		
            pHeader = (int*)HeapAlloc(hHeadersHeap, HEAP_ZERO_MEMORY, lSizeOfHeaders);
    	
            
        
        pHeader = pHeader + 4;
        
        lDifference = (pHeader - pVBHeader);
        
       
    	pHeader=pVBHeader+0x6A;
    
    	pNames[0]=(pVBHeader + 0x58+0x10);
    
        for (lIndex = 0;lIndex<=3;lIndex++)
            pNames[lIndex] = pNames[lIndex] - lDifference;
      
    	ptr=pHeader + 0x58;
        ptr=pNames[0]+0x10;
          // In order to keep global variables
         // Change the VbPublicObjectDescriptor.lpPublicBytes, VbPublicObjectDescriptor.lpStaticBytes
        pProjInfo = (pHeader + 0x6A);
         pProjInfo=pOldProjInfo+0x23C;
           // Update on VBHeader
        pProjInfo=  (pHeader + 0x30);
    
         // Create copy of Object table
        pObjTable = pProjInfo + 0x23C;
    
       	pObjTable= pOldObjTable+0x54;
     
        
    	// Update
        pObjTable = pProjInfo + 0x4;
    
        // Allocate descriptors
        pDescriptors = pObjTable + 0x54;
    
     	pDescriptors= pOldDesc+ lModulesCount * 0x30;
     
    	// Update
        pDescriptors=pObjTable + 0x30;
    
    
        // Allocate variables block
        pVarBlock = pDescriptors + lModulesCount * 0x30;
    
        for (lIndex = 0; lIndex++;lIndex<=lModulesCount - 1)
    	{
             // Zero number of public and local variables
            pVarBlock=pDescriptors + lIndex * 0x30 + 0x8;
            ptr=(pDescriptors + lIndex * 0x30 + 0xC);
    
    }
          return pHeader;
        
    
    
    }
    
    
    
    ////////////////////////////////////////////////////////////////////////
    
    
    
    
    
    ULONG WINAPI ThreadProc(TThreadData *pData) {
    
    
    		fCreateIExprSrvObj(0,4,0);// for enabling API calls in new thread
    
    
    /////////////////////////////////////get vbheader ofvb6 std exe//////////////////////////////////////////
        int *cvbHeader;
    
    	
    	int ptr=0;
    	int lvbHeader;
    	
    	char s[10];
    
    	ULONG lOldProtect;
    	msvbvmvbHandle=LoadLibrary("msvbvm60.dll");
    
    	vbHandle = GetModuleHandle(NULL);//app instance of vbstd exe
    	
    	ptr=*(int*)((int)vbHandle + 0x3C);
    
    	sprintf(s,"vbHandle+3C %d",ptr);
    	
    
    
    	ptr=*(int*)(ptr + 0x28 + (int)vbHandle);
    	sprintf(s,"vbHandle+28 %d",ptr);
    
    
    
    	lvbHeader=*(int*)(ptr + (int)vbHandle+1);
    //	ptr=*(int*)(ptr+1);
        sprintf(s,"vbHeader vc %d",lvbHeader);
    
       VirtualProtect(&lvbHeader, 0x64, PAGE_EXECUTE_READWRITE, &lOldProtect);
        // Remove Sub Main
        ptr = lvbHeader + 0x2C;
    
        int *ptr2=&ptr;
    
        ptr2=NULL;
        VirtualProtect(&lvbHeader, 0x64, lOldProtect, 0);
    
    
    
    
    
    
    
    
    ///////////////////getcopy of vbheader//////////////////////////////
    
    
       cvbHeader=CreateVBHeaderCopy(&lvbHeader);
    
    
    ///get VBDllGetClassObject pointer from msvbvm60.dll
    
         pv1=(pVBDllGetClassObject)GetProcAddress((struct HINSTANCE__ *)msvbvmvbHandle, "VBDllGetClassObject");
    
    	try
    	{
    	pv1((struct HINSTANCE__ *)vbHandle,0, cvbHeader,clsid, IID_IDispatch, (LPVOID *)&IDisp);//IID_IClassFactory, (LPVOID *)&pIFactory);//run VBDllGetClassObject with new vbheader
    	}
        catch(...)
    	{
    	
    	}
     
    
    
    	    pfn1=(long (WINAPI *)(long,long))pData->pfn;	
                (*pfn1)(pData->l1 , pData->l2);//crashes here when we try to call vbstdexe callback
    	
    
    	
    
    	GlobalFree(pData);
    
    	return 0;
    
    }
    
    
    
    extern "C" HRESULT WINAPI CreateThreadAndCallback(LPVOID pfn, LONG l1, LONG l2) {
    	HRESULT hr = S_OK;
    	pData = (TThreadData*)GlobalAlloc(GMEM_ZEROINIT, sizeof(TThreadData));
    
    	if (!pData)
    		return E_OUTOFMEMORY;
    
    	pData->pfn = pfn;
    	pData->l1 = l1;
    	pData->l2 = l2;
    
    
       
    hMod = LoadLibrary ("msvbvm60.dll"); 
     if (hMod != NULL) 
      
     fCreateIExprSrvObj = (long (WINAPI *)(long , long , long ))GetProcAddress (hMod, "CreateIExprSrvObj");
    
    
    	if (!CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadProc, pData, 0,&d)) {
    		
    		GlobalFree(pData);
    		hr = E_FAIL;
    	}
    
    	return hr;
     
    }





    I am able to get vbheader of vbstd exe and get copy of new vbheader in c/c++.

    Now when I call callback function it crashes.
    Please correct me where I am doing wrong so that the code works fine.


    Complete project source code which includes vbstd exe project and cbdll(c/c++ std dll code) attached in cb folder in cb.zip.
    .def file has to be incuded in cbdll c/c++ std dll project to export CreateThreadAndCallback as follows:

    cbdll.def
    Code:
    EXPORTS
              CreateThreadAndCallback
    Thanks
    Attached Files Attached Files
    Last edited by smkperu; Mar 18th, 2022 at 05:31 AM.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width