I understand the name is a bit confusing, so let me explain what I'm trying to do:
I just finished writing a simple DLL injector to prove the concept I'm trying to write. The program takes a snapshot of the current processes, lists the process tree, and inserts the DLL into its direct parent process. Now, under ideal conditions, this works great: the 32-bit version of the injector can inject into 32-bit parent processes, and the 64-bit version of the injector can inject into 64-bit parent processes.
However, now I want to add the 32-bit DLL to the 32-bit parent process from the x64 injector. After this DLL was injected, I was hoping then to introduce a call to one of the functions exported by the embedded DLL. I am not sure though if this is really possible. (I already compiled some code to determine if the parent process is a 32-bit process or a 64-bit process, so this will not be a problem)
Now, I've already found code that seems to do the first part of injecting precompiled machine code into a process . (At least I think that what he does). Usually, after entering a call to LoadLibraryW, I get the address returned by this call, add the relative offset to the exported function that I want to call, and insert a call to this function. In this case, I cannot load the 32-bit library into my 64-bit injector, so I cannot find the relative offset of the function using GetProcAddress , as usual. I walked past this issue by doing the following:
Since I cannot find the function offset of the 32-bit DLL using conventional means, I am now reading the file into the buffer using this buffer to fill in IMAGE_NT_HEADERS32 and the IMAGE_EXPORT_DIRECTORY enumeration to find the names and relative offsets of all exported functions.
So at this moment I have the following:
- 32-bit DLL loaded in a 32-bit process
- The value equivalent to funcAddr when running the following code in a 32-bit process:
code:
HMODULE hInjectedDLL = LoadLibrary("mydll.dll"); DWORD funcAddr = (DWORD)GetProcAddress(hInjectedDLL, "ExportedFunc") - (DWORD)hInjectedDLL;
Theoretically, all I need now is the value of hInjectedDLL, and I should be able to make a call to this function. Unfortunately, I donโt know enough about assembly or machine codes to know how to do this.
Any ideas?
(In addition, I know that I could save a lot of trouble just by compiling two versions of the injector, and one starting the other when the parent processor architecture of the processor does not match. To avoid this route, though.)
Change Perhaps this will help explain what I'm actually trying to fulfill in this proof of concept.
I am experimenting with the idea that I should allow the execution of a child process in the current console, without the need for the original process to wait for the child to finish. Since there is no built-in API for the console application, you usually loop around the process tree, all waiting for the completion of their child process. To facilitate this functionality, I want to do the following:
Injection
The DLL injector will play the role of the "execution process". (a process that usually needs to wait for a child process to complete). When it starts, it determines the platform of its parent process and whether the parent process is even a console application. If this is not the case, the process simply uses the exec family of functions to start the desired subprocess immediately exiting. If the parent process is a console application, the injector determines which DLL to use, pauses the thread that originally created the injector process, and then inserts the DLL into the parent process.
Resolution of our function
Once the DLL is in place, the injector determines the address of the function exported by the DLL. (I usually did this by calling CreateRemoteThread to do the initial injection, and then use GetExitCodeThread in this thread to get the base address of the DLL in the parent process. Once I have this, try arithmetic to find the address of our exported function, which then I can use a second call to this function to enter.
Call our function
The exported function will look like this:
BOOL RewriteHProcess (HANDLE hProcess)
The injector will again use CreateRemoteThread to call this function from the context of the parent process, with hProcess being the handle to the injector process. On the side of the DLL, the function will do one of two things (I'm not quite sure if my first idea is possible, given the security limitations of memory access by threads, so I put together a second idea to return if it fails first.)
RewriteHProcess will open a previously paused stream for reading and writing and using ReadProcessMemory , it will look for the process memory for the HANDLE to our injection process. (We assume that the parent process is currently blocking further execution using the WaitForSingleObject function. I know that Command Prompt does, at the very least, and that my focus is currently on). The DLL then calls an internal function to create the desired child process, closes the old descriptor, and overwrites the memory with the descriptor of our new child process. At this stage, he cleans everything he can and returns. The injector then performed any remaining flushing to resume the paused thread, close the process and thread descriptors, and exit, leaving the parent process to continue locking while it waits for the new child process to complete.
If this route is not possible, my reserve was simply to suspend the blocking stream from the injector, create a new child process in the injected DLL, clean and exit the injector, and wait in the DLL until the child process is complete. At this point, the DLL will clear, resume the paused thread, and unload itself. (The disadvantage of this route is that the return code returned by the parent process from the injector may not be the same as the return code from our target child process)