BOOL DoInjectModuleInto(DWORD pProcessId)
{
BOOL bResult = FALSE;
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
PSTR pszLibFileRemote = NULL;
try
{
// Get a handle for the process we want to inject into
hProcess = ::OpenProcess(
PROCESS_ALL_ACCESS, // Specifies all possible access flags
FALSE,
pProcessId
);
if (hProcess == NULL)
__leave;
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PSTR)::VirtualAllocEx(
hProcess,
NULL,
cch,
MEM_COMMIT,
PAGE_READWRITE
);
if (pszLibFileRemote == NULL)
__leave;
// Copy the DLL's pathname to the remote process's address space
if (!::WriteProcessMemory(
hProcess,
(PVOID)pszLibFileRemote,
(PVOID)szLibFile,
cch,
NULL))
__leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
::GetProcAddress(::GetModuleHandle("Kernel32"), "LoadLibraryA");
if (pfnThreadRtn == NULL)
__leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = ::CreateRemoteThread(
hProcess,
NULL,
0,
pfnThreadRtn,
(PVOID)pszLibFileRemote,
0,
NULL
);
if (hThread == NULL)
__leave;
// Wait for the remote thread to terminate
::WaitForSingleObject(hThread, INFINITE);
bResult = TRUE;
}
__finally
{
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
::VirtualFreeEx(hProcess, (PVOID)pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
::CloseHandle(hThread);
if (hProcess != NULL)
::CloseHandle(hProcess);
}
return bResult;
}