利用Windows API开发的DLL注入工具
有一些操作放在目标程序中比远程执行更方便,可定制性强。注入DLL可以帮助目标程序实现更多功能。
- 选择DLL
- 输入进程名,大小写敏感(推荐使用火绒剑查看)
- 点击“注入”按钮
- (此时转到DLL操作)
- 点击“卸载”按钮(如果不卸载就不能再次注入)
- 退出本程序
- 如果点击“注入”按钮之后,DLL没有注入或者无反应,则是DLL的问题,与本程序无关。
- 如果多次点击“注入”按钮没有反应,先尝试点击“卸载”按钮,知道弹出“卸载失败”后再次注入。
大概流程如下:
- 打开进程,获取进程句柄
- 在目标进程中申请内存空间
- 写入DLL路径
- 创建远程调用线程通过LoadLibrary载入dll
涉及的API主要如下:
-
OpenProcess
-
VirtualAllocEx
-
WriteProcessMemory
-
VirtualFreeEx
-
CreateRemoteThread
-
WaitForSingleObject
示例代码:
BOOL InjectDll(char * szDllPath, DWORD dwPID)
{
// 获取进程访问权限
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (!hProcess)
{
return FALSE;
}
// 申请内存空间
LPVOID lpDllMem = VirtualAllocEx(hProcess, NULL, sizeof(szDllPath),
MEM_COMMIT, PAGE_READWRITE);
if (!lpDllMem)
{
CloseHandle(hProcess);
return FALSE;
}
// dll路径写入内存
if (0 == WriteProcessMemory(hProcess, lpDllMem, szDllPath,
sizeof(szDllPath), NULL))
{
VirtualFreeEx(hProcess, lpDllMem, sizeof(szDllPath), MEM_DECOMMIT);
CloseHandle(hProcess);
return FALSE;
}
// 调用远程dll
HMODULE hK32 = GetModuleHandle(_T("Kernel32.dll"));
LPVOID lpLoadLibAddr = GetProcAddress(hK32, "LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)lpLoadLibAddr, lpDllMem, 0, 0);
if (!hThread)
{
VirtualFreeEx(hProcess, lpDllMem, sizeof(szDllPath), MEM_DECOMMIT);
CloseHandle(hProcess);
return FALSE;
}
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, lpDllMem, sizeof(szDllPath), MEM_DECOMMIT);
CloseHandle(hThread);
CloseHandle(hProcess);
/*TCHAR test[100] = { 0 };
_sntprintf_s(test, sizeof(test)/sizeof(TCHAR), _T("写入的地址: %p"),
lpDllMem);
OutputDebugString(test);*/
return TRUE;
}
卸载与注入步骤类似,注入用的LoadLibrary,卸载用FreeLibrary。示例如下:
BOOL UnInjectDll(char * szDllPath, DWORD dwPID)
{
char szDName[0x100] = "WeChatHelperDll.dll";
// 获取进程访问权限
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (!hProcess)
{
return FALSE;
}
HMODULE hK32 = GetModuleHandle(_T("Kernel32.dll"));
LPVOID lpFreeLibAddr = GetProcAddress(hK32, "FreeLibraryAndExitThread");
HMODULE hDll = GetDLLHandle(szDName, dwPID);
if (!hDll)
{
CloseHandle(hProcess);
return FALSE;
}
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)lpFreeLibAddr, hDll, 0, 0);
if (!hThread)
{
CloseHandle(hProcess);
return FALSE;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
注意这里没有使用的FreeLibrary
,在Win10系统中测试注入微信,发生了异常崩溃,改用FreeLibraryAndExitThread
后正常卸载,原因尚不明确。