A Dos Game CD-check with Sourcer 7
I agree totally with FootSteps: cracking is the big game: your brain, your wit and your intuition against clever opponents (and you'll note that FootSteps divides his essay using the messages of the old game)... that's LIFE!
Yes... the old proverb by +ORC helds true: if you teach a man how to reverse he will never be thirsty again... because of the fun he'll have in the reversing itself!
I'm like FootSteps, I regularly peruse my old 'big black' floppies searching for 'forgotten' mighty protections... and you would be amazed to see how easily you can port these old dos protections to windoze!
YOU ARE STANDING IN A OPEN FIELD WEST OF A WHITE HOUSE... Hello! Well, I don't know about you, but I'm a guy who play gladly oldies; I mean old games. Do you remember Zork? You know: "You are standing in a open field, ..." then, "open mailbox", etc... Oldies are interesting, because: First, you must *find* them on the web. Beyond the Warez, where you can find a few, you can use here what we've learned in the Fravia site to search them. Like zork.zip <- This is a easy and ridiculous example! :-) Try to find "The Guild of Thieves"... A good one... theguildofthieves.zip ? No, no... Search better! Second, when you've found them, enjoy to play them. You can find jewels. Remember "Bard's Tale"? Marvelous to play this 8086's one with a Pentium! Third, even if found in the WareZ scene, you're playing for a moment when you see something like that: "Please enter the word of the page..."! Well, this is where the oldies is very funny to play: cracking this old protection scheme. Because they are DOS-based, and sometimes, very difficult. Well, follow me for a easy one, a 1994 DOS game (not so much oldie...) with two CD-checks, whose the second is interesting, interesting cause if you are like me, unable to run Softice DOS due to some video card problems, you'll run this game with WindoZ95, using Winice, but our beloved and young Winnie hang running this oldie! Better, IDA Pro 3.7 doesn't reverse correctly it! Then, welcome to Sourcer 7, cracked by Frog's Print, somewhere on our Fravia WebSite!
THE GREAT UNDERGROUND EMPIRE (was called Zork itself)
Well, we say that you've done a good research and found the target, the game DOMINUS, 13.9Mo. I know, you're hurry to play with it. Ok, run it. Well, an amazing "Please insert the Dominus CD" screen come in front of our honest eyes; sure, we'd like buy and insert this CD :-) but we cannot find it nowhere in any store... it's a DEAD program! Then, since on the contrary we can find Winnie on the net, we run it nevertheless... You want to know how? Did you read the good essay of Animadei on the DOS CD checks? Well, we use Winnie to do a BPINT 2F IF (AH==15) Remember? The DOS CD-ROM resident MSCDEX is called with this interruption, 2F, and AH set to 15. We don't care AL. We want just to know where is the *first* CD-check that this game does. Run Dom.bat. Winnie stops; good. We are in LOADER.EXE, that is in the batch DOM.BAT we've started. 3AB7:0099 B8 1500 mov ax,1500h 3AB7:009C CD 2F int 2Fh ; Yes! 3AB7:009E 89 0E 29CA mov WORD PTR [29CA],cx 3AB7:00A2 8B C1 mov ax,cx 3AB7:00A4 07 pop es ... 3AB7:00AC CB retf We see an INT 2F called with AX set to 1500. Look at your Interrupt list. This is done to know how many CD-ROM drives you've got on your machine. Just hit F12, to land in this classic protection scheme you can trace for the pleasure (we land in 350D:0147 after hiting F12): 350D:0140 59 pop cx 350D:0141 59 pop cx 350D:0142 9A 3AB7:008F call 3AB7:008F ; how many CD drives? 350D:0147 A3 017A mov word ptr 017A,ax 350D:014A 83 3E 017A 00 cmp word ptr 017A,0 ; no CD drives? 350D:014F 74 54 je 350D:01A5 ; then jump to "insert CD..." 350D:0151 1E push ds 350D:0152 B8 0227 mov ax,227h 350D:0155 50 push ax 350D:0156 16 push ss 350D:0157 8D 46 96 lea ax,[bp-6Ah] 350D:015A 50 push ax 350D:015B 9A 3067:41EF call 3067:41EF ; stringcopy "A:\DOMINUS.ZIP" 350D:0160 83 C4 08 add sp,8 350D:0163 A0 017A mov al,byte ptr 017A ; the number of your CD drive 350D:0166 04 41 add al,41h ; change to "X:DOMINUS.ZIP" 350D:0168 88 46 96 mov [bp-6Ah],al 350D:016B 1E push ds 350D:016C B8 0236 mov ax,236h 350D:016F 50 push ax 350D:0170 16 push ss 350D:0171 8D 46 96 lea ax,[bp-6Ah] 350D:0174 50 push ax 350D:0175 9A 3067:2F38 call 3067:2F38 ; open "X:DOMINUS.ZIP" 350D:017A 83 C4 08 add sp,8 350D:017D 89 56 FE mov [bp-02],dx ; Was 350D:0180 89 46 FC mov [bp-04],ax ; the good file DOMINUS.ZIP 350D:0183 0B 46 FE or ax,[bp-02] ; on the CD? 350D:0186 75 2F jnz 350D:01B7 ; ax!=0 then jump to good user! .... else, ax==0 and "Insert CD" and no game... how sad... Well, it's not too difficult, in fact, it's like the classic Win32 GetDriveTypeA we all know when reversing WindoZ applications. The program, here LOADER.EXE, look first for the number of CD drives you got using the interruptions of MSCDEX. No matter if you haven't loaded it because WindoZ95 emulate it (at least one thing it can do). LOADER.EXE find your drive, elsewhere you'll got the message "Insert CD". Then, it copies in memory the string "A:DOMINUS.ZIP". Uh? Strange? Next, it copies the letter of your CD drive, let say 'X' in this string, which becomes "X:DOMINUS". Then, using again some 2F interruptions we'll not describe here because it has been already done by Animadei, it just check if the file "X:DOMINUS.ZIP" is on your CD-drive, how fun! If ax!=0, you're a good gamer, since you've bought the right CD. Since we are also good crackers ;-), we just change the 350D:0140 bytes with: 350D:0140 EB 75 jmp 01B7 ; jmp good user! avoiding with this all the boring CD and comparison checks. Not our fault, as I said: the right CD isn't in any shop. Well, we run the game, see a pretty US-GOLD presentation screen, (of 1994 of course), and we run a new game. I DON'T KNOW THE WORD "SOFTICE" Err... we won't play a new game, because SoftIce has hanged. We just can reboot our machine. Reset. Bios check. Presentation screen. Yes, I say presentation screen because we've got to boot in DOS. I'm sure you've got a boot manager, haven't you? hehehe... Then, we boot DOS. And we run the game. The same that under W95: The PC hangs. That is here we gonna use this sympathic freeware, X-RAY 1.5, a good spy utility. We must know what's going on just before the PC hangs. Just use: XRAY /J /F To say the program to Jump instead of calling the original interrupt address (seems to work better with that.), and to write a log File on our hard drive, named c:\xray.log Then, run dom.bat. The game hangs when you choose a new game. Well, reboot with WindoZ 95. Open XRAY.LOG with your favorite text editor. Xray just show the Interrupts 21 calls. But it's enough. Cause if you're not tired, you will see at the line 5113 the following Int 21: 34h, GET BUSY FLAG 30h, GET DOS VERSION 3Dh, OPEN FILE, F:\DOMINUS.ZIP ;line 5113 3Fh, READ DEVICE, Handle=5, 0Ah bytes 3Eh, CLOSE FILE, Handle=5 Ha ha! Seems like the program search a second time for his favorite file on his favorite CD! Mmmm... If you disassemble LOADER.EXE with IDA Pro, all will be great, but you'll not see others CD-checks references in it. Then, the bytes we've changed don't appear any more in this executable. This is not this program which checks for the second time the CD. Who checks? Mmm... Just hit control+f in WindoZ95. Search the string "DOMINUS.ZIP" in all your \DOMINUS directory. Haha! It is present in LOADER.EXE, we knew it, and in TEMP.EXE But Softice hang, we couldn't trace this second CD check, then we run in laughing IDA Pro 3.7, asking it to reverse this ridiculous TEMP.EXE of little 210Ko. Argh again! IDA Pro 3.7 doesn't reverse correctly this little executable. We see a lot of DB, you know all that. Curious. Coz IDA recognize well this program compiled with Borland C, like the precedent LOADER.EXE, marking sometimes some call _fileopen and other call _strcpy. But the rest of the listing is a pretty garbage. What happens to you, beloved IDA? ;-) You can try to reverse TEMP.EXE with W32Dasm, it does it well, but you know how W32Dasm reverse Dos based applications, we get no Data X-Ref at all, and it's not funny at all to follow such a dead listing... At this point, I was really bored, without my Winice and IDA, frightened to the idea to follow a long W32Dasm listing with no help at all, lost in these large and dark codewoods for many hours,.. IT'S PITCH DARK I began to follow this "Data Xref crippled" listing of TEMP.EXE reversed by W32Dasm, and it took me a lot of hours to understand very little. It made me think to all these old text adventures games we played, when we were lost in giant labyrinths. Darker and darker... I thought that reversing was exactly the same thing that playing text adventure games. A lot of places, you're obliged to write a map, some of them were very difficult, some were easy, some were fabulous, some were boring... And like in all this kind of game, come the point where you're stuck. Really stuck. With no way out, no solution... Reversing is really like playing a big huge ZORK! Cause at a given moment, you find the right thing to do, you remember the right tool to use, you devise the right sentence to enter. LIGHT LAMP Well, I've remembered a nice soft I've let in a dark and sad place on my HD, forgetting it since using IDA. It was Sourcer 7, reversed by Frog's Print. Hope came in my mind. I used the version 6.51 of it before passing to (welcome) IDA in order to debug Dos applications, and it was already a nice one. Put TEMP.EXE in your Sourcer directory, be sure to have enough low Dos memory left, and just type: SR TEMP.EXE setting the Passes to 9; the more analysys you got, the better is the result. And yeepee! We got a pretty listing, with all the Data Xref we want! Sorry to have almost forgotten you, Sourcer! Welcome again! Because you now just need to search the dead-listing TEMP.LST for "DOMINUS.ZIP" with your favorite Text-Editor! And look, it's here, just in front of your eyes: ;Indexed Entry Point 31A9:00A1 loc_233: 31A9:00A1 74 2B jz loc_235 ; Jump if zero 31A9:00A3 04 41 add al,41h ; 'A' assume ds:seg_j 31A9:00A5 A2 01A7 mov byte ptr data_845,al ; (54AC:01A7='A:\DOMINUS.ZIP') 31A9:00A8 9A 4872:01EA call far ptr sub_593 ; (4872:01EA) 31A9:00AD B4 3D mov ah,3Dh ; '=' 31A9:00AF B0 00 mov al,0 31A9:00B1 BA 01A7 mov dx,offset data_845 ; (54AC:01A7='A:\DOMINUS.ZIP') 31A9:00B4 CD 21 int 21h ; DOS Services ah=function 3Dh ; open file, al=mode,name@ds:dx 31A9:00B6 72 16 jc loc_235 ; Jump if carry Set 31A9:00B8 8B D8 mov bx,ax 31A9:00BA B4 3F mov ah,3Fh ; '?' 31A9:00BC B9 000A mov cx,0Ah 31A9:00BF BA 01A7 mov dx,offset data_845 ; (54AC:01A7='A:\DOMINUS.ZIP') 31A9:00C2 CD 21 int 21h ; DOS Services ah=function 3Fh ; read file, bx=file handle ; cx=bytes to ds:dx buffer 31A9:00C4 72 08 jc loc_235 ; Jump if carry Set 31A9:00C6 B4 3E mov ah,3Eh 31A9:00C8 CD 21 int 21h ; DOS Services ah=function 3Eh ; close file, bx=file handle 31A9:00CA 72 02 jc loc_235 ; Jump if carry Set 31A9:00CC EB 05 jmp short loc_236 ; (00D3) 31A9:00CE loc_235: ; xref 31A9:00A1, 00B6, 00C4, 00CA 31A9:00CE B8 4C01 mov ax,4C01h 31A9:00D1 CD 21 int 21h ; DOS Services ah=function 4Ch ; terminate with al=return code 31A9:00D3 loc_236: ; xref 31A9:00CC GOOD USER... Should I really comment better this part of code Sourcer already reversed? Really self-explanatory, no? Then... this second crack to the CD check is quickly made: The program came at 31A9:00A1 which is the protection check. The "jz loc_235" is here to see if you got at least one CD drive. You got no one? Or you got, like you see in the following code, not the right CD? Then this program eject you immediately to the terrific int 21 with ah set to 4C, the DOS termination... Oh, no... But, we are very clever. Remark the "jmp short loc_236" at offset 31A9:00CC, just at the end of the protection routine and just before the horrible Dos termination. Then we just need to jump to this location. What about a sympathic: 31A9:00A1 JMP loc_236 instead of the original sad: 31A9:00A1 jz loc_235 which say the program we got obviously the right CD rom in our drive? Yes? We just need to change the jz loc_235 74 2B in our clever JMP loc_236. First, replace the jz opcode "74" by the jmp opcode "EB". Second, we need to jmp location 236 instead of the 235 one, which is placed 5 octets after. Then, jmp loc_236 is jmp loc_235 + 5, is EB (2B + 5), is finally EB 30. Yeah! Then, just four bytes more to change, for esthetic you know, to avoid the light of our CD drive twinkle when TEMP.EXE ask MSCDEX to look how many CD drives you got. If you haven't no CD drive on your machine, just don't care. But if you are Cresus or Bill Gates, you'd like avoid all of your 56 CD light drives to light! :-) Remember that it was INT 2F with ah set to 15 that check your CD drive? Then, we've got just to replace in our code the opcode CD 2F, present at two locations, with some 40 48 opcodes, for example. Then, exit your hexeditor and run a new game. Well, it works! And now we can play!
We won't play a long time finally, coz this game isn't a wonderful oldie... Cracking it was more fun... than playing it...
All right, back to the Net, looking for a new Dos oldie to crack! And soon we realize that Cracking is the best adventure game we've ever played... --FootSteps.