写段代码教会你什么是HOOK技术?HOOK技术能干什么?

  1. 何谓HOOK技术?HOOK技术(钩子技术)属于一种拦截技术,能够为原有的代码执行流程增添逻辑,或者对其逻辑加以改变。
  2. HOOK技术有何作用?
    2.1 截获键盘与鼠标输入;2.2 拦截系统API调用;2.3 修改软件执行流程;2.4 在软件中增添新功能。

上述内容是个人对HOOK的定义。接下来,我们将通过一个软件实例进一步了解HOOK技术。

VC编程-开发自己的加密视频专用播放器3保护你的播放器和视频不被逆向「链接」

上篇中调用了三方SDK进行文件保护操作,里面也有HOOK框架。为了方便学习,我们同样采用三方SDK学习下对系统API的一个HOOK。一起了解下HOOK的一个过程。

我使用VS2017新建个MFC程序。添加如下按钮

复制代码
正常按钮的代码如下:

void ChookDlg::OnBnClickedButton1()
{
    MessageBoxW(L"这是正常的提示框");
}

在当今的软件技术领域,HOOK 技术作为一种强大且实用的工具,有着广泛的应用。在本篇内容中,我们就以 HOOK 消息提示函数为例,深入探究其在实际软件场景中的运用。

HOOK 技术,即钩子技术,它能够对系统或软件的正常执行流程进行干预和控制,通过在关键节点插入自定义的逻辑,实现诸如截获输入、修改程序行为等功能。消息提示函数在软件中是极为常见的一个功能,它用于向用户展示各种信息,如操作结果、警告提示等。

当我们聚焦于一个具体的软件时,会发现其存在一些特定的交互流程。假设这个软件有一个特定的按钮,当用户按下这个按钮后,按照正常的程序逻辑,软件会调用消息提示函数,弹出一个提示框,向用户显示"这是正常的提示框"这样的消息。这是软件原本预设的交互方式,用户在点击按钮后,就会看到这个固定的提示信息,它是软件与用户进行信息沟通的一种常规手段。

然而,借助 HOOK 技术,我们可以对这个消息提示函数进行干预。通过编写相应的 HOOK 代码,我们可以在消息提示函数被调用之前或之后插入额外的逻辑。例如,我们可以修改提示框中显示的内容,将"这是正常的提示框"替换为其他更具个性化或特定含义的消息;或者在提示框弹出之前进行一些额外的检查,只有在满足特定条件时才让提示框正常弹出,否则给出不同的提示信息。这样一来,我们就能够改变软件原本的消息提示行为,实现更加灵活和定制化的交互体验。

通过这个以 HOOK 消息提示函数为例的场景,我们可以看到 HOOK 技术在软件领域的巨大潜力和应用价值,它为软件开发者提供了一种强大的手段来对软件的行为进行调整和优化。

现在编写HOOK函数的代码

1.添加三方SDK

1.1.把SDK复制到项目内,把.H和.LIB文件添加到项目里

复制代码
#include "..\\BoxedAppSDK\\include\\BoxedAppSDK.h"
#pragma comment(lib, "..\\BoxedAppSDK\\lib\\bxsdk32.lib")

2.编写HOOK按钮代码

2.1.获取原API的地址

复制代码
BoxedAppSDK_Init(); //初始化SDK

    PVOID pMeaasgeboxW = (PVOID)GetProcAddress(
        GetModuleHandleW(L"user32.dll"),
        "MessageBoxW");

2.2。用三方SDK进行HOOK

复制代码
g_HOOKMessageBox = BoxedAppSDK_HookFunction(pMeaasgeboxW, &MY_MessageBox, FALSE);

定制个全局句柄接收

复制代码
HANDLE g_HOOKMessageBox = NULL;

这里我们写个和系统函数一样参数的新函数进行替换达到一个HOOK。三方的API可以参考文档看说明。

2.3.首先获取系统原API的原形及参数。并自己构造一个新函数

复制代码
int MessageBoxW(
  [in, optional] HWND    hWnd,
  [in, optional] LPCWSTR lpText,
  [in, optional] LPCWSTR lpCaption,
  [in]           UINT    uType
);

我们自己的消息函数
int WINAPI MY_MessageBox (HWND    hWnd,  LPCWSTR lpszText, LPCWSTR lpszCaption, UINT nType)
{
    typedef  int (WINAPI *PMessageBox) (HWND    hWnd, LPCWSTR lpszText, LPCWSTR lpszCaption, UINT nType);

    PMessageBox pMessageBox= (PMessageBox)BoxedAppSDK_GetOriginalFunction(g_HOOKMessageBox);

    lpszText = L"这是被污染的框框";



    return pMessageBox(hWnd,lpszText,lpszCaption, nType);
}

如此一来,我们便成功构造出了新的函数。借助第三方的软件开发工具包(SDK)来实施 HOOK 操作,当程序调用 MessageBoxW 函数时,就会转而进入我们自行编写的函数。

从上述代码中能够看出,在我们自定义的函数里,仅仅对提示内容进行了修改,随后直接调用原函数并返回结果。

完成代码编写之后,我们对程序进行编译,接着开展测试工作。

我们点击 HOOK 按钮,随后再次点击"正常"按钮,此时会发现消息内容已然发生了改变。

这表明程序已被顺利 HOOK。HOOK 技术,本质上就是对程序原有的内容进行变更,或是增添全新的内容。在此,为了便于直观地演示 HOOK 技术,我们直接在同一个程序中编写代码。倘若针对的是其他进程,我们可以编写一个动态链接库(DLL),待注入操作成功之后,同样能够达成这般效果。

最后,添加上"卸载"按钮的代码,以恢复 HOOK 前的状态。

复制代码
BoxedAppSDK_EnableHook(g_HOOKMessageBox, FALSE);

至此,我们的程序已恢复至初始状态。

所谓的 HOOK 技术,若想洞悉其原理,我们借助反汇编技术,利用调试器一探究竟便可明白。

我们运用反汇编调试器来启动所编写的程序,启动之后,按下"CTRL + G"组合键,即可定位到系统函数 MessageBoxW 的地址。

复制代码
74CEFECF >  8BFF            mov edi,edi
74CEFED1    55              push ebp
74CEFED2    8BEC            mov ebp,esp
74CEFED4    6A 00           push 0x0
74CEFED6    FF75 14         push dword ptr ss:[ebp+0x14]
74CEFED9    FF75 10         push dword ptr ss:[ebp+0x10]
74CEFEDC    FF75 0C         push dword ptr ss:[ebp+0xC]
74CEFEDF    FF75 08         push dword ptr ss:[ebp+0x8]
74CEFEE2    E8 A3FFFFFF     call user32.MessageBoxExW
74CEFEE7    5D              pop ebp
74CEFEE8    C2 1000         retn 0x10

此乃正常函数的起始部分。当我们点击软件界面上的"HOOK"选项之后,不妨再次进行查看。

此时会发现,代码已然发生了改变。至此,诸位是否能更为直观地理解 HOOK 技术的内涵了呢?简而言之,HOOK 技术就是让原函数的执行流程在起始处便跳转至我们自行编写的函数,进而执行自定义的逻辑。