I am using CreateRemoteThread() + LoadLibrary() method to inject code. Everything is OK when I running my injector in my Windows7 64bit OS laptop, and it still work in Windows Server 2012 R2 64bit for some target app.
BUT, in this Windows Server 2012 environment, for some target app, which is old MFC application, the CreateRemoteThread succeeded but the DllMain did not get called and I found the LoadLibrary() seems failed, by using GetExitCodeThread() on the created remote thread.
For the memory to write in target process, I counted the terminating 0 byte.
Also, I already knew the kernel32.dll address are the same for both the Windows 7 and Windows Server 2012, using the method introduced in below URL answer part.
The GetExitCodeThread() below got an zero exit code.
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
if(hThread == NULL) {
OutputDebugString(_T("Error: the remote thread could not be created.\n"));
writeLog("Error: the remote thread could not be created.");
}
else {
DWORD dResult = WAIT_OBJECT_0;
dResult = WaitForSingleObject(hThread, 1000*3);// the thread may already exited, so do not wait INFINITE
DWORD dwExitCode = 0;
GetExitCodeThread(hThread, &dwExitCode);
if(dwExitCode == 0)
{
writeLog("Error: LoadLibraryA failed.");
}
else
{
OutputDebugString(_T("Success: the remote thread was successfully created.\n"));
writeLog("Success: the remote thread was successfully created.");
}
}
Do you have any idea what should I suspect next?
To summarize, in below diagram, you can see the only fail is only when I run injector on Windows Server 2012 to inject into some old MFC application.
In below diagram, there is the information about HOW old the MFC application is:
I am trying to provide enough information, kindly let me know if you need some more information.
below is the complete code for inject my dll:
void inject(int procID, char* pszHookDll)
{
g_nTargetProcId = procID;
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
g_hTargetProc = process;
BOOL bInit = SymInitialize(g_hTargetProc, g_sPdbFolder, TRUE);// for analysing the information spy.dll send out
if(process == NULL) {
writeLog("Error: the specified process couldn't be found.");
}
/*
* Get address of the LoadLibrary function.
*/
LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if(addr == NULL) {
writeLog("Error: the LoadLibraryA function was not found inside kernel32.dll library.");
}
//addr = getProcAddrInTargetProcess(procID, process);
/*
* Allocate new memory region inside the process's address space.
*/
int nBufSize = strlen(pszHookDll)+1;
LPVOID arg = (LPVOID)VirtualAllocEx(process, NULL, nBufSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if(arg == NULL) {
writeLog("Error: the memory could not be allocated inside the chosen process.");
}
/*
* Write the argument to LoadLibraryA to the process's newly allocated memory region.
*/
int n = WriteProcessMemory(process, arg, pszHookDll, nBufSize, NULL);
if(n == 0) {
writeLog("Error: there was no bytes written to the process's address space.");
}
/*
* Inject our DLL into the process's address space.
*/
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
if(hThread == NULL) {
writeLog("Error: the remote thread could not be created.");
}
else {
DWORD dResult = WAIT_OBJECT_0;
dResult = WaitForSingleObject(hThread, 1000*3);
DWORD dwExitCode = 0;
GetExitCodeThread(hThread, &dwExitCode);
if(dwExitCode == 0)
{
writeLog("Error: LoadLibraryA failed.");
}
else
{
OutputDebugString(_T("Success: the remote thread was successfully created.\n"));
writeLog("Success: the remote thread was successfully created.");
}
}
/*
* Close the handle to the process, becuase we've already injected the DLL.
*/
//CloseHandle(process);close after symcleanup
}