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 @;
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示例的更多相关文章
- Windows API 调用示例
Ø 简介 本文主要记录 Windows API 的调用示例,因为这项技术并不常用,属于 C# 中比较孤僻或接触底层的技术,并不常用.但是有时候也可以借助他完成一些 C# 本身不能完成的功能,例如:通 ...
- 钩子(hook)
钩子(hook)编程 钩子(hook)编程 一.钩子介绍 1.1钩子的实现机制 钩子英文名叫Hook,是一种截获windows系统中某应用程序或者所有进程的消息的一种技术.下图是windows ...
- 理解钩子Hook以及在Thinkphp下利用钩子使用行为扩展
什么是钩子函数 个人理解:钩子就像一个”陷阱”.”监听器”,当A发送一个消息到B时,当消息还未到达目的地B时,被钩子拦截调出一部分代码做处理,这部分代码也叫钩子函数或者回调函数 参考网上说法 譬如我们 ...
- C# 钩子HOOK专题(1)
目录 基本概念 运行机制 钩子类型 作者 基本概念 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程 ...
- Windows API Hook
原文地址:http://blog.sina.com.cn/s/blog_628821950100xmuc.html 原文对我的帮助极大,正是由于看了原文.我才学会了HOOK.鉴于原文的排版不是非常好, ...
- [转]Windows钩子
Windows钩子 Windows应用程序的运行模式是基于消息驱动的,任何线程只要注册了窗口类就会有一个消息队列来接收用户的输入消息和系统消息.为了取得特定线程接收或发送的消息,就要 Windows提 ...
- 《windows核心编程系列》十八谈谈windows钩子
windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...
- 框架Thinkphp5 简单的实现行为 钩子 Hook
这篇文章主要介绍了关于框架Thinkphp5 简单的实现行为 钩子 Hook,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 实现在一个方法开始和结束加入两个行为:api_init.ap ...
- Windows Communication Foundation (WCF)和Windows CardSpace的示例程序
微软公司昨天发布了一个Windows Communication Foundation (WCF)和Windows CardSpace的示例程序包,内容极为丰富,从最简单的Hello World到复杂 ...
随机推荐
- Myeclipse中误报错误解决办法
下午写jsp页面的时候,用了一个js文件,拖到MyEclipse下了报错,开始还以为是js文件问题,折腾了半天,后来才知道原来是Myeclipse误报错误.真坑爹啊呀~~ 解决方法: 点击你需要忽略错 ...
- cocos2d-JS (二)Cocos Creater
我觉得我们开发使用最新的工具.这对于我们非常有帮助. 由于新的工具有着新的功能,简化了我们开发的模式. 站在巨人的肩膀上~~~~~~~~~~~~~ CocosCreator.最大的两个特点 组件化 ...
- 类加载器与Web容器
在关于类加载器中已经介绍了Jvm的类加载机制,然而对于运行在Java EE容器中的Web应用来说,类加载器的实现方式与一般的Java应用有所不同.不同的Web容器的实现方式也会有所不同. Tomcat ...
- C# 个人疏漏整理
1.dynamic和var不能混为一谈. var声明局部变量只是一种简化语法,var要求编译器根据之后的表达式推断具体的数据类型. var只能用于声明方法内部的局部变量,dynamic则可用于局部变量 ...
- java.lang.IllegalArgumentException: n must be positive
public static String randomKey(){ Random random = new Random(); int key = random.nextInt(((int)Syste ...
- The Ball Puzzle
自己做的小游戏 google play store: https://play.google.com/store/apps/details?id=com.ffipp.theBall app store ...
- 卧槽! JavaScript JVM运行Java!!
由于任何计算机语言都具有巨大的灵活性,软件世界变得有点疯狂.一旦你已经吸收了用这种语言编写的编译器的想法,那么它会编译还有什么可以留下来的?但是......用JavaScript编写的Java虚拟机J ...
- android之ViewPager修改滑动速度
在android中,使用过viewpager的人都清楚,我们如果使用viewpager进行滑动时,如果通过手指滑动来进行的话,可以根据手指滑动的距离来实现,但是如果通过setCurrentItem函数 ...
- java 学习笔记--mybatis 三剑客(mybatis)
Java项目中使用Mybatis入门程序 wanna 关注 2017.03.23 14:33* 字数 270 阅读 1243评论 0喜欢 5 MyBatis 是支持定制化 SQL.存储过程以及高级映射 ...
- page coloring小结
页着色是一种通过选择性物理页分配来实现把虚存映射到特定cache位置的软件方法. 最早引入页着色概念是在计算机体系结构,是为了解决地址别名问题引入的. 首先对cache是使用虚拟地址还是物理地址的问题 ...