DLL注入技术之消息钩子注入(HOOK简单的实现)

低头不是认输,是要看清自己的路。仰头不是骄傲,是看见自己的天空。——致自己

Hook,是Windows消息处理机制的一个平台,应用程序可以在上面设置子程序以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。简单来说,如下图所示(个人理解,如有错误请留言):

现在开始简单的编写一个程序,简单的实现下hook,以notepad.exe为例(因为它比较简单,hook它不用考虑权限其他啥的),对其进行hook,拦截其键盘消息。首先编写一个安装钩子的程序。

#include<stdio.h>
#include<conio.h>
#include<windows.h>

#define DLL_NAME   "HookKeyBoard.dll"
#define HOOK_START "HookStart"
#define HOOK_STOP  "HookStop"

typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();

int main()
{
    HMODULE hDll =NULL;
    PFN_HOOKSTART HookStart = NULL;
    PFN_HOOKSTOP  HookStop  = NULL;
    char ch = 0;

    //加载dll
    hDll = LoadLibraryA(DLL_NAME);

    //获取导出函数的地址
    HookStart = (PFN_HOOKSTART)GetProcAddress(hDll,HOOK_START);
    HookStop  = (PFN_HOOKSTOP)GetProcAddress(hDll,HOOK_STOP);

    //开始hook
    HookStart();

    //输入Q退出hook
    printf("输入Q退出hook!\n");
    while(1)
    {
    	char h = getch();
    	putch(h);
    	if( h == 'Q')
    	break;
    }
    //结束hook
    HookStop();

    //卸载dll
    FreeLibrary(hDll);
    return 0;  
}

可以看到,我加载了一个HookKeyBoard.dll,并使用了它的两个导出函数HookStart和HookStop,一个用来hook,一个用来Unhook,下面开始写HookKeyBoard.dll(注意写的是dll)。

#include<stdio.h>
#include<windows.h>

#define HOOK_PROCESS_NAME "notepad.exe"

HINSTANCE hInstance = NULL;
HHOOK hHook = NULL;
HWND hWnd = NULL;

BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD dwReason, LPVOID IpvReserved)
{
	switch( dwReason )
	{
	case DLL_PROCESS_ATTACH: 
		hInstance = hinstDLL;
		break;
	case DLL_PROCESS_DETACH: 
		break;
	}
	return TRUE;
}

LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
	char szPath[MAX_PATH]={0,};
	CHAR *p = NULL;
	if(!(lParam & 0x80000000))//释放按键时
	{
		GetModuleFileNameA(NULL,szPath,MAX_PATH);
		p = strrchr(szPath,'\\');
		//比较进程名称
		if(!_stricmp(p+1,HOOK_PROCESS_NAME))
		{
			//MessageBox(NULL,TEXT("hook成功"),TEXT("MY"),MB_OK);
			return 1;
		}
	}
	//不是hook的程序,则传递到出去
	return CallNextHookEx(hHook,nCode,wParam,lParam);
}
extern "C" __declspec(dllexport) void HookStart() 
{
    hHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hInstance,0);
	//MessageBox(NULL,TEXT("hook成功"),TEXT("MY"),MB_OK);
}
 
extern "C" __declspec(dllexport) void HookStop()
{
    if(hHook)
	{
		UnhookWindowsHookEx(hHook);
		hHook = NULL;
	}
}

消息钩子注入原理是利用Windows 系统中SetWindowsHookEx()这个API,他可以拦截目标进程的消息到指定的DLL中导出的函数,利用这个特性,我们可以将DLL注入到指定进程中。(msdn没搜到这个函数,msdn只列出了A版和W版的函数,他们的区别就是A字符串用ascii编码,W 宽字符,字符串用Unicode编码,所以区别不大)。

看下参数

可以看到,我挂钩KeyboardProc这个系统函数。

程序写完了,代码比较简单,有点编程基础的应该都能看懂,现在开始进行测试。测试之前,先将HookKeyBoard.dll拷贝到工程生成hook.exe的目录下,否则它找不到DLL,就会出现下面的情况。详细原因请参考之前我写的这篇博客DLL搜索的目录顺序

然后测试,第一步先打开notepad.exe,然后点击hook.exe

然后打开Process Explorer进程监视器,查看加载的DLL,然后尝试在notepad.exe里面输入东西,可以看到HookKeyBoard.dll被notepad.exe加载了,并且在notepad.exe输入任何东西都不能显示出来(被hook了),其他地方则可以正常显示。

 

  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
c hook注入dll是一种在Windows系统中实现函数钩子技术。下面给出一个完整的例子: 首先,创建一个c文件,命名为hookdll.c,代码如下: #include <Windows.h> // 定义要hook的目标函数 typedef bool (WINAPI* ORIGINAL_FUNCTION)(LPCTSTR); ORIGINAL_FUNCTION OriginalFunction; // 定义hook的替代函数 bool WINAPI HookFunction(LPCTSTR lpFileName) { // 在这里编写你的hook函数逻辑 // 可以在这个函数中修改传入参数或返回值,实现钩子的目的 // ... // 调用原始函数 return OriginalFunction(lpFileName); } // Dll入口函数 BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { // 加载kernel32.dll HMODULE kernel32 = LoadLibrary("kernel32"); if (kernel32 != NULL) { // 获取目标函数地址 OriginalFunction = (ORIGINAL_FUNCTION)GetProcAddress(kernel32, "函数名"); if (OriginalFunction != NULL) { // 修改函数的内存属性为可执行和可写 DWORD oldProtect; VirtualProtect(OriginalFunction, sizeof(ORIGINAL_FUNCTION), PAGE_EXECUTE_READWRITE, &oldProtect); // 修改函数的指针为hook函数的指针 *OriginalFunction = &HookFunction; // 还原函数的内存属性 VirtualProtect(OriginalFunction, sizeof(ORIGINAL_FUNCTION), oldProtect, &oldProtect); } // 释放kernel32.dll内存 FreeLibrary(kernel32); } } return TRUE; } 编译这个项目,得到一个dll文件,命名为hookdll.dll。 然后,创建一个使用目标dll的示例程序,例如使用了kernel32.dll中的某个方法。然后按照以下步骤实现hook注入: 1. 打开示例程序的源代码,编辑代码,添加以下代码段: #pragma comment(lib, "hookdll.lib") 2. 将hookdll.dll拷贝到示例程序的目录下。 3. 使用LoadLibrary函数在程序中动态加载hookdll.dll。 4. 调用示例程序中使用kernel32.dll中方法的代码,此时会执行被hook函数的替代函数。 通过以上步骤,我们就实现了c hook注入dll的完整例子。在hook函数中可以对传入的参数或返回值进行修改,实现我们想要的钩子效果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值