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?
LVL 1
fsanchezAsked:
Who is Participating?
 
MadshiCommented:
Let me just show you the power of my package. This will probably work to get the desired pointer (not tested):

uses ..., madDisAsm;

procedure Find_InternalReadComponentRes : pointer;
begin
  ParseFunction(@ReadComponentResEx).FarCalls[0].Target;
end;

This little innocent looking code disassembles the function "ReadComponentResEx", and gives you the address of the first function that "ReadComponentResEx" calls, which should be "InternalReadComponentRes". Nice, isn't it?   :-)

Regards, Madshi.
0
 
MadshiCommented:
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.
0
 
fsanchezAuthor Commented:
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.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

 
MadshiCommented:
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.
0
 
fsanchezAuthor Commented:
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.
0
 
MadshiCommented:
>> 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.
0
 
fsanchezAuthor Commented:
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
0
 
MadshiCommented:
"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.
0
 
MadshiCommented:
P.S: With overflow checking turned off, the possible overflow is "correct" and works correctly.
0
 
fsanchezAuthor Commented:
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.
0
 
fsanchezAuthor Commented:
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.
0
 
fsanchezAuthor Commented:
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
0
 
MadshiCommented:
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.
0
 
fsanchezAuthor Commented:
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.
0
 
MadshiCommented:
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.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.