通过设置消息钩子,达到和dll注入相同的目的,但这个方法与其他DLL注入方法又不一样,它不会把自己的DLL加载到目标进程,所以也就实现不来DLL的隐藏,这样很容易被杀软KILL掉,亲测360秒杀,但实现简单还有有相当的应用场景,下面是一个通用的消息勾取主函数,它将关键的消息勾取函数SetWindowsHookEx函数放到了DLL当中,通过DLL调用来实现消息勾取,因为此逻辑相对简单,此处就不详细介绍,直接贴代码。
#include "stdafx.h"
#include "windows.h"
#define DEF_DLL_NAME "KeyHook_Con.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"
typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();
void _tmain(int argc, _TCHAR* argv[])
{
HMODULE hDll = NULL;
PFN_HOOKSTART HookStart = NULL;
PFN_HOOKSTOP HookStop = NULL;
hDll = LoadLibraryA(DEF_DLL_NAME);
//获取导出函数地址
HookStart= (PFN_HOOKSTART)GetProcAddress(hDll,DEF_HOOKSTART);
HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll,DEF_HOOKSTOP);
//开始勾取
HookStart();
//等待用户输入“q”结束
printf("press q to quit\n");
while(getchar()!='q');
//终止勾取
HookStop();
//卸载KeyHook.dll
FreeLibrary(hDll);
}
下面是DLL函数
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#define DEF_PROCESS_NAME "notepad.exe"
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook =NULL;
HWND g_hWnd = NULL;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
BOOL WINAPI DllMain( HINSTANCE hinstDll, DWORD dwReason, LPVOID lpreserved )
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
g_hInstance = hinstDll;
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,'\\');
//比较当前进程名 若为notepad.exe 则消息不会传递给应用程序(或下一个钩子)
if(!strcmp(p+1,DEF_PROCESS_NAME))
{
//当我在WIN10 64位机运行的时候,发现很容易是目标进程卡
//住,不知道是什么原因,而XP 32位并没有此现象
printf("记事本键盘消息已被截取\n");
return 1;
}
}
//若非notepad.exe 则调用CallNextHookEx()函数,将消息传递给应用程序或者下一个钩子
return CallNextHookEx(g_hHook,nCode,wParam,lParam);
}
#ifdef __cplusplus
extern "C"{
#endif
__declspec(dllexport) void HookStart()
{
//关键函数这一个,安装消息钩子
g_hHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,g_hInstance,0);
}
__declspec(dllexport) void HookStop()
{
if (g_hHook)
{
UnhookWindowsHookEx(g_hHook);
g_hHook =NULL;
}
}
#ifdef __cplusplus
}
#endif