另类D3DHOOK
- 格式:docx
- 大小:14.98 KB
- 文档页数:2
DLL劫持技术当一个可执行文件运行时,Windows加载器将可执行模块映射到进程的地址空间中,加载器分析可执行模块的输入表,并设法找出任何需要的DLL,并将它们映射到进程的地址空间中。
由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件。
首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境变量中列出的各个目录下查找。
利用这个特点,先伪造一个系统同名的DLL,提供同样的输出表,每个输出函数转向真正的系统DLL。
程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功能后,再跳到系统DLL同名函数里执行,如图18.3所示。
这个过程用个形象的词来描述就是系统DLL被劫持(hijack)了。
图18.3 DLL劫持技术演示利用这种方法取得控制权后,可以对主程序进行补丁。
此种方法只对除kernel32.dll、ntdll.dll等核心系统库以外的DLL有效,如网络应用程序的ws2_32.dll、游戏程序中的d3d8.dll,还有大部分应用程序都调用的lpk.dll,这些DLL都可被劫持。
利用第5章5.6.2节提供的CrackMeNet.exe来演示一下如何利用劫持技术制作补丁,目标文件用Themida v1.9.2.0加壳保护。
1.补丁地址去除这个CrackMe网络验证方法参考第5章5.6.2节,将相关补丁代码存放到函数PatchProcess()里。
例如将401496h改成:00401496 EB 29 jmp short 004014C1补丁编程实现就是:unsigned char p401496[2] = {0xEB, 0x29};WriteProcessMemory(hProcess,(LPVOID)0x401496, p401496, 2, NULL);p401496这个数组的数据格式,可以用OllyDbg插件获得,或十六进制工具转换。
HOOK技术之SSDThook(x86x64)x86 SSDT Hook32位下进⾏SSDT Hook⽐较简单,通过修改SSDT表中需要hook的系统服务为⾃⼰的函数,在⾃⼰的函数中进⾏过滤判断达到hook的⽬的。
获取KeServiceDescriptorTable基地址要想进⾏ssdt hook,⾸先需要获得SSDT表的基地址。
因为KeServiceDescriptorTable是ntoskrnl.exe导出的,所以我们可以直接在程序中声明导⼊符号得到KeServiceDescriptorTable的值。
typedef struct ServiceDescriptorEntry {unsigned int *ServiceTableBase;unsigned int *ServiceCounterTableBase;unsigned int NumberOfServices;unsigned char *ParamTableBase;} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;extern "C" __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;可以通过ntoskrnl.exe的EAT导出表得到KeServiceDescriptorTable的值。
还可以通过搜索KeAddSystemServiceTable进⾏硬编码0xB883得到KeServiceDescriptorTable的值获取KeServiceDescriptorTableShadow基地址因为KiServiceDescriptorTableShadow并未被win32k.sys导出,所以只能通过硬编码搜索KeAddSystemServiceTable/KeRemoteSystemServiceTable得到基地址差法,⼀般KiServiceDescriptorTableShadow就在KiServiceDescriptorTable附近如果xp就是 KeServiceDescriptorTableShadow=KeServiceDescriptorTable-0×40。
大漠hook方法大漠是一个知名的游戏引擎,它提供了一系列的API和方法来实现游戏的功能和交互。
在大漠中,Hook是一种重要的技术手段,它可以用来修改游戏中的默认行为或者扩展游戏的功能。
下面将详细介绍大漠Hook方法的相关内容。
一、大漠Hook方法的概念在大漠中,Hook是一种对游戏引擎默认行为进行修改或扩展的技术。
它通过截取和处理游戏引擎的函数调用,来实现对游戏行为的干预和控制。
通过使用Hook 技术,开发者可以在不修改游戏源代码的情况下,对游戏进行一些定制化的改造,以满足特定的需求。
二、大漠Hook方法的实现原理大漠Hook方法的实现原理主要基于Windows系统中的函数钩子(Function Hook)机制。
函数钩子是一种在运行时动态修改函数调用的技术,它允许开发者通过修改函数表中的函数指针,来实现对函数调用的干预和控制。
大漠利用函数钩子机制,在游戏引擎的函数调用前后插入自定义的代码,从而实现对游戏行为的Hook。
具体来说,大漠Hook的实现步骤如下:1.找到需要Hook的函数,并获取其函数地址。
2.创建一个新的函数,该函数包含与原始函数相同的参数和返回值类型。
3.在新的函数中,添加需要在函数调用前后执行的自定义代码。
4.使用Windows系统提供的函数钩子机制,将新的函数指针替换掉原始函数的函数指针。
5.当游戏引擎调用原始函数时,实际上会跳转到新的函数中执行自定义代码,然后再调用原始函数。
6.在新的函数中,可以修改原始函数的返回值或者参数,以达到修改游戏行为的目的。
三、大漠Hook方法的分类在大漠中,Hook方法主要分为以下几类:1.键盘Hook:用于截取和修改键盘输入信号,从而实现自定义的键盘操作行为。
键盘Hook可以帮助开发者实现一些快捷键、自定义按键等功能。
2.鼠标Hook:用于截取和修改鼠标输入信号,从而实现自定义的鼠标操作行为。
鼠标Hook可以实现一些定制化的鼠标点击、移动和拖拽等功能。
新手目前过驱动HOOK保护的常见方法学习各种外挂制作技术,马上去百度搜索"魔鬼作坊"点击第一个站进入、快速成为做挂达人。
运行游戏后,那么游戏驱动保护了R0函数修改或r3函数被修改。
也差不多HOOK了某函数内部字节或函数前几个字节,我们可以用工具对比一下内核数据HOOK前字节或HOOK后字节,以及RIN3函数。
当然可以自己制作工具写个读取内核数据然后自己把字节反汇编,OD官方站点就有开源插件下载,我们就复盖悼这些被修改的字节。
hook NtOpenProcess inline hook5字节kd>u0x805751e6NtOpenProcess地址kd>u0x805751e6////没HOOK之前我们看看下面汇编ReadVirtual:805751e6not properly sign extended805751e668c4000000push0C4h805751eb68d8b04e80push offset nt!ObWatchHandles+0x25c (804eb0d8)805751f0e846e2f6ff call nt!_SEH_prolog(804e343b)805751f533f6xor esi,esi805751f78975d4mov dword ptr[ebp-2Ch],esi805751fa33c0xor eax,eax805751fc8d7dd8lea edi,[ebp-28h]805751ff ab stos dword ptr es:[edi]kd>u0x805751e6///HOOK之后HOOK后函数体ReadVirtual:805751e6not properly sign extended805751e668c4000000push0C4h805751eb e9186d8101jmp81d8bf08//跳转地址跳转到我们自己定义的函数805751f0e846e2f6ff call nt!_SEH_prolog(804e343b)805751f533f6xor esi,esi805751f78975d4mov dword ptr[ebp-2Ch],esikd>u0x81d8bf08///我们自己字义的函数ReadVirtual:81d8bf08not properly sign extended81d8bf0868d8b04e80push offset nt!ObWatchHandles+0x25c (804eb0d8)81d8bf0d e8297575fe call nt!_SEH_prolog(804e343b)////复盖指令81d8bf12e9de927efe jmp nt!NtOpenProcess+0xf(805751f5)这里跳转原函数前+0xf十六字节81d8bf170002add byte ptr[edx],al81d8bf190000add byte ptr[eax],al81d8bf1b0030add byte ptr[eax],dh81d8bf1d006900add byte ptr[ecx],ch81d8bf2052push edx再解释。
.
D3Dwindower的主界面:
小编就以侠盗猎车手为例,演示一下D3DWindower窗口化工具的使用方法!
1、首先将下载好的工具中的D3dHook.dll文件放到游戏根目录中
2、运行窗口化工具,并点击+符号选择圣安地列斯的启动文件(gta_sa.exe 汉化的用gtasa_cn.exe)
3、在工具中右击鼠标选择导入的文件,设置参数比如窗口大小等,然后在辅助DLL位置选择刚刚放到游戏目录中的D3dHook.dll文件。
设置完毕后点击确定
4、选择游戏,并且右击蓝色启动标志即可窗口化运行游戏啦
再用金融帝国2示范一次:
如有侵权请联系告知删除,感谢你们的配合!
精品。
易语言DNF召唤、无敌、技能HOOK源码教程。
学习各种外挂制作技术,马上去百度搜索"魔鬼作坊" 点击第一个站去那里学习喽。
F1=十字改轮子F2=吸头改分针F3=银光改喷毒F4=裂波改紫风F5=加血F6=加蓝.版本2007CDCFC 20050007D2066 20016007CD571 200280064A0E6 21001006494F8 22208.程序集窗口程序集1.程序集变量十字改召唤野猪魔剑, 整数型.程序集变量十字改分针, 整数型.程序集变量银光改地火, 整数型.程序集变量银光改爆炎, 整数型.程序集变量SSS, 整数型.程序集变量霸体, 整数型.子程序_窗口1_创建完毕鼠标显示()内存操作.提升权限()内存操作.打开进程()十字改召唤野猪魔剑=热键.注册(窗口1.取窗口句柄(), 0, #F1键, &十字改召唤野猪魔剑) 十字改分针=热键.注册(窗口1.取窗口句柄(), 0, #F2键, &十字改分针)银光改地火=热键.注册(窗口1.取窗口句柄(), 0, #F3键, &银光改地火)银光改爆炎=热键.注册(窗口1.取窗口句柄(), 0, #F4键, &银光改爆炎)SSS =热键.注册(窗口1.取窗口句柄(), 0, #F5键, &SSS)霸体=热键.注册(窗口1.取窗口句柄(), 0, #F6键, &霸体).子程序十字改召唤野猪魔剑写内存整数型(取窗口进程ID (窗口1.取窗口句柄()), 十六到十(“0079556D”), 860615) ' 十字改召唤野猪魔剑.子程序十字改分针写内存整数型(取窗口进程ID (窗口1.取窗口句柄()), 十六到十(“0079556D”), 860622) ' 十字改分针.子程序银光改地火写内存整数型(取窗口进程ID (窗口1.取窗口句柄()), 十六到十(“00799F38”), 20044) ' 银光改地火.子程序银光改爆炎写内存整数型(取窗口进程ID (窗口1.取窗口句柄()), 十六到十(“00799F38”), 860330) ' 银光改爆炎.子程序霸体内存操作.写代码(“010CF69C+4F0=1”) ' 霸体.子程序SSS内存操作.写代码(“0169EEA9={144,144,144}”) ' 3S.子程序_按钮1_被单击内存操作.写代码(“01080FD4+1CA8=5”) ' 远程卖.子程序_按钮2_被单击内存操作.写代码(“01080FD4+1CA8=6”) ' 远程修版本2.子程序dnf进程ID, , 公开.子程序VMP保护标记结尾, , 公开.子程序VMP保护标记开始, , 公开.子程序倍功, , 公开.参数人物基址, 文本型.参数物攻偏移, 文本型.参数攻击伤害, 整数型.参数魔攻偏移, 文本型.子程序超级瞬移CALL, , 公开.参数区域id, 整数型, , 3-塔.参数位置id, 整数型, , 7-塔.参数X轴参数, 文本型.参数y轴参数, 文本型.参数z轴参数, 文本型.参数头部参数, 文本型.子程序打开DNF进程, , 公开.子程序动作CALL, , 公开, 0.收放1.蹲下2.打坐5.死亡7.跳打9.被打12.出击15冲击打16拾取.参数基址, 整数型.参数动作ID, 整数型.参数动作CALL, 文本型.子程序返回BOSS地址, 整数型, 公开.参数类型, 整数型, , 529是怪物273是APC 1057是普通建筑33是特殊建筑.参数阵营, 整数型, 可空, 默认为队友,-1为不限100为敌人200为建筑0为队友.参数人物基址, 文本型.子程序恢复血蓝, , 公开.参数人物基址, 文本型.子程序加密, , 公开.参数地址357, 整数型.参数加密参数1, 文本型.参数加密参数2, 文本型.参数数值, 整数型.子程序解除禁闭, , 公开.子程序解除虚弱, , 公开.参数人物基址, 文本型.参数虚弱偏移, 文本型.子程序解密, 整数型, 公开.参数加密参数1, 文本型.参数加密参数2, 文本型.参数地址159, 整数型.子程序全屏捡物, , 公开.参数人物基址, 文本型.子程序人物假死, , 公开.参数人物基址, 文本型.子程序是否指定怪物, 整数型, 公开.参数地址, 整数型.参数阵营, 整数型.参数类型, 整数型.参数人物基址, 文本型.子程序鼠标显示, , 公开.子程序提升权限, , 公开.子程序无限负重, , 公开.参数人物基址, 文本型.子程序物品CALL, , 公开.参数物品基址, 整数型.参数物品代码, 整数型.参数物品CALL偏移, 文本型.子程序异界秒怪, , 公开.参数人物基址, 文本型.子程序远程出售, , 公开.参数商店基址, 文本型.子程序远程修理, , 公开.参数商店基址, 文本型学习各种外挂制作技术,马上去百度搜索"魔鬼作坊" 点击第一个站去那里学习喽。
Windows下的函数hook技术都是很成熟的东西了,这几天看了看,总结一下而已。
讨论了Windows下hook 函数的几种方法。
提供了一个hook TextOutA的完整例子。
通过CreateRemoteThread的方法把hook dll注入到一个普通的应用程序中。
Hooking Imported Functions by name调用imported functions'时的步骤/实现在程序中调用从其它模块引入的函数的方法和普通的函数调用有所不同。
对于普通的函数调用,直接使用call address来调用即可,但是对于imported functions ,在编译的时候compiler/link 并不知道实际的函数实现会被加载到那个地址,函数实现在那个地址在运行的时候才会确定。
对于imported functions ,首先是call 引入表中的一个函数,在运行时再初始化引入表,使用jmp 跳转到真实的函数实现。
引入表:实现原理•找到PE文件的Image_Import_Descriptor 结构•找到Original LAT和Real LAT.•通过要hook 的函数的名字在Original LAT找到要hook的imported function在数组中的index.•保存并修改Real LAT在相应index的function addressHooking Imported Functions by ordinal原理和Hook Imported functions by name 一样,只是是通过要hook 的函数的ordinal 在original LAT 中找到index.Hooking a function in this dll当一个DLL 是通过LoadLibrary 载入的时候,我们无法通过hook imported function 的方法的hook它中的function。
【原创】从来没人公开的秘密D3D HOOK的捷径看雪安全论坛> Windows > 『编程技术』> 【原创】从来没人公开的秘密-----D3D HOOK的捷径PDA查看完整版本: 【原创】从来没人公开的秘密-----D3D HOOK的捷径页:[1]2chengqiyan2014-06-28, 22:46:23D3D HOOK,google baidu 一大把的东西,要么是劫持的,要么是硬编码的,我介绍一种通吃各个系统DX版本的方法分为EXE和DLL,DLL采用驱动注入,然后内存重载DLL并且抹PE标志。
EXE通过FileMap与游戏内存中的DLL通信,主要是通信一些D3D偏移部分代码是内存的所以只发关键:confused:表达有限看不懂勿喷EXE层: cpp#ifndef _FINDDNF_H#include#include //#include "Find.h"//#include "MyOcr.h"//#include "GobalStruct.h"// MOMO 命令目标#include typedef struct _ImeMessage{bool IsSendIme;char SendStr[102400];LONG SendImeLenth;}MyImeStr,*PMyImeStr;typedef struct _FindPicdx{char FindPicDx_Path[1024];int FindPic_simmin;int FindPic_simmax;int FindPic_x1;int FindPic_x2;int FindPic_y1;int FindPic_y2;int FindPic_RetX;int FindPic_RetY;int FindPic_Retsim;}FindPicdx,*PFindPicdx;typedef struct _SendKey{int HasDownKey;bool IsSendKey;BYTE SendGameDxKeyDate[0xed];}SendKey,*PSendKey;typedef struct _SendMouse {bool IsSendMouse;int x;int y;}SendMouse,*PSendMouse;typedef struct _KuoZan{bool IsHookGetSelfWindow;bool IsHookGetCurSor;}Kuozan,*Pkuozan; typedef struct _MyDic{char Dic1Path[256];char Dic2Path[256];bool IsloadOk;}MyDic,*PMyDic;typedef struct _MyShowDic {char Strname[256];int DicIndex;bool IsshowDic;}MyShowDic,*PMyShowDic; /*BSTR MOMO::FindStrII( LONG Index,LONG DicIndex,LONG X1,LONG Y1,LONG X2,LONG Y2, LPCTSTR StrName,LPCTSTR ColorStr, VARIANT* FindCout)*/typedef struct _MyFindDxStr {int DicIndex;int X1;int Y1;int X2;int Y2;char StrnameS[256];char Colors[256];int RetFindHows;//返回的数据,找到多少字char RetStr[1024];bool IsFindOk;}MyFindDxStr,*PMyFindDxStr;typedef struct _Test_XY{int X;int Y;bool IsOk;}TESTXY,*PTESTXY;typedef struct _RENWU_GOTO_XY{int X;int Y;int Z;}RENWU_GOTO_XY,*PRENWU_GOTO_XY; typedef struct _Wupinsub{WCHAR Name[50];int ShuLiang;WCHAR LeiXingName1[50];int Lv;int ZhongLiang;WCHAR ZhongLeiName[50];//魔法封印此处字符串是"1" 未启用崩溃int NaiJiu;//当前耐久}Wupinsub,*PWupinsub;typedef struct _WupinAll{Wupinsub JinBi_FuHuo[3];Wupinsub KuaiJieLan[6];Wupinsub ZhuangBeiLan[56];Wupinsub XiaoHaoLan[56];Wupinsub CaiLiaoLan[56];Wupinsub RenWuLan[48];}WupinAll,*PWupinAll;typedef struct _SmallCangku{WupinsubCangku[6];}SmallCangku,*PSmallCangku;typedef struct _CurZhuangBei{Wupinsub Wuqi;Wupinsub ShangYi;Wupinsub HuJian;Wupinsub XiaZhuang;Wupinsub XieZi;Wupinsub YaoDai;Wupinsub HuWan;Wupinsub JieZhi ;WupinsubXiangLian;}CurZhuangBei,*PCurZhuangBei;typedef struct_GetLv_Name_Info{int Level;WCHAR Name[200];int Pilao;int CurFuzhong;int MaxFuzhong;}GetLv_Name_Info;typedef struct _XiGuai_GOTO_XY {int X;int Y;}XiGuai_GOTO_XY,*PXiGuai_GOTO_XY;typedef struct _3S{int BIG;int SMALL;}SSS3,*P3S;typedef struct _ZhiYe {BOOL IsGetZhiYe;WCHAR Zhiye[256];}ZhiYe,*PZhiYe; typedef struct _DATA_TO_DX{int Bind_moshi;int Bind_moshi_KEY;bool NeedWait;bool iscpu;int cpu_sleepTime;bool IsScreen;char ScreenPath[1024];HWND thisWindow;HWND MYWINDOWS;bool IsFindPic_QuanPing;char FindPci_Path[1024];bool Begin_CF;DWORD D3D_44;//SetTransform偏移量DWORD D3D_17;//Present偏移量DWORD D3D_81;DWORD D3D_82;//DrawIndexedPrimitive偏移量DWORD D3D_65;//DrawIndexedPrimitive偏移量bool Is_Bind2_ok;bool Is_Bind1_ok;bool Is_Bind_KEY1_ok;bool IsScreenXY;int x1;int x2;int y1;int y2;bool IS_FindPicDX;FindPicdx findPicdx_struct;bool IS_FindPicDX_XY; FindPicdx findPicdx_xy_struct; MyImeStr myImeMessage; HWND ImeHwnd;DWORD D3DKEY_9;DWORD D3DKEY_10;DWORD Unacquire_8;DWORD SetCooperativeLevel_13; SendKey DxKeyTogame; SendMouse DxMouseTogame;Kuozan SuperKuozan;POINT MOUSE_MOVE_WINDOWS; MyDic mydic;MyShowDic myshowdic; MyFindDxStr myDxStr;BYTE ASM_CODE[1024];int Asm_code_len;TESTXY TestXY;int GuaiwuShuliang;int WUPUN_WULIANG;BOOL ISXIGUAI;BOOL ISXIWU;RENWU_GOTO_XY RENWU_XY; WupinAll GameBeiBao;GetLv_Name_Info Name_Lv;bool IsChuShou;CurZhuangBei curzb;bool IsXiuli;bool Isadd_Liliang;int liliang;bool IsRetTili;int Rettili;int Tili;int Lv;bool IsGetName_Lv_Pilao; bool IsGetJinbi;int jinbi;BOOL IsGetBeibao;BOOL IsGetCurZhuangBei; BOOL IsEndXiuLiMaiWu; BOOL IsBeginXiuliMaiWu; int XiuliMaiwuWat;BOOL IsGetGuaiwuShuliang;BOOL IsGetWupinShuLiang; BOOL IsShunyibefor;BOOL IsShunyi;int Shunyi_Fangxiang;BOOL IsSetXiGuaiFangXiang; int XiGuaiFangXiang;BOOL Is3S;XiGuai_GOTO_XY Guai_add_xy; BOOL ISGETFANGXIANG;int RetGetFangXiang;bool IsSet3s;SSS3 sss;bool IsAddDuli;int Duli_Value;bool IsAddJingShen; int JingShen_Value; bool IsAddZL;int ZL_Value;bool IsRuoGuai; bool IsTest;bool IsSY; DWORD sdjz;DWORD fx;DWORD CallBase;BOOL Is_GetCangku;SmallCangku GameCanuku;int PrintTest;BOOL ISGOTOXY;int XIGUAI_TYPE;//吸怪类型1 排队2移到怪物那ZhiYe zhiye;}DATA_TO_DX,*PDATA_TO_DX;class MyMOMO{public:MyMOMO();~MyMOMO();HANDLE File_Maping_HANDLE;PDATA_TO_DX data; //绑定后就用它来更新控制数据DATA_TO_DX NewData;//用来存放初始化的不可以是指针哦LPVOID FileMapDATA;HWND Thehwnd;DWORD Processid;char FileName[1024];bool IsBind;LONG BindWindow(HWND hwnd,LONGBIND_MOSHI,LONG BIND_MOSHI_KEYBORD); void SendTo_Game(DATA_TO_DX* data);//MyFind myfind;//MyOcr myocr[2];//KeyArrayMap Keymap;void GetWuPinArray();void GetCurZhungbeiArray();protected:private:};class MOMO{public:MOMO();//virtual ~MOMO();MyMOMO momo1[1];IplImage* imagelistWindow;ULONG_PTR Bind_shuliang;ULONG_PTR Bind_index;LONG MOMO::Ready1(LONG Index,LONG Hwnd, char* show,char* Key_Bord,char* HELP);LONG LoadDic(LONG Index, char* DicPath, LONG DicIndex);//由于DNF,所以只在前台加载字库,即本进程加载字库。
#include <d3d8.h>
#include <d3dx8.h>
#pragma comment(lib, "d3dx8.lib")
typedef HRESULT ( WINAPI* oPresent ) ( LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
oPresent pPresent;
void *DetourFunc(BYTE *src, const BYTE *dst, const int len)
{
BYTE *jmp = (BYTE*)malloc(len+5);
DWORD dwBack;
VirtualProtect(src, len, PAGE_READWRITE, &dwBack);
memcpy(jmp, src, len);
jmp += len;
jmp[0] = 0xE9;
*(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
src[0] = 0x90; //50
src[1] = 0x90; // 58
src[2] = 0xE9;
*(DWORD*)(&src[3]) = (DWORD)(dst - src) - 7;
for (int i=7; i<len; i++) src = 0x90;
VirtualProtect(src, len, dwBack, &dwBack);
return (jmp-len);
}
HRESULT WINAPI myPresent ( LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion )
{
_asm pushad;
Sleep(100);
_asm popad;
return pPresent( pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion );
}
bool bCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
for(;*szMask;++szMask,++pData,++bMask)
if(*szMask=='x' && *pData!=*bMask )
return false;
return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask)
{
for(DWORD i=0; i < dwLen; i++)
if( bCompare( (BYTE*)( dwAddress+i ),bMask,szMask) )
return (DWORD)(dwAddress+i);
return 0;
}
int hookPresent()
{
DWORD* VTableHook = 0;
DWORD hD3D8 = (DWORD)GetModuleHandle("d3d8.dll");
DWORD VIRTUALTABLE = FindPattern(hD3D8, 0x128000, (PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86", "xx????xx????xx");
memcpy(&VTableHook, (void*)(VIRTUALTABLE+2), 4);
DWORD dwPresent = VTableHook[15];
pPresent = (oPresent)DetourFunc((PBYTE)dwPresent, (PBYTE)myPresent, 7);
return 0;
}
原理就是找到d3d8.dll的入口,搜索特征码,找到Vtalbe(虚函数表),查表找到需要hook的函数的地址,然后hook
这个比较简单,不需要在游戏启动的时候通过COM的方式取得地址,相对难度要简单得多
需要hook D3D其它函数的可以查一下有关资料,看看相关的函数在虚函数表的位置,然后hook就可以了如果要hook DX9,改对应的特征码就可以了。