I will never get the time to write a protected mode programming tutorial, wich I wanted to do before publishing anything about dos4gw cracking. However you don't need to be able to program in pmode to crack dos4gw or other programs using dosextenders. However I suggest you go and read some of the very fine tutorials avaiable free on the net, to get a basic understanding what pmode is about and how dosextenders work. Neither will be explained here due to lack of time and knowledge. I'll only explain how to approach dosextended appz and how to debug them.
The problem with dos4g(w) games and appz is that winice won't debugg them in a normal way, it refuses to stop when placing breakpoints on interrupts :( Alittle extra work is needed. Softice for dos is not capable of debugging pmode programs, so we are left with winice.
Run GF from dos under an interrupt spy like Xray. Unfortnuatly Xray doesn't seem to work properly when running in a win95 dos box. I get different results when running in a dos box or from plain dos with mscdex loaded. So you better run the game with MSCDEX in memory, just to be sure.
Get the log from Xray and see what interrupt that is executed before the game terminates. Scan the log until you see that the program was terminated, in this case gfishexe.
----Xray LOG---- 1Ah, SET DTA, Time=.00ms, OK 1Ah, SET DTA, Time=.00ms, OK 4Eh, MATCH FILE, F:\*.*, Time=457ms, OK 44h, I/O CONTROL, 00h, Get Device information, Handle=1, Time=.00ms, OK 44h, I/O CONTROL, 00h, Get Device information, Handle=1, Time=.00ms, OK 40h, WRITE DEVICE, Handle=1, 29h bytes, Time=.27ms, OK 42h, MOVE POINTER, Handle=4, Time=.00ms, to offset 00h, OK 42h, MOVE POINTER, Handle=4, Time=.00ms, to offset 00h, OK 42h, MOVE POINTER, Handle=3, Time=.00ms, to offset 00h, OK 42h, MOVE POINTER, Handle=3, Time=.00ms, to offset 00h, OK 42h, MOVE POINTER, Handle=2, Time=.00ms, to offset 03D0h, OK 42h, MOVE POINTER, Handle=2, Time=.00ms, to offset 03D0h, OK 42h, MOVE POINTER, Handle=1, Time=.00ms, to offset 03D0h, OK 42h, MOVE POINTER, Handle=1, Time=.00ms, to offset 03D0h, OK 42h, MOVE POINTER, Handle=0, Time=.00ms, to offset 03D0h, OK 42h, MOVE POINTER, Handle=0, Time=.00ms, to offset 03D0h, OK 4Ch, TERMINATE PROGRAM, Status=1, OK -------end of LOG-----The last things that are done is:
Most likely we are dealing with a label check here or the presence of a file that is not copied on installation (stupid idea but you never know). Now we need to debugg this game to know for sure wich one of the above tricks that is used here. Since placing a bpint in winice would be no good we need to find a way to make winice break with out using the bpint. It has a feature that enables it to break as soon as it encounters an int 1 or an int 3 instruction. This is very nice for us cause if we could place an int 3 around the area where the match file is executed we would be able to continue from that point. The machine code for int 3 is CC. Now how do we find the area where the find first matching file is. Well open gfishexe in you favourite hexeditor and search for B4 4E CD 21 wich corresponds to:
Mov ah,4e
Int 21
You'll find 3 locations, place a CC over the CD in CD 21 on the first location found. Turn I3here on in winice by typing I3here ON. Run gfishexe and winice will stop. Assemble back the int 21 instruction. The Match file interrupt will fill the DTA (disk transfer area) with the label and the files found. You need to dump the DTA, wich was set by an int 21 just above your current Eip.
0247:83303743 89DA MOV EDX,EBX 0247:83303745 B41A MOV AH,1A 0247:83303747 CD21 INT 21 ; Set DTA TO ES:DX 0247:8330374A 5A POP EDX 0247:8330374B B44E MOV AH,4E ; match file 0247:8330374D CD21 INT 21 0247:8330374F E81EE00000 CALL 83311772 0247:83303754 89DA MOV EDX,EBX 0247:83303756 E821000000 CALL 8330377C 0247:8330375B 59 POP ECX 0247:8330375C C3 RET
As you can see the adress to the DTA is kept in EBX so just dump EBX and step over the Find First Match interrupt and you will see that the label of the current CD in the data window.
024F:8366880C 87 3F 3F 3F 3F 3F 3F 3F-3F 3F 3F 3F 00 00 00 00 .???????????.... 024F:8366881C 00 00 00 05 00 09 75 77-33 24 00 00 00 00 50 43 ......uw3$....PC 024F:8366882C 46 41 39 38 30 32 00 83-14 57 64 83 2A 89 66 83 FA9802...Wd.*.f. 024F:8366883C 08 00 00 00 25 C2 27 83-01 00 00 00 00 00 00 00 ....%.'......... 024F:8366884C DE 1C 58 83 21 C2 27 83-01 00 00 00 00 00 00 00 ..X.!.'......... 024F:8366885C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 024F:8366886C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 024F:8366887C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................My CD had the label PCFA9802
Put a breakpoint on one of those letter (ie the first) and move on. You'll get here. The label is then moved to a new adress, here:
0247:835CF059 LODSB 0247:835CF05A MOV [EDI],AL 0247:835CF05C INC EDI 0247:835CF05D CMP AL,00 0247:835CF05F JNZ 835CF059 The label is then encrypted in this routine: 0247:835F97C2 PUSH EBX 0247:835F97C3 PUSH EDX 0247:835F97C4 MOV EBX,EAX 0247:835F97C6 MOV DL,[EAX] 0247:835F97C8 TEST DL,DL 0247:835F97CA JZ 835F97DC 0247:835F97CC SUB DL,61 0247:835F97CF CMP DL,19 0247:835F97C3 PUSH EDX 0247:835F97C4 MOV EBX,EAX 0247:835F97C6 MOV DL,[EAX] 0247:835F97C8 TEST DL,DL 0247:835F97CA JZ 835F97DC 0247:835F97CC SUB DL,61 0247:835F97CF CMP DL,19 0247:835F97D2 JA 835F97D9 0247:835F97D9 INC EAX 0247:835F97DA JMP 835F97C6 And finally the check is made here: 0247:833DD839 8A08 MOV CL,[EAX] 0247:833DD83B 8A2A MOV CH,[EDX] 0247:833DD83D 38E9 CMP CL,CH ; Here is the check!!! 0247:833DD83F 740E JZ 833DD84F 0247:833DD841 31DB XOR EBX,EBX 0247:833DD843 31C0 XOR EAX,EAX 0247:833DD845 88CB MOV BL,CL 0247:833DD847 88E8 MOV AL,CH
A pretty stright forward and simple protection, but it could be deadly if you don't know how to debugg a dos4gw. Also in this game only three occurances of the B4 4E CD 21 was found wich made things alot easier than if 40 location used B4 4E CD 21. The other two locations are also worth studying since one of them is a mirror to the check we debugged. That second check is executed when trying to open a saved game.
But what if the target dont use any interrupts in the protection routine?
I have chosen an old Dos game for a second target. This game is wide spread so you shouldn't have any problems getting your hands on it. Just scan some of your old warez CD-Roms or if you like Doom alike gamez, buy it. This Doom copy is interresting for us students because it doesn't use any interrupts at all plus that it's using dos4gw dosextender. The protection is of the old (and obsolete) "manual protection" type. On startup it asks you to type in a number wich you are supposed to find in the manual that came with the game. If the right number is entered you'll pass the protection and the game starts. See previous lesson on how to defeat these simple schemes.
We will concentrate on how to debugg and locate the heart of the protection. As you know the problem with Winice under dosextenders is the bpint command. In quarantine this is not a problem cause it doesn't execute any interrupts in the protection routine. When you have found an entrance through winice all other breakpoin commands will work fine especially the bpx command. Since we cannot put a CC byte in the exe file here (we could but we don't know the area where the protection dwells) we need to find another entrance to the protection.
Run quarantine and when the manual protection screen appears, switch back to softice. Normally you could have stopped at:
In this case you always end up in quarantines code. But if you should end up in something else just switch back and forth through winice until you land in the targets code. Now type in any number ie 555 and switch back to softice and search for the number you typed in. You'll land in a screen update routine that will loop until return is pressed. This loop is executed several times a second so there's no chance to press return before winice breaks.
0217:834D1FC0 ADC EAX,83037440 ; Winice breaks here 0217:834D1FC5 MOV BX,[83037476] 0217:834D1FCC MOV [EAX-01],DL 0217:834D1FCF INC EAX 0217:834D1FD0 MOV DL,[83037441] 0217:834D1FD6 INC EBX 0217:834D1FD7 MOV [EAX-01],DL 0217:834D1FDA MOV DL,[83037442] 0217:834D1FE0 MOV [83037476],BX 0217:834D1FE7 MOV [EAX],DL | | 0217:834D2095 POP EBP 0217:834D2096 POP ESI 0217:834D2097 POP EDX 0217:834D2098 POP ECX 0217:834D2099 POP EBX 0217:834D209A RET ; RETURN 0217:834D1E1A CALL 834D1ED4 0217:834D1E1F CALL 8302E28D ; The ret takes you here 0217:834D1E24 JMP 834D1D30 0217:834D1E29 MOV EAX,000000B4 0217:834D1E2E MOV EBX,00000100 0217:834D1E33 CALL 834BB964 0217:834D1E38 XOR EDX,EDX 0217:834D1E3A MOV EAX,8303B870 0217:834D1D30 MOV SI,[830523F6] And the JMP takes you here. 0217:834D1D37 TEST SI,SI 0217:834D1D3A JNZ 834D1E29 0217:834D1D40 MOV EAX,[8303C120] 0217:834D1D45 CALL 834BB0A6 0217:834D1D4A CALL 834D214C 0217:834D1D4F CMP WORD PTR [83052404],00 0217:834D1D57 JZ 834D1E1A ; This jump takes us back to the start 0217:834D1D5D MOV EAX,[EBP-12] 0217:834D1D60 SAR EAX,10 0217:834D1D63 CALL 834D1E50 0217:834D1D68 CMP AX,0001 0217:834D1D6C JNZ 834D1DA5 0217:834D1D6E MOV EDI,EAX 0217:834D1D70 MOV [830523F6],AX
The JZ at 0217:834D1D57 takes us back to routine where winice keeps breaking, put a breakpoint on the command below and disable the breakpoint on your passord number. When winice breaks enable the bmp or bpr on your password number. You will then see that the password check is done inside the code at:
0217:834D1D63 CALL 834D1E50 0217:834D1D68 CMP AX,0001 ; if password is incorrect 0217:834D1D6C JNZ 834D1DA5 ; jump to bad boy!!
Well as you just experienced we solved this protection without any int 3 insertions in the exe file. If you ask me I think this way is very convinient, it took me about 2-3 minutes to find and crack this game. In this case we were quite lucky that we always ended up in quarantines code. Normally you'll end up in windows tasks and other things that's constantly running in your system. Try to have as little programs running in the background as possible when you are trying to break into your targets code. If many tasks is running you'll end up more often inside them instead of your target.
DOS4G(W) dissassembling:
As far as I know there's no good dissassembler for dos4gw. There are many dissassembler that are capable of doing the job. One of them is W32Dasm, however it will give a 16 bit disassembly listing instead of 32 bit. And references are quite gone too. There will be alot of "unindexed" routines and so, you could always give it a try if everything else fails. I like the live approach though, deadlisting a dos4g(w) is not exactly pleasant.
Now I suggest you dig out every old dos4g game you might have and practice these two techniques until you know control them. As usual you are welcomed to ask questions by email, DON'T ASK ME FOR WAREZ though.
Well I think that would be enough for today, I'll get back in this matter later in a Lesson #4d wich will be about other dos protection applied in games (mainly).
Later
/Indian_Trail