windows钩子 Hook示例

Posted 早上起来洗澡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows钩子 Hook示例相关的知识,希望对你有一定的参考价值。

1.首先编写一个 win32 dll工程.

#include "stdafx.h"
int WINAPI add(int a,int b) { return a+b; }
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) {
return TRUE; }

在def文件添加显式导出: (没找到def文件需要添加)

LIBRARY
DESCRIPTION "ADD LA"
EXPORTS
 add  @1;

 

2.编写调用此dll的主程序  新建基于对话框的MFC工程

在dlg头文件里添加声明:

#include <windef.h>
public:
 HINSTANCE hAddDll;
 typedef int (WINAPI*AddProc)(int a,int b);
 AddProc add;

在程序入口 编写加载函数:

if (hAddDll==NULL)
  hAddDll=::LoadLibrary("add.dll");

 add=(AddProc)::GetProcAddress(hAddDll,"add");

 

添加一个按钮函数 调用:

 int a=1;
 int b=2;
 int c=add(a,b);
 CString temp;
 temp.Format("%d+%d=%d",a,b,c);
 AfxMessageBox(temp);

 

到这里运行主程序 就会看到。弹窗 1+2 = 3的结果。

 

3.编写hook dll 新建一个MFC dll 工程。

 在InitInstance函数中添加:

 hinst=::AfxGetInstanceHandle();
 DWORD dwPid=::GetCurrentProcessId();
 hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); 
 //调用注入函数
 Inject();
 return CWinApp::InitInstance();

所有的声明:

#pragma data_seg("SHARED")
static HHOOK  hhk=NULL; //鼠标钩子句柄
static HINSTANCE hinst=NULL; //本dll的实例句柄 (hook.dll)
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,rws")

CString temp; //用于显示错误的临时变量
bool bHook=false; //是否Hook了函数
bool m_bInjected=false; //是否对API进行了Hook
BYTE OldCode[5]; //老的系统API入口代码
BYTE NewCode[5]; //要跳转的API代码 (jmp xxxx)
typedef int (WINAPI*AddProc)(int a,int b);//add.dll中的add函数定义
AddProc add; //add.dll中的add函数
HANDLE hProcess=NULL; //所处进程的句柄
FARPROC pfadd;  //指向add函数的远指针
DWORD dwPid;  //所处进程ID://end of 变量定义

//函数定义
void HookOn();
void HookOff(); //关闭钩子
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam); //鼠标钩子函数
void Inject(); //具体进行注射,替换入口的函数
int WINAPI Myadd(int a,int b); //我们定义的新的add()函数
BOOL InstallHook(); //安装钩子函数
void UninstallHook(); //卸载钩子函数

 

声明函数的实现:

LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    LRESULT RetVal= CallNextHookEx(hhk,nCode,wParam,lParam);
    return RetVal;
}

BOOL InstallHook()
{

    hhk=::SetWindowsHookEx(WH_MOUSE,MouseProc,hinst,0);
    return true;
}

void UninstallHook()
{
    ::UnhookWindowsHookEx(hhk);
}



    void Inject()
{
    if (m_bInjected==false)
    { 

    m_bInjected=true;


    HMODULE hmod=::LoadLibrary("add.dll");
    add=(AddProc)::GetProcAddress(hmod,"add");
    pfadd=(FARPROC)add;

    if (pfadd==NULL)
    {
        AfxMessageBox("cannot locate add()");
    }

    // 将add()中的入口代码保存入OldCode[]
    _asm 
    { 
        lea edi,OldCode 
            mov esi,pfadd 
            cld 
            movsd 
            movsb 
    }

    NewCode[0]=0xe9;//实际上0xe9就相当于jmp指令
    //获取Myadd()的相对地址
    _asm 
    { 
        lea eax,Myadd
            mov ebx,pfadd 
            sub eax,ebx 
            sub eax,5 
            mov dword ptr [NewCode+1],eax 
    } 
    //填充完毕,现在NewCode[]里的指令相当于Jmp Myadd
    HookOn(); //可以开启钩子了
 }
}


void HookOn() 
{ 
    ASSERT(hProcess!=NULL);

    DWORD dwTemp=0;
    DWORD dwOldProtect;

    //将内存保护模式改为可写,老模式保存入dwOldProtect
    VirtualProtectEx(hProcess,pfadd,5,PAGE_READWRITE,&dwOldProtect); 
    //将所属进程中add()的前5个字节改为Jmp Myadd 
    WriteProcessMemory(hProcess,pfadd,NewCode,5,0);
    //将内存保护模式改回为dwOldProtect
    VirtualProtectEx(hProcess,pfadd,5,dwOldProtect,&dwTemp);

    bHook=true; 
}

void HookOff()//将所属进程中add()的入口代码恢复
{ 
    ASSERT(hProcess!=NULL);

    DWORD dwTemp=0;
    DWORD dwOldProtect;

    VirtualProtectEx(hProcess,pfadd,5,PAGE_READWRITE,&dwOldProtect); 
    WriteProcessMemory(hProcess,pfadd,OldCode,5,0); 
    VirtualProtectEx(hProcess,pfadd,5,dwOldProtect,&dwTemp); 
    bHook=false; 
}


int WINAPI Myadd(int a,int b)
{
    //截获了对add()的调用,我们给a,b都加1
    a=a+1;
    b=b+1;

    HookOff();//关掉Myadd()钩子防止死循环

    int ret;
    ret=add(a,b);

    HookOn();//开启Myadd()钩子

    return ret;
}

在def文件 添加显式导出:

 InstallHook  
 MouseProc
 Myadd
 UninstallHook 

 hook dll 就完成了。

 

4.回到主程序 添加2个按钮 一个注入 一个卸载:

注入:

 hinst=LoadLibrary("hook.dll");
 if(hinst==NULL)
 {
  AfxMessageBox("no hook.dll!");
  return;
 }
 typedef BOOL (CALLBACK *inshook)(); 
 inshook insthook;

 insthook=::GetProcAddress(hinst,"InstallHook");
 if(insthook==NULL)
 {
  AfxMessageBox("func not found!");
  return;

DWORD pid=::GetCurrentProcessId();
BOOL ret=insthook();

 

卸载:

 typedef BOOL (CALLBACK *UnhookProc)(); 
 UnhookProc UninstallHook;

 UninstallHook=::GetProcAddress(hinst,"UninstallHook");
 if(UninstallHook==NULL) UninstallHook();
 if (hinst!=NULL)
 {
  ::FreeLibrary(hinst);
 }
 if (hAddDll!=NULL)
 {
  ::FreeLibrary(hAddDll);
 }
 CDialog::OnCancel();

 

运行主程序:

计算:显示1+2 =3

注入:显示 1+2=5

完。

有任何不明白的地方欢迎骚扰:0x7317AF28

 

以上是关于windows钩子 Hook示例的主要内容,如果未能解决你的问题,请参考以下文章

php中钩子(hook)的应用示例demo

面试官: 什么是 Hook (钩子) 线程以及应用场景?

--hook,某电商(bao)app签名实现数据采集,欢迎交流

如何将 react-hook-form 用于嵌套数组

Hook(钩子技术)基本知识讲解,原理

钩子(hook)编程