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

时间: 2024-11-11 23:10:17

windows钩子 Hook示例的相关文章

Windows钩子的使用

我们知道Windows中的窗口程序是基于消息,由事件驱动的,在某些情况下可能需要捕获或者修改消息,从而完成一些特殊的功能(MFC框架就利用Windows钩子对消息进行引导).对于捕获消息而言,无法使用IAT或Inline Hook之类的方式去进行捕获,这就要用到接下来要介绍的Windows提供的专门用于处理消息的钩子函数. 1. 挂钩原理 Windows下的应用程序大部分都是基于消息机制的,它们都会有一个消息过程函数,根据不同的消息完成不同的功能.Windows操作系统提供的钩子机制的作用就是用

Windows API Hook

原文地址:http://blog.sina.com.cn/s/blog_628821950100xmuc.html 原文对我的帮助极大,正是因为看了原文,我才学会了HOOK,鉴于原文的排版不是很好, 又没有原工程例子源码下载,因此我决定对其重新整理,文章后面附有我测试时的工程源码下载地址. 注:我测试的环境为Win7+VS2008+MFC 原文出处,好像是这篇:http://blog.csdn.net/glliuxueke/article/details/2702608      //后来才看到

Windows Socket编程示例-TCP示例程序

前面一部分是介绍,后面有示例 1.网络中进程之间如何通信? 首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的.其实TCP/IP协议族已经帮我们解决了这个问题,网络层的"ip地址"可以唯一标识网络中的主机,而传输层的"协议+端口"可以唯一标识主机中的应用程序(进程).这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互. 使用TCP

《windows核心编程系列》十八谈谈windows钩子

windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功能.所谓的指定窗体并不局限于当前进程的窗体,也能够是其它进程的窗体.当监视的某一消息到达指定的窗体时,在指定的窗体处理消息之前,钩子函数将截获此消息,钩子函数既能够加工处理该消息,也能够不作不论什么处理继续传递该消息.使用钩子是实现dll注入的方法之中的一个.其它经常使用的方法有:注冊表注入,远程线

WINDOWS基本数据类型示例

最近也学学这些,争取把所有东东都串起来. #include <Windows.h> #include <stdio.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE PrevInstance, LPSTR lpCmdLine, int nCmdShow ) { LPSTR szString = "WINDOWS DATA TYPE, STRING"; CHAR lpString[120]; DWORD d

Windows Communication Foundation (WCF)和Windows CardSpace的示例程序

微软公司昨天发布了一个Windows Communication Foundation (WCF)和Windows CardSpace的示例程序包,内容极为丰富,从最简单的Hello World到复杂的解决方案一应俱全.对于Windows Communication Foundation (WCF)和Windows CardSpace这两个新东西而言,这些示例程序无疑就是最好的学习资源. 下载地址:http://www.microsoft.com/downloads/details.aspx?F

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

我们先来回顾下原本的开发流程:产品汪搞出了一堆需求:当用户注册成功后需要发送短信.发送邮件等等:然后聪明机智勇敢的程序猿们就一扑而上:把这些需求转换成代码扔在 用户注册成功 和 跳转到首页 之间: 没有什么能够阻挡:充满创造力的猿们: <?php class Test{ public function index(){ // 用户注册成功 /* 此处是一堆发送短信的代码 */ /* 此处是一堆发送邮件的代码 */ /* 此处是一堆其他功能的代码 */ // 前往网站首页 } } $test=ne

钩子(hook)编程

一.钩子介绍 1.1钩子的实现机制 钩子英文名叫Hook,是一种截获windows系统中某应用程序或者所有进程的消息的一种技术.下图是windows应用程序传递消息的过程: 如在键盘中按下一键,操作系统将收到键按下消息,把消息放入消息队列,然后消息队列对消息进行派发,发给相应的应用程序,经过应用程序处理后发给操作系统,操作系统再调用相应的应用程序的创建的窗口过程. 我们可能通过钩子截获这些消息,让消息不再往下传递,或者说截获到感兴趣的消息后做点什么. 1.2钩子分类与实现 钩子分进程内钩子与全局

实现拦截API的钩子(Hook)

道理不多讲,简单说就是将系统API的跳转地址,替换为我们自己写的API的地址,所以要求我们自定义的API函数要和被拦截的API有相同的参数.在用完后,记得恢复. 因为要挂全局的钩子,所以Hook的部分,做成DLL.   源码下载 Hook.DLL主工程文件代码 [delphi] view plaincopy library Hook; uses SysUtils, Windows, Classes, ApiDefine in 'ApiDefine.pas', APIHook in 'APIHoo