2024年1月6日发(作者:)
本来我是很不情愿再写一篇OD逆向分析的,因为此时写这篇文章会很累,时间多,字也打得多,
而且很可能会在一段时间后,游戏更新了,未来本文可能就会失效.但还是写了,为了独立团论坛的学员大家,也给前面的做个佐证与一点补充.
先创建一个QQ游戏大厅的进程,
然后去创建第二个QQ游戏大厅进程时,会创建失败,并且第一个进程的大厅窗口会被激活置为前台,另外任务栏下的QQ游戏按钮也会被闪烁几下.
会闪烁可是好事啊,可以给我们找关键的禁止双开的CALL提供很多的帮助.
下面我们在开着第一个QQ游戏大厅的情况下,用OD载入第二个QQ游戏大厅程序,然后下断点在以下两个会终止进程的API上
ExitProcess
TerminateProcess
API断点设置如下:
在OD里按F9运行,会中断在 ExitProcess 上.
见堆栈窗口情况:
0012FEDC 785421CC ?Tx /CALL 到 ExitProcess 来自
MSVCR90.785421C6
0012FEE0 00000000 .... ExitCode = 0
看堆栈提示,是 MSVCRT 领空的 785421C6处指令 MSVCRT 是VC++的运行时库,与易语言的核心库一样的概念.
另外就是易语言与易核心库是用VC++编的,所以我们编写的易程序在运行时,也会加载这个 MSVCRT 运行库的
现在我们直接复制完堆栈数据窗口的所有返回信息:
0012FEDC 785421CC ?Tx /CALL 到 ExitProcess 来自 MSVCR90.785421C6
0012FEE0 00000000 .... ExitCode = 0
0012FEE4 /0012FF28 (.
0012FEE8 |78542411 $Tx 返回到 MSVCR90.78542411 来自
MSVCR90.785421B5
0012FEEC |00000000 ....
0012FEF0 |A28413F9 ?劉
0012FEF4 |00412B4C L+A. QQGame.00412B4C
0012FEF8 |00151F01 .
0012FF10 |0012FEF0 瘙.
0012FF14 |00000000 ....
0012FF18 |0012FFB0 ?. 指向下一个 SEH 记录的指针
0012FF1C |7858CBDE 匏Xx SE处理程序
0012FF20 |DACC2861 a(腾
0012FF24 |FFFFFFFE
0012FF28 ]0012FF3C
0012FF2C |78542466 f$Tx 返回到 MSVCR90.78542466 来自
MSVCR90.78542306
0012FF30 |00000000 ...
0012FF3C ]0012FFC0 ?.
0012FF40 |00409DEC 鞚@. 返回到 QQGame.00409DEC 来自
0012FF44 |00000000 ....
0012FF48 |B0AB7FEA ?
0012FF4C |7C930228 (搢 ntdll.7C930228
0012FF50 |FFFFFFFF
0012FF54 |7FFDE000 .帻•
0012FF58 |00000044 D...
0012FF5C |00153920 9.
0012FF60 |00153B38 8;. ASCII "WinSta0Default"
0012FFB0 |0012FFE0 ?. 指向下一个 SEH 记录的指针
0012FFB4 |0040A4A5 イ@. SE处理程序
0012FFB8 |B0F9549A 歍
0012FFBC |00000001 ...
0012FFC0 0012FFF0 ?.
0012FFC4 7C817077 wp亅 返回到 kernel32.7C817077
0012FFC8 7C930228 (搢 ntdll.7C930228
0012FFCC FFFFFFFF
0012FFD0 7FFDE000 .帻•
0012FFD4 805522FA ?U
我们要找创建互斥体的CALL,这样才能找到这个call的压入参数(互斥体名称),分析出QQ游戏大厅限制双开的互斥体名称,
那么找CALL,当然是在进程的凌空找,从上面堆栈的所有返回信息来看,只有:
0012FF40 |00409DEC 鞚@. 返回到 QQGame.00409DEC 来自
这句是游戏进程的凌空,其他都是在 MSVCR90 或 kernel32 模块凌空里,所以其他就不需要跟踪了,我们来看
返回到 QQGame.00409DEC 来自 鼠标选中堆栈数据窗口这条代码,右键 选中
来到这里:
发现上面有2个CALL,我们对这2个CALL下断点,在这里需要注意的是,因为我们跳转到这的代码是在这2个CALL之后,
所以要让程序再执行到我们下断点的这2个CALL的话,需要重新载入一次,选择OD菜单里的
然后在按F9 运行调试。这个时候程序就被执行到 第1个CALL时,被断下来了,
我们按F8单步步过这个CALL时候,发现QQ游戏大厅窗口闪了一下,、
这是因为我们OD里加载的这个游戏大厅发现了系统中,早已经打开了一个QQ游戏大厅,把正在运行的大厅窗口最前闪动操作
那么这个CALL肯定跟互斥体有关系,我们跟入 CALL 00403DAF 这个CALL里面进去看看,
进入CALL 00403DAF 内部:
00403DAF /$ 55 PUSH EBP //来到这 我们继续F8一条一条调试往下执行看看
00403DB0 |. 8BEC MOV EBP,ESP
00403DB2 |. 83EC 78 SUB ESP,78
00403DB5 |. A1 B4114100 MOV EAX,DWORD PTR DS:[4111B4]
00403DBA |. 33C5 XOR EAX,EBP
00403DBC |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00403DBF |. 53 PUSH EBX
00403DC0 |. 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8]
00403DC3 |. 56 PUSH ESI
00403DC4 |. 57 PUSH EDI
00403DC5 |. 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]
00403DC8 |. 68 60C34000 PUSH QQGame.0040C360
00403DCD |. FF15 2CB04000 CALL DWORD PTR
DS:[<&Dir>; DirectoryW
00403DD3 |. FF15 28B04000 CALL DWORD PTR DS:[<&kCo>; [GetTickCount
00403DD9 |. 8B35 00B04000 MOV ESI,DWORD PTR
DS:[<&>; DebugStringW
00403DDF |. 68 80BA4000 PUSH QQGame.0040BA80 ; /String =
"QQGame timestamp WinMain"
00403DE4 |. 8945 88 MOV DWORD PTR SS:[EBP-78],EAX ; |
00403DE7 |. FFD6 CALL ESI ;
OutputDebugStringW
00403DE9 |. E8 C3FCFFFF CALL QQGame.00403AB1
00403DEE |. E8 9DF9FFFF CALL QQGame.00403790
00403DF3 |. E8 87F8FFFF CALL QQGame.0040367F
00403DF8 |. 85C0 TEST EAX,EAX
00403DFA |. 74 0C JE SHORT QQGame.00403E08
00403DFC |. 68 40BA4000 PUSH QQGame.0040BA40 ; UNICODE
"createResource: recordFileExits"
00403E01 |. FFD6 CALL ESI
00403E03 |. E8 59F7FFFF CALL QQGame.00403561
00403E08 |> 8D4D 8C LEA ECX,DWORD PTR SS:[EBP-74]
00403E0B |. E8 9AEDFFFF CALL QQGame.00402BAA
00403E10 |. 85FF TEST EDI,EDI
00403E12 |. 74 33 JE SHORT QQGame.00403E47
00403E14 |. 57 PUSH EDI ; /String
00403E15 |. FF15 24B04000 CALL DWORD PTR DS:[<&nA>>; lstrlenA
00403E1B |. 8BF0 MOV ESI,EAX
00403E1D |. 46 INC ESI
00403E1E |. 81FE FFFFFF3F CMP ESI,3FFFFFFF
00403E24 |. 7E 04 JLE SHORT QQGame.00403E2A
00403E26 |. 33C0 XOR EAX,EAX
00403E28 |. EB 14 JMP SHORT QQGame.00403E3E
00403E2A |> 8D0436 LEA EAX,DWORD PTR DS:[ESI+ESI]
00403E2D |. E8 EE5D0000 CALL QQGame.00409C20
00403E32 |. 8BC4 MOV EAX,ESP
00403E34 |. 6A 00 PUSH 0
00403E36 |. 56 PUSH ESI
00403E37 |. 57 PUSH EDI
00403E38 |. 50 PUSH EAX
00403E39 |. E8 EBF6FFFF CALL QQGame.00403529
00403E3E |> FF75 88 PUSH DWORD PTR SS:[EBP-78]
00403E41 |. FF75 14 PUSH DWORD PTR SS:[EBP+14]
00403E44 |. 50 PUSH EAX
00403E45 |. EB 08 JMP SHORT QQGame.00403E4F
00403E47 |> FF75 88 PUSH DWORD PTR SS:[EBP-78]
00403E4A |. FF75 14 PUSH DWORD PTR SS:[EBP+14]
00403E4D |. 6A 00 PUSH 0
00403E4F |> 53 PUSH EBX
00403E50 |. 8D4D 8C LEA ECX,DWORD PTR SS:[EBP-74]
00403E53 |. E8 E6F5FFFF CALL QQGame.0040343E
00403E58 |. 8D4D 8C LEA ECX,DWORD PTR SS:[EBP-74]
00403E5B |. E8 3BE9FFFF CALL QQGame.0040279B
00403E60 |. 33C0 XOR EAX,EAX
00403E62 |. 8DA5 7CFFFFFF LEA ESP,DWORD PTR SS:[EBP-84]
00403E68 |. 5F POP EDI
00403E69 |. 5E POP ESI
00403E6A |. 5B POP EBX
00403E6B |. 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
00403E6E |. 33CD XOR ECX,EBP
00403E70 |. E8 695C0000 CALL QQGame.00409ADE
00403E75 |. C9 LEAVE
00403E76 . C2 1000 RETN 10
发现 当我们F8 从头执行调试到 粉色 代码处后,我们正在运行的另外QQ游戏大厅窗口(非OD加载的QQ游戏大厅),又闪了一次,
那么老样子,我们步入进去
CALL QQGame.0040343E 这个CALL里面瞧瞧 至于为什么这个CALL要进去看看,
是因为其他上面的CALL执行后,游戏大厅窗口都没有闪,没有任何反应,只有这个call执行完后,QQ游戏大厅才闪了一下,所以要进入看看
进入后来到了:
0040343E /$ 6A 08 PUSH 8 //来到这 我们又继续F8一条一条调试往下执行看看
00403440 |. B8 2AA64000 MOV EAX,QQGame.0040A62A
00403445 |. E8 02670000 CALL QQGame.00409B4C
0040344A |. 894D F0 MOV DWORD PTR SS:[EBP-10],ECX
0040344D |. 33DB XOR EBX,EBX
0040344F |. 53 PUSH EBX
00403450 |. FF15 F8B34000 CALL DWORD PTR
DS:[<&ialize>; ialize
00403456 |. 68 58B74000 PUSH QQGame.0040B758 ; /String =
"Tenio Initialize!"
0040345B |. FF15 00B04000 CALL DWORD PTR DS:[<&Deb>;
OutputDebugStringW
00403461 |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
00403464 |. E8 48F4FFFF CALL QQGame.004028B1
00403469 |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
0040346C |. E8 0FF4FFFF CALL QQGame.00402880
00403471 |. 6A 14 PUSH 14
00403473 |. E8 96670000 CALL
00403478 |. 59 POP ECX
00403479 |. 8945 EC MOV DWORD PTR SS:[EBP-14],EAX
0040347C |. C745 FC 01000>MOV DWORD PTR SS:[EBP-4],1
00403483 |. 3BC3 CMP EAX,EBX
00403485 |. 74 11 JE SHORT QQGame.00403498
00403487 |. 68 B4B74000 PUSH QQGame.0040B7B4
""
0040348C |. 8BC8 MOV ECX,EAX
0040348E |. E8 5DF6FFFF CALL QQGame.00402AF0
00403493 |. 8945 EC MOV DWORD PTR SS:[EBP-14],EAX
00403496 |. EB 03 JMP SHORT QQGame.0040349B
00403498 |> 895D EC MOV DWORD PTR SS:[EBP-14],EBX
0040349B |> 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
0040349E |. 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4]
004034A1 |. 834D FC FF OR DWORD PTR SS:[EBP-4],FFFFFFFF
004034A5 |. 3BC3 CMP EAX,EBX
004034A7 |. 74 5B JE SHORT QQGame.00403504
004034A9 |. 6A 02 PUSH 2
004034AB |. FFD0 CALL EAX
004034AD |. 8BF0 MOV ESI,EAX
004034AF |. 59 POP ECX
004034B0 |. 3BF3 CMP ESI,EBX
004034B2 |. 74 50 JE SHORT QQGame.00403504
004034B4 |. 8B06 MOV EAX,DWORD PTR DS:[ESI]
004034B6 |. 68 0CE00200 PUSH 2E00C
004034BB |. 68 9CB74000 PUSH QQGame.0040B79C
""
004034C0 |. 53 PUSH EBX
004034C1 |. 8BCE MOV ECX,ESI
004034C3 |. FF50 08 CALL DWORD PTR DS:[EAX+8]
004034C6 |. 8BF8 MOV EDI,EAX
004034C8 |. 3BFB CMP EDI,EBX
004034CA |. 74 27 JE SHORT QQGame.004034F3
004034CC |. 8B07 MOV EAX,DWORD PTR DS:[EDI]
; UNICODE
; UNICODE
004034CE |. 8BCF MOV ECX,EDI
004034D0 |. FF50 4C CALL DWORD PTR DS:[EAX+4C] ; 执行到这CALL后,{:100_157:}发现游戏窗口又闪了一次,所以再进入这个CALL瞧瞧
004034D3 |. 85C0 TEST EAX,EAX
004034D5 |. 74 13 JE SHORT QQGame.004034EA
004034D7 |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
004034DA |. 53 PUSH EBX
004034DB |. E8 C9F2FFFF CALL QQGame.004027A9
004034E0 |. FF75 14 PUSH DWORD PTR SS:[EBP+14]
004034E3 |. 8B07 MOV EAX,DWORD PTR DS:[EDI]
004034E5 |. 8BCF MOV ECX,EDI
004034E7 |. FF50 50 CALL DWORD PTR DS:[EAX+50]
004034EA |> 8B06 MOV EAX,DWORD PTR DS:[ESI]
004034EC |. 53 PUSH EBX
004034ED |. 57 PUSH EDI
004034EE |. 8BCE MOV ECX,ESI
004034F0 |. FF50 0C CALL DWORD PTR DS:[EAX+C]
004034F3 |> 8B4D EC MOV ECX,DWORD PTR SS:[EBP-14]
004034F6 |. E8 B2F1FFFF CALL QQGame.004026AD
004034FB |. FF75 EC PUSH DWORD PTR SS:[EBP-14]
004034FE |. E8 D5650000 CALL
00403503 |. 59 POP ECX
00403504 |> E8 37FEFFFF CALL QQGame.00403340
00403509 |. FF15 FCB34000 CALL DWORD PTR
DS:[<&itiali>; itialize
0040350F |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
00403512 |. E8 C7F3FFFF CALL QQGame.004028DE
00403517 |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
0040351A |. E8 89F3FFFF CALL QQGame.004028A8
0040351F |. 33C0 XOR EAX,EAX
00403521 |. E8 C5660000 CALL QQGame.00409BEB
00403526 . C2 1000 RETN 10
F8一步步调试执行到 上面代码粉色执行到这CALL后,这个CALL瞧瞧
发现来到:
发现游戏窗口又闪了一次,所以再进入
这个跳转是往上跳转的,先不管它那么多,我们继续F8看看,独立团论坛,发现来到了
这个时候就要注意啦,调试代码时候,我们需要观察代码的值和注释,因为我们要找的是Mutex类型的互斥体,所以要留意任何出现
Mutex 的信息,当我们F8调试到这时候
出现一个"QQGame_Mutex03/01/2003" 名称的互斥体名称,为了证实它是不是我们要找的QQ游戏大厅限制双开的互斥体名,
我们在工具里找到这个互斥体名称关闭看看,发现QQ游戏大厅可以再开一个了,{:100_168:}
下面介绍一款多开工具,是我们独立团自己研发的,主要用于查看游戏进程或软件进程里的互斥体名称,
这个工具可以对进程互斥体进行关闭,来判断哪个是用于限制双开的互斥体名
称,从而找出游戏里那个限制双开的互斥体
当然这种方法是最笨的一种找限制双开互斥体的方法,属于盲目乱找,每结束一个互斥体,然后再运行一次游戏,
如果出现游戏能多开了,那就说明结束的那个互斥体是对的,那就是限制双开的互斥体,
关闭限制双开的进程互斥后,发现能打开2个QQ游戏大厅了
由此可见
PUSH 0E29714 因为0E29714 这个地址里存放着 "QQGame_Mutex03/01/2003" 这个内容
2014 QQ游戏大厅限制玩家刷分,限制一台电脑上只能开1个QQ游戏大厅的进程互斥体名称就是:QQGame_Mutex03/01/2003
现在分析完了QQ游戏双厅后,如果要制作针对其双开的功能代码就没什么难的
了,
可以参考 / 这篇文章的代码进行解除.
注意,本文写于2014年2月5日.用的是此时最新版的QQ游戏大厅.未来版本的大厅情况会如何就不清楚了,
大伙在学着调试时出现与本文不符现象,就得靠自已研究了{:100_157:}!
截了那么多图,写了那么多字,很累哦,但是为了独立团论坛的学员们,想想又很值得,如果你身边有朋友要学习游戏辅助技术,
叫他们一起来这吧!
我们的宗旨是:
从零基础教学编写外挂技术各种数据分析思路和代码编写技术知识,
学员掌握各种技术知识基础后,可以编写所有游戏外挂程序!
我们的永久官方网站:


发布评论