首页
社区
课程
招聘
[求助]dll 线程调用游戏主线程,30分-1小时崩溃
发表于: 2014-2-28 09:14 13995

[求助]dll 线程调用游戏主线程,30分-1小时崩溃

2014-2-28 09:14
13995
问题:dll 注入游戏后,开线程 自动选怪-》判断是否可攻击-》攻击

while(1)
{
    if(选中 && )
    {
         if(是否可攻击)
       {
               攻击
        }
    }else
    {
         循环当前场景怪物,回去最近怪物并选中;
    }
   sleep(1000);
}

以上是线程中的写法。

开启线程后,30分钟到1小时差不多的时间,就崩了,有时候会更少。windbg 挂起来,也没找到,dll 哪里出问题。后来得知是dll线程和游戏主线称冲突。
有人说,找到出错的调用,安装键盘钩子,用时钟调用。但终究不是正经的解决办法。
求大神看看。如何解决。
注:我去掉while(1) 然后将里面的代码,放到时钟里面,2-3小时都没问题。

此问题,困扰太久了,希望能有高手指点。
因为我之前是用c# 的,想着能有异步来代替线程,发现异步也是开启线程来执行。
这几周来寻求解决办法,无果,希望看雪上的大大能不吝赐教。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (21)
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
时钟。。。。 那叫Timer ,或者叫定时器。

崩溃没有现场?
2014-2-28 09:19
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
现象1:0xxxxxxxx不能 出错,类型write,getlasterror: 000000
我在挂机过程中从未写入任何数据
现象2:游戏直接消失掉。我用vs 和od 挂接,也没捕获到任何错误。
本人新手,水平有限,不知道其他的解决办法啊,或者告诉我如果查找这种错误来源也可以
2014-2-28 09:23
0
雪    币: 7048
活跃值: (3527)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
4
看情况应该是访问冲突,OD加载时,设置不忽略任何异常。生成DLL时,记得生成PDB文件。这样OD可以源码级调试。
放在定时器里就没这情况,你定时器设置的多久触发一次啊。
LZ建议看看这篇文章。
http://blog.csdn.net/scucj/article/details/3479829

在你的"攻击"和"循环当前场景怪物"的代码中,有没有访问或者写入有可能已经失效的地址。
2014-2-28 09:34
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
5
回:定时器也是1秒一次的。跟sleep(1000),我之前也觉得是不是延时太小。后来测试发现不是。
用windbg 挂起来,捕获到的都是在游戏exe 领空。这个我再次开启游戏,定位到地址后发现跟我打怪不相关~~
2014-2-28 09:41
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
6
好的。我认真看看这篇博文。
2014-2-28 09:44
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
内存不能为write,不是说你写入了什么数据。。。。 这种类型的出错都属于内存访问出错,比如指针访问出错等。

楼下说的是对的加上pdb 文件。 崩溃时看看现场对应的代码。
2014-2-28 09:48
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
8
好的,我回去试一下。

刚才楼上的仁兄说的,加上pdb 可以源码级调试,我有点不太明白。
vs下附加到进程调试的话,跟od 的源码级调试,是否是一种。
2014-2-28 09:54
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
9
晚上回去贴代码,从怪物遍历,到每个call 的调用。

怪物遍历的话,有的指针,每一个地址都做了校验,而且如果是dll 读取出错误的话,vs调试就能捕获到了。所以我之前排除了。应该是调用某个游戏call 出的问题。
2014-2-28 09:56
0
雪    币: 1392
活跃值: (5207)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
10
不创建线程。使用SetTimer进入游戏主线程执行
2014-2-28 09:58
0
雪    币: 7048
活跃值: (3527)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
11
VS的源码级调试,是可以精确到变量的。
OD使用PDB源码级调试,仅能找出源码和汇编代码之间的对应关系。亦可从源码转到汇编代码。
2014-2-28 10:33
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
把 动作 用 SendMessage发送到 游戏主窗口.
跟时钟一样的效果. 更容易写逻辑.
2014-2-28 11:19
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
是线程同步的问题吧.
2014-2-28 11:27
0
雪    币: 128
活跃值: (2788)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
不懂的线程同步的还是乖乖的用Timer吧
2014-2-28 11:57
0
雪    币: 0
活跃值: (954)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
15
最简单的办法设置Settimer定时打怪

游戏客户端会在你按键按下创建一个打怪线程出来,然后技能释放是一个线程.
2014-2-28 12:50
0
雪    币: 0
活跃值: (954)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
让游戏主线程去调用就可以解决。
2014-2-28 12:51
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
17
恍然大悟的感觉,谢谢网络游侠
2014-2-28 13:12
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
18
恩恩,就是想让他到游戏主线程取执行,因为编程水平的问题,一直不知道如何做啊,
还望游侠大大 不吝赐教

我看到一篇文章 关于用户态APC 的。想看看这个有用否。
http://blog.csdn.net/evi10r/article/details/6745138
2014-2-28 13:14
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
冒昧一问,游戏是如何区别某个流程是否为主线程调用的呢?
线程ID,还是返回地址? 还是消息相关的判断方法。
主线程调用和其它线程的区别在哪里?还是因为线程之间使用不同堆栈的关系导致崩溃?
2014-2-28 13:50
0
雪    币: 6556
活跃值: (4356)
能力值: ( LV10,RANK:163 )
在线值:
发帖
回帖
粉丝
20
建议:线程里面再创建线程来循环调用;
类似:
DWORD WINAPI ThreadProc(.....)
{
......
::CloseHandle(::CreateThread(NULL, 0, ThreadProc, ......));
}
死循环或者无数次的递归,堆栈不够用.....
2014-2-28 17:54
0
雪    币: 82
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
/* if(选中 && )
    {
         if(是否可攻击)
       {
               攻击
        }
    }else
    {
         循环当前场景怪物,回去最近怪物并选中;
    }
*/
可以一步一步注释可能有问题的代码,确定崩溃原因
2014-2-28 18:13
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
22
这在其他语言叫做轮循,没想到c++ 也可以这么用,不过我想确认一下,不断的开线程,关闭句柄,会不会出问题
2014-2-28 20:40
0
游客
登录 | 注册 方可回帖
返回
//