WinDbg符号路径设置

c:windowssymbols;.sympath SRV*d:localsymbols*http://msdl.microsoft.com/download/symbols

Advertisements

Win32逆向工程二探——自作蓝色天使队1资料片(BlueFlowEX)免CD补丁

《蓝色天使队》是工画堂于2005年出品的一款SLG游戏。比起著名的《特勤机甲队》系列,《蓝色天使队》里的机甲画风更加唯美,机种特色更鲜明,剧情也走起了正太后宫路线(感官上实在有点无法接受哦)。到目前为止游戏陆续出品了1,1EX,2,2EX。

这里主要是讨论蓝色天使队1资料片(BlueFlowEX)(下简称1EX)的硬盘版补丁。VeryCD那里下载到的1EX是光盘镜像,原有4CD的容量,其实游戏盘也仅是CD1而已,mdf格式,502MB。挂载或解压出来后能成功安装。但是运行出现问题,弹出Big5编码的乱码消息框。经内码转换后,发现是要求插入游戏盘。原帖没有提示如何运行游戏。经反汇编发现,其实是要用虚拟光驱加载data0这个小镜像就行了。由于用的是老款笔记本玩游戏,不放心安装虚拟光驱(怕死机),于是就有了这次尝试。

打开OllyICE,一路单步执行下来很快就能发觉关键跳。

00462AC0 > 50     push    eax          ; /Arg4
00462AC1 . FF75 9C push    dword ptr [ebp-64]  ; |Arg3
00462AC4 . 56      push    esi          ; |Arg2
00462AC5 . 56      push    esi          ; |/pModule
00462AC6 . FF15 00A24600 call dword ptr [<&KERNEL32.GetModuleH>; |GetModuleHandleA
00462ACC . 50      push    eax          ; |Arg1
00462ACD . E8 0EB6FFFF   call 0045E0E0  ; BLUEFLOW.0045E0E0

跟进去不多久就会发现一段代码在枚举各分区,判断分区类型是不是光驱。

0045DF76 > /55     push    ebp    ; /RootPathName
0045DF77 . FF15 D0A14600 call dword ptr [<&KERNEL32.GetDrive>; GetDriveTypeA
0045DF7D . 83F8 05 cmp     eax, 5
0045DF80 . 0F85 A1000000 jnz 0045E027
0045DF86 . 8BFD    mov     edi, ebp

eax与5比较即是判断是否为光驱,将其改为3,改为判断是否为硬盘分区。其后的代码无非是判断C:data0是否存在,如存在就加载,否则继续枚举D分区。由于对汇编还是不熟,且目的已达到,就不再深入了。

小结:打开UE,将55FF15D0A1460083F805改为55FF15D0A1460083F803,将小镜像data0放在C:或任意硬盘分区根目录下即可进入游戏。

最后声明,本人不对任何因为此修改所带来的问题和责任而负责!本文为独家原创,谢绝转载!

Win32逆向工程初探——自作《八年抗战》1.06免CD补丁

《八年抗战》是台湾尼奥科技有限公司于2001-2002期间出品的一款纪念抗日战争的单机老游戏。由于是繁体中文版,且由于某些原因,只在台湾发行。我于今年九一八期间,才刚刚接触到这款优秀的游戏,真是有点相见恨晚的感觉。

该游戏的光盘版,只能在繁体时区下运行。而我用的是硬盘版1.0(最老的版本)。然而,1.0版的bug有不少,虽然网上有1.06版补丁,但都是光盘版的补丁。终于,玩到第23关力守九嶺山时,我也像所有人一样卡关了。该关在未使用1.02版(或之后任一版)补丁的情况下,即使全歼日军也无法正常过关。

虽然有win密技可直接过关,但会少一枚勋章。追求完美的我,抱着试试看的心理,在网上搜寻制作免CD补丁的技术,终于还是稍有斩获。

首先,有达人制作的1.0版免CD补丁Wor.exe和1.06版免区域检测补丁Wor_sc.exe,这对初探Win32逆向工程的我给予了莫大的帮助。抱着多一事不如少一事的态度,我决定在Wor_sc.exe的基础上进一步制作免CD补丁。启动OllyICE,调入Wor_sc.exe,发觉是用VC写的没有加壳的程序,万幸。一路单步运行下来至

00442F63   > /56            push    esi
00442F64   . |8D4C24 10     lea     ecx, dword ptr [esp+10]
00442F68   . |68 EC724800   push    004872EC                         ;  ASCII "%C:"
00442F6D   . |51            push    ecx
00442F6E   . |E8 38900200   call    0046BFAB
00442F73   . |83C4 08       add     esp, 8
00442F76   . |8D5424 10     lea     edx, dword ptr [esp+10]
00442F7A   . |8BCC          mov     ecx, esp
00442F7C   . |896424 0C     mov     dword ptr [esp+C], esp
00442F80   . |52            push    edx
00442F81   . |E8 BD9E0200   call    0046CE43
00442F86   . |E8 1513FCFF   call    004042A0
00442F8B   . |83C4 04       add     esp, 4
00442F8E   . |85C0          test    eax, eax
00442F90     |75 1E         jnz     short 00442FB0
00442F92     |46            inc     esi
00442F93     |83FE 5A       cmp     esi, 5A
00442F96   .^7E CB         jle     short 00442F63

发现该段代码在枚举分区。这是一个好兆头。标红的是关键跳,下面会提到。在循环后下断点,发现跳出循环后到了下面标红的关键Call,弹出MessageBox,要求插入CD。

00442F98   .  50            push    eax                              ; /Arg3
00442F99   .  6A 04         push    4                                ; |Arg2 = 00000004
00442F9B   .  68 C8724800   push    004872C8                         ; |Arg1 = 004872C8
00442FA0   .  E8 FF0C0300   call    00473CA4 ; Wor_sc.00473CA4
00442FA5   .  83F8 07       cmp     eax, 7
00442FA8   .  0F84 8A020000 je      00443238
00442FAE   .^ EB AE         jmp     short 00442F5E

于是,00442F90处就是进入游戏时的关键跳。将jnz改为je,顺利进入游戏,没有再要求插入光盘!自信心大增。进入游戏后的主界面,可以看到左上角的版本号为1.06。

于是,我兴奋地调出了力守九嶺山最后一回合的存档。再一次全歼日军,还是过不了关!!我傻眼了。不是说早在1.02补丁已经修复了这个bug了吗。我又尝试了读取力守九嶺山第一回合的存档和布阵时的存档,依旧无法过关。看来要重打整个第23关才行。没办法,只好读取第22关结束后的战备状态的存档,然后按进入下一关。此时,该死的要求插入光盘的MessageBox又一次跳了出来。狂受打击,看来只是进入游戏还不够啊。1.0硬盘版补丁就做得很好,我得从头再来。

第二次学乖了,老老实实地查API调用吧。在Command输入bpx GetDriveType,列出了N多外部调用。再输入bpx GetDriveTypeA,标红了一个,找到了!这是判断分区类型的API。免CD一般都从这开始。

004042A0  /$  6A FF         push    -1
004042A2  |.  68 30624700   push    00476230                         ;  SE 处理程序安装
004042A7  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
004042AD  |.  50            push    eax
004042AE  |.  64:8925 00000>mov     dword ptr fs:[0], esp
004042B5  |.  51            push    ecx
004042B6  |.  53            push    ebx
004042B7  |.  56            push    esi
004042B8  |.  57            push    edi
004042B9  |.  A1 40964800   mov     eax, dword ptr [489640]
004042BE  |.  33DB          xor     ebx, ebx
004042C0  |.  895C24 18     mov     dword ptr [esp+18], ebx
004042C4  |.  894424 0C     mov     dword ptr [esp+C], eax
004042C8  |.  8B4C24 20     mov     ecx, dword ptr [esp+20]
004042CC  |.  C64424 18 01  mov     byte ptr [esp+18], 1
004042D1  |.  51            push    ecx                              ; /RootPathName
004042D2  |.  FF15 88B14700 call    dword ptr [<&KERNEL32.GetDriveTy>; GetDriveTypeA
004042D8  |.  83F8 05       cmp     eax, 5
004042DB      75 77         jnz     short 00404354
004042DD  |.  8B3D ACB24700 mov     edi, dword ptr [<&SHLWAPI.PathFi>;  SHLWAPI.PathFileExistsA
004042E3  |.  33F6          xor     esi, esi
004042E5  |>  8B5424 20     /mov     edx, dword ptr [esp+20]
004042E9  |.  56            |push    esi
004042EA  |.  52            |push    edx
004042EB  |.  8D4424 14     |lea     eax, dword ptr [esp+14]
004042EF  |.  68 00744800   |push    00487400                        ;  ASCII "%sWORDATngDAT.%0#2i"
004042F4  |.  50            |push    eax
004042F5  |.  E8 B17C0600   |call    0046BFAB
004042FA  |.  8B4C24 1C     |mov     ecx, dword ptr [esp+1C]
004042FE  |.  83C4 10       |add     esp, 10
00404301  |.  51            |push    ecx
00404302  |.  FFD7          |call    edi
00404304  |.  85C0          |test    eax, eax
00404306      74 4C         je      short 00404354
00404308  |.  46            |inc     esi
00404309  |.  83FE 0A       |cmp     esi, 0A
0040430C  |.^ 7C D7         jl      short 004042E5
0040430E  |.  75 44         jnz     short 00404354
00404310  |.  8D5424 20     lea     edx, dword ptr [esp+20]
00404314  |.  B9 684E4900   mov     ecx, 00494E68
00404319  |.  52            push    edx
0040431A  |.  E8 588E0600   call    0046D177
0040431F  |.  8D4C24 0C     lea     ecx, dword ptr [esp+C]
00404323  |.  885C24 18     mov     byte ptr [esp+18], bl
00404327  |.  E8 A28D0600   call    0046D0CE
0040432C  |.  8D4C24 20     lea     ecx, dword ptr [esp+20]
00404330  |.  C74424 18 FFF>mov     dword ptr [esp+18], -1
00404338  |.  E8 918D0600   call    0046D0CE
0040433D  |.  5F            pop     edi
0040433E  |.  5E            pop     esi
0040433F  |.  B8 01000000   mov     eax, 1
00404344  |.  5B            pop     ebx
00404345  |.  8B4C24 04     mov     ecx, dword ptr [esp+4]
00404349  |.  64:890D 00000>mov     dword ptr fs:[0], ecx
00404350  |.  83C4 10       add     esp, 10
00404353  |.  C3            retn
00404354  |>  8D4C24 0C     lea     ecx, dword ptr [esp+C]
00404358  |.  885C24 18     mov     byte ptr [esp+18], bl
0040435C  |.  E8 6D8D0600   call    0046D0CE
00404361  |.  8D4C24 20     lea     ecx, dword ptr [esp+20]
00404365  |.  C74424 18 FFF>mov     dword ptr [esp+18], -1
0040436D  |.  E8 5C8D0600   call    0046D0CE
00404372  |.  8B4C24 10     mov     ecx, dword ptr [esp+10]
00404376  |.  5F            pop     edi
00404377  |.  5E            pop     esi
00404378  |.  33C0          xor     eax, eax
0040437A  |.  5B            pop     ebx
0040437B  |.  64:890D 00000>mov     dword ptr fs:[0], ecx
00404382  |.  83C4 10       add     esp, 10
00404385  .  C3            retn

在004042DD下断点,发现只有光驱的分区才能进入,无论是物理光驱还是虚拟光驱。接着发现,这段程序不断地在判断光驱中的目录和文件,好像文件数并不多。我想这也是为什么有的台湾达人能够制作出几百KB的模拟运行盘(b盘),欺骗检测程序了。几个循环下来,经过尝试,终于发现了标红的00404306处关键跳。将je改为jnz,顺利免CD!!

马上使用UE进行十六进制编辑,将做好的1.06版免CD补丁命名为Wor106b.exe。使用Wor106b.exe时发现,在打第23关时,背景音效有些轻微的混乱,不过到了第24关又恢复正常了。应该是原版的问题,无关大碍。其他暂时还没有发现什么问题。

网上目前还没有《八年抗战》1.06免CD补丁(硬盘版补丁)。本修改纯为个人钻研技术的需要,不牵涉任何商业利益,所以本人也不打算提供该补丁的下载了。希望各位同好支持国产的正版游戏,支持《八年抗战》,共同期待《八年抗战2》的到来。

最后声明,本人不对任何因为此修改所带来的问题和责任而负责!本文为独家原创,谢绝转载!