-
[vb6] AddressOf for Class, Form, UC methods
This will be of little use to the masses, but can be of good use for thunk creators/users and the curious.
VB gives us the AddressOf function which can return the function address of any method within a bas module. We have no such function to return addresses within non-module code pages like classes, forms, usercontrols, etc. This can be a suitable substitute.
Why would you even need these addresses? Normally, you wouldn't. The most obvious case would be if you wanted to call a class function, particularly a private one, from a thunk. Can apply if wanting to do same thing from a bas module, but there are easier workarounds for calling private class methods from a module.
CODE REMOVED. I could not get a reliable function address of a specific private nor public method other than the final private method in all VB code pages.
I concede and tip my hat to Paul Caton whose method seems to be the most reliable. At this point, I cannot top it, except for one specific case: classes. Unfortunately, my logic will not work reliably in any other code page that is built on other interfaces: form, usercontrol, property page, etc.
If interested in Paul Caton's method, it is a matter of googling for "self-subclasser Paul Caton".
I'll ask the moderators to remove this thread.
-
Re: [vb6] AddressOf for Class, Form, UC methods
Have you looked at how setting Ordinal's manually in the object browser affect this?
-
Re: [vb6] AddressOf for Class, Form, UC methods
Quote:
Originally Posted by
DEXWERX
Have you looked at how setting Ordinal's manually in the object browser affect this?
Wasn't aware you can change the ordinals via the object browser, don't see such an option. But you did make me think of a scenario I haven't tested: the hidden attribute of a public method and how that might mess with the ordinals...
-
Re: [vb6] AddressOf for Class, Form, UC methods
I think I'm confusing ProcedureID/DispatchID with Ordinal. Are they possibly related?
I htought they were related, but it's possible the DispatchID is independant of the Ordinal / VTable.
I think I'm just used to seeing DispatchIDs that are kind of sorted the same as the Interface definition.
-
Re: [vb6] AddressOf for Class, Form, UC methods
Quote:
I htought they were related, but it's possible the DispatchID is independant of the Ordinal / VTable.
They are independent. The DISPID or MEMBERID of the function doesn't appear to have any effect on the order that VB adds them to the vTable. I did play with hidden attributes for public methods & no harm, no foul, works ok.
However, where my logic does break is if adding WithEvents to a class. The code fails to find the final private method. This is something I will try to figure out and adjust the code or comments as needed.
Follow up: I was able to get it working perfectly for classes, but not for forms, usercontrols and property pages.
-
Re: [vb6] AddressOf for Class, Form, UC methods
-
Re: [vb6] AddressOf for Class, Form, UC methods
I was interested in this addressOf for Class etc, I think we need to use GetTypeInfo, call GetFuncDesc on ITypeInfo and then look for pfuncdesc->oVft, there is vtable pointer. For performance save pointers to collection after you get it for first time.
-
Re: [vb6] AddressOf for Class, Form, UC methods
-
1 Attachment(s)
Re: [vb6] AddressOf for Class, Form, UC methods
My couple thoughts.
I think you can obtain an address of method in any module.
In IDE you can get ITypeLib information about project using EbGetExecutingProj function that returns a IVBAProject that supports ITypeLib interface. This information contains everything about modules even private methods. For instance:
Attachment 136657
It shows information about itself project. As you can see it shows private methods Form_Load etc.
In the compiled form you can't obtain the information about a private method by the name but you can get VTable of interface parsing the VBHeader and the children structures of a VB project.
Take a look about the public methods that is public variables in an object module. These variables actually are the methods too and the information about they can be obtained by DISPID.
I've explained about compiled form from my memory, i can be wrong. I can't find out the project where i did it.
@dz32, yes when you call a function from a standard module it actually jump to the 0x001F8282 label, when you use AddressOf it returns the 0xAB0C74 address which check the mode (run/pause/stop), therefore if you change code of 0xAB0C74 label it won't affect to simple call. There is no verifications in the compiled form. You can obtain both 0x001F8282 and 0xAB0C74 address programmatically.
When you call a method of object module it actually call MethCallEngine function in IDE.
-
Re: [vb6] AddressOf for Class, Form, UC methods
In compiled version - what if we will use call to initialization method, that loads asm thunk that looks for procedure start address in stack? This call would be the first in method/function, e.g. right below form_load and could be used for private method also.
-
3 Attachment(s)
Re: [vb6] AddressOf for Class, Form, UC methods
Quote:
Originally Posted by
izero76
In compiled version - what if we will use call to initialization method, that loads asm thunk that looks for procedure start address in stack? This call would be the first in method/function, e.g. right below form_load and could be used for private method also.
What do you mean? How do you want to obtain an address from an asm-thunk?
You can get a method table by VBHeader and child structures in the compiled form.
When a project is being loaded it fills the vTable from the several places.
The first place is from the standard BASIC_CLASS_*** methods:
Attachment 136743
The second place is the standard methods from MSVBVM:
Attachment 136745
The third place is from an EXE:
Attachment 136747
I've mentioned about only the private methods. There are the few places you can reconstruct vTable therefrom.
-
Re: [vb6] AddressOf for Class, Form, UC methods
I mean something like this:
Public colAddressess as Collection
Sub SomeMethod()
Call initMethod() 'first call in method we want use as callback
End Sub
Sub initMethod()
asm thunk to look on callstack and get address to SomeMethod, save it to colAddressess
End Sub
But I am not sure if this is possible in VB, I din't play with olly, it's only idea, maybe it's easier to populate some quick implemenation of collection by reading VBHeader to achieve speed required for callbacks.
-
Re: [vb6] AddressOf for Class, Form, UC methods
I think it won't work.
Firstly, why do you want to use the asm thunk? You can get address of a variable in the stack through VB.
Secondly, when a method is being called it puts some data on the stack (an error handler, temporary variables ect.). You can't know the address of the SomeMethod from the initMethod because you exactly don't know the number of variables on stack.
-
Re: [vb6] AddressOf for Class, Form, UC methods
Address of variable is not around method entry address. If you call initMethod() as the first call right below sub declaration, then you will have only few adresses in callstack and one of this is entry point of your method (few call address back). But as I said, I am not sure how VB uses callstack, it's only idea.
-
1 Attachment(s)
Re: [vb6] AddressOf for Class, Form, UC methods
Quote:
Originally Posted by
izero76
Address of variable is not around method entry address.
You can pass a parameter to Init, and get its address. You can move relatively this address in order to get other data from the stack.
Quote:
Originally Posted by
izero76
If you call initMethod() as the first call right below sub declaration, then you will have only few adresses in callstack and one of this is entry point of your method (few call address back).
Look here:
Attachment 136759
This is Form_Load handler. You can change something and it will be affected on the Form_Load code. Same for any other method.
-
Re: [vb6] AddressOf for Class, Form, UC methods
Sure, you are right, my mistake. And few bytes back from passed parameter's address we (probably) have entry point.
-
Re: [vb6] AddressOf for Class, Form, UC methods
-
Re: [vb6] AddressOf for Class, Form, UC methods
-
Re: [vb6] AddressOf for Class, Form, UC methods
Quote:
Originally Posted by
The trick
My couple thoughts.
I think you can obtain an address of method in any module.
In IDE you can get ITypeLib information about project using
EbGetExecutingProj function that returns a
IVBAProject that supports
ITypeLib interface. This information contains everything about modules even private methods. For instance:
Attachment 136657
It shows information about itself project. As you can see it shows private methods Form_Load etc.
In the compiled form you can't obtain the information about a private method by the name but you can get VTable of interface parsing the VBHeader and the children structures of a VB project.
Take a look about the public methods that is public variables in an object module. These variables actually are the methods too and the information about they can be obtained by DISPID.
I've explained about compiled form from my memory, i can be wrong. I can't find out the project where i did it.
@dz32, yes when you call a function from a standard module it actually jump to the 0x001F8282 label, when you use AddressOf it returns the 0xAB0C74 address which check the mode (run/pause/stop), therefore if you change code of 0xAB0C74 label it won't affect to simple call. There is no verifications in the compiled form. You can obtain both 0x001F8282 and 0xAB0C74 address programmatically.
When you call a method of object module it actually call
MethCallEngine function in IDE.
can u add a demo of which you show in this picture please?
-
Re: [vb6] AddressOf for Class, Form, UC methods
-
Re: [vb6] AddressOf for Class, Form, UC methods
Thanks the trick, really wonderful demo
i have translate all Russia words to English by google