以下的代码在VS2003下通过测试
1. 先运行Notepad.exe
2. 新建Windows控制台空项目DllLoadTest, 加入DllLoadTest.cpp
3. 新建Win32空Dll项目TestDll, 加入TestDll.cpp, 编译后的Dll输出到C:#include <Windows.h> //Dll加载 BOOL RemoteLoadLibrary( DWORD dwProcessID, char *lpszDll) { //打开目标进程 HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessID ); //向目标进程地址空间写入DLL名称 DWORD dwSize, dwWritten; dwSize = strlen( lpszDll ) + 1; LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE ); if ( NULL == lpBuf ) { CloseHandle( hProcess ); return FALSE; } if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) ) { // 要写入字节数与实际写入字节数不相等,仍属失败 if ( dwWritten != dwSize ) { VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT ); CloseHandle( hProcess ); return FALSE; } } else { CloseHandle( hProcess ); return FALSE; } //不再加载已载入Dll(只加载一次) { // 使目标进程调用GetModuleHandle,获得DLL在目标进程中的句柄 DWORD dwHandle, dwID; LPVOID pFunc = GetModuleHandleA; HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID ); // 等待GetModuleHandle运行完毕 WaitForSingleObject( hThread, INFINITE ); // 获得GetModuleHandle的返回值 GetExitCodeThread( hThread, &dwHandle ); CloseHandle( hThread ); if (dwHandle != NULL) { VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT ); CloseHandle( hProcess ); return TRUE; } } // 使目标进程调用LoadLibrary,加载DLL DWORD dwID; LPVOID pFunc = LoadLibraryA; HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID ); // 等待LoadLibrary加载完毕 WaitForSingleObject( hThread, INFINITE ); // 释放目标进程中申请的空间 VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT ); CloseHandle( hThread ); CloseHandle( hProcess ); return TRUE; } //Dll卸载 BOOL RemoteFreeLibrary(DWORD dwProcessID, char *lpszDll) { // 打开目标进程 HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessID ); // 向目标进程地址空间写入DLL名称 DWORD dwSize, dwWritten; dwSize = strlen( lpszDll ); LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE ); if ( NULL == lpBuf ) { CloseHandle( hProcess ); return FALSE; } if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) ) { // 要写入字节数与实际写入字节数不相等,仍属失败 if ( dwWritten != dwSize ) { VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT ); CloseHandle( hProcess ); return FALSE; } } else { CloseHandle( hProcess ); return FALSE; } // 使目标进程调用GetModuleHandle,获得DLL在目标进程中的句柄 DWORD dwHandle, dwID; LPVOID pFunc = GetModuleHandleA; HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID ); // 等待GetModuleHandle运行完毕 WaitForSingleObject( hThread, INFINITE ); // 获得GetModuleHandle的返回值 GetExitCodeThread( hThread, &dwHandle ); // 释放目标进程中申请的空间 VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT ); CloseHandle( hThread ); // 使目标进程调用FreeLibrary,卸载DLL pFunc = FreeLibrary; hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwID ); // 等待FreeLibrary卸载完毕 WaitForSingleObject( hThread, INFINITE ); CloseHandle( hThread ); CloseHandle( hProcess ); return TRUE; } void main() { HWND hTarget = FindWindow("Notepad", "无标题 - 记事本"); DWORD dwProcID; GetWindowThreadProcessId(hTarget, &dwProcID); RemoteLoadLibrary(dwProcID, "C:\\TestDll.dll"); RemoteFreeLibrary(dwProcID, "C:\\TestDll.dll"); }
#include <Windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(0, "测试Dll加载", "测试Dll", MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
MessageBox(0, "测试Dll卸载", "测试Dll", MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL);
break;
}
return TRUE;
}
4. 将两个项目编译, 运行DllLoadTest.exe