API HOOK库

摘要:
由于Visual Studio 2013Preview实现的C++类仍然不允许非int静态变量,但允许函数中的静态变量,因此我将将目标指针数据备份到静态成员:staticBYTE*MemoryAddress(){staticBYTEbackup[6];returnbackup;}然后,在使用时,从Hooker:ViewCodeclassMessageBoxHooker:Hooker<MessageBoxHooker>{public:staticvoidBeginBook(){HookFunction;}staticvoidStopHook(){UnHookFunction();}private:staticintWINAPIMyMessageBoxW{StopHoo克();intx=MessageBox;BeginHook(;returnx;}};要启用Hook,只需调用:MessageBoxHooker::BeginHook();我为这个APIHOOK库使用了一个模板。使用模板的原因是C++函数指针不包含指向实例的指针。
API HOOK库

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

API HOOK库第1张 View Code

#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继承一个类即可:

API HOOK库第2张 View Code

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库》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用java8的stream对数组进行求和Mybatis-第N篇配置log4j1、log4j2打印执行的sql语句下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

socks5代理使用和安装配置

如上图所示,选择Socks5代理的类型,然后正确填写Socks代理服务器的IP、端口、用户和密码。示例3:Firefox代理Firefox浏览器连接设置可以配置为使用Socks5代理。问题是它没有提供用户输入和密码验证项目。如上图所示,客户端的默认规则是所有应用程序都使用Socks代理,这就是为什么Firefox透明地使用Socks,而不进行任何代理设置。P...

Centos7 挂载

1.Mount命令:Mount语法格式:Mount Mount设备文件信息Mount point(目录)注意:装载点(目录)必须有一个装载CD-ROM驱动器:Mount/dev/cdrom/mnt 2.卸载命令:umount语法格式:umountmount point(directory)3.查看磁盘装载状态/查看磁盘使用情况df4。存储设备通电时自动装载#...

Visual studio之C#实现数字输入模拟键盘

所以我想自己实现软键盘。这篇文章是来做记录的。在Load event表单中,添加所有标签控件的click event mybutton _ clicked,privatevoidlazerctrl _ Load{//注册键盘,单击事件keyb1。单击+=newEventHandler;keyb2。单击+=newEventHandler,keyb3。单击++=...

win10 优化批处理

@ECHOoffECHO关闭自动修复bcdedit/setrecoveryenabledNOecho完成ECHO关闭WindowsDefenderregadd“HKEY_LOCAL_MACHINESOFTWARE策略MicrosoftWindowsDefender”/v“DisableAntiSpyware”/d1/tReG_ DWORD/fcho完成ECH...

基于 WebRTC 的 RTSP 视频实时预览

该方案采用基于WebRTC的视频即时消息,其原生支持RTP协议的解码,因此延迟可以非常低,约为0.2-0.4秒。其他方案的延迟大于1秒。WebRTC需要浏览器。您可以在以下地址查看支持的浏览器。WebRTC实现基于web的视频会议。标准是WHATWG协议。其目的是通过浏览器提供简单的javascript来实现实时通信功能。Github中有很多WebRTC的实...

可用的rtmp互联网地址

Rtmp:vlc使用ffmpeg获取Rtmp网络流。代码文件路径:vlc-2.2.1 modulesassesavio。hvlc-2.2.1模块。c在模块的开放回调函数OpenAvio中,使用以下代码打开rtmp网络流。avio_打开(&amp;avio_FLAG_READ);//或者这个avio_open2(&amp;sys-&gt...