看流星社区-最新易语言安卓C/C++驱动辅助技术分享社区

 找回密码
 注册账号
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
查看: 73|回复: 2

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

[复制链接]
发表于 2019-9-11 11:09:32 | 显示全部楼层 |阅读模式

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

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


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

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

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

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

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

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

SetWindowLong 和SetWindowsHookEx

基本方式相差不大

DWORD Call_Hook主线程()
{
HWND hGame=Call_获取窗口句柄();
DWORD ndThreadId=GetWindowThreadProcessId(hGame,NULL);
if(ndThreadId!=0)
{
   g_Hook返回=SetWindowsHookEx(WH_CALLWNDPROC,Call_主线程回调函数,NULL,ndThreadId);
}
return 1;
}

函数名以用中文替代

重新设置的回调函数如下

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

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

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

case ID_发送明文包:
    Call_输出调试信息("YYC3D   主线程调用明文发包\r\n");
    封包=(T封包参数*)lpArg->lParam;
    Call_明文发包(封包->nd包长,封包->p);
    return 1;
break;
case ID_寻路:
    Call_输出调试信息("YYC3D   主线程调用寻路\r\n");
    寻路=(T寻路参数*)lpArg->lParam;
    Call_寻路(寻路->nfX,寻路->nfY);
    return 1;
break;
case ID_按键:
    Call_输出调试信息("YYC3D   主线程调用按键Call\r\n");
    Call_按键((DWORD)lpArg->lParam);
    return 1;
break;
case ID_控件点击:
    Call_输出调试信息("YYC3D   主线程调用控件点击Call\r\n");
    Call_控件点击((DWORD)lpArg->lParam);
    return 1;
break;
case ID_控件选择:
    Call_输出调试信息("YYC3D   主线程调用控件选择Call\r\n");
    Call_控件选择((DWORD)lpArg->lParam);
    return 1;
break;
case ID_计算坐标夹:
    Call_输出调试信息("YYC3D   主线程调用计算坐标夹\r\n");
    坐标夹参数=(T坐标夹参数*)lpArg->lParam;
    坐标夹=Call_计算坐标夹(坐标夹参数->nfX,坐标夹参数->nfY);
    return 1;
break;
case ID_走路:
    Call_输出调试信息("YYC3D   主线程调用走路Call\r\n");
    走路=(T走路参数*)lpArg->lParam;
    Call_走路(走路->nfX,走路->nfY);
    return 1;
break;
}
}
}
    return CallNextHookEx(g_Hook返回,nCode,wParam,lparam);
}

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

直接发送消息即可

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

例如
void Msg_走路(FLOAT X,FLOAT Y)
{
   T走路参数 走路;
   走路.nfX=X;
   走路.nfY=Y;
   ::SendMessageA(Call_获取窗口句柄(),g_My消息ID,ID_走路,(LPARAM)&走路);


发表于 7 天前 | 显示全部楼层
看到这么好的资源真是高兴,楼主辛苦了!
发表于 7 天前 | 显示全部楼层
支持楼主,支持看流星社区,以后我会经常来!
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2019-9-20 19:23

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表