前几篇文章,是通过远程线程的方式来注入目标进程,来实现DLL注入的,这次我们换一个新的方式注入,那就是通过
SetWindowsHookEx来远程注入。
介绍:
SetWindowsHookEx
HHOOK WINAPI SetWindowsHookEx(
__in int idHook, \\钩子类型
__in HOOKPROC lpfn, \\回调函数地址
__in HINSTANCE hMod, \\实例句柄
__in DWORD dwThreadId); \\线程ID
int idHook:
指的是钩子的类型,钩子类型有很多种,一般分为常用的几种:WH_KEYBOARD、WH_MOUSE
详情:https://blog.csdn.net/linux7985/article/details/39643577
HOOKPROC lpfn:
回调函数地址,如果dwThreadId ==0 ,或者说是dwThreadId是其他进程下的线程,那么lpfn必须是DLL中的一个函数地址,否则不做要求。
HINSTANCE hMod:
DLL的基址,也就是DLL模块句柄,是l包含lpfn函数的DLL基址,如果 dwThreadId 是当前进程下的一个线程,那么该参数必须为NULL。
DWORD dwThreadId:
线程ID
步骤:
和之前的注入过程基本相同
- 获取进程ID 通过进程名称
- 编写DLL,将需要的函数进行导出
- 获取目标进程中的线程ID,为了保证线程ID的有效性,把所有的线程ID都获取出来,一一注入,直到注入成功
- SetWindowsHookEx,实现钩子注入
获取进程ID:
https://blog.csdn.net/qq_42021840/article/details/106137368
编写DLL,将需要的函数进行导出:
要在def文件中将Sub_1导出
LIBRARY
EXPORTS
Sub_1 @1
BOOL WINAPI DllMain(
HMODULE hinstDLL,
DWORD fdwReason,
LPVOID lpReserved
) //dll main 函数
{
printf("%p\r\n", hinstDLL);
switch (fdwReason)
{
case DLL_PROCESS_DETACH: //0
{
break;
}
case DLL_PROCESS_ATTACH: //1
{
HANDLE ProcessID = (HANDLE)GetCurrentProcessId();
TCHAR v1[MAX_PATH]{ 0 };
_stprintf(v1, _T("%d Success"), ProcessID);
MessageBox(NULL, v1, _T("Matthew"), 4);
break;
}
case DLL_THREAD_ATTACH: //2
{
break;
}
case DLL_THREAD_DETACH: //3
{
break;
}
}
return TRUE;
}
void Sub_1()
{
HANDLE ProcessIdentify = (HANDLE)GetCurrentProcessId();
TCHAR v1[MAX_PATH] = { 0 };
_stprintf(v1, _T("%d Sub_1()"), ProcessIdentify);
MessageBox(NULL, v1, _T("Injection"), 0);
}
获取目标进程中的线程ID,为了保证线程ID的有效性,把所有的线程ID都获取出来,一一注入,直到注入成功:
BOOL GetThreadIdentify(HANDLE ProcessIdentify, vector<HANDLE>& ThreadIdentify)
{
BOOL IsOk = FALSE;
HANDLE SnapshotHandle = INVALID_HANDLE_VALUE;
THREADENTRY32 ThreadEntry32 = { 0 };
ThreadEntry32.dwSize = sizeof(THREADENTRY32);
int LastError = 0;
if (IsBadReadPtr(&ProcessIdentify, sizeof(HANDLE)))
{
LastError = ERROR_INVALID_PARAMETER;
goto Exit;
}
SnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (SnapshotHandle == INVALID_HANDLE_VALUE)
{
LastError = GetLastError();
goto Exit;
}
if (!Thread32First(SnapshotHandle, &ThreadEntry32))
{
LastError = GetLastError();
goto Exit;
}
do
{
if (ThreadEntry32.th32OwnerProcessID == (DWORD)ProcessIdentify)
{
ThreadIdentify.emplace_back((HANDLE)ThreadEntry32.th32ThreadID);
IsOk = TRUE;
}
} while (Thread32Next(SnapshotHandle, &ThreadEntry32));
Exit:
if (SnapshotHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(SnapshotHandle);
}
SnapshotHandle = INVALID_HANDLE_VALUE;
SetLastError(LastError);
return IsOk;
}
SetWindowsHookEx,实现钩子注入 :
ModuleBase = LoadLibrary(BufferData);
if (ModuleBase == NULL)
{
LastError = GetLastError();
goto Exit;
}
Sub_1 = GetProcAddress(ModuleBase, "Sub_1");
if (Sub_1 == NULL)
{
LastError = GetLastError();
goto Exit;
}
for (int i = 0; i < ThreadID.size(); ++i)
{
HookHandle = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)Sub_1, ModuleBase, (DWORD)ThreadID[i]);
if (HookHandle != NULL)
{
break;
}
}
效果展示:
DLL加载成功