Link to home
Start Free TrialLog in
Avatar of fsanchez
fsanchez

asked on

How to get a pointer to a function not declared in the interface section?

I need to get a pointer to the InternalReadComponentRes function of the classes unit. The problem is that this function is not declared in the interface section.

Anyone has a solution?
Avatar of Madshi
Madshi

Can't you just copy the source code of this function to your own unit? Finding the pointer to this function is quite difficult. You have 3 possibilities:

(1) Use a disassembler unit that programmatically parses your own binary to find the pointer. Possible, but *very* difficult.
(2) Create a map file to your project (see linker options) and parse this file. The address of the function should be in there.
(3) Compile your project with debugger infos and parse those infos (that's possible somehow, but I don't know how).

Regards, Madshi.
Avatar of fsanchez

ASKER

I have to intercept calls to this function along the whole project, and these calls are always done within the VCL, so copying the function won't work.

I was thinking on a solution similar to (1): detect at runtime the address of the function and modify its code, maybe to derive the execution to my own code or maybe to substitute the TResourceStream it uses by my own class. I don't know if this is possible at all.
Look here:

http://help.madshi.net/Data/madCodeHook.htm

This Delphi package allows you to easily hook such a function, it also contains a little disassembler, which may help you finding the address of the function. The package "madCodeHook" is free for non-commercial purpose only.

Regards, Madshi.
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It looks great. But I can't use it because I have to distribute full source code.

I have been looking your website and it seems that I need the 'Simple Code Overwriting' approach. I suppose this would not work if the project is compiled with runtime packages, isn't it?

Thank you.
>> It looks great. But I can't use it because I have to distribute full source code.

That's bad...   :-(

>> I have been looking your website and it seems that I need the 'Simple Code Overwriting' approach.

Right. Well, I'd prefer the Extended Code Overwriting, but basically the Simple variant works, too...

>> I suppose this would not work if the project is compiled with runtime packages, isn't it?

It should work nevertheless. Hmmmm... Perhaps it would need some tweaking, but I think it should work.

Regards, Madshi.
Hi,

I have already found how to get the address of the function. Now I just have to put the jump to my function. I think I have to use the following API:

VirtualProtect(ImportJump^.Proc,5,PAGE_EXECUTE_READWRITE,@SaveProtect);

but I'm not sure about the exact implementation, mainly how to determine the jump address. Can you show me some sample code?

In any case, I have given you the points, you deserve them.

Regards,
Francisco Sanchez
"ImportJump"? So I guess you're relying on runtime packages, right? Is that good enough for your purpose? That won't work without runtime packages.

Yes, you have to unprotect the code by using VirtualProtect, that is right. Then you have to create a jump call, 5 bytes are needed. The first byte has to be $E9 (relative JMP assembler instruction), followed by a 4 byte integer, which calculates like this:

dword(@YourHookFunction) - dword(@OriginalFunction) - 5

This calculation may violate integer overflow checking, if your function is located in a lower memory position than the original function is. So please turn the integer overflow check off. Alternatively check which address is bigger to avoid the overflow.

Regards, Madshi.
P.S: With overflow checking turned off, the possible overflow is "correct" and works correctly.
Sorry about the ImportJump, I was just copying and pasting from an API hook code I have been using. It should be:

VirtualProtect(IRCR,5,PAGE_EXECUTE_READWRITE,@SaveProtect);

where IRCR is a pointer to InternalReadComponentRes.

Thank you again.
Sorry about the ImportJump, I was just copying and pasting from an API hook code I have been using. It should be:

VirtualProtect(IRCR,5,PAGE_EXECUTE_READWRITE,@SaveProtect);

where IRCR is a pointer to InternalReadComponentRes.

Thank you again.
Any clue on what would be needed to make this work with runtime packages?

I could create a new entry with more points for you if you can give me a working solution with full source code.

Regards,
Francisco Sanchez
Browse the export table of the vcl/rtl runtime package(s). I guess "InternalReadComponentRes" should be exported there. So this way it's probably even easier to get the address of the function when using runtime packages. The hooking should be the same.

Regards, Madshi.
I have no idea how can I browse the export table programmatically. Or are you talking about a manual process? I have to do this at runtime.
Browse it manually to find the exported name, it's a bit cryptical, but contains the full function name. Then at runtime simply call GetProcAddress.