Create suspended process
I need to prevent the call to a WinAPI function in the target process when a certain value is passed as argument. The WinAPI function will be called by the target process in its initialisation state. The idea is to set a diversion route on the WinAPI function before it will be called when the target process initializes. Therefore I create the target process in suspended mode. My problem is that the target process will be suspended before it has loaded its load-time dynamic link libraries which makes it impossible to set the diversion route on the WinAPI function.
Start target process in suspended mode.
Allocate memory in target process.
Write code cave in allocated memory region of target process.
Redirect WinAPI function in target process to the code cave.
Resume main thread of target process.
Restore WinAPI function in target process after initialization.
Free allocated memory (code cave) in target process.
The only workaround solution I have found is to call the CreateRemoteThread function before I resume the main thread of the target process. Parsing the address of the GetCurrentProcess function as the lpStartAddress parameter to reduce the CPU usage as much as possible. All the load-time dynamic link libraries will be loaded before the remote thread terminates. Now it becomes possible to set the diversion route. Unfortunately this remains a nasty workaround which I rather avoid.
The following quote on the CreateRemoteThread documentation page of MSDN surprises me: "The function must exist in the remote process". In this particular case described above it seems to have the opposite effect. Maybe someone can enlighten me on the internal workings of this specific Windows component because it seems I do not fully understand it.
Thanks for your time,
You might want to look into Detours, which is a Microsoft package meant for exactly this kind of runtime hooking. If for some reason you can't do that, you can create the process suspended, attach to it as if you are a debugger (you can do that by setting DEBUG_PROCESS in dwCreationFlags), set a hardware breakpoint at the executable entry point, then resume the process. It will break once it reaches the entry point, at which time the DLLs are resolved and you can inject your hooks. Twiddle the hardware breakpoint back, and resume execution.
Another method is to rewrite the executable's import table to import a custom DLL instead of the regular one -- the custom DLL just contains forwarders to the actual DLL except for the one function you are trying to hook.
But seriously, there are frameworks for doing this and you really should try to use one of those if possible.