龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 2213|回复: 0

主线程调用过程环境检查以及防止游戏崩溃

[复制链接]

19

主题

0

回帖

28

积分

编程入门

Rank: 1

龙马币
94

先给大家说两种情况,也许这些情况都是你遇见过的。

案例一,逆向软件,调试游戏找到了某个CALL,我们编写DLL,把这个call写入到DLL中,然后把DLL注入到软件内部,对这个CALL进行调用,发生游戏直接崩溃报错的情况。又或则直接用代码注入器编写内联汇编直接注入代码导致崩溃。(有的时候代码注入器不会出问题,因为他是进程挂靠的方式 优于DLL中非主线程调用的方式)

案例二,编写了具有单一功能或则是一系列功能的DLL,测试以后功能正确,代码无误,可是总是在长时间运行时出现莫名其妙的崩溃情况。

其实这两种情况都是因为非主线程调用函数导致的。

第一种情况,检测调用 环境,非主线程调用导致崩溃,当然前提是你的函数编写正确,不正确也会导致崩溃。

第二种情况,是长时间运行,导致数据访问冲突,而产生的崩溃,同样,如果用主线程队列去调用就可以完全避免了。

那么我们来看看主线程调用的代码实现方式。

有两个函数可以实现主线程调用

SetWindowLong 和SetWindowsHookEx

基本方式相差不大

  1. DWORD Call_Hook主线程()
  2. {
  3.    HWND hGame=Call_获取窗口句柄();
  4.    DWORD ndThreadId=GetWindowThreadProcessId(hGame,NULL);
  5. if(ndThreadId!=0)
  6. {
  7.    g_Hook返回=SetWindowsHookEx(WH_CALLWNDPROC,Call_主线程回调函数,NULL,ndThreadId);
  8. }
  9. return 1;
  10. }
复制代码


函数名以用中文替代

重新设置的回调函数如下

调用代码写在这个函数里即可,被回调函数调用的即相当于主线程调用的函数。

并且代码中也列举了几个函数CALL调用的例子

  1. LRESULT CALLBACK Call_主线程回调函数(int nCode,WPARAM wParam,LPARAM lparam)
  2. {
  3. CWPSTRUCT *lpArg=(CWPSTRUCT*)lparam;//结构  hwnd message wParam lParam
  4. if (nCode==HC_ACTION)//自己进程的消息
  5. {
  6. if (lpArg->hwnd==Call_获取窗口句柄()&&lpArg->message==g_My消息ID)//我们自己的消息  
  7. {
  8. switch (lpArg->wParam)
  9. {
  10. T封包参数*封包;
  11. T寻路参数*寻路;
  12. T坐标夹参数*坐标夹参数;
  13. T坐标夹 坐标夹;
  14. T走路参数*走路;

  15. case ID_发送明文包:
  16.     Call_输出调试信息("YYC3D   主线程调用明文发包\r\n");
  17.     封包=(T封包参数*)lpArg->lParam;
  18.     Call_明文发包(封包->nd包长,封包->p);
  19.     return 1;
  20. break;
  21. case ID_寻路:
  22.     Call_输出调试信息("YYC3D   主线程调用寻路\r\n");
  23.     寻路=(T寻路参数*)lpArg->lParam;
  24.     Call_寻路(寻路->nfX,寻路->nfY);
  25.     return 1;
  26. break;
  27. case ID_按键:
  28.     Call_输出调试信息("YYC3D   主线程调用按键Call\r\n");
  29.     Call_按键((DWORD)lpArg->lParam);
  30.     return 1;
  31. break;
  32. case ID_控件点击:
  33.     Call_输出调试信息("YYC3D   主线程调用控件点击Call\r\n");
  34.     Call_控件点击((DWORD)lpArg->lParam);
  35.     return 1;
  36. break;
  37. case ID_控件选择:
  38.     Call_输出调试信息("YYC3D   主线程调用控件选择Call\r\n");
  39.     Call_控件选择((DWORD)lpArg->lParam);
  40.     return 1;
  41. break;
  42. case ID_计算坐标夹:
  43.     Call_输出调试信息("YYC3D   主线程调用计算坐标夹\r\n");
  44.     坐标夹参数=(T坐标夹参数*)lpArg->lParam;
  45.     坐标夹=Call_计算坐标夹(坐标夹参数->nfX,坐标夹参数->nfY);
  46.     return 1;
  47. break;
  48. case ID_走路:
  49.     Call_输出调试信息("YYC3D   主线程调用走路Call\r\n");
  50.     走路=(T走路参数*)lpArg->lParam;
  51.     Call_走路(走路->nfX,走路->nfY);
  52.     return 1;
  53. break;
  54. }
  55. }
  56. }
  57.     return CallNextHookEx(g_Hook返回,nCode,wParam,lparam);
  58. }
复制代码


然后需要调用什么函数的时候

直接发送消息即可

这样代码执行再久也不会发生数据访问冲突而导致崩溃了。

例如
  1. void Msg_走路(FLOAT X,FLOAT Y)
  2. {
  3.    T走路参数 走路;
  4.    走路.nfX=X;
  5.    走路.nfY=Y;
  6.    ::SendMessageA(Call_获取窗口句柄(),g_My消息ID,ID_走路,(LPARAM)&走路);
复制代码


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表