API HOOK库

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(), 6, 0);
DWORD dwCalc = ((DWORD) lpFunction - dwAddr - 5); //((to)-(from)-5)
memcpy(&jmp[1], &dwCalc, 4); //build the jmp
WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, jmp, 6, 0);
return dwAddr;
}
static BOOL UnHookFunction(LPCWSTR lpModule, LPCSTR lpFuncName)
{
DWORD dwAddr = (DWORD) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), 6, 0))
return TRUE;
return FALSE;
}
static BYTE* MemoryAddress()
{
static BYTE backup[6];
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(), 12, 0);
UINT64 dwCalc = (UINT64) lpFunction;
memcpy(&jmp[2], &dwCalc, 8); //build the jmp
WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, jmp, 12, nullptr);
return dwAddr;
}
static BOOL UnHookFunction(LPCWSTR lpModule, LPCSTR lpFuncName)
{
UINT64 dwAddr = (UINT64) GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) dwAddr, MemoryAddress(), 12, 0))
return TRUE;
return FALSE;
}
static BYTE* MemoryAddress()
{
static BYTE backup[12];
return backup;
}
};
#endif

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

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

    static BYTE* MemoryAddress()
{
static BYTE backup[6];
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有两种做法,一种是SetWindowHookEx,简单易用,但如果做其它的HOOK,如HOOK OpenProcess,就需要修改内存地址了,内存地址可以通过WriteProcessM ...

  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. 我的MYSQL学习心得(七)

    原文:我的MYSQL学习心得(七) 我的MYSQL学习心得(七) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL ...

  2. js中从blob提取二进制

    文章结构: 一.所遇到的问题 二.解决方法 一. 服务器端通过websocket向浏览器端传输图片(二进制),需要根据不同的图片把图片显示在不同的位置,可行的一个方法是先把图片转化成二进制数组,再把二 ...

  3. finally 对 return 值没有影响

    public int gettest(ref int i, ref int k) { int j = 0; try { return i / j; } catch (Exception Ex) { k ...

  4. 高性能双端js模板

    高性能双端js模板(新增filter)---simplite simplite是一款js实现的模板引擎,它能够完成浏览器端js模版和node服务器端js模板的数据渲染. 渲染性能十分突出. 支持浏览器 ...

  5. C语言库函数大全及应用实例二

    原文:C语言库函数大全及应用实例二                                              [编程资料]C语言库函数大全及应用实例二 函数名: bioskey 功 能 ...

  6. Android注入事件的三种方法比较

    方法1:使用内部APIs 该方法和其他所有内部没有向外正式公布的APIs一样存在它自己的风险.原理是通过获得WindowManager的一个实例来访问injectKeyEvent/injectPoin ...

  7. curl_redir_exec()函数

    function curl_redir_exec($ch,$debug="") { static $curl_loops = 0; static $curl_max_loops = ...

  8. sb2-admin

    近期开发中遇到的问题总结   最近准备把后台管理系统重新设计开发下,使用了bootstrap,在网上找了个漂亮的后台模板:sb2-admin,在使用中遇到了不少问题,总结下,以免以后忘记. 1.EF5 ...

  9. 快速构建Windows 8风格应用16-SettingContract原理及构建

    原文:快速构建Windows 8风格应用16-SettingContract原理及构建 本篇博文主要介绍Setting Contract概述.Setting Contract实现基本原理.如何构建Se ...

  10. Thrift学习

    Thrift学习 一:thrift介绍 Thrift是facebook开发的用来处理各不同系统之间数据通讯的rpc服务框架,后来成为apche的开源项目.thrift支持多种程序语言,包括Java,P ...