I know this seems like a over-answered question but this one is different.
I have this ActiveX object which exports some methods. I need to set a hook on one of its methods, namely Func1, I know how to do this by using VirtualProtect(), etc. If I open ollydbg and dig into the ActiveX DLL I see exactly the address of the Func1 where I need to set the hook.
Using Visual Studio 2008, I am using the precompiler directive:
#import "myactx.dll" no_namespace, named_guids, raw_interfaces_only
And in my code I am trying to do this:
LPVOID ptr = &IMyActx::Func1;
which returns an error when compiling:
error C2440: 'initializing' : cannot convert from 'HRESULT (__stdcall IMyActx::* )(BSTR,BSTR)' to 'LPVOID'.
I researched and found that I can't cast a pointer-to-class-method to a pointer-to-function because of the implicit this param.
However, I don't intend to call this function. I just want to know its address in memory so that I can pass it to my hooking routine (which expects a LPVOID pointer).
This seems inconceivable to me that I can call a function but not get its raw address in memory. It makes me want to insert some x86 assembly code just to get the pointer I want.
Any suggestion is greatly appreciated, thanks for reading.
EDIT...
Now thinking of it... LPVOID ptr = &IMyActx::Func1; should not work because IMyActx is a pure virtual class! Anyway I tried some combinations before of instantiating an object and trying to get the raw pointer to Func1 but nothing worked so far. I see in ollydbg that a call to Func1 is generated as:
mov edx, [eax];
call dword ptr ds:[edx + 0x1C];
So I can assume I need to read the DWORD at vptr + 0x1C bytes and voilá.
If I recall correctly, the Component Object Model guarantees that it will always be the Func1 ptr laying at [vptr + 0x1C] given the same Interface ID. forever. Right?
I will probably do something like this, in somewhat pseudo-code:
#define FUNC1_ENTRY 0x1C / sizeof(LPBYTE)
CoCreateInstance(CLSID_MyActx, 0, CLSCTX_ALL, IID_IMyActxObj, (LPVOID*) &pObj);
LPVOID pToHook = (*pObj)[FUNC1_ENTRY];
Methods of COM objects actually are ordinary functions. That's what enables COM clients written in C instead of C++.
I recommend generating the header file for a C client, the function address will then be easily retrieved. You do first need an instance of the class you intend to hook, however.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With