I was wondering, assuming I wrote a dll in C++ and could access another application's memory, is it possible to call outside functions if I had the address?
K, I'll take a stab at an answer. If you create a DLL that gets loaded by a process, of which there are numerous different methods, you can execute your code in the context of the remote process, not strictly what the question is about, but some groundwork. The common techniques are:
- Calling VirtualAllocEx, WriteProcessMemory and CreateRemoteThread. Writing the name into the remote process and creating a thread on LoadLibrary.
- Calling VirtualAllocEx, WriteProcessMemory and CreateRemoteThread. Writing a reflective DLL into the process, and executing the loader.
- Calling NtCreateSection, NtMapViewOfSection, and CreateRemoteThread. Writing a reflective DLL into the section which is mapped to both processes.
So now that we have code running in the remote process. We can do anything we want in that process ONLY, with some caveats:
- If you want to call a DLL function in another DLL, in the context of the process you are injected into, you can walk the export table for that DLL to find the exported function. The base address for the DLL can be found by walking the PEB.
- If you want to call a function in the specific exe, the problem is actually finding the address. With ASLR enabled, this address will change on each boot, meaning it can't just be hardcoded. If the process is static and won't change with updates etc, you can look up the base address for the process and work from that index. If version changes can change the code, all bets are off. There is no way to ensure the function will be present in future versions, or even that the parameters will remain the same. You could always do something similar to what IDA does with FLIRT, which identifies functions even if they have small modifications, but I wouldn't rely on it.
- If you want to communicate with another process from within the injected one, you have to use some form of IPC as noted by Julian.
So, yes, it's possible to interact with code in another process. Depending on the scenario it might not be reliable, and likely won't be portable across versions.