DLL注入(一)全局钩子注入进行键盘信息监听

DLL注入之全局钩子注入进行键盘信息监听

参考《逆向工程核心原理》

一、编写键盘监听DLL

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include <Windows.h>
#include <stdio.h>

HMODULE g_hDll;
HHOOK g_hHook;

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        g_hDll = hModule;
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

LRESULT CALLBACK KeyboarProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	char szPath[MAX_PATH];
	char* p = NULL;
	if (nCode >= 0)
	{
		if (!(lParam & 0x80000000))
		{
			GetModuleFileNameA(NULL, szPath, MAX_PATH);
			p = strrchr(szPath, '\\');
			if (!_stricmp(p + 1, "notepad.exe"))//只对notepad进程拦截
			{
				return 1;
			}
		}
	}
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

EXTERN_C __declspec(dllexport) void HookStart()
{
	g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboarProc, g_hDll, 0);
	DWORD errCode = GetLastError();
	printf("%d", errCode);
}

EXTERN_C __declspec(dllexport) void HookStop()
{
	if (g_hHook)
	{
		UnhookWindowsHookEx(g_hHook);
		g_hHook = NULL;
	}
}
  • 使用SetWindowsHookEx可以将一个回调函数挂钩到系统信息队列添加消息到应用信息队列的过程中。这样,我们设置的钩子就比应用先一步获得系统传递过来的消息并进行处理。相当于拦截了系统发送过来的消息。SetWindowsHookEx将最后一个参数设为0就是全局钩子,可以拦截所有应用的消息。
  • 回调函数就是由系统调用的函数。在本例中,告诉系统如果发送过来的消息是WH_KEYBOARD则调用KeyboardProc函数。这个KeyboardProc函数就是回调函数,该函数应该在一个DLL中实现。在进行处理之后,如果不 return CallNextHookEx 则该消息就会被丢弃,进程就得不到该消息。
  • SetWindowsHookEx设置好钩子后,某个进程产生特定信息时就会将DLL注入到该进程实现消息拦截。

二、编写DLL加载器

//hook.cpp
#include <Windows.h>
#include <conio.h>
#include <stdio.h>

typedef void(*HOOKSTART)();
typedef void(*HOOKSTOP)();

int main()
{
	HMODULE hDll = LoadLibrary(L"kbhook.dll");
	if (!hDll)
	{
		return 0;
	}

	HOOKSTART hookStart = (HOOKSTART)GetProcAddress(hDll, "HookStart");
	if (!hookStart)
	{
		return 0;
	}
	HOOKSTOP hookStop = (HOOKSTOP)GetProcAddress(hDll, "HookStop");
	if (!hookStop)
	{
		return 0;
	}
	hookStart();
	printf("press 'q' to quit\n");

	while (_getch() != 'q')
	{
	}

	hookStop();

	FreeLibrary(hDll);
}

三、编译运行

  • 项目结构

image-20210719230711609

​ 注意,因为我这台电脑是win10,64位,所以应该编译成64位运行,否则32位的DLL不能注入64位的程序就会整个窗口卡住。

  • 以管理员身份运行,然后在Typora打几个字,通过processExplorer可以看到dll已经被注入到Typora进程,但是打字不受影响

image-20210719235152948

  • 再看看notepad,随便打开个txt

image-20210719235343147

​ 可以看到dll被注入,并且无论输入什么都不会输出

posted @ 2021-07-22 00:26  S1mba  阅读(437)  评论(0编辑  收藏  举报