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 @;

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=;
int b=;
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,,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[]; //老的系统API入口代码
BYTE NewCode[]; //要跳转的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,);
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[]=0xe9;//实际上0xe9就相当于jmp指令
//获取Myadd()的相对地址
_asm
{
lea eax,Myadd
mov ebx,pfadd
sub eax,ebx
sub eax,
mov dword ptr [NewCode+],eax
}
//填充完毕,现在NewCode[]里的指令相当于Jmp Myadd
HookOn(); //可以开启钩子了
}
} void HookOn()
{
ASSERT(hProcess!=NULL); DWORD dwTemp=;
DWORD dwOldProtect; //将内存保护模式改为可写,老模式保存入dwOldProtect
VirtualProtectEx(hProcess,pfadd,,PAGE_READWRITE,&dwOldProtect);
//将所属进程中add()的前5个字节改为Jmp Myadd
WriteProcessMemory(hProcess,pfadd,NewCode,,);
//将内存保护模式改回为dwOldProtect
VirtualProtectEx(hProcess,pfadd,,dwOldProtect,&dwTemp); bHook=true;
} void HookOff()//将所属进程中add()的入口代码恢复
{
ASSERT(hProcess!=NULL); DWORD dwTemp=;
DWORD dwOldProtect; VirtualProtectEx(hProcess,pfadd,,PAGE_READWRITE,&dwOldProtect);
WriteProcessMemory(hProcess,pfadd,OldCode,,);
VirtualProtectEx(hProcess,pfadd,,dwOldProtect,&dwTemp);
bHook=false;
} int WINAPI Myadd(int a,int b)
{
//截获了对add()的调用,我们给a,b都加1
a=a+;
b=b+; 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示例的更多相关文章

  1. Windows API 调用示例

    Ø  简介 本文主要记录 Windows API 的调用示例,因为这项技术并不常用,属于 C# 中比较孤僻或接触底层的技术,并不常用.但是有时候也可以借助他完成一些 C# 本身不能完成的功能,例如:通 ...

  2. 钩子(hook)

    钩子(hook)编程     钩子(hook)编程 一.钩子介绍 1.1钩子的实现机制 钩子英文名叫Hook,是一种截获windows系统中某应用程序或者所有进程的消息的一种技术.下图是windows ...

  3. 理解钩子Hook以及在Thinkphp下利用钩子使用行为扩展

    什么是钩子函数 个人理解:钩子就像一个”陷阱”.”监听器”,当A发送一个消息到B时,当消息还未到达目的地B时,被钩子拦截调出一部分代码做处理,这部分代码也叫钩子函数或者回调函数 参考网上说法 譬如我们 ...

  4. C# 钩子HOOK专题(1)

    目录   基本概念 运行机制 钩子类型 作者 基本概念   钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程 ...

  5. Windows API Hook

    原文地址:http://blog.sina.com.cn/s/blog_628821950100xmuc.html 原文对我的帮助极大,正是由于看了原文.我才学会了HOOK.鉴于原文的排版不是非常好, ...

  6. [转]Windows钩子

    Windows钩子 Windows应用程序的运行模式是基于消息驱动的,任何线程只要注册了窗口类就会有一个消息队列来接收用户的输入消息和系统消息.为了取得特定线程接收或发送的消息,就要 Windows提 ...

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

    windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...

  8. 框架Thinkphp5 简单的实现行为 钩子 Hook

    这篇文章主要介绍了关于框架Thinkphp5 简单的实现行为 钩子 Hook,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 实现在一个方法开始和结束加入两个行为:api_init.ap ...

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

    微软公司昨天发布了一个Windows Communication Foundation (WCF)和Windows CardSpace的示例程序包,内容极为丰富,从最简单的Hello World到复杂 ...

随机推荐

  1. MooseFS管理

    一.goal(副本) 副本,在MFS中也被称为目标(Goal),它是指文件被复制的份数,设定目标值后可以通过mfsgetgoal命令来证实,也可以通过mfssetgoal命令来改变设定. 1 2 3 ...

  2. Form.ShowWithoutActivation 属性

    获取一个值,该值指示显示窗口时是否激活它. 命名空间:  System.Windows.Forms程序集:  System.Windows.Forms(在 System.Windows.Forms.d ...

  3. 斑马Zebra ZPLII指令集中文说明解释

      我们最常用的斑马(Zebra)条码打印机,应用ZPLII命令来控制打印,说明书中有每条指令的详细说明及相关示例,下面是各指令的中文释义: ^A 对Zebra内置点阵字体缩放 ^A(可缩放/点阵字体 ...

  4. 使用ZBar来读取条形码和二维码的方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.使用ZBar项目.下载地址是: http://zbar.sourceforge.net/iphone/index.html 2.新建一个项目. ...

  5. poj 1636 Prison rearrangement

    Prison rearrangement   Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 2158   Accepted: ...

  6. 使用Django框架

    1.安装Django 在命令行模式下使用pip工具来安装Django,pip工具的安装方法见此篇 pip install django 2.确认是否安装成功 在Python交互模式下 import d ...

  7. 利用yum下载rpm离线包

    # 利用yum下载rpm包 ### 简介-----------------------------yum是基于red hat系统的默认包管理器.使用yum可以安装或更新一个rpm包,并且他会自动解决包 ...

  8. JQuery EasyUI datagrid pageNumber 分页 请求/加载 两次

    解决方案: 原因是 jquery.easyui.min.js 源文件中,由于第1页的total和其他页的total不相等,EasyUI会重新发起第1页的请求!1.jQuery EasyUI 1.4.1 ...

  9. (译)Getting Started——1.2.3 Defining the Interaction(定义交互)

    IOS应用编程是基于事件驱动的编程.也就是说,应用的流程由事件来决定:事件包括系统事件和用户操作.界面上用户执行的操作会触发事件.这些事件导致应用的逻辑被执行,数据被操作.应用对用户动作的响应反映在界 ...

  10. SAML2.0 协议初识(三)——IDP

    IDP,即提供身份认证服务的一端,通常,当 IDP 接收到 SP 发送的 SAML 认证请求后,解析 SAMLRequest 参数,包括 acs 地址.SP EntityId.绑定方式.是否加密等信息 ...