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?
1Do you want to run your DLL in the same context as the application? With DLL injection or the like? Or do you want the DLL to run in one process, and call functions from another process?– s3cApr 19, 2019 at 17:34
I'd like it to call functions from the process that it's injected into.– XxMulti GamerxXApr 19, 2019 at 20:23
Once injected into a process, a DLL resides within the same address space in virtual memory presented to that process by the operating system. Interacting with a different process would require some form of inter-process communication. Please refer to the following discussion of the utility of DLL injection in the context of reverse engineering: What is DLL Injection and how is it used for reversing?– julian ♦Apr 20, 2019 at 7:52
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.
Would it be possible to use
CreateRemoteThread(or something else) that would execute a function in process of which we have the process id? Just call a function of that exe, not inject a dll, just a bit of code that calls function at address X. Thanks Nov 15, 2020 at 22:28
1Yeah, trivially, assuming you can find the address of the function after relocation. To pass parameters that need a block of data you specify you'll need to allocate memory in the remote process with VirtualAllocEx and call WriteProcessMemory to populate it. And if you need access to the result, use ReadProcessMemory if it's stored in a buffer, or some sort of IPC if it's more complex. Alternatively, you can create exports for the specific piece of code and use it like a DLL (possible with EXEs as well). I did a talk on this a while back: youtube.com/watch?v=fe49ZOaTh6Y– s3cNov 20, 2020 at 12:07
Wow, thanks for the quick reply. I'll go and watch the talk. Thanks again Nov 21, 2020 at 13:03