Thankyou for the awesome detailed advanced explanation.
I was asking for a simple vb6 multithreading working example in the sense it is
1. A simple dll code in c/c++ which I can compile and generate dll
2 Which can be used by any vb6 std exe application for creating a new thread.
For me it is enough with any particular version of vb6 msvbvm60.dll (need not cover all versions) so that I can understand Sub Main suppression ,vbaaptoffset,how to create and initialize a new thread properly for which I am thankful to you.
Do you have troubles to translate from VB6 to C++?
Hello The Trick,
I have gone through the link you provided.Everything is done by modMultiThreading.bas module.It is not so easy to translate the module into c/c++ since it is so advanced that you are using many undocumented apis in it.You know how much I struggled to get rtcMsgBox api work which could not have happened without your awesome support.
I could not even understand what JSVenu suggested me for avoiding additional vb actx dll in my first post regarding undocumented APIs.
So I request you to provide me a simple c/c++ dll like I requested FireHacker containing same functionality as modMultiThreading2.bas for which I will be happy.
Can you show how to use the GetMem4 and VBDllGetClassObject APIs of msvbvm60.dll properly without compilation errors
and use the dll to multithread in vb6.project link is attached.
You have to use specific type instead of PVOID for pointers when using GetMem4 or RtlMoveMemory.
All the errors are related to GetMem4 api call of msvbvm60.dll.
You also have to create a new copy of vbheader for initializing runtime in vb6 standard exe which is CreateVBheadercopy function in modmultithreading module of Trick's code.
You have to use specific type instead of PVOID for pointers when using GetMem4 or RtlMoveMemory.
All the errors are related to GetMem4 api call of msvbvm60.dll.
You also have to create a new copy of vbheader for initializing runtime in vb6 standard exe which is CreateVBheadercopy function in modmultithreading module of Trick's code.
regards,
JSVenu
Hello JSVenu,
Ok I have to copy vbheader and send it as input to vbdllgetclassobject api.
I tried to use specific type such as int * or long * in place of PVOID as JSVenu
suggested but still I get compilation errors.
Do you have troubles to translate from VB6 to C++?
Hello The Trick,
I think I am missing something in the usage of GetMemX API of msvbvm60.dll.
Can you show me an example of how to use GetMem4 API of msvbvm60.dll in c/c++ in a proper way.
You have to use specific type instead of PVOID for pointers when using GetMem4 or RtlMoveMemory.
All the errors are related to GetMem4 api call of msvbvm60.dll.
You also have to create a new copy of vbheader for initializing runtime in vb6 standard exe which is CreateVBheadercopy function in modmultithreading module of Trick's code.
regards,
JSVenu
Dear smkperu,
Replace your export function initruntime with the following code in the project and then your project builds without errors:
Code:
// This is an example of an exported function.
VBSIM1_API int initvbruntime(void)
{
INT vbDLLPointer;
PVOID VBLIBPointerThunRTMain;
PVOID VBLIBPointerVDGCO;
HANDLE VBThread;
PVOID VBLIBPointerDGCO;
PVOID ptr;
CLSID clsid;
HRESULT hr,hr1;
ULONG lOldProtect;
msvbvmvbHandle=LoadLibrary("msvbvm60.dll");
pRtlMoveMemory=(pGetMem4)GetProcAddress((struct HINSTANCE__ *)msvbvmvbHandle, "GetMem4");
vbHandle = GetModuleHandle(NULL);//LoadLibrary(DLLName);
//VBLIBPointerDGCO = GetProcAddress(vbHandle,"DllGetClassObject");
/* Load the VB DLL */
//vbDLLPointer = *(int*)((int)VBLIBPointerDGCO + 2); /* Get the Project Pointer */
// Get e_lfanew
pRtlMoveMemory((int*)((int)vbHandle + 0x3C),ptr);
//GetMem4 ByVal hModule + &H3C, ptr
// Get AddressOfEntryPoint
// pRtlMoveMemory(*(int*)((int)ptr) + 0x28 + vbHandle,ptr);
ptr=(int*)((int*)ptr + 0x28 + (int)vbHandle);
//GetMem4 ByVal ptr + &H28 + hModule, ptr
// Get VBHeader
pRtlMoveMemory((int*)ptr + (int)vbHandle + 1,VBLIBPointerDGCO);
// Allow to write to that page
VirtualProtect(VBLIBPointerDGCO, 0x64, PAGE_EXECUTE_READWRITE, &lOldProtect);
// 'Remove Sub Main
//ptr = mpVbHeader + &H2C
//GetMem4 0&, ByVal ptr ' 'AddressOf mymain
pRtlMoveMemory((int*)((int)VBLIBPointerDGCO + 0x2C),0);
VirtualProtect(VBLIBPointerDGCO, 0x64, lOldProtect, 0);
//GetMem4 ByVal ptr + hModule + 1, GetVBHeader
//msvbvmvbHandle=LoadLibrary("msvbvm60.dll");
VBLIBPointerThunRTMain = GetProcAddress((struct HINSTANCE__ *)msvbvmvbHandle,"ThunRTMain"); /* Get the VB Runtime Initialization Pointer */
pv1=(pVBDllGetClassObject)GetProcAddress((struct HINSTANCE__ *)msvbvmvbHandle, "VBDllGetClassObject");
try
{
hr1= pv1((struct HINSTANCE__ *)vbHandle,0, VBLIBPointerDGCO,clsid, IID_IDispatch, (LPVOID *)&IDisp);//IID_IClassFactory, (LPVOID *)&pIFactory);
}
catch(...)
{
if( FAILED( hr1 ) )
{
MessageBox(0,"\nDllGetClassObject failed",0,0);
}
}
return 42;
}
You shouldn't use GetMem4 and another memory access functions because C/C++ already has pointers features. I don't know how to explain you all because you have the troubles with this elementary things. When you begin with threading you'll have much more troubles/deadlocks/etc.
You shouldn't use GetMem4 and another memory access functions because C/C++ already has pointers features.
And this is a very polite way of saying it :-))
When I first saw the code my WТF-per-minute metric sky-rocketed and I immediately jotted a reply with a lot of WТFs, LOLs and smilies but then just discarded it when my head cooled down.
Everyone has been there. . . Starting from multi-threading in a public forum can be a humiliating experience so patience (or silence) is a virtue here.
I don't know how to explain you all because you have the troubles with this elementary things. When you begin with threading you'll have much more troubles/deadlocks/etc.
Actually, I disagree. The wizardry of making multi-threading work in VB6 is way and I mean way over my head. It looks like something God would write. It's just incomprehensible to me and other mere mortals. However, I have zero problems with nuances of writing multi-threaded applications like deadlocks and synchronization.
I think the real problem here is that people are out there in the world seeing what others are doing in other languages. I mean take Python. It's dead simple to write multi-threaded code in that language. Then you have languages like JavaScript make it easy to write asynchronous code. And of course .Net makes it very easy to write all kinds of multi-threaded and asynchronous code. Programmers are out there seeing these things and think they can just come to VB6 and do the same thing. VB6 is 20+ years old. You can't expect to do these things with the same ease. You're going to have to get your hands dirty by getting down into the plumbing.
A lot of people think I hate VB6 because of the things I say especially with regards to how it compares to .Net and other modern languages. No, it's not hate. Threads like this are the reason why. You're going to really struggle in VB6 if you're trying to do stuff like this without a low level understanding of COM, VB6, it's runtime along with other low levels stuff like pointers and memory allocation. Like you really have to know what you're doing.
Anyways, don't mind me. Just felt like ranting a little bit. Kinda tipsy right now.
It just pains me so much to see developers way over their heads like this for no reason. Would it hurt so bad to give VB.Net a try where this would be easy as pie?
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
You shouldn't use GetMem4 and another memory access functions because C/C++ already has pointers features. I don't know how to explain you all because you have the troubles with this elementary things. When you begin with threading you'll have much more troubles/deadlocks/etc.
Hello The Trick,
Thankyou for the response.
Firehacker has explained about his c/c++ dll for vb6 multithreading which he gave awesome explanation.
So I tried that in c/c++ in a simple way for which you showed a link but in vb6.So I was trying to achieve atleast some part of it
in c/c++.Since I donot want to disturb you again and again I shall be happy if could provide me a simple c/c++ dll demo atleast with limited features
which exports a vbCreateThread function which can be used in vb6 std exe so that I can understand CreateIExprSrvObj,GetMem4(RtlMoveMemory),
CreateVBHeaderCopy and VBDllGetClassObject in order to improve my knowledge in vb6 as well as c/c++ for which I am indebted to you.
Niya, VB6 supports multithreading and had supported it since 1998 year. There are two types of project - ActiveX EXE and ActiveX DLL (OCX) where your code can live in the different ST-apartments. This is the quite famous information but most of the VB6-programmers i guess never read the official help. Most of the multithreading task can be solved within VB6 but peoples want to break rules and use unsafe things in VB6 shooting themself in the foot. I still don't understand why TS wants to use it and i won't help until i get answer because i think such tasks are related to malware coding. There is no issues if you breaks the rules when you know how things works and you can bypass some things to make the code more performanced or bypass some good restrictions. But when i see the code like above - i think this is no reason to help because there is no understanding at all and it will only get worse.
Last edited by The trick; Jan 22nd, 2022 at 06:08 AM.
Ah well. Don't take what I wrote too seriously. I was a bit tipsy. Just kind of what I was thinking when reviewing this thread. I was just thinking out loud as it were.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Niya, VB6 supports multithreading and had supported it since 1998 year. There are two types of project - ActiveX EXE and ActiveX DLL (OCX) where your code can live in the different ST-apartments. This is the quite famous information but most of the VB6-programmers i guess never read the official help. Most of the multithreading task can be solved within VB6 but peoples want to break rules and use unsafe things in VB6 shooting themself in the foot. I still don't understand why TS wants to use it and i won't help until i get answer because i think such tasks are related to malware coding. There is no issues if you breaks the rules when you know how things works and you can bypass some things to make the code more performanced or bypass some good restrictions. But when i see the code like above - i think this is no reason to help because there is no understanding at all and it will only get worse.
Hello the Trick,
I donot know what to answer.
How can you judge me as trying to write malware or worse code.I tried to write in c/c++ the same code which you did in vb6 and
and you helped me by showing the link based on my conversation with FireHacker.Initially I did'nt even asked you for the help.
You only responded to me after which I tried and requested for help only for improvement and not anything else.
I donot bother about others who commented me since I only interacted with FireHacker ,yourself and JSVenu who really helped
me technically since my first post.
If you see the above code I am using GetModuleHandle(0) which takes instance handle of a vb6 std exe when this
dll is loaded into vb6 std exe which shows that I am considering using vb6 object instead of using msvbvm60.dll directly as you
suggested me in first post for initializing project.
How can you judge me as trying to write malware or worse code.
Because you can't explain why you need that. I suppose you want to create a malware because i know few scenarios where it's applicable, malware is one of them. Because of that most of AVs trigger on most of VB6 exacutable.
Because you can't explain why you need that. I suppose you want to create a malware because i know few scenarios where it's applicable, malware is one of them. Because of that most of AVs trigger on most of VB6 exacutable.
Ok.From what you said I understand that If we try to initialize a project by creating a vb6 Ax object it is not a malware.Other than that all other methods is malware.
This is true for vb6 Ax dll as follows:
call any vb apis exported from the same above vb ax dll;//crashes in new threads in vb6 standard exe.
So for initializing project and runtime in standard exe you showed me a vb6 link from which I wanted
I wanted to develop a c/c++ dll with export function vbruntimeincdll() so that the above scenario works without crash as follows:
vb6 standard exe:
sub ThreadProc() 'vb6 non main thread
//initialize project and runtime for this new thread using c/c++ exported dll
call any vb apis 'works fine in new threads in vb6 standard exe.
End ThreadProc
Since the above vbruntimeincdll() is a must for initializing runtime in new thread in vb6 standard exe I donot consider this as malware for which I asked a simple c/c++ dll with atleast limited features with the above vbruntimeincdll() exported function.
The proper way is to transmit the call to specified apartment. VB6 oficially supports only ST apartments. If you want break the rule - use my module. There is no need to use an external C-DLL. Why won't you use module why do you need a C dll? Just use functions InitCurrentThreadAndCallFunction/InitCurrentThreadAndCallFunctionIDEProc. This is related to callbacks from arbitrary threads.
You still can initialize runtime and project from an AX-dll. I don't know why you decided it isn't possible.
The proper way is to transmit the call to specified apartment. VB6 oficially supports only ST apartments. If you want break the rule - use my module. There is no need to use an external C-DLL. Why won't you use module why do you need a C dll? Just use functions InitCurrentThreadAndCallFunction/InitCurrentThreadAndCallFunctionIDEProc. This is related to callbacks from arbitrary threads.
You still can initialize runtime and project from an AX-dll. I don't know why you decided it isn't possible.
Hello The Trick,
Even Initializing runtime and project from an AX-dll for a vb6 standard exe would not make
callbacks from arbitrary threads work fine without using functions InitCurrentThreadAndCallFunction/InitCurrentThreadAndCallFunctionIDEProc.
This is what I was trying to do using c/c++ dll which I already mentioned in https://www.vbforums.com/showthread....=1#post5552367.
Thanks
Last edited by smkperu; Jan 24th, 2022 at 08:32 PM.
You still didn't describe, what it is you're developing (if it isn't malware).
Why is it that hard, to answer this simple question?
(you'd get a whole lot more replies, when the efforts "the regulars spend on your behalf",
will happen "for a good reason, in a scenario others can later identify - and learn from").
Give some context, man...
Olaf
Last edited by Schmidt; Jan 25th, 2022 at 05:03 AM.
From the discussions between you and SmkPeru I understand that
We have to use VB Ax dll for initializing runtime for non-malware solution.
There are two scenarios to achieve runtime initialization :
1. From non-vb standard exe ie c/c++ application from any thread as follows:
Code:
ThreadProc()
Set cObj = CreateIExprSrvObj(0, 4, 0)
CoInitialize ByVal 0&
pClsid = StrPtr("Vb AX DllSample.publicmultiuseclass")
tIID_IDispatch.c1 = 13.2096@
tIID_IDispatch.c2 = 504403158265495.5712@
'// create an instance and get IDispatch pointer
hr = CoCreateInstance(pClsid, 0, CLSCTX_INPROC_SERVER, VarPtr(tIID_IDispatch), cObj)
rtcMsgBox "in vbcallback"
End ThreadProc
2.But in a vb6 standard exe the above does not work in new thread in the sense it will not execute code after CoCreateInstance and returns silently without error without crashing.
But the following code works perfect and displays msgbox perfectly without crash or error:
Code:
ThreadProc()
Set cObj = CreateIExprSrvObj(0, 4, 0)
CoInitialize ByVal 0&
pNewHeader = CreateVBHeaderCopy()
If pNewHeader Then
tIID.c2 = 504403158265495.5712@
VBDllGetClassObject hModule, 0, pNewHeader, tClsId, tIID, 0
End If
rtcMsgBox "in vbcallback"
End ThreadProc
SmkPeru wants to achieve the second scenario using vb Ax dll like scenario 1(non-malware solution) using c/c++ dll.
I still don't understand. If you want to initialize an AxDll project from a C++ application you should use CoCreateInstance - nothing more. If you want to use callbacks in a StdExe project from a C++ application - use InitCurrentThreadAndCallFunction/InitCurrentThreadAndCallFunctionIDEProc - nothing more. Moreover there are the usage examples in the repository. Sometimes i guess jsvenu and smkperu are same person in the sense that they cannot explain normally what they need.
Sometimes i guess jsvenu and smkperu are same person in the sense that they cannot explain normally what they need.
Yup - I've asked both of them multiple times now, what the "end-goal" of all this is,
but my simple question was always either outright ignored - or avoided with: "for learning purposes".
When I followed up with "if you learned what you needed, what will you build then?" -
also no answer was given.
To me that clearly hints to either "hacking- or cracking" (using the C-Dll for "hooking into VB6-runtime-based Apps").
The special requirements of the VB6-runtime-initialization (especially in threaded-scenarios),
are throwing off the existing "copy-paste"-tools for "aspiring h4ck0rs", I guess...
ThreadProc()
Set cObj = CreateIExprSrvObj(0, 4, 0)
CoInitialize ByVal 0&
pNewHeader = CreateVBHeaderCopy()
If pNewHeader Then
tIID.c2 = 504403158265495.5712@
VBDllGetClassObject hModule, 0, pNewHeader, tClsId, tIID, 0
End If
rtcMsgBox "in vbcallback"
End ThreadProc
cannot run without using VBDllGetClassObject and cannot be achieved using another vb ax dll like scenario 1 in vb6 standard exe in new thread.
I still don't understand. If you want to initialize an AxDll project from a C++ application you should use CoCreateInstance - nothing more. If you want to use callbacks in a StdExe project from a C++ application - use InitCurrentThreadAndCallFunction/InitCurrentThreadAndCallFunctionIDEProc - nothing more. Moreover there are the usage examples in the repository. Sometimes i guess jsvenu and smkperu are same person in the sense that they cannot explain normally what they need.
Hello The Trick,
If I want to use callbacks in a StdExe project from a C++ application - why should I use InitCurrentThreadAndCallFunction in vb6.Why not I shift the complexity from vb6 to c/c++ by implementing
InitCurrentThreadAndCallFunction in c/c++ and put vb6 std exe application as simple as possible.Why you are stopping me from doing it by discouraging Me and JSVenu.
In fact what JSVenu told is correct regarding scenario 2.
InitCurrentThreadAndCallFunction calls vbdllgetclassobject.
This thread is getting increasingly weird, and has a certain odor to it, which both Olaf and The Trick have stated pretty plainly. The inability to explain any legitimate use for the code when asked repeatedly certainly sounds like malware. The inability to keep straight which username is being posted under sounds more like Moti, though the question doesn't.
To the OP: If you feel this is legitimate, feel free to send a PM to any of the moderators explaining what the program is supposed to do.