【C++】实现D3D9 的 Inline hook
#include<process.h>
int __stdcall DllMain(void* _DllHandle, unsigned long _Reason, void*_Reserved)
{
if (_Reason == DLL_PROCESS_ATTACH)
{
_beginthreadex(nullptr, 0, initialize_d3d9, nullptr, 0, nullptr);
}
return 1;
}
// 注:initialize_d3d9是d3d9部分的函数
用上面的函数HOOK掉D3D9的函数
#pragma once
#include<Windows.h>
constexpr int byte_length = 5; //修改函数的前五个字节,修改为jmp class inline_hook
{
private:
using uchar = unsigned char;
using dword = DWORD;
uchar m_original_byte[byte_length];
uchar m_self_byte[byte_length];
int m_original_address; //原始函数的地址
int m_self_address;//自己函数的地址
dword motify_memory_attribute(int address, dword attribute = PAGE_EXECUTE_READWRITE)
{
dword old_attributes;
VirtualProtect(reinterpret_cast<void*>(address), byte_length, attribute, &old_attributes);
return old_attributes;
}
public:
inline_hook(int original_address, int self_address) :m_original_address(original_address), m_self_address(self_address)
{
m_self_byte[0] = '\xe9'; //jmp的硬编码
int offset = self_address - (original_address + byte_length); //计算偏移
memcpy(&m_self_byte[1], &offset, byte_length - 1); //构造字节
dword attribute = motify_memory_attribute(original_address); //修改内存属性
memcpy(m_original_byte, reinterpret_cast<void*>(original_address), byte_length); //将程序原来的函数代码保存到 m_original_byte
motify_memory_attribute(original_address, attribute); // 还原内存属性
}
void motify_address() //修改原来的函数
{
dword attribute = motify_memory_attribute(m_original_address); //修改内存属性
//写入自己构造的字节
memcpy(reinterpret_cast<void*>(m_original_address), m_self_byte, byte_length);// 将构造好的字节,覆盖到原来的函数的地方
motify_memory_attribute(m_original_address, attribute); //还原内存属性
}
void restore_address() //恢复原来的函数
{
dword attribute = motify_memory_attribute(m_original_address);
memcpy(reinterpret_cast<void*>(m_original_address), m_original_byte, byte_length);
motify_memory_attribute(m_original_address, attribute);
}
};
代码部分(D3D9部分):
/*需要包含的头文件*/
#include<d3d9.h>
#include<HOOK部分代码>
#pragma comment(lib,"d3d9.lib")
/*一些必要的全局变量*/
IDirect3D9 * g_direct3d9 = nullptr;
IDirect3DDevice9 *g_direct3ddevice9 = nullptr;
D3DPRESENT_PARAMETERS g_present;
HWND g_hwnd = FindWindowA(nullptr, "Counter-Strike: Global Offensive - Direct3D 9");
//HWND g_hwnd = FindWindowA("Valve001",nullptr); inline_hook*g_Reset_hook = nullptr; //hook Reset 函数
inline_hook*g_EndScene_hook = nullptr;
inline_hook*g_DrawIndexedPrimitive_hook = nullptr; /*如果需要劫持Reset函数,则写一个函数代替原来的Reset*/ HRESULT __stdcall self_Reset(IDirect3DDevice9 *g_direct3ddevice9, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
printf("join\n"); //自己需要实现的功能写在这里
HRESULT result = D3D_OK;
g_Reset_hook->restore_address();
if (g_direct3ddevice9)
{
ImGui_ImplDX9_InvalidateDeviceObjects();
HRESULT result = g_direct3ddevice9->Reset(pPresentationParameters); //调用原来的Reset函数
ImGui_ImplDX9_CreateDeviceObjects();
}
g_Reset_hook->motify_address();
return result;
} /*DLL注入后执行此函数*/ unsigned int __stdcall initialize_d3d9(void*data)
{
AllocConsole();
freopen("CON", "w", stdout);
g_direct3d9 = Direct3DCreate9(D3D_SDK_VERSION);
check_error(g_direct3d9, "Direct3DCreate9失败");
memset(&g_present, 0, sizeof(g_present));
g_present.Windowed = TRUE;
g_present.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_present.BackBufferFormat = D3DFMT_UNKNOWN;
g_present.EnableAutoDepthStencil = TRUE;
g_present.AutoDepthStencilFormat = D3DFMT_D16;
HRESULT result = g_direct3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_present, &g_direct3ddevice9);
check_error(result == 0, "CreateDevice失败");
int *direct3d9_table = (int*)*(int *)g_direct3d9;
int *direct3ddevice9_table = (int*)*(int *)g_direct3ddevice9;//这里是一个表,储存了direct的函数,通过劫持这些函数,转接到自己的函数,通过速览IDirect3DDevice9的定义可以看到函数
g_Reset_hook = new inline_hook(direct3ddevice9_table[16], (int)self_Reset); //hook掉了reset
g_Reset_hook->motify_address(); //还原了Reset
//direct3ddevice9_table[下标],下标通过速览定义IDirect3DDevice9结构可知,看需要hook掉的函数在结构的第几位,减去一则是下标
return 0;
}
此时以DLL编译,完成后用DLL注入器注入,则完成D3D9的inline hook,需要HOOK其他函数,则仿照Reset_hook 的写法
g_Reset_hook = new inline_hook(direct3ddevice9_table[16], (int)self_Reset); //hook掉了reset
g_Reset_hook->motify_address(); //还原了Reset
HOOK 掉 DrawIndexedPrimitive举例
先写自己的函数
HRESULT __stdcall self_DrawIndexedPrimitive(IDirect3DDevice9 *g_direct3ddevice9,D3DPRIMITIVETYPE type, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount)
{
HRESULT result = D3D_OK;
{
/*自己的功能*/
}
g_DrawIndexedPrimitive_hook->restore_address(); result = g_direct3ddevice9->DrawIndexedPrimitive(type, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); g_DrawIndexedPrimitive_hook->motify_address(); return result;
}
在 initialize_d3d9 函数中增加
g_DrawIndexedPrimitive_hook = new inline_hook(direct3ddevice9_table[82], (int)self_DrawIndexedPrimitive); //hook掉了DrawIndexedPrimitive
g_DrawIndexedPrimitive_hook->motify_address();
至此,完成对DrawIndexedPrimitive的HOOK
ENDING.............
【C++】实现D3D9 的 Inline hook的更多相关文章
- 对付ring0 inline hook
对付ring0 inline hook的基本思路是这样的,自己写一个替换的内核函数,以NtOpenProcess为例,就是MyNtOpenProcess.然后修改SSDT表,让系统服务进入自己的函数M ...
- Inline Hook NtQueryDirectoryFile
Inline Hook NtQueryDirectoryFile 首先声明这个是菜鸟—我的学习日记,不是什么高深文章,高手们慎看. 都总是发一些已经过时的文章真不好意思,几个月以来沉迷于游戏也是时候反 ...
- android inline hook
最近终于沉下心来对着书把hook跟注入方面的代码敲了一遍,打算写几个博客把它们记录下来. 第一次介绍一下我感觉难度最大的inline hook,实现代码参考了腾讯GAD的游戏安全入门. inline ...
- 在已有软件加壳保护 下实现 Inline hook
如写的不好请见谅,本人水平有限. 个人简历及水平:. http://www.cnblogs.com/hackdragon/p/3662599.html 正常情况: 接到一个项目实现对屏幕输出内容的获取 ...
- windows 32位以及64位的inline hook
Tips : 这篇文章的主题是x86及x64 windows系统下的inline hook实现部分. 32位inline hook 对于系统API的hook,windows 系统为了达成hotpatc ...
- Inline Hook
@author: dlive IAT Hook时如果要钩取的API不在IAT中(LoadLibrary后调用),则无法使用该技术.而Inline Hook不存在这个限制. 0x01 Inline Ho ...
- INLINE HOOK过简单驱动保护的理论知识和大概思路
这里的简单驱动保护就是简单的HOOK掉内核API的现象 找到被HOOK的函数的当前地址在此地址处先修改页面保护属性然后写入5个字节.5个字节就是一个简单的JMP指令.这里说一下JMP指令,如下: 00 ...
- x86平台inline hook原理和实现
概念 inline hook是一种通过修改机器码的方式来实现hook的技术. 原理 对于正常执行的程序,它的函数调用流程大概是这样的: 0x1000地址的call指令执行后跳转到0x3000地址处执行 ...
- Android Hook框架adbi的分析(2)--- inline Hook的实现
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/74452308 一. Android Hook框架adbi源码中inline Hoo ...
随机推荐
- 借助SpotBugs将程序错误扼杀在摇篮中
背景 最近一年多在一家toB业务的公司,部门主要做的是建筑行业的招投标业务信息化,希望借助软件来达到"阳光.降本.提效"的目的,我刚入职时大概30多家客户,截止现在已经超过100家 ...
- 基于slate构建文档编辑器
基于slate构建文档编辑器 slate.js是一个完全可定制的框架,用于构建富文本编辑器,在这里我们使用slate.js构建专注于文档编辑的富文本编辑器. 描述 Github | Editor DE ...
- DDos、CC攻击与防御
DDoS介绍 DDoS是英文Distributed Denial of Service的缩写,意即"分布式拒绝服务",那么什么又是拒绝服务(Denial of Service)呢? ...
- lvm逻辑卷创建及使用
创建逻辑卷 pvcreate /dev/md0 pvs 查看创建的pv组 pvdisplay /dev/md0 查看磁盘详细信息 添加vg组: 创建vg组: vgcreate vg1 /dev/md0 ...
- 基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 【PostgreSQL 】PostgreSQL 15对distinct的优化
示例表 table t_ex; c1 | c2 ----+---- 2 | B 4 | C 6 | A 2 | C 4 | B 6 | B 2 | A 4 | B 6 | C 2 | C 以下SQL语 ...
- Solution -「Local 11145」诗意狗
0x01 前置芝士 树形结构?贪心?思维?眼睛? 好有趣... link 0x02 题目大意:给你一颗有 \(n\) 个节点的树,你需要尽可能多的删掉边,使得剩下的图中有 \(k\) 个点满足互相能走 ...
- c# 添加指定扩展名的系统右键菜单(Windows11以前)
在上篇文章c# 添加系统右键菜单(Windows11以前)中我们说了怎么在文件夹上增加一个菜单项,但是我们可能还需要给某个单独的扩展名添加右键菜单. 这里我们不用常见的扩展名来做,我们新做一个.jx的 ...
- 透过Redis源码探究Hash表的实现
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/667 本文使用的Redis 5.0源码 概述 我们在学习 Redis ...
- 沙漠世界1.0 c++小游戏
#include<bits/stdc++.h> #include<time.h> #include<windows.h> #include<stdlib.h& ...