游戏环境下如何实现真正D3D的窗口?启动进程和取得进程的方法
(资料图)
前些日子一直忙,也没来看看,说要给出代码和方法的一直没有给出来请大家见谅,今天给出来! 声明:我不是做游戏外挂的,所以对外挂部分还比较薄弱,没做,只做实现窗口这一块! 1.先看实现的图片,等下慢慢解释。
2.首先解释要如何启动诸仙的进程。我们要想拥有自己的窗口,那么就必须在诸仙的进程启动之前得到Direct3DCreate8接口(诸仙用Direct3D8)。所以启动过程如下: //启动诸仙并获取诸仙进程句柄 ZhuXianProc.OpenExe("C://游戏目录//诛仙//element//elementclient.exe"); if(!ZhuXianProc.GetProcess()) { MessageBox(NULL, " 无法正常启动《诸仙》主程序/n/n获取帮助请与本工作室技术人员联系", "天涯工作室程序运行错误提示!",MB_OK); return TRUE; } //在程序运行之前先HOOK住所需要HOOK的API HookApi("C://游戏目录//诛仙//element//elementclient.exe","C://游戏目录//诛仙//element//ZxDll.dll"); ZhuXianFunc(); ZhuXianProc.CloseAllHandle(); 关于ZhuXianProc是一个CGetProc类型,这个类主要是打开进程和取得进程的一些信息,GetProcess()取的改进程的句柄。这个类里面要解释下的是:void CGetProc::OpenExe(CString str) { memset(&si,0,sizeof(si)); si.cb=sizeof(si); si.wShowWindow=SW_SHOW; si.dwFlags=STARTF_USESHOWWINDOW; CreateProcess(str,NULL,NULL,FALSE,NULL,CREATE_SUSPENDED,NULL,NULL,&si,&pi); } “CREATE_SUSPENDED”指明该进程并不是一开始就让他运行,原因是我们要想得到Direct3DCreate8接口就必须在运行进程之前注入我们的DLL,并让我们的DLL里的HOOK Direct3DCreate8接口跑到他的初始化之前。我们来看看HookApi()的内容:bool CUIThread::HookApi(char* pszFileExe,char* pszFileDll) { //让程序启动的时候JMP到自己的DLL中去 HANDLE hProcess = ZhuXianProc.GetProcess(); // 在目标进程申请空间,存放字符串pszDllName,作为远程线程的参数 int cbSize = (strlen(pszFileDll) + 1); LPVOID lpRemoteDllName = ::VirtualAllocEx(hProcess, NULL, cbSize, MEM_COMMIT, PAGE_READWRITE); ::WriteProcessMemory(hProcess, lpRemoteDllName, pszFileDll, cbSize, NULL); // 取得LoadLibraryA函数的地址,我们将以它作为远程线程函数启动 HMODULE hModule=::GetModuleHandle ("kernel32.dll"); LPTHREAD_START_ROUTINE pfnStartRoutine = (LPTHREAD_START_ROUTINE)::GetProcAddress(hModule, "LoadLibraryA"); // 启动远程线程 ::ResumeThread(ZhuXianProc.GetThread()); HANDLE hRemoteThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnStartRoutine, lpRemoteDllName, 0, NULL); if(hRemoteThread == NULL) { ::CloseHandle(hProcess); return FALSE; } ::CloseHandle(hRemoteThread); return TRUE; } 这段关键是在: // 启动远程线程 ::ResumeThread(ZhuXianProc.GetThread()); HANDLE hRemoteThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnStartRoutine, lpRemoteDllName, 0, NULL); 必须这样,ResumeThread诸仙进程之后立即启动我们的DLL。呵呵,也不能弄反,如果进程没启动,我们注入的DLL就启动了,进程可能就崩溃了。 在这里有个小技巧,诸仙进程启动不代表就立即进行Direct3DCreate8初始化,他还有些事情要做,到他初始化的时候我们的DLL早就跑了一段了:)。 3.来看看我们的重点,我们注入的ZXDLL.DLL到底做了些什么事情。 #pragma comment(lib, "d3d8.lib")// CZxDllAppBEGIN_MESSAGE_MAP(CZxDllApp, CWinApp)END_MESSAGE_MAP()// CZxDllApp 构造CZxDllApp::CZxDllApp(){// TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中}// 唯一的一个 CZxDllApp 对象CZxDllApp theApp;CAPIHook hookapi2("d3d8.dll","Direct3DCreate8",(PROC)NewDirect3DCreate8);// CZxDllApp 初始化BOOL CZxDllApp::InitInstance(){CWinApp::InitInstance(); return TRUE;}看完DLL的这一段小程序,基本上是VC向导完成的,只有一句:CAPIHook hookapi2("d3d8.dll","Direct3DCreate8",(PROC)NewDirect3DCreate8);这 句在DLL一运行的时候他就运行了,并把Direct3DCreate8给变成了新的入口地址NewDirect3DCreate8了,那么当诸仙运行的 时候这个函数就跑到我们的NewDirect3DCreate8里来了,呵呵,正好,我们抓住了Direct3DCreate8接口了,来我们一起看看 NewDirect3DCreate8函数里的内容。IDirect3D8 * WINAPI NewDirect3DCreate8(UINT SDKVersion){static int count = 0; static IDirect3D8* test = NULL; hookapi2.Unhook(); IDirect3D8 * m = Direct3DCreate8(SDKVersion); hookapi2.Rehook();//程序一共3个3维平面驱动 count++; if(count==2){//1,窗口模式请用2,全屏模式请用3 lpD3D = m; //替换VTable,实现对IDirect3Draw 的 COM接口的挂钩 NewlpD3d = new MyIDirect3D8; m = (IDirect3D8*)NewlpD3d; } return m;}呵 呵,诸仙对IDirect3D8接口其实是驱动了3次,我没查出来第一次是干什么的,但是后两次一个是在窗口模式下用的,一个是在全屏模式下用的。光得到 IDirect3D8接口是没用的这里我们还要进行COM HOOK 获得Direct3DDevice8(D3D 设备) 的接口的指针从而得到我们的Render该放到什么地方。COM HOOK其实就是写一个同样的类用来替换COM的VTable,不做详细的解释,实在搞不懂就google(俺也是这么得来的:))。MyIDirect3D8就是一个新的IDirect3D8类,他是从IDirect3D8继承来的,定义如下:class MyIDirect3D8 : public IDirect3D8{public: HRESULT APIENTRY QueryInterface(REFIID riid, void** ppvObj); ULONG APIENTRY AddRef(); ULONG APIENTRY Release(); /*** IDirect3D8 methods ***/ HRESULT APIENTRY RegisterSoftwareDevice(void* pInitializeFunction); UINT APIENTRY GetAdapterCount(); HRESULT APIENTRY GetAdapterIdentifier(UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER8* pIdentifier); UINT APIENTRY GetAdapterModeCount(UINT Adapter); HRESULT APIENTRY EnumAdapterModes(UINT Adapter,UINT Mode,D3DDISPLAYMODE* pMode); HRESULT APIENTRY GetAdapterDisplayMode(UINT Adapter,D3DDISPLAYMODE* pMode); HRESULT APIENTRY CheckDeviceType(UINT Adapter,D3DDEVTYPE CheckType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL Windowed); HRESULT APIENTRY CheckDeviceFormat(UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat); HRESULT APIENTRY CheckDeviceMultiSampleType(UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType); HRESULT APIENTRY CheckDepthStencilMatch(UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat); HRESULT APIENTRY GetDeviceCaps(UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS8* pCaps); HMONITOR APIENTRY GetAdapterMonitor(UINT Adapter); HRESULT APIENTRY CreateDevice(UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface); MyIDirect3D8(void); IDirect3D8 * lpD3D; IDirect3DDevice8 * lpD3DD8; IDirect3DDevice8 * lpD3DD8bak; ULONG m_count;};pGame就是我们的外挂的主类包括界面处理等等,在下一点讲解。IpD3DDevice是Direct3DDevice8(D3D 设备) 的接口的指针,我们也要想办法解决,不急,等下慢慢说。替换VTable其实很简单,我们只需要new一个我们自己的的MyIDirect3D8把老的IDirect3D8的指针内容直接替换就行了,呵呵://替换VTable,实现对IDirect3Draw 的 COM接口的挂钩NewlpD3d = new MyIDirect3D8;m = (IDirect3D8*)NewlpD3d;Direct3DDevice8(D3D 设备) 的接口的指针是在IDirect3D8里面Create的我们再看看MyIDirect3D8的CreateDevice函数如何定义:HRESULT APIENTRY MyIDirect3D8::CreateDevice(UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface){static MyIDirect3DDevice8 * id3dd8 = NULL; HRESULT m = lpD3D->CreateDevice(Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,ppReturnedDeviceInterface); lpD3DD8 = *ppReturnedDeviceInterface; //Hook IDirect3DDevice8 ::ShowWindow(hFocusWindow,SW_HIDE); lpD3D->CreateDevice(Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,&lpD3DD8bak); ::ShowWindow(hFocusWindow,SW_SHOW); ::SetFocus(hFocusWindow); id3dd8 = new MyIDirect3DDevice8(lpD3DD8bak); *ppReturnedDeviceInterface = (IDirect3DDevice8*)id3dd8; return m;}至于::ShowWindow(hFocusWindow,SW_HIDE);初始化后::ShowWindow(hFocusWindow,SW_SHOW);保证进程不挂,呵呵。IDirect3DDevice8要想得到IDirect3DDevice8的里面的内容,我们也采用同样方法的偷粱换柱子。MyIDirect3DDevice8定义就不再贴出来了,浪费页面。要解释下的地方是HRESULT APIENTRY MyIDirect3DDevice8::BeginScene(){return g_pD3DDevice->BeginScene();}HRESULT APIENTRY MyIDirect3DDevice8::EndScene(){if(pGame!=NULL) pGame->Render(); return g_pD3DDevice->EndScene();}我们的画图函数按道理讲要放到BeginScene()之后,但是我们不是写自己的3D游戏,而是在做外挂,程序是这么处理的:别人调用BeginScene();别人Render();别人调用EndScene();看看这个,我们把自己的pGame->Render();放到MyIDirect3DDevice8::BeginScene()里,结果就是自己的画图全被别人的图覆盖了,所有选择放到MyIDirect3DDevice8::EndScene()里去。到这里我们从诸仙得到的东西已经能满足我们的需求了,那我们就专心的干我们的事情吧,做外挂界面吧。4.游戏外挂界面处理类CGAME实现游戏外挂界面做外挂自己做个UI,估计没那必要,所以要选个UI,这里我选的是CEGUI来实现的。解释之前先来看看CEGUI做出来的最终效果:
至于怎么没读出一些人物信息,没办法,我的诛仙版本是很久以前的,也懒得升级,无法登陆,在这里说明问题就行了。我的CGame定义如下:#pragma once#include
标签: 狗皮膏药
相关推荐:
最新新闻:
- 游戏环境下如何实现真正D3D的窗口?启动进程和取得进程的方法
- 【环球时快讯】函数的length是什么意思?javascript函数的length
- 最新:Gaia、Gecko和Gonk的区别在哪里?一文读懂网络操作系统WebOS
- 如何开通QQ聊天工具界面?如何取消QQ验证设置?:环球观点
- 化身鸡哥!《消光2》外观DLC“狂鸡捆绑包”上线 全球百事通
- 特斯拉一夜暴跌6%:市值蒸发401亿美元_环球快讯
- 杜兆才落网后!孙雯正式被提拔,49岁扛起足协重任 全球独家
- 性能对标RTX 3080!RTX 4070桌面显卡OpenCL跑分曝光
- 【环球热闻】QQ如何使用声卡?QQ检测不到声音的解决方法
- 会议电话由哪些设备组成?会议电话组成设备介绍
- dota2为什么一直显示连接至游戏协调服务器中?详情介绍:当前头条
- 2016年笔记本销量排行榜 你的笔记本上榜了吗?:世界即时看
- 苹果ipad3 ios6.1怎么越狱?苹果ipad3 ios6.1越狱教程介绍
- Win10怎么关闭自动更新?Win10正式版关闭自动更新解决方法分享 世界播报
- 联想笔记本dvd驱动安装及使用说明 光驱弹不出的解决方法
- 淘宝超级店长是什么?超级店长适用于所有淘宝网店
- 80072f78无法更新怎么办?80072F78无法更新解决教程
- skype不能登录了怎么办?解决skype不能登录的方法步骤
- hhukcert02.exe是什么?hhukcert02.exe注册表文件途径在哪?
- 如何在安全模式下打开Word文档/Office?安全模式下打开Word文档操作步骤
- 电脑知识:cmd命令提示符的使用方法
- Win10如何防止U盘中毒?防止U盘中毒的解决方法
- 天天速读:如何用ghost进行一键还原?六个步骤教你正确使用
- 龙之谷加点模拟器怎么洗点?龙之谷加点模拟器安装方法
- 世界观点:手机手绘密码忘记了怎么办?京崎手机和这款手机解锁教程来了
- 三星S5830i内存不足怎么办?刷机教程来了
- dnf怎么屏蔽其他玩家?dnf光环幻化栏怎么弄?
- 如何安装HTC更新实用程序?Android手机更新实用程序
- 泓能移动电源怎么样?泓能移动电源价格介绍:每日消息
- tslog是什么文件夹?tslog文件夹彻底删除办法
- 焦点滚动:电脑假死怎么办? 三种方法解决教程
- office2007注册码破解方法 office2007注册码表及使用说明
- 电脑dns错误怎么办?dns错误怎么解决?-天天信息
- 如何解决家中的无线信号覆盖问题?wifi无线覆盖解决方案 环球最资讯
- qq飞车s车有哪些?qq飞车s车大全QQ级赛车排行榜
- 世界微速讯:一台电脑多少瓦?关于电脑功耗的解答
- umd是什么格式?umd格式怎么打开?
- 世界快看:车载gps终端怎么样?车载gps终端介绍
- 简讯:顽皮狗:《最后生还者》先优化好PC版 才能登SteamDeck
- 经济学家向松祚:90%以上的经济学家会被ChatGPT取代
- 山高新能源集团(01250.HK)公告2022年度业绩,盈利喜迎向上拐点:头条焦点
- 小米13 Ultra官方预热:雷军疯狂暗示:当前关注
- 世界实时:moto razr+ 2023曝光:新折叠屏要来了!
- 世界热文:向全球精英发出邀请“奔向蓝海”,象山再次启动这场大赛
- 越骂越买 iPhone 13全球最畅销手机
- 小米米家智能晾衣机1S发布:35kg承重、一键隐形
- 重点聚焦!卡普空股价大涨创历史新高!《生化危机4:重制版》立大功
- 《小美人鱼》真人电影新预告 美丽之鱼浮出水面-每日播报
- 《Dark and Darker》开发者有意众筹50万美元 现已暂停:热资讯
- 焦点信息:经典游戏系列《大笨猫》设计师迈克尔·博林去世 享年73岁
- 宫颈癌疫苗预防疾病_宫颈癌疫苗如何使用 有效预防宫颈癌办法
- 潮流配色 简约时尚标杆之作 三星Galaxy A54 5G火热预约登记中|世界热点
- 快看点丨RTX 4060笔记本售价5899!将星游戏本性价比之王!
- 环球看热讯:Wi-Fi联盟报告:研究显示Wi-Fi有助于节能减排
- 苹果MR头显即将推出、库克称十年内用其取代iPhone
- 电脑每次开机都自检怎么解决?电脑每次开机都自检解决方法
- 诺基亚X发布时间是什么时候?诺基亚X上市价格是多少?
- 如何刻盘光盘?笔记本电脑刻录光盘教程
- 微信登录系统错误什么意思?微信登录密码忘记了怎么找回?
- 剑灵错误代码14001怎么解决?剑灵错误代码14001解决方法
- 怎么使用按键精灵制作游戏脚本?按键精灵制作游戏脚本步骤
- 雨滴桌面秀使用方法 rainmeter皮肤包怎么用?
- 什么是oa系统?一套oa系统大概需要多少钱?OA系统价格
- ipad闪退修复方法 ipad闪退app该如何解决?
- H264帧格式解析 详解H264Annexb与AVCC格式解析 天天观点
- qqpctray.exe是什么?qqpctray.exe程序占用率高怎么办?
- 如何获取xlsx的Excel文件行数?xlsx的Excel文件使用方法 即时
- 笔记本电脑当无线路由器怎么设置?设置流程|天天观热点
- 天天信息:如何使用视频剪辑软件将qsv格式视频转换为MP4格式?方法步骤
- 天天热门:中国大学MOOC网站资源点汇总(收藏)
- javascript首字母字符串开发教程 用于获取汉字的首字母拼音的开发方法|天天快资讯
- C语言基础知识入门 C语言的具体结构
- VEX为什么要用到中间表达式?为什么要用到VEX?|环球头条
- 中国“北斗”卫星导航系统——定位模块需求介绍
- DirectSound能帮我们做什么?DirectSound开发指南 天天观察
- 每日信息:pp助手安装失败怎么办?PP助手修复方法
- iOS13越狱教程:如何安装AppSync和afc2补丁?
- 全球快消息!进销存软件哪家强?上百种进销存软件大比拼
- 操作系统中死锁的算法——银行家算法-环球播报
- 当前资讯!在哪里看股指期货的行情?股指期货行情信息
- 热门看点:【激活码】180天诺顿NAVirus2012版本安装
- 磁盘垃圾文件清理器是什么?python接收命令行参数的方式及步骤-今日热讯
- 环球今热点:【全国计算机等级考试】2级公共基础120题之四(11)
- 世界速读:5.0以下的主流图片加载框架有哪些?安卓加载图片四大框架
- test.c测试游戏:测试三子棋的逻辑-最新资讯