频道栏目
首页 > 资讯 > 加密解密 > 正文

逆向一个老的双升扑克游戏,并完成外挂

11-02-17        来源:[db:作者]  
收藏   我要投稿



逆向一个老的双升扑克游戏,并完成外挂
【文章作者】: cdanlover
【软件名称】: 古今大战80分
【加壳方式】: 无
【保护方式】: Name/Serial
【编写语言】: Delphi
【使用工具】: peid、DeDeDark、RadASM、MASM32、OD、WINDOWS计算器
【操作平台】: WINXP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】

    好久没有逆向过程序了,手都有点生了,今天有空就找了一个简单的来练练手,原来写过这个游戏的注册机,算法挺简单,估计软件设计也不会太复杂,于是就有了这篇笔记。
    这个游戏是用Delphi编程的,于是找来DeDeDark对其反了一下,很容易找到菜单的调用过程地址:

        Caption = 开局(K)
        OnClick = MIShuffleClick    00464A58  

        Caption = 摸牌(M)
        OnClick = MISettleClick     00464A60  

        Caption = 扣牌(D)
        OnClick = MIDiscardClick      00464A70 

        Caption = 出牌(C)        
        OnClick = MIShowClick        00464A78   


        Caption = 作弊模式
        OnClick = MIShowCardClick     004649FC

      Caption = 察看
        Caption = 底牌
        OnClick = N14Click           00466CAC
首先是对“开局”进行跟踪的,发现在发牌的过程中,在寄存器中反复出现同一个地址,我就想到有可能是程序申请到的一块内存的开始地址,用来存放牌面信息,在我的办公电
脑上是00B53250,后来在另一台电脑上跟踪时发现这个地址变了,于是就想找出是什么时间开始取的这块内存,发现在程序一开始就进行了申请:
004678E4 > $  55            push ebp
004678E5   .  8BEC          mov ebp,esp
004678E7   .  83C4 F4       add esp,-0C
004678EA   .  B8 1C774600   mov eax,0046771C
004678EF   .  E8 B8DEF9FF   call 004057AC                            ;  申请内存
004678F4   .  A1 408E4600   mov eax,dword ptr ds:[468E40]
004678F9   .  8B00          mov eax,dword ptr ds:[eax]
004678FB   .  E8 746AFCFF   call 0042E374
00467900   .  8B0D 348D4600 mov ecx,dword ptr ds:[468D34]            ;  古今大战.00469980
00467906   .  A1 408E4600   mov eax,dword ptr ds:[468E40]
0046790B   .  8B00          mov eax,dword ptr ds:[eax]
0046790D   .  8B15 74614500 mov edx,dword ptr ds:[456174]            ;  古今大战.004561B4
00467913   .  E8 746AFCFF   call 0042E38C                            ;  在call之前,内存已申请好,在call过后,地址指针等已经分配好了,开始出界面
00467918 > .  A1 408E4600   mov eax,dword ptr ds:[468E40]
0046791D   .  8B00          mov eax,dword ptr ds:[eax]
0046791F   .  E8 F46AFCFF   call 0042E418                            ;  已完全运行
就开始找这个00B53250,最早出现的地方,是在
mov ecx,dword ptr ds:[468D34]
[468D34] 保存一个地址:00469980,程序正常运行后,在[00469980]保存了基址:------>00B53250
在00467918处下条件记录断点,可直接定位到分配的内存基址。

 

在后来的分析中,发现以这个基址有很多可能关注的地方:
+F34  [00B54184]  代表本局中出的第几张牌。
+4E4  [00B53734]  比较是否为庄家,4为庄家,1为最后出牌(分析结果:1代表左边的,2代表对家,3代表右边的,4代表玩家自己)

一开始没有找到存放牌信息的地方,后来就对“扣牌”过程进行分析,其中有段:
004641E8  |.  B8 14000000   mov eax,14                               ;  20个元素
004641ED  |.  8D55 B0       lea edx,[local.20]                       ;  初始化一个数组,用于保存出的牌是手中的第几张牌
004641F0  |>  33C9          /xor ecx,ecx
004641F2  |.  890A          |mov dword ptr ds:[edx],ecx
004641F4  |.  83C2 04       |add edx,4
004641F7  |.  48            |dec eax
004641F8  |.^ 75 F6         jnz short 004641F0
004641FA  |.  B8 01000000   mov eax,1
004641FF  |>  8B9483 4C0400>/mov edx,dword ptr ds:[ebx+eax*4+44C]
00464206  |.  8B52 34       |mov edx,dword ptr ds:[edx+34]
00464209  |.  8B8B 18030000 |mov ecx,dword ptr ds:[ebx+318]
0046420F  |.  83E9 0A       |sub ecx,0A
00464212  |.  3BD1          |cmp edx,ecx
00464214  |.  75 05         |jnz short 0046421B
00464216  |.  46            |inc esi
00464217  |.  8944B5 AC     |mov dword ptr ss:[ebp+esi*4-54],eax     ;  一个数组,记录出的第几张牌
0046421B  |>  40            |inc eax
0046421C  |.  83F8 1A       |cmp eax,1A                              ;  与26比较,每个玩家手中25张牌
0046421F  |.^ 75 DE         jnz short 004641FF

发现在mov edx,dword ptr ds:[ebx+eax*4+44C]这个地方计算是哪张牌,查看这块内存发现挺有规律的,有很多4SD开始的,继续向上翻,找到第一个4SD的单元,重新跟踪,对其

下内存写入断点,就找到了这块保存牌面信息的地方,当eax=1时,即可以算出玩家手中第一张牌保存的地方了,每个双字保存一个地址指针,指向每一张牌:

左手边玩家的:
00B53574  94 99 B5 00 70 BA B5 00 50 BC B5 00 48 BE B5

相关TAG标签
上一篇:Shellcode分段执行技术原理
下一篇:腾讯动漫频道上传任意图片bug
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站