/
// @Name: ThreadInject
// @Author: luoluo
// @Time: 2005-04-17
// @Param: pid spacifies the pid of the process to be thread injected
// @Ret: if success return TRUE else return FALSE
//
BOOL WINAPI ThreadInject(DWORD pId)
{
HANDLE hProcess;
LPVOID lpCodeMemory;
BOOL bRet = FALSE;
BOOL bRetVal;
RemotePara myRemotePara;
PRemotePara pRemotePara;
HANDLE hThread;
DWORD dwByteWrite;
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
MEMORY_BASIC_INFORMATION mbi;
SIZE_T szRet;
DWORD dwOldProtect;
// Open process token to ajust privileges
bRetVal = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
if (! bRetVal)
{
//MessageBox(NULL, "failed OpenProcessToken", "Error", MB_ICONERROR);
goto FreeAndExit;
}
// Get the LUID for debug privilege
bRetVal = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
if (! bRetVal)
{
//MessageBox(NULL, "failed LookupPrivilegeValue", "Error", MB_ICONERROR);
goto FreeAndExit;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Adjust token privileges
bRetVal = AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(&tkp), (PTOKEN_PRIVILEGES)NULL, 0);
if (! bRetVal)
{
//MessageBox(NULL, "failed AdjustTokenPrivileges", "Error", MB_ICONERROR);
goto FreeAndExit;
}
// Open remote process
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pId);
if (hProcess == NULL)
{
//MessageBox(NULL, "failed OpenProcess", "Error", MB_ICONERROR);
goto FreeAndExit;
}
// Allocate memory from remote process
lpCodeMemory = VirtualAllocEx(hProcess, NULL, THREADSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpCodeMemory == NULL)
{
//MessageBox(NULL, "failed VirtualAllocEx", "Error", MB_ICONERROR);
goto FreeAndExit;
}
// Query the page information
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION));
szRet = VirtualQueryEx(hProcess, lpCodeMemory, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (szRet == 0)
{
//MessageBox(NULL, "failed VirtualQueryEx", "Error", MB_ICONERROR);
goto FreeAndExit;
}
// Modify the page protection for write
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect);
if (! bRetVal)
{
//MessageBox(NULL, "failed VirtualProtectEx", "Error", MB_ICONERROR);
goto FreeAndExit;
}
// Write my code to remote process memory
bRetVal = WriteProcessMemory(hProcess, lpCodeMemory, &ThreadProc, THREADSIZE, 0);
if (! bRetVal)
{
//MessageBox(NULL, "failed WriteProcessMemory", "Error", MB_ICONERROR);
VirtualFreeEx(hProcess, lpCodeMemory, THREADSIZE, MEM_RELEASE);
goto FreeAndExit;
}
// Modify the page protection to protect
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);
if (! bRetVal)
{
//MessageBox(NULL, "failed VirtualProtectEx 2", "Error", MB_ICONERROR);
goto FreeAndExit;
}
// Fill in the parameter
ZeroMemory(&myRemotePara, sizeof(RemotePara));
CreateParameter((PRemotePara)&myRemotePara);
// Allocate memory in the remote process to store the parameter
pRemotePara = (PRemotePara)VirtualAllocEx(hProcess, NULL, sizeof(RemotePara), MEM_COMMIT, PAGE_READWRITE);
if (pRemotePara == NULL)
{
//MessageBox(NULL, "failed VirtualAllocEx", "Error", MB_ICONERROR);
VirtualFreeEx(hProcess, lpCodeMemory, THREADSIZE, MEM_RELEASE);
goto FreeAndExit;
}
// Query page information
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION));
szRet = VirtualQueryEx(hProcess, pRemotePara, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (szRet == 0)
goto FreeAndExit;
// Modify page protection for write
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect);
if (! bRetVal)
goto FreeAndExit;
// Write para to the remote process's memory
bRetVal = WriteProcessMemory(hProcess, pRemotePara, &myRemotePara, sizeof(myRemotePara), 0);
if (! bRetVal)
{
//MessageBox(NULL, "failed WriteProcessMemory", "Error", MB_ICONERROR);
VirtualFreeEx(hProcess, lpCodeMemory, THREADSIZE, MEM_RELEASE);
VirtualFreeEx(hProcess, pRemotePara, sizeof(RemotePara), MEM_RELEASE);
goto FreeAndExit;
}
// Modify page protection to protect
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);
if (! bRetVal)
goto FreeAndExit;
// Create remote thread
hThread = CreateRemoteThread(hProcess, 0, 0, lpCodeMemory, pRemotePara, 0, &dwByteWrite);
if (hThread == NULL)
{
//MessageBox(NULL, "failed CreateRemoteThread", "Error", MB_ICONERROR);
VirtualFreeEx(hProcess, lpCodeMemory, THREADSIZE, MEM_RELEASE);
VirtualFreeEx(hProcess, pRemotePara, sizeof(RemotePara), MEM_RELEASE);
goto FreeAndExit;
}
bRet = TRUE;
FreeAndExit:
if (hProcess != NULL) CloseHandle(hProcess);
if (hToken != NULL) CloseHandle(hToken);
return bRet;
}