网上看到一个游戏,叫突变怪物,是一个ISO镜像,发布者注明“英文版无需光盘中文版需要光盘”,产生好奇心,便下了回来
下回来载入镜像,安装,把镜像卸了,运行游戏,弹出一个窗口,“请将《突变怪物》的中文版安装光盘放入光驱”
进入游戏目录,发现有两个可执行程序,thething.exe和thething中文版.exe,运行thething.exe,不用光盘便可进入游戏,应该是原版的英文破解版。再看thething中文版.exe,大小只有41.5K,且图标是MFC,初步估计游戏采用的是外挂式汉化。
PEiD查看,VC7,无壳
用W32DASM载入thething中文版.exe,搜索字符串,无果
查看输入函数,几乎全部是MFC70.Ordinal:08C4之类的,也找不到messagebox,但有GetDriverTypeA,尝试改了附近几个跳转,不是无效就是出错
用WinHex打开程序,搜索字符串,发现以下东西
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00003400 00 00 00 00 00 00 00 00 25 73 0D 0A B1 BE B5 D8 ........%s..本地
00003410 BB AF D6 C6 D7 F7 A3 BA 20 68 74 74 70 3A 2F 2F 化制作: http://
00003420 77 77 77 2E 4C 6F 63 61 6C 47 61 6D 65 73 2E 6E http://www.LocalGames.n
00003430 65 74 2F 0D 0A 73 75 70 70 6F 72 74 40 6C 6F 63 et/..support@loc
00003440 61 6C 67 61 6D 65 73 2E 6E 65 74 0D 0A 00 00 00 algames.net.....
00003450 B3 F6 B4 ED D0 C5 CF A2 00 00 00 00 C7 EB BD AB 出错信息....请将
00003460 25 73 B7 C5 C8 EB B9 E2 C7 FD A3 A1 00 00 00 00 %s放入光驱!....
00003470 A1 B6 CD BB B1 E4 B9 D6 CE EF A1 B7 B5 C4 D6 D0 《突变怪物》的中
00003480 CE C4 B0 E6 B0 B2 D7 B0 B9 E2 C5 CC 00 20 20 20 文版安装光盘.
看来此程序应该是一个通用的Loader,字符串一部分在345C,一部分在3470
既然字符串并没有加密,猜想程序中可能会直接引用地址
查看EP段
Object01: .text RVA: 00001000 Offset: 00000400 Size: 00002600 Flags: 60000020
Object02: .rdata RVA: 00004000 Offset: 00002A00 Size: 00001800 Flags: 40000040
Object03: .data RVA: 00006000 Offset: 00004200 Size: 00000200 Flags: C0000040
Object04: .rsrc RVA: 00007000 Offset: 00004400 Size: 00006200 Flags: 40000040
2A00-(1000+400)=1600
345C+1600=4A5C
3470+1600=4A70
直接上OD,载入,搜索,来到此处
00401FA1 MOV EBP,DWORD PTR DS:[<&MSVCR70.sprintf>>; MSVCR70.sprintf
00401FA7 PUSH thething.00404A70 ; /<%s> = "《突变怪物》的中文版安装光盘"
00401FAC LEA ECX,DWORD PTR SS:[ESP+424] ; |
00401FB3 PUSH thething.00404A5C ; |format = "请将%s放入光驱!"
00401FB8 PUSH ECX ; |s
00401FB9 CALL EBP ; \sprintf
00401FBB MOV EDX,DWORD PTR DS:[404A50]
00401FC1 MOV EAX,DWORD PTR DS:[404A54]
00401FC6 MOV CL,BYTE PTR DS:[404A58]
00401FCC PUSH thething.00404A70
00401FD1 MOV DWORD PTR SS:[ESP+24],EDX
00401FD5 LEA EDX,DWORD PTR SS:[ESP+30]
00401FD9 PUSH thething.00404A08
00401FDE PUSH EDX
00401FDF MOV DWORD PTR SS:[ESP+30],EAX
00401FE3 MOV BYTE PTR SS:[ESP+34],CL
00401FE7 CALL EBP
00401FE9 LEA EAX,DWORD PTR SS:[ESP+38] ; |
00401FED PUSH EAX ; |Arg1
00401FEE CALL thething.004013A0 ; \thething.004013A0 \\此处应该为关键CALL,跟入
00401FF3 ADD ESP,1C
00401FF6 TEST EAX,EAX
00401FF8 JNZ SHORT thething.00402016 ; \\此处疑为关键跳转
00401FFA PUSH EBX
00401FFB LEA ECX,DWORD PTR SS:[ESP+18]
00401FFF PUSH ECX
00402000 LEA EDX,DWORD PTR SS:[ESP+428]
00402007 PUSH EDX
00402008 MOV ECX,ESI
0040200A CALL <JMP.&MFC70.#3890>
0040200F PUSH EBX ; /status
00402010 CALL DWORD PTR DS:[<&MSVCR70.exit>] ; \exit
哈哈,一目了然。将关键跳转处改过,已经可以免CD。
跟进关键CALL
004013F1 MOV ESI,DWORD PTR SS:[EBP+8]
004013F4 MOV EDI,DWORD PTR DS:[<&MSVCR70.strstr>] ; MSVCR70.strstr
004013FA XOR EBX,EBX
004013FC MOV DWORD PTR SS:[ESP+534],EBX
00401403 /MOV AL,BL
00401405 |LEA ECX,DWORD PTR SS:[ESP+20]
00401409 |ADD AL,43 \\遍历盘符
0040140B |PUSH ECX ; /RootPathName \\盘符名
0040140C |MOV BYTE PTR SS:[ESP+24],AL ; |
00401410 |CALL DWORD PTR DS:[<&KERNEL32.GetDriveT>; \GetDriveTypeA \\很熟悉的函数
00401416 |CMP EAX,5
00401419 |JNZ SHORT thething.00401493 \\不是光驱则跳走
0040141B |MOV EDX,DWORD PTR DS:[404750]
00401421 |MOV CX,WORD PTR DS:[404758]
00401428 |MOV EAX,DWORD PTR DS:[404754]
0040142D |PUSH 0
0040142F |MOV DWORD PTR SS:[ESP+27],EDX
00401433 |PUSH 0
00401435 |LEA EDX,DWORD PTR SS:[ESP+28]
00401439 |MOV WORD PTR SS:[ESP+33],CX
0040143E |PUSH EDX
0040143F |LEA ECX,DWORD PTR SS:[ESP+1C]
00401443 |MOV DWORD PTR SS:[ESP+33],EAX \\走过这一句,EDX内指向内容为G:\xfhsm.inf(G为我的光驱盘符)
00401447 |CALL <JMP.&MFC70.#4870>
0040144C |TEST EAX,EAX \\判断光驱根目录内是否有xfhsm.inf文件
0040144E |JE SHORT thething.0040148E \\没有的话也继续下一个盘符
00401450 |MOV EAX,ESI
00401452 |LEA EDX,DWORD PTR DS:[EAX+1]
00401455 |/MOV CL,BYTE PTR DS:[EAX]
00401457 ||INC EAX
00401458 ||TEST CL,CL
0040145A |\JNZ SHORT thething.00401455
0040145C |SUB EAX,EDX
0040145E |ADD EAX,2
00401461 |PUSH EAX
00401462 |LEA EAX,DWORD PTR SS:[ESP+124]
00401469 |PUSH EAX
0040146A |LEA ECX,DWORD PTR SS:[ESP+18]
0040146E |CALL <JMP.&MFC70.#5095> \\这里是kernel32.ReadFile,强制跳转则光驱内无文件,当然出错
00401473 |LEA ECX,DWORD PTR SS:[ESP+10] \\xfhsm.inf内的内容已被读取到ECX中
00401477 |CALL <JMP.&MFC70.#1306> \\这里是KERNEL32.CloseHandl
0040147C |LEA ECX,DWORD PTR SS:[ESP+120]
00401483 |PUSH ESI
00401484 |PUSH ECX
00401485 |CALL EDI
00401487 |ADD ESP,8
0040148A |TEST EAX,EAX
0040148C |JNZ SHORT thething.004014D7
0040148E |MOV BYTE PTR SS:[ESP+23],0
00401493 |INC EBX
00401494 |CMP EBX,18
00401497 \JL thething.00401403 \\跳回去取下一个盘符
0040149D LEA ECX,DWORD PTR SS:[ESP+10]
004014A1 MOV DWORD PTR SS:[ESP+534],-1
004014AC CALL <JMP.&MFC70.#570>
004014B1 XOR EAX,EAX
004014B3 MOV ECX,DWORD PTR SS:[ESP+52C]
004014BA MOV DWORD PTR FS:[0],ECX
004014C1 MOV ECX,DWORD PTR SS:[ESP+524]
004014C8 XOR ECX,DWORD PTR SS:[EBP+4]
004014CB CALL thething.00402A09
004014D0 POP EDI
004014D1 POP ESI
004014D2 POP EBX
004014D3 MOV ESP,EBP
004014D5 POP EBP
004014D6 RETN
总结:程序检查所有光驱内根目录是否有xfhsm.inf文件,将00401FF8处的75改为EB即可实现免CD,xfhsm.inf是一个存放汉化者版权声明的txt
PS:很多老游戏只能将光盘或镜像放在第一个光驱盘符,应该是因为判断光驱目录内是否有XXX文件后,没有继续下一个盘符,可能当时没有想到有多光驱盘符的情况
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课