API HOOK有两种做法,一种是SetWindowHookEx,简单易用,但如果做其它的HOOK,如HOOK OpenProcess,就需要修改内存地址了,内存地址可以通过WriteProcessMemory来修改,先将调用函数的地址改成自己的(jmp到自己的函数),然后需要时,再改回来。

#pragma once

#ifdef _M_IX86
template <typename T>
class Hooker
{
protected:
static DWORD HookFunction(LPCWSTR lpModule, LPCSTR lpFuncName, PROC lpFunction)
{
DWORD dwAddr = (DWORD) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
BYTE jmp [] =
{
0xe9, //jmp
0x00, 0x00, 0x00, 0x00, //address
0xc3 //retn
}; ReadProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), , ); DWORD dwCalc = ((DWORD) lpFunction - dwAddr - ); //((to)-(from)-5) memcpy(&jmp[], &dwCalc, ); //build the jmp WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, jmp, , ); return dwAddr;
} static BOOL UnHookFunction(LPCWSTR lpModule, LPCSTR lpFuncName)
{
DWORD dwAddr = (DWORD) GetProcAddress(GetModuleHandle(lpModule), lpFuncName); if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), , ))
return TRUE; return FALSE;
} static BYTE* MemoryAddress()
{
static BYTE backup[];
return backup;
}
};
#elif _M_AMD64
template <typename T>
class Hooker
{
protected:
static UINT64 HookFunction(LPCWSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction)
{
UINT64 dwAddr = (UINT64) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
BYTE jmp [] =
{
0x48, 0xb8, //jmp
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, //address
0x50, 0xc3 //retn
}; ReadProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), , ); UINT64 dwCalc = (UINT64) lpFunction; memcpy(&jmp[], &dwCalc, ); //build the jmp WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, jmp, , nullptr); return dwAddr;
} static BOOL UnHookFunction(LPCWSTR lpModule, LPCSTR lpFuncName)
{
UINT64 dwAddr = (UINT64) GetProcAddress(GetModuleHandle(lpModule), lpFuncName); if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), , ))
return TRUE; return FALSE;
} static BYTE* MemoryAddress()
{
static BYTE backup[];
return backup;
}
};
#endif

值得注意的是,64位和32位的注入字节有些许不同。

由于目前Visual Studio 2013 Preview实现的C++类中,还是不允许有非int静态变量,但却允许函数中有静态变量,所以我将目标指针数据备份到静态成员中:

    static BYTE* MemoryAddress()
{
static BYTE backup[];
return backup;
}

然后,在使用时,从Hooker继承一个类即可:

class MessageBoxHooker : Hooker<MessageBoxHooker>
{
public:
static void BeginHook()
{
HookFunction(L"user32.dll", "MessageBoxW", (PROC) MyMessageBoxW);
}
static void StopHook()
{
UnHookFunction(L"user32.dll", "MessageBoxW");
}
private:
static int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
StopHook();
int x = MessageBox(hWnd, L"hooked", lpCaption, uType);
BeginHook();
return x;
}
};

要开启Hook,只需调用:

MessageBoxHooker::BeginHook();

这个API HOOK库我使了一个模板,之所以用模板是因为C++函数指针不包含实例的指针。这种使用模板来解决C++指针的缺点的做法很常见,ATL也是这样实现的。

本文提供的代码可以随意引用,但请充分测试后再部署,出问题本人不承担任何责任,欢迎有任何建议和补充~

我的API HOOK库的更多相关文章

  1. API HOOK库

    API HOOK库 API HOOK有两种做法,一种是SetWindowHookEx,简单易用,但如果做其它的HOOK,如HOOK OpenProcess,就需要修改内存地址了,内存地址可以通过Wri ...

  2. 10分钟API Hook MessageBox

    10分钟API Hook MessageBox 分类: C++2012-04-12 22:52 877人阅读 评论(4) 收藏 举报 hookwinapidllthreadpython编程 转载注明出 ...

  3. Detours HOOK 库 过滤LoadLibraryExW

    Detours HOOK 库 Hook 过滤LoadLibraryExW 一丶简介 1.1 Detours库简介 Detours是微软提供的HOOK库.为我们Hook提供了方便.再也不用手撸 HOOK ...

  4. Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术

    catalogue 1. 引言2. 使用注册表注入DLL3. 使用Windows挂钩来注入DLL4. 使用远程线程来注入DLL5. 使用木马DLL来注入DLL6. 把DLL作为调试器来注入7. 使用c ...

  5. 进程动态拦截注入API HOOK

    最近工作中遇到一个问题,需要通过程序界面进行判断程序的运行状态,刚开始认为很简单,不就是一个窗体控件获取,获取Button的状态和Text.刚好去年干过该事情,就没太在意,就把优先级排到后面了,随着项 ...

  6. API Hook基本原理和实现

    API Hook基本原理和实现 2009-03-14 20:09 windows系统下的编程,消息message的传递是贯穿其始终的.这个消息我们可以简单理解为一个有特定意义的整数,正如我们看过的老故 ...

  7. API HOOK介绍 【转】

    什么是“跨进程 API Hook”? 众所周知Windows应用程序的各种系统功能是通过调用API函数来实现.API Hook就是给系统的API附加上一段小程序,它能监视甚至控制应用程序对API函数的 ...

  8. 【译】值得推荐的十大React Hook 库

    十大React Hook库 原文地址:https://dev.to/bornfightcompany/top-10-react-hook-libraries-4065 原文作者:Juraj Pavlo ...

  9. 信鸽推送 .NET (C#) 服务端 SDK rest api 调用库(v1.2)

    信鸽推送 .NET  服务端 SDK rest api 调用库-介绍 该版本是基于信鸽推送v2版本的时候封装的,先拿出来与大家分享,封装还还凑合,不依赖其他http调用件,唯一依赖json序列化dll ...

随机推荐

  1. 多维算法思考(三):AB组合问题

    多维算法思考(三):AB组合问题 题目:x个A,y个B可以组合成多少个不同排列的问题. 首先,我们用数学的方式思考,这个问题属于<组合数学>的问题,我们的第一种方法可以用组合思路来求解. ...

  2. MVC创建XML,并实现增删改

    原文:MVC创建XML,并实现增删改 如果创建如下的XML: <?xml version="1.0" encoding="utf-8" standalon ...

  3. Swift入门教程:基本语法(三)

    打印输出 Swift提供了2个打印输出函数 println :输出内容后会自动换行 print :对比println,少了个自动换行的功能 示例 输出字符串 println("欢迎学习传智播 ...

  4. ZOJ 2675 Little Mammoth(计算几何)

    圆形与矩形截面的面积 三角仍然可以做到这一点 代码: #include<stdio.h> #include<string.h> #include<stdlib.h> ...

  5. 错 &#39;Cannot run program &quot;/home/uv/IDE/adt/sdk/platform-tools/adb&quot;: error=2, No such file or directory

    为linux平台搭建android开发环境的人,您可能会遇到问题,如下面有: 64位置linux安装64位置eclipse和64位置jdk开场后eclipse错误后 ""Canno ...

  6. 空连接ipc$入侵

    使用命令 net use url=file://\\IP\ipc$\\IP\ipc$ "" /user:"" 就可以简单地和目标建立一个空连接(需要目标开放ip ...

  7. 增加VMWare开机画面时间,来防止快速跳过而无法进入BIOS

    用记事本打开xx.vmx,在里面添加一行: bios.bootDelay = "30000" 意思是开机后,在开机画面里停留30秒.

  8. 在ubuntu下把php的网页调试功能打开

    我这儿的环境是 Ubuntu 14.04  + Lighttpd + PHP5.5 默认情况下php的网页调试功能是不打开的,当PHP解析到一个错误的语法时会直接输出为空白. 我在网上找一许多文章,说 ...

  9. JCronTab 定时调用

    习惯使用 unix/linux 的开发者应该对 crontab 都不陌生.Crontab 是一个很方便的用于 unix/linux 系统的任务调度命令.JCronTab 则是一款全然依照 cronta ...

  10. 如何使用AdvancedInstaller在安装包中运行一个.bat文件

    原文:如何使用AdvancedInstaller在安装包中运行一个.bat文件 1,  首先要保证你的Files and Folders模块下的Application Folder文件夹下包含你要运行 ...