利用反汇编技术将游戏《英雄无敌3》修改为硬盘版

最近好不容易找到我最喜欢的游戏《英雄无敌3之埃拉西亚的光复》,可惜是光盘版的,要用虚拟光驱来运行,感觉不爽,网上也找不到免CD补丁,于是决定自己动手。

首先感谢这篇文章的作者

http://bbs.pediy.com/showthread.php?t=101023

是他引领我进入反汇编的大门。这篇文章的第一步,就是找到GetDriveType的调用(GetDriveType就是判断某盘符是光驱、硬盘或网络磁盘等的API函数),于是我用C32Asm,对游戏主程序Heroes3.exe进行反汇编,再查找GetDriveType,结果还真有,如下:

::005A8437::  FF15 48A05B00            CALL [5BA048]                               >>>: KERNEL32.DLL:GetDriveTypeA

::005A843D::  85C0                 TEST EAX,EAX                            

::005A843F::  74 0A                 JE SHORT 005A844B                       \:JMPDOWN

::005A8441::  83F8 01             CMP EAX,1                               

::005A8444::  74 05                 JE SHORT 005A844B                       \:JMPDOWN

::005A8446::  6A 01                 PUSH 1                                  \:BYJMP JmpBy:005A8420,

::005A8448::  58                       POP EAX                                 

::005A8449::  5D                      POP EBP                                 

::005A844A::  C3                      RETN                                 

 

但是和文章中不一样啊,他在调用GetDriveTypeA之后,判断返回值是否为5(5是光驱),而我这里却是1

::005A8441::  83F8 01                  CMP EAX,1

后面的逻辑也不一样。而继续查找GetDriveType也找不到了。于是我再仔细看看上面的代码,发现“>>>: KERNEL32.DLL:GetDriveTypeA”这只是反汇编器加上的注释,真正调用的是5BA048这个地址的代码,于是又搜5BA048,结果又找到一处

::004E7B69::  8B35 48A05B00   MOV ESI,[5BA048]                        

::004E7B6F::  33ED                      XOR EBP,EBP                             

::004E7B71::  8BF8                       MOV EDI,EAX                             

::004E7B73::  896C24 10             MOV [ESP+10],EBP                        

::004E7B77::  BB 02000000        MOV EBX,2                               

::004E7B7C::  BA 01000000       MOV EDX,1                               \:BYJMP JmpBy:004E7BAF,

::004E7B81::  8BCB                     MOV ECX,EBX                             

::004E7B83::  D3E2                     SHL EDX,CL                              

::004E7B85::  85D7                      TEST EDI,EDX                            

::004E7B87::  74 22                     JE SHORT 004E7BAB                       \:JMPDOWN

::004E7B89::  8AC3                     MOV AL,BL                               

::004E7B8B::  04 41                    ADD AL,41                               

::004E7B8D::  68 DC495E00              PUSH 5E49DC                                 \->: A:\

::004E7B92::  A2 DC495E00              MOV [5E49DC],AL                         

::004E7B97::  FFD6                     CALL ESI                                

::004E7B99::  83F8 05                  CMP EAX,5                               

原来它是把5BA048给了 ESI,然后在后面 CALL ESI。找到这里就可以改了,把 CMP EAX,5,也就是83F8 05改成83F8 03,汇编代码的地址是004E7B99,对应的十六进制代码地址就是000E7B99。改完之后保存运行,发现还是报告找不到光盘。我就继续参考上面那篇文章,发现他后面的逻辑又和我的对不上了,应该是两游戏的版本不同。接下来该怎么办呢?我只好硬着头皮,从CMP EAX,5接着往下看,发现有这么一段:

::004E7C8C::  BF 387D5E00     MOV EDI,5E7D38                              \->: d;^kIwuL{

::004E7C91::  F2                          REPNE SCASB                             

::004E7C92::  AE                         SCASB                                   

::004E7C93::  F7D1                     NOT ECX                                 

::004E7C95::  49                          DEC ECX                                 

::004E7C96::  74 1A                    JE SHORT 004E7CB2                       \:JMPDOWN

::004E7C98::  2892 387D5E00 SUB [EDX+5E7D38],DL                     \:BYJMP JmpBy:004E7CB0,

::004E7C9E::  83C9 FF              OR ECX,FFFFFFFF                         

::004E7CA1::  33C0                    XOR EAX,EAX                             

::004E7CA3::  42                         INC EDX                                 

::004E7CA4::  BF 387D5E00    MOV EDI,5E7D38                              \->: d;^kIwuL{

::004E7CA9::  F2                         REPNE SCASB                             

::004E7CAA::  AE                       SCASB                                   

::004E7CAB::  F7D1                   NOT ECX                                 

::004E7CAD::  49                        DEC ECX                                 

::004E7CAE::  3BD1                   CMP EDX,ECX                             

::004E7CB0::  72 E6                  JB SHORT 004E7C98                       \:JMPUP

::004E7CB2::  68 00800000     PUSH 8000                               \:BYJMP JmpBy:004E7C96,

::004E7CB7::  80C3 41             ADD BL,41                               

::004E7CBA::  68 387D5E00              PUSH 5E7D38                                 \->: d;^kIwuL{

::004E7CBF::  881D 387D5E00     MOV [5E7D38],BL                         

::004E7CC5::  E8 27960B00          CALL 005A12F1

这个5E7D38里面是什么东东,后面的代码貌似对它进行了加工(SUB [EDX+5E7D38],DL和MOV [5E7D38],BL),于是请出反汇编调试利器--Visual Studio!利用VS的F11单步调试,程序直接停在入口处(main函数对应的汇编代码),然后在004E7C8C处下断点,并且打开内存查看窗口,查看5E7D38处的内容,发现是一串奇怪的字符串“.;^kIwuL{: d;^kIwuL{

接下来就好办了,只要把光盘里的文件复制到游戏根目录下、把d;^kIwuL{

1.用虚拟光驱打开游戏光盘的ISO文件,复制heroes3文件夹到硬盘上英雄无敌的根目录下。

2.用ASCII码转换工具,把d;^kIwuL{

3.还是VS,找到004E7C8C所对应的十六进制地址000E7C8C(原来汇编地址和十六进制地址相差0x00400000),把从000E7C8C开始,到004E7CC5为止,所有的十六进制数都改成90,即空指令NOP,这样就把解密算法去掉了。

最后保存运行一下,直接进入了,大功告成! 

你可能感兴趣的:(汇编,游戏,汇编)