天天看點

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)