QQGAME 2009 多开 逆向 源码 讲解

下面来说说具体的,准备工具ollyice
下载地址:http://www.kumouse.com/article.asp?id=46 首先来讲一下常用的防多开的方法: 方法1: 查找窗口法,使用FindWindowA(W)或GetWindowTextA(W)
方法2: 使用互斥对象,用到CreateMutexA(W)
方法3: 使用共享区块 QQ使用的是方法2,具体程序要具体分析(由于我水平有限讲解不了)如果分析不出来可以上google查查,网上有很多牛人的.
先打开一个QQ游戏的窗口然后(原因看下边),我们用ollyice打开qqgame.exe我的文件版本是2.3.103.9大小164808字节,游戏版本QQGAME2009 beta3 sp3 打开程序后,程序会停在这里

00402150 >/$ 55 push ebp ; (initial cpu selection)
00402151 |. 8BEC mov ebp, esp
00402153 |. 6A FF push -1
00402155 |. 68 38314000 push 00403138
0040215A |. 68 D6224000 push <jmp.&MSVCRT._except_handler3> ; SE 处理程序安装
0040215F |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00402165 |. 50 push eax
00402166 |. 64:8925 00000>mov dword ptr fs:[0], esp
00402150这行是程序的开始处,我们在下边的command处输入"bp CreateMutexA"这句的意思是在CreateMutexA这个函数下断,也就是方法2中使用到的函数.
然后我们按F9运行这个程序程序会停在
7C80E9CF > 8BFF mov edi, edi
7C80E9D1 55 push ebp
7C80E9D2 8BEC mov ebp, esp
7C80E9D4 51 push ecx
7C80E9D5 51 push ecx
7C80E9D6 56 push esi
7C80E9D7 33F6 xor esi, esi
7C80E9D9 3975 10 cmp dword ptr [ebp+10], esi
7C80E9DC 74 31 je short 7C80EA0F
7C80E9CF就是CreateMutexA的第一行,我们这时按Alt+F9返回用户代码来到
746824B0 FF75 08 push dword ptr [ebp+8]
746824B3 FF15 88116874 call dword ptr [74681188] ; kernel32.CreateMutexA
746824B9 33C9 xor ecx, ecx
746824BB 85C0 test eax, eax
746824BD 0F95C1 setne cl
746824C0 8906 mov dword ptr [esi], eax
746824C2 5E pop esi
746824C3 8BC1 mov eax, ecx
746824C5 5D pop ebp
746824C6 C2 0800 retn 8
746824B9这行,看看上一行746824B3后边的注解写着什么,kernel32.CreateMutexA也就是刚刚调用了最关键的函数,但是这个函数在程序里调用了很多次,我们怎么知道哪一次的才是不让多开的代码呢?答案很简单,就是试,试也要靠方法的,对于QQ游戏来说,我们开打开一个QQ游戏的登陆窗口,不用登陆,然后再打开第二个,发现什么了?对原来那个窗口在闪,行了,我们就通过判断窗口闪,来得到具体是哪一次调用是禁止打开第二个游戏的代码.下边我们来试,刚才按了一次F9和一次Alt+F9,我们继续重复刚才的工作,直到看到QQ窗口闪动,说明禁止双开的代码以经被执行了,一共按了多少次Alt+F9呢?17次,说明第17次调用才是真正的禁止双开. 好了,我们这时按Ctrl+F2重新打开程序,程序又停在了00402150处,我们按Alt+b打开断点窗口看到有一个地址为7C80E9CF的断点,我们用鼠标选中它,按回车,来到这里
7C80E9CF > 8BFF mov edi, edi
7C80E9D1 55 push ebp
7C80E9D2 8BEC mov ebp, esp
7C80E9D4 51 push ecx
7C80E9D5 51 push ecx
7C80E9D6 56 push esi
眼熟吗?这里就是CreateMutexA的第一行,我们选中7C80E9CF这行,按Shift+F4设置一下条件
暂停程序那里选择"按条件"后边的条件满足次数写16,为什么是16呢?第17次就以经禁止双开了,我们让他停在第16次调用之后,好看看具体是哪个语句禁止双开的.
设置完成后按确定,再按F9运行程序.程序又停在了7C80E9CF这行上,不过这次是第16次,我们按Alt+F9回到用户代码处.
10012886 85C0 test eax, eax
10012888 8946 4C mov dword ptr [esi+4C], eax
1001288B 74 24 je short 100128B1
1001288D FF15 ACC00110 call dword ptr [<&KERNEL32.GetLastErr>; ntdll.RtlGetLastWin32Error
10012893 3D B7000000 cmp eax, 0B7
10012898 8BCE mov ecx, esi
1001289A 75 07 jnz short 100128A3
1001289C E8 BE000000 call 1001295F
100128A1 EB 2A jmp short 100128CD
100128A3 E8 90010000 call 10012A38
100128A8 85C0 test eax, eax
100128AA 74 21 je short 100128CD

程序停在了10012886处,我们按F8步过.执行到10012893这句时看到信息面板,也就是代码窗口下边的小窗口写着eax=000000B7,而10012893这句的代码是cmp eax,0B7 这句的意思就是比较eax和0B7,接着执行按F8,当来到1001289A这行时,注意了, jnz short 100128A3的意思是说,刚才比较的eax和B7如果这两个不相等则跳转到100128A3,否则不跳,刚才eax=B7也就是相等,所以程序接着执行,并不跳转.接着按F8,执行到100128A1这行,发现先前打开的QQ游戏窗口闪了,100128A1上一行call 1001295F,调用了这个子程序后QQ游戏才被禁止运行的.这是关键的部分了. 我们具体分析一下这段代码
10012893 3D B7000000 cmp eax, 0B7
10012898 8BCE mov ecx, esi
1001289A 75 07 jnz short 100128A3
1001289C E8 BE000000 call 1001295F
100128A1 EB 2A jmp short 100128CD
100128A3 E8 90010000 call 10012A38
100128A8 85C0 test eax, eax
100128AA 74 21 je short 100128CD
100128AC 897D FC mov dword ptr [ebp-4], edi
10012893这句把eax和B7做了比较,1001289A这句判断eax和B7不相等则跳转到100128A3,但实际情况是相等,也就是不跳转.如果执行了1001289C这行的子程序,就禁止双开了
我们来简化一下流程
10012893 3D B7000000 cmp eax, 0B7
1001289A 75 07 jnz short 100128A3
1001289C E8 BE000000 call 1001295F
100128A3 E8 90010000 call 10012A38
根据上边所说的,我们如果不执行1001289C这行,就可以双开,最简单的办法有两个,可以跳过1001289C 这行,一是改10012893这行,把eax和B6比,或别的数,反正不是B7就行了.改过后当执行到1001289A时,会直接跳到100128A3去执行,1001289C没有被执行也就是可以双开.二是把1001289A这句的jnz改成je也就是把原来的eax和B7不相等则跳转到100128A3,变成了相等则跳转. 我们用第一种方法试试.
选中10012893,也就是cmp eax,0B7这句,按F2,然后按ALt+B把刚才的7C80E9CF那个断点删除了,只剩下10012893这个,然后按ALT+C,再按Ctrl+F2重新载入程序,按F9运行]] >

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注