Hehe, i got bashed by Cypher! ^^
I wrote this code at work in 2 minutes to show an example code to reproduce the error. The code is minimized to the needed elements, to make it easy to understand.
I would never use code like this in my own projects, like you said, no error handling, no timeout or sleep in the loop. normaly i use my framework where i wrapped all used winapi handles and use them only through smartpointers. (impossible to leave a handle unclosed)
Here i rewrite it, now its safer, but still ugly.
Code:
#include <windows.h>
void ExecuteAndInject(const char* pApplication, const char* pDllName)
{
DWORD rVal;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
void* pMemory;
DWORD Size;
DWORD NOB;
HANDLE hThread;
DWORD ThreadId;
DWORD Code;
DWORD Timeout;
Size = strlen(pDllName) + 1;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
rVal = CreateProcess(pApplication, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo);
if(rVal)
{
pMemory = VirtualAllocEx(ProcessInfo.hProcess, NULL, Size, MEM_COMMIT, PAGE_READWRITE);
if(pMemory)
{
rVal = WriteProcessMemory(ProcessInfo.hProcess, pMemory, pDllName, Size, &NOB);
if(rVal && (NOB == Size))
{
hThread = CreateRemoteThread(ProcessInfo.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, pMemory, 0, &ThreadId);
if(hThread)
{
Timeout = GetTickCount() + 10000;
Code = 0;
while(Timeout > GetTickCount())
{
GetExitCodeThread(hThread, &Code);
if(STILL_ACTIVE != Code)
{
break;
}
Sleep(10);
}
rVal = CloseHandle(hThread);
}
}
rVal = VirtualFreeEx(ProcessInfo.hProcess, pMemory, 0, MEM_RELEASE);
}
rVal = ResumeThread(ProcessInfo.hThread);
rVal = CloseHandle(ProcessInfo.hThread);
rVal = CloseHandle(ProcessInfo.hProcess);
}
}
int main(void)
{
ExecuteAndInject(
"D:\\Programme\\Internet Explorer\\iexplore.exe",
"");
return 0;
}
Everyone can compile and run it, you dont need to pass a valid DllName. IE8 still looks weird, but why?