#undef _UNICODE #undef UNICODE #include typedef HINSTANCE (__stdcall *PLOADLIB)(LPCTSTR); struct INJDAT { _TCHAR dll[MAX_PATH]; HINSTANCE hInst; DWORD err; PLOADLIB LoadLibrary; }; static DWORD WINAPI LLProc(LPVOID _pInjDat) { struct INJDAT *pDat = (struct INJDAT *)_pInjDat; SetLastError(0); pDat->hInst = pDat->LoadLibrary(pDat->dll); if(!pDat->hInst) pDat->err = GetLastError(); else pDat->err = 0; return pDat->err; } static void LLProcEnd() {} // Mark the end HINSTANCE __stdcall InjectDll(HANDLE hProc, LPCTSTR dll) { const unsigned cb = ((unsigned)LLProcEnd) - ((unsigned)LLProc); struct INJDAT dat; HINSTANCE hKernel = 0; PVOID pRemoteDat = 0; HANDLE hThread = 0; DWORD id = 0; LPTHREAD_START_ROUTINE pRemoteProc = (LPTHREAD_START_ROUTINE)VirtualAllocEx( hProc, // Target process NULL, // Let the VMM decide where cb, // Size MEM_COMMIT, // Commit the memory PAGE_EXECUTE_READWRITE); // Protections if(!pRemoteProc) return 0; __try { if(!WriteProcessMemory( hProc, // Target process pRemoteProc, // Source for code LLProc, // The code cb, // Code length NULL)) // We don't care return 0; // Now fill in a INJDAT strcpy(dat.dll, dll); hKernel = LoadLibrary("KERNEL32.DLL"); if(!hKernel) return 0; dat.LoadLibrary = (PLOADLIB)GetProcAddress(hKernel, "LoadLibrary"); if(!dat.LoadLibrary) return 0; // Now copy the INJDAT pRemoteDat = VirtualAllocEx(hProc, NULL, sizeof(struct INJDAT), MEM_COMMIT, PAGE_READWRITE); if(!pRemoteDat) return 0; if(!WriteProcessMemory(hProc, pRemoteDat, &dat, sizeof(struct INJDAT), NULL)) return 0; // Now spawn the thread hThread = CreateRemoteThread( hProc, // Target process NULL, // No security 4096 * 16, // 16 pages of stack pRemoteProc, // Thread proc pRemoteDat, // Data 0, // Run NOW &id); if(!hThread) return 0; // Wait for it!! WaitForSingleObject(hThread, INFINITE); // Read the data back out if(!ReadProcessMemory( hProc, // Target process pRemoteDat, // Their data &dat, // Our data sizeof(struct INJDAT), // Size NULL)) // We don't care return 0; // Restore the status SetLastError(dat.err); return dat.hInst; } __finally // Clean up { DWORD lerr = GetLastError(); if(pRemoteProc) VirtualFreeEx(hProc, pRemoteProc, cb, MEM_RELEASE); if(hKernel) CloseHandle(hKernel); if(pRemoteDat) VirtualFreeEx(hProc, pRemoteDat, sizeof(struct INJDAT), MEM_RELEASE); if(hThread) CloseHandle(hThread); SetLastError(lerr); } return 0; // Something blew up!!