First of all, I don't want to inject a dll. I want to inject code using WriteProcessMemory() (if this is even possible). I already used ReadProcessMemory() so I think writing is not a big deal.
Well, lets say there is a function at TargetProgram.exe+D78C612
and let's say it could be called like this:
push eax
push [esp+08]
push edx
push 00
push TargetProgram.exe+AF76235
push 04
call TargetProgram.exe+D78C612
How exactly would I accomplish this with WriteProcessMemory()?
I mean where do I find a section in which I can inject my code without overwriting important stuff. And most importantly, how would I call the function?
Just put a jump to my code in the active routine, jump back and delete it afterwards? But how would I find the routine?
So many questions and I have no idea how to start... I hope you can help me. :)
And if you have the time I would really like to see an example code of a function-call-injection.
You can use VirtualAllocEx
to allocate memory in the remote process and then copy your procedure into this memory.
Here are the steps to do the injection:
SuspendThread(hThread); // Suspend the remote thread
remote_address = VirtualAllocEx(hProcess, ...) // allocate memory for your code
WriteProcessMemory(hProcess, remote_address, local_address, length, NULL) // copy your code to remote process
WriteProcessMemory(hProcess, remote_fixup, ...) // insert a jump to your code
ResumeThread(hThread); // Resume the remote thread
As mentioned by Max's answer, VirtualAllocEx is one way to allocate memory pages in a remote process, assuming you have the PROCESS_VM_OPERATION access right for the process in question. You will also want to make sure the new pages are marked PAGE_EXECUTE_READWRITE for their protection level during the writing and then change it later to PAGE_EXECUTE_READ
using VirtualProtectEx.
Note that branching and some call instructions in x86 are IP-relative. This means their encodings are dependent upon where they are located in memory, as they use a signed relative displacement from the end of the instruction. So if you plan on calling an existing function from your new code, make sure you take this into account when using a relative call instruction or use an indirect/immediate form instead.
However, without knowing exactly what you're trying to accomplish here, it's difficult to recommend a technique for executing your new target code. With the new code in place, you could just inject a remote thread using CreateRemoteThread to execute it without having to disrupt any existing threads. This would be the simplest solution to execute the new code, but requires that the code you're calling is thread-safe. Picking an already running thread, suspending it, modifying EIP or introducing a detour, and resuming it without side effects (properly saving context across the injected call) is very tricky to say the least.
Personal note: as the author of the code coverage tool in Visual Studio 2012 that uses a bunch of tricks to rewrite third-party x86/x86-64 code on the fly to collect coverage data, this stuff is oh-so-much fun to hack and think on :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With