在介绍 截获系统消息钩子 之前,这几个函数是密切相关的:

SetWindowsHookEx() 介绍:

功能:将应用程序定义的挂钩过程安装到挂钩链中。

函数原型:HHOOK SetWindowsHookEx(
                  int   idHook,  // 钩子类型。
                  HOOKPROC  lpfn, // 指向挂钩过程的指针。
                  HINSTANCE   hmod, // 包含 lpfn 参数指向的挂钩过程的 DLL 的句柄。
                  DWORD   dwThreadId // 与挂钩过程关联的线程的标识符。如果为 0,则为全局钩子。
                  );

返回值:如果函数成功, 则返回值是挂钩过程的句柄。如果函数失败, 返回值为 NULL。

参数 idHook:

含义
WH_CALLWNDPROC 安装的钩子过程监视信息在系统将它们发送给目标窗口之前。
WH_CALLWNDPROCRET 安装的钩子过程监视信息在系统将它们发送给目标窗口之后。
WH_KEYBOARD 安装监视击键消息的挂钩过程。
WH_MOUSE 安装监视鼠标消息的挂钩过程。
WH_GETMESSAGE 安装用于监视将消息发送给消息队列的挂钩过程
WH_DEBUG 安装用于调试其他挂钩过程的挂钩过程。

CallNextHookEx() 介绍:

功能:将挂钩信息传递到当前挂钩链中的下一个挂钩过程。钩子过程可以在处理钩子信息之前或之后调用此函数。

函数原型:LRESULT CallNextHookEx(
                  HHOOK  hhk,  // 通常被忽略。
                  int  nCode,  // 传递给当前挂钩过程的挂钩代码。下一个挂钩过程使用此代码来确定如何处理挂钩信息。
                  WPARAM  wParam, // 传递给当前挂钩过程的 wParam 值。此参数的含义取决于与当前挂钩链关联的挂钩的类型。
                  LPARAM  lParam // 传递给当前挂钩过程的 lParam 值。此参数的含义取决于与当前挂钩链关联的挂钩的类型。
                  );

返回值:此值由链中的下一个挂钩过程返回。当前挂钩过程还必须返回此值。返回值的含义取决于挂钩类型。

UnhookWindowsHookEx() 介绍:

功能:移除由 SetWindowsHookEx 函数安装在钩子链中的挂钩过程。

函数原型:BOOL UnhookWindowsHookEx(
                  HHOOK hhk // 要移除的钩子的句柄。
                  );

返回值:非零表示成功,零表示失败。

用户自定义钩子:(生成 dll 文件,并注入到相应的进程)

#include<windows.h>
#include<stdlib.h>
HANDLE hProc;
FARPROC pfMessageBoxA;
FARPROC pfMessageBoxW;
// 注意:自定义函数得和被 HOOK 函数的形式一样,否则会发生异常。
int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR sl, UINT u);
int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR sl, UINT u);
BYTE OldMessageBoxACode[], NewMessageBoxACode[];
BYTE OldMessageBoxWCode[], NewMessageBoxWCode[];
DWORD CurrentProcessId, dwOldProtect;;
BOOL BHook = FALSE;
BOOL Init();
void HookOn();
void HookOff();
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Init();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
HookOff();
break;
}
return TRUE;
}
BOOL Init()
{
HMODULE hModule;
DWORD Address;
hModule = LoadLibraryA("user32.dll");
pfMessageBoxA = GetProcAddress(hModule, "MessageBoxA");
pfMessageBoxW = GetProcAddress(hModule, "MessageBoxW");
if (pfMessageBoxA == NULL || pfMessageBoxW == NULL)
return FALSE; memcpy(OldMessageBoxACode,pfMessageBoxA,); // 拷贝原来函数地址的前五个字节以备复原。
NewMessageBoxACode[] = 0xe9; // 即 jmp 指令。
Address = (DWORD)MyMessageBoxA - (DWORD)pfMessageBoxA - ; // 自定义函数与原函数的偏移地址。
memcpy(NewMessageBoxACode+,&Address,); memcpy(OldMessageBoxWCode,pfMessageBoxW,);
NewMessageBoxWCode[] = 0xe9;
Address = (DWORD)MyMessageBoxW - (DWORD)pfMessageBoxW - ;
memcpy(NewMessageBoxWCode+,&Address,); CurrentProcessId = GetCurrentProcessId();
HookOn();
return TRUE;
} int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR pl, UINT u)
{
HookOff();
MessageBoxA(hWnd, "请重新安装系统", "重要提示", MB_OK);
HookOn();
return TRUE;
} int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR pl, UINT u)
{
HookOff();
MessageBoxW(hWnd, L"请重新安装系统", L"重要提示", MB_OK);
HookOn();
return TRUE;
} void HookOn()
{
hProc = OpenProcess(PROCESS_ALL_ACCESS, , CurrentProcessId);
// 打开进程,关闭内存保护,向内存空间前五个字节写入 jmp 指令,最后打开进程保护。
VirtualProtectEx(hProc, pfMessageBoxA, , PAGE_READWRITE, &dwOldProtect);
WriteProcessMemory(hProc, pfMessageBoxA, NewMessageBoxACode, , );
VirtualProtectEx(hProc, pfMessageBoxA, , dwOldProtect, &dwOldProtect); VirtualProtectEx(hProc, pfMessageBoxW, , PAGE_READWRITE, &dwOldProtect);
WriteProcessMemory(hProc, pfMessageBoxW, NewMessageBoxWCode, , );
VirtualProtectEx(hProc, pfMessageBoxW, , dwOldProtect, &dwOldProtect); CloseHandle(hProc);
BHook = TRUE;
} void HookOff()
{
hProc = OpenProcess(PROCESS_ALL_ACCESS, , CurrentProcessId);
// 同理,只不过是复原内存指令。
VirtualProtectEx(hProc, pfMessageBoxA, , PAGE_READWRITE, &dwOldProtect);
WriteProcessMemory(hProc, pfMessageBoxA, OldMessageBoxACode, , );
VirtualProtectEx(hProc, pfMessageBoxA, , dwOldProtect, &dwOldProtect); VirtualProtectEx(hProc, pfMessageBoxW, , PAGE_READWRITE, &dwOldProtect);
WriteProcessMemory(hProc, pfMessageBoxW, OldMessageBoxWCode, , );
VirtualProtectEx(hProc, pfMessageBoxW, , dwOldProtect, &dwOldProtect); CloseHandle(hProc);
BHook = FALSE;
}

注入后,如下图所示:

HOOK 技术的更多相关文章

  1. HOOK技术的一些简单总结

    好久没写博客了, 一个月一篇还是要尽量保证,今天谈下Hook技术. 在Window平台上开发任何稍微底层一点的东西,基本上都是Hook满天飞, 普通应用程序如此,安全软件更是如此, 这里简单记录一些常 ...

  2. Hook技术

    hook钩子: 使用技术手段在运行时动态的将额外代码依附现进程,从而实现替换现有处理逻辑或插入额外功能的目的. 它的技术实现要点有两个: 1)如何注入代码(如何将额外代码依附于现有代码中). 2)如何 ...

  3. 程序破解之 API HOOK技术 z

    API HOOK,就是截获API调用的技术,在程序对一个API调用之前先执行你的函数,然后根据你的需要可以执行缺省的API调用或者进行其他处理,假设如果想截获一个进程对网络的访问,一般是几个socke ...

  4. API HOOK技术

    API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...

  5. 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展

    [Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...

  6. 逆向实用干货分享,Hook技术第一讲,之Hook Windows API

    逆向实用干货分享,Hook技术第一讲,之Hook Windows API 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) ...

  7. 逆向实用干货分享,Hook技术第二讲,之虚表HOOK

    逆向实用干货分享,Hook技术第二讲,之虚表HOOK 正好昨天讲到认识C++中虚表指针,以及虚表位置在反汇编中的表达方式,这里就说一下我们的新技术,虚表HOOK 昨天的博客链接: http://www ...

  8. x64内核HOOK技术之拦截进程.拦截线程.拦截模块

    x64内核HOOK技术之拦截进程.拦截线程.拦截模块 一丶为什么讲解HOOK技术. 在32系统下, 例如我们要HOOK SSDT表,那么直接讲CR0的内存保护属性去掉. 直接讲表的地址修改即可. 但是 ...

  9. Windows Hook技术

    0x01 简介 有人称它为“钩子”,有人称它为“挂钩”技术.谈到钩子,很容易让人联想到在钓东西,比如鱼钩就用于钓鱼.编程技术的钩子也是在等待捕获系统中的某个消息或者动作.钩子的应用范围非常广泛,比如输 ...

  10. Android so注入(inject)和Hook技术学习(三)——Got表hook之导出表hook

    前文介绍了导入表hook,现在来说下导出表的hook.导出表的hook的流程如下.1.获取动态库基值 void* get_module_base(pid_t pid, const char* modu ...

随机推荐

  1. Apache RocketMQ 消息队列部署与可视化界面安装

    一.介绍 Apache RocketMQ是一个分布式.队列模型的消息中间件,具有低延迟.高性能和高可靠.万亿级容量和灵活的可扩展性.核心组件由四部分组成:Name Servers,Brokers,Pr ...

  2. .Net基础篇_学习笔记_第七天_计算质数(找出0-100以内说有质数)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. shell中sh, exec, source, fork, ./的区别

    shell中sh, exec, source, fork, ./的区别 1,sh sh test.sh ​ sh是通过创建子进程(subshell)去执行脚本,父进程无法使用子进程中的变量,而子进程对 ...

  4. 【学习笔记】第五章 python3核心技术与实践--字典和集合

    [第四章]思考题的答案,仅供参考: []比list()更快,因为调用了list函数有一定的时间,而[]却没有. 前面我们学习了 Python 中的列表和元组,了解了他们的基本操作和性能比较.这节章,我 ...

  5. C++类的this指针详解

    这篇文章主要讲解隐式this指针的概念,以及如何使用,包含const 先直接给出一个C++Primer里的类,你可能还不能完全看懂,但是不着急,我们一点点解释 class Sales_data { s ...

  6. Android静态注册广播无法接收的问题(8.0+版本)

    如果你静态注册的广播无法接收到消息,请先检查下:你的安卓版本是不是8.0+ * 前言** Google官方声明:Beginning with Android 8.0 (API level 26), t ...

  7. String的优化 Stringbuffer和Stringbuilder

    string 上次说到string是最好衍生出来的一种字符类型,实现原理是由char[].我们知道数组一旦创建时不可更改的,所以每一次进行字符串的拼接都是在new一个新的字符串进行添加,这样的话对内存 ...

  8. [AWS] EC2 & GPU

    Amazon Elastic Compute Cloud (Amazon EC2) EC 2的使用 机型的选择 经验谈 Ref: Amazon EC2 实例类型 实践派 搭建网站:MediaWiki ...

  9. 将maven项目导入到eclipse中

    一,前言 本文来演示一下如何将一个新的maven项目到入到eclipse中. 在文章使用命令行创建maven web项目中我们使用maven命令行,创建了web工程,接下来为了开发方便我要将新建的工程 ...

  10. jenkins自动化部署项目1--下载安装启动(windows)

    年初以来断断续续研究jenkins自动化部署项目,前些天终于搞定了,接下来一点点把做的时候遇到的坑以及自己的心得写下来,方便以后复用. 我的jenkins服务是是部署在windows上的 一.下载安装 ...