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. ocp11g培训内部教材_053课堂笔记(043)_数据备份

    053:数据库高级管理: 目录 第一部分:数据库备份与恢复... 4 第一章:备份恢复概述... 4 1.1 备份的意义: 4 1.2 数据库故障的类型:... 4 1.3 制定你的备份和恢复的计划. ...

  2. uva 12003 Array Transformer (大规模阵列)

    白皮书393页面. 乱搞了原始数组中.其实用另一种阵列块记录. 你不能改变原始数组. 请注意,与原来的阵列和阵列块的良好关系,稍微细心处理边境.这是不难. #include <cstdio> ...

  3. 从头开始学JavaScript (九)——执行环境和作用域

    原文:从头开始学JavaScript (九)--执行环境和作用域 一.执行环境:定义了变量或者函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有与之关联的变量对象. 变量对象:保存着环境中 ...

  4. 使用DPM(Deformable Part Model,voc-release3.1)算法INRIA通过训练你的身体检测模型数据集

    我的环境 DPM源代码版本号:voc-release3.1 VOC开发包版本号:VOC2007_devkit_08-Jun Matlab版本号:MatlabR2012b c++编译器:VS2010 系 ...

  5. poj 1556 zoj1721 BellmanFord 最短路+推断直线相交

    http://poj.org/problem?id=1556 The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions ...

  6. JavaScript两种方法来定义一个函数

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 项目管理实践 -- 健身小管家(Fitness housekeeper)的管理

      最近在网上看到一篇文章<王石:我每天都强迫自己做的一件事>,[http://blog.sina.com.cn/s/blog_4dfc1c330102v0d0.html] 原始链接不详. ...

  8. struts2文件下载 <result type="stream">

    <!--struts.xml配置--> <action name="download" class="com.unmi.action.DownloadA ...

  9. 【android】WebView缓存数据收集

    Android WebView 缓存 Android高手进阶教程(二十四)之---Android WebView的缓存!!! Android webView 缓存 Cache + HTML5离线功能 ...

  10. Scala Sublime text 3 Build 编译

    使用Sublime text 3编译Scala 在sublime工具栏中[tools]->[Build System]->[new Build System]添加如下文本 { " ...