I’d like to call a function that resides in a 3rd-party .exe and obtain its result. It seems like there should be a way, as long as I know the function address, calling-convention, etc… but I don’t know how.
Does anyone know how I would do this?
I realize that any solution would be a non-standard hack, but there must be a way!
My non-nefarious use-case: I’m reverse engineering a file-format for my software. The calculations in this function are too complex for my tiny brain to figure out; I’ve been able to pull the assembly-code directly into my own DLL for testing, but of course I can’t release that, as that would be stealing. I will be assuming users already have this particular application pre-installed so my software will run.
OK, I’ve put together a prototype.
This program creates another instance of itself as a debugged child process.
An automatic breakpoint will be encountered before main() and CRT initialization code. This is when we can change the memory and registers of the debugged process to make it execute a function of interest. And that’s what the program does.
It tries to catch and handle all the bad situations (e.g. unexpected exceptions) and reports them as errors.
One bad situation is actually a good one. It’s the #UD exception from the UD2 instruction that the program places into the debugged process. It uses this #UD to stop the process execution after the function of interest has returned.
A few more notes:
This code is 32-bit only. I didn’t even try to make it 64-bit compilable or support 64-bit child processes.
This code will likely leak handles. See the Windows Debug API function descriptions on MSDN to find out where they need to be closed.
This code is a proof of concept only and does not support passing and returning data via pointers or registers other than EAX, ECX and EDX. You’ll have to extend it as necessary.
This code requires some privileges in order to be able to create and fully debug a process. You may have to worry about this if your program’s users aren’t admins.Enjoy.
Code:
Output: