Hello, I'm currently writing a injector in C# for a hobby project and i know the rough outlines of injection:
- retrive handle with OpenProcess
- retrive pointerToMemory with VirtualAllocEx
- write function into pointerToMemory with WriteProcessMemory
- start a thread with CreatRemoteThread
- wait for exit of created thread (WaitForSingleObject)
- free up memory and close handle
I've run into trouble at step 3 though, because i'd really like to omit the c++ dll that stands for the CLR hosting.
After looking into doing this on google i found this article: Dynamically Writing and Executing Native Assembly in C# - Devin Jenson's WebLog - Site Home - MSDN Blogs which mentions writing and compiling the native function and then storing it in a byte array, however this is only with a simple function that adds two args and return the result so i was wondering if my much larger function that includes the clr hosting API isn't gonna try to acces something outside of the function and thus crash because it hasn't been copied over to the remote process?
(the second problem with above approach and the reason for me not trying it out is that i was unable to find when a function starts and stop in byte code and then get the bytes inbetween)
My first idea to solve this was to store the whole dll in a byte array (Resharper hates that file and have crashed visual studio once or twice btw
) and then just set the remote threads entry point to the beginning of the injected array...
That however doesn't work which i could have told myself so once again i'm back to finding the offset for the beginning of the function, any hints on how todo this? Or am i just being really dumb for injecting the whole dll in that way because it must be mapped by LoadLibrary or something similar?
(The whole loadLibrary comes from me reading the source for the c++ injector i'm using at the moment):
Code:
bool InjectLibrary(DWORD dwProcessId, char* lpDll)
{
HMODULE hMod;
FARPROC fpLoad = 0;
HANDLE hThread = 0, hProcess = 0;
LPVOID lpRemoteAddress = 0;
int ret;
try{
hMod = GetModuleHandle("Kernel32");
if(hMod == 0)
throw MException("GetModuleHandle()");
fpLoad = GetProcAddress(hMod, "LoadLibraryA");
if(fpLoad == 0)
throw MException("GetProcAddress()");
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, dwProcessId);
if(hProcess == 0)
throw MException("OpenProcess()");
lpRemoteAddress = VirtualAllocEx(hProcess, 0, strlen(lpDll), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if(lpRemoteAddress == 0)
throw MException("VirtualAllocEx()");
ret = WriteProcessMemory(hProcess, lpRemoteAddress, (LPVOID)lpDll, strlen(lpDll), 0);
if(ret == 0)
throw MException("WriteProcessMemory()");
hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)fpLoad, lpRemoteAddress, 0, 0);
if(hThread == 0)
throw MException("CreateRemoteThread()");
WaitForSingleObject(hThread, INFINITE);
ret = VirtualFreeEx(hProcess, lpRemoteAddress, 0, MEM_RELEASE);
if(ret == 0)
throw MException("VirtualFreeEx()");
ret = CloseHandle(hProcess);
if(ret == 0)
throw MException("CloseHandle()");
}catch(MException& ex){
if(lpRemoteAddress != 0)
VirtualFreeEx(hProcess, lpRemoteAddress, 0, MEM_RELEASE);
if(hProcess != 0)
CloseHandle(hProcess);
GetError(GetLastError(), ex.ErrorMessage);
return false;
}
return true;
}
But since i suck at c++ i'm not sure what this does "(LPTHREAD_START_ROUTINE)fpLoad" but i think it essentially tells the spawned thread to call LoadLibrary with the parameter which is our dll, correct? however that's still using a dll to launch the CLR which i kinda want to avoid...
Thanks in advance for any help and comments