天天看点

Inject集合----远程线程注入(SetWindowsHookEx)

   前几篇文章,是通过远程线程的方式来注入目标进程,来实现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;
		}
	}
           

效果展示:

Inject集合----远程线程注入(SetWindowsHookEx)

DLL加载成功

Inject集合----远程线程注入(SetWindowsHookEx)
Inject集合----远程线程注入(SetWindowsHookEx)