HANDLE WINAPI CreateRemoteThread(
__in HANDLE hProcess,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId
);
lpStartAddress 必须是LoadLibraryW绝对地址(GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"));
不能直接写LoadLibraryW名字,因为它是个导入函数,先是经过转换函数再跳到上面绝对地址,不能把导入函数地址当成实际地址使用。
lpParameter 必须是目标进程空中中的地址。
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID) pszLibFile, cb, NULL)
exemain.cpp
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <stdio.h>
wchar_t log[1024] = { 0 };
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL bOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL, hThread = NULL;
PWSTR pszLibFileRemote = NULL;
__try {
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Calculate the number of bytes needed for the DLL's pathname
int cch = 1 + lstrlenW(pszLibFile);
int cb = cch * sizeof(wchar_t);
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL) __leave;
// Copy the DLL's pathname to the remote process' address space
if (!WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) pszLibFile, cb, NULL)) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
DWORD remoteTID = 0;
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, pszLibFileRemote, 0, &remoteTID);
wsprintfW(log,L"CreateRemoteThread tid:%d for inject dll.\n",remoteTID);
::OutputDebugStringW(log);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
bOk = TRUE; // Everything executed successfully
}
__finally { // Now, we can clean everything up
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(bOk);
}
BOOL WINAPI EjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL bOk = FALSE; // Assume that the function fails
HANDLE hthSnapshot = NULL;
HANDLE hProcess = NULL, hThread = NULL;
__try {
// Grab a new snapshot of the process
hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (hthSnapshot == INVALID_HANDLE_VALUE) __leave;
// Get the HMODULE of the desired library
MODULEENTRY32W me = { sizeof(me) };
BOOL bFound = FALSE;
BOOL bMoreMods = Module32FirstW(hthSnapshot, &me);
for (; bMoreMods; bMoreMods = Module32NextW(hthSnapshot, &me)) {
bFound = (_wcsicmp(me.szModule, pszLibFile) == 0) ||
(_wcsicmp(me.szExePath, pszLibFile) == 0);
if (bFound) break;
}
if (!bFound) __leave;
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION |
PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION, // For CreateRemoteThread
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Get the real address of FreeLibrary in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls FreeLibrary()
//hThread = CreateRemoteThread(hProcess, NULL, 0,
// pfnThreadRtn, me.modBaseAddr, 0, NULL);
DWORD remoteTID = 0;
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, me.hModule, 0, &remoteTID);
wsprintfW(log,L"CreateRemoteThread tid:%d for Eject dll.\n",remoteTID);
::OutputDebugStringW(log);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
bOk = TRUE; // Everything executed successfully
}
__finally { // Now we can clean everything up
if (hthSnapshot != NULL)
CloseHandle(hthSnapshot);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(bOk);
}
void main(int argc, wchar_t **argv)
{
wchar_t szLibFile[MAX_PATH];
GetModuleFileNameW(NULL, szLibFile, _countof(szLibFile));
wchar_t *pFilename = wcsrchr(szLibFile, L'\\') + 1;
wcscpy_s(pFilename, _countof(szLibFile) - (pFilename-szLibFile),L"injectdll.dll");
DWORD pid = 0;
wprintf_s(L"Please put in inject process ID:\n");
wscanf_s(L"%d",&pid);
//pid = GetCurrentProcessId();
InjectLibW(pid,szLibFile);
getchar();
EjectLibW(pid,szLibFile);
}
dllmain.cpp
#include <windows.h>
wchar_t log[1024] = { 0 };
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
wsprintfW(log,L"DLL_PROCESS_ATTACH tid:%d \n",GetCurrentThreadId());
::OutputDebugStringW(log);
break;
case DLL_THREAD_ATTACH:
wsprintfW(log,L"DLL_THREAD_ATTACH tid:%d \n",GetCurrentThreadId());
::OutputDebugStringW(log);
break;
case DLL_THREAD_DETACH:
wsprintfW(log,L"DLL_THREAD_DETACH tid:%d \n",GetCurrentThreadId());
::OutputDebugStringW(log);
break;
case DLL_PROCESS_DETACH:
wsprintfW(log,L"DLL_PROCESS_DETACH tid:%d \n",GetCurrentThreadId());
::OutputDebugStringW(log);
break;
}
return TRUE;
}