I have a question about remote threads.I’ve read Mike Stall’s article present here: <Link>
I would like to create a remote thread that executes a delegate in another process, just like Mike Stall does. However, he declares the delegate in the target process, obtaining a memory address for it and then he creates the remote thread from another process using that address. The code of the target process CANNOT be modified.
So, I cannot use his example, unless I can allocate memory in the target process and then WriteProcessMemory() using my delegate.
I have tried using VirtualAllocEx() to allocate space in the target process but it always returns 0.
This is how it looks so far.
Console.WriteLine("Pid {0}:Started Child process", pid);
uint pidTarget= uint.Parse(args[0]);
IntPtr targetPid= new IntPtr(pidTarget);
// Create delegate I would like to call.
ThreadProc proc = new ThreadProc(MyThreadProc);
Console.WriteLine("Delegate created");
IntPtr fproc = Marshal.GetFunctionPointerForDelegate(proc);
Console.WriteLine("Fproc:"+fproc);
uint allocSize = 512;
Console.WriteLine("AllocSize:" + allocSize.ToString());
IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pidParent);
Console.WriteLine("Process Opened: " + hProcess.ToString());
IntPtr allocatedPtr = VirtualAllocEx(targetPid, IntPtr.Zero, allocSize, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
Console.WriteLine("AllocatedPtr: " + allocatedPtr.ToString());
Now my questions are:
-
In the code above, why does
VirtualAllocEx()not work? It has been imported using DLLImport from Kernel32. TheallocatedPtris always 0. -
How can I calculate alloc size? Is there a way I can see how much space the delegate might need or should I just leave it as a large constant?
-
How do I call
WriteMemory()after all of this to get my delegate in the other process?
Thank you in advance.
That blog post is of very questionable value. It is impossible to make this work in the general case. It only works because:
Which it achieves by handing the client process everything it needs get that thread started. The far more typical usage of CreateRemoteThread is to do so when the target process does not cooperate. In other words, you don’t have the CLR, you have to inject a DLL with the code, that code can’t be managed, you have to deal with the DLL getting relocated and Windows will balk at all this.
Anyhoo, addressing your question: you don’t check for any errors so you don’t know what is going wrong. Make sure your [DllImport] declarations have SetLastError=true, check the return value for failure (IntPtr.Zero here) and use Marshal.GetLastWin32Error() to retrieve the error code.