views:

125

answers:

4

I have a program which loads DLLs and I need to call one of the non-exported functions it contains. Is there any way I can do this, via searching in a debugger or otherwise? Before anyone asks, yes I have the prototypes and stuff for the functions.

A: 

I'm afraid there are no "safe" way to do so if referred library does not explicitly export its object (class/func). Because you will have no idea where is the required object mapped in code memory.

However, by using RE tools, you can find offset for interested object within the library, then add it to any known exported object address to obtain the "real" memory location. After that, prepare a function prototype etc and cast into your local structure for usage.

YeenFei
What are RE tools?
Nilbert
Disassembler, and its probably good idea to find those who offer assembly interpretation capability (PE is a good one)
YeenFei
+1  A: 

Yes there is, at least sort of, but it isn't a good idea.

In C/C++ all a function pointer is, is an address in memory. So if you somehow where able to find the address of this function you could call it.

Let me ask some questions though, how do you know this DLL contains this function? Do you have the source code? Otherwise I don't know how you could no for certain this function exists or if it is safe to call. But if you have the source code, then just expose the function. If the DLL writer didn't expose this function, they never expect you to call it and can change/remove the implementation at any time.

Warnings aside, you can find the function address if you have debug symbols or a MAP file you can find the offset in the DLL. If you don't have anything but the DLL, then there is no way to know where that function exists in the DLL - it is not stored in the DLL itself.

Once you have the offset you can then insert that into the code like so:

const DWORD_PTR funcOffset = 0xDEADBEEF;
typedef void (UnExportedFunc)();

....
void CallUnExportedFunc() {
     // This will get the DLL base address (which can vary)
     HMODULE hMod = GetModuleHandle("My.dll"); 
     // Calcualte the acutal address 
     DWORD_PTR funcAddress = (DWORD_PTR)hMod + funcOffset;
     // Cast the address to a function poniter
     UnExportedFunc func = (UnExportedFunc)funcAddress;
     // Call the function
     func();
}

Also realize that the offset of this function WILL CHANGE EVERY TIME the DLL is rebuilt so this is very fragile and let me say again, not a good idea.

shf301
Alas, the problem was finding the address in the DLL, and yeah, all I have is the DLL, but I am sure the function exists in it. What do you mean by "If you don't have anything but the DLL, then there is no way to know where that function exists in the DLL - it is not stored in the DLL itself."?
Nilbert
What I was trying to say is that the DLL doesn't contain any mapping between the function's name the address inside the DLL where that code reside. You will not find the function's name listed anywhere inside the DLL itself.
shf301
You can try looking at the DLL in OllyDBG and finding where the function is but it might be very difficult
Chris T
A: 

If the function you want isn't exported, then it won't be in the export address table. Assuming Visual Studio was used to produce this DLL and you have its associated PDB (program database) file, then you can use Microsoft's DIA (debug interface access) APIs to locate the desired function either by name or, approximately, by signature.

Once you have the function (symbol) from the PDB, you will also have its RVA (relative virtual address). You can add the RVA to the loaded module's base address to determine the absolute virtual address in memory where the function is stored. Then, you can make a function call through that address.


Alternatively, if this is just a one-off thing that you need to do (i.e. you don't need a programmatic solution), you can use windbg.exe in the Debugging Tools for Windows toolkit to attach to your process and discover the address of the function you care about. In WinDbg, you can use the x command to "examine symbols" in a module.

For example, you can do x mymodule!*foo* to see all functions whose name contains "foo". As long as you have symbols (PDB) loaded for your module, this will show you the non-export functions as well. Use .hh x to get help on the x command.

Chris Schmich
I guess it sucks then if I only have the .DLL and not the .pdb then right?
Nilbert
Yes, it would be very difficult to find your non-exported function without PDB information. You could try using a disassembler to guess where it's located by looking for x86 prolog/epilogs and taking a guess-and-check approach, see http://www.smidgeonsoft.prohosting.com/pebrowse-pro-file-viewer.html
Chris Schmich
A: 

The most general way to do this (and it's still a bad idea, as everyone else pointed out already) is to scan the DLL code at runtime after it's loaded, and look for a known, unique section of code in that function, and then use code similar to that in shf301's answer to call it. If you know that the DLL won't ever change, than any solution based on determining the offset in the DLL should work.

To find that unique section of code, disassemble the DLL using a disassembler that can show you the machine code in addition to the assembly language mnemonics (I can't think of anything that won't do that) and watch out for call and jmp instructions.

I actually had to do something similar once to apply a binary patch to a DOS exe; it was a bug fix, and the code wasn't under revision control so that was the only way to fix it.

I'd be really curious to know why you need this, by the way.

Ori Pessach