CrackingTutorial-03

0

                          CRACKING 101 - 2008 edition

                                    Lesson 2

                              ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
                              ³ DOC CHECK PRIMER ³
                              ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

                               by HackerVinoth

              Ok, in   this  textfile,  I  will  start  talking  about
         removing doc check protection schemes.  I find, the doc check
         scheme to be slightly more difficult  to  work on than normal
         INT 13 schemes.

              What is  a  doc  check.   Usually, a doc  check  when  a
         program ask the  user to enter a phrase or code supplied with
         the manual.  Now, one might think  that  "Shit,  we  can just
         type all the codes in to a textfile and upload  it  with  the
         DOCS", but that  way of thinking breaks down on programs such
         as Future Classics where there  are  6  pages  with about 200
         codes per page.   So  it is just better to remove  the  check
         completely.

              In this  primer, I will get in to the theory of removing
         a doc check, then start with  a  simple  example  (Electronic
         Art's ESCAPE FROM HELL).  Then in the next file,  I will take
         you deeper in  to  the world of doc checks and work with more
         difficult examples.  But for now, lets get started.

              A doc check, in basic theory works much like normal
         INT 13 copy protection.  Somewhere  in  the  beginning of the
         program before it really starts, the check is  made.   If the
         result is ok  (ie the user enters the correct word or phrase)
         then the program continues.  If  not, then the program simply
         exits to dos.

              Simple right,  well  not  really.   Usually,  the  input
         routine is part  of the standard input routine of the program
         so you just can't go about modify  the  call  to INT 16h (the
         keyboard interrupt) like you could with INT 13h.   So,  where
         do we start.   If  you  think back to cracking the old INT 13
         protection schemes, you would  use  a program like PCWATCH or
         TRAP13 to get a rough idea of where the call  resides.   With
         doc checks, this is really not the best way to do it.

              I suggest  that  you try to break in to the program well
         before the protection is checked.   Remember,  we must remove
         the check without messing with the actual input routine so we
         want to come in highest level.

              So, how  do we break in.  By using a good  debugger.   I
         suggest Periscope.  I find it is the best and easiest to use.
         Once we are  in,  all  the  is  left  is to trace through the
         program until we find the topmost call to the doc check.  Now
         we're moving.

              So let's say we have broken  in to the program and found
         the topmost call to the doc check.  What next.   We  must try
         to figure out   what   the   program   does.    There  are  2
         possibilities.  First, the program  could  simply  check  the
         inputed string against a value in memory, and  if  they don't
         match simply exit  to  dos and if they do, just continue with
         the program; or if the input  matches  it  can  set a flag in
         memory that is checked by some routine later.

              So, on  to  the  example.   NOTE! All address  might  be
         different.  This is  how  it  looked when I cracked it.  ALSO
         NOTE, you should  be cracking  without  any  memory  resident
         programs.  Make sure MEMORY is clear, and that  you  load the
         system the same   way  each  time.   Remember,  if  you  load
         everything the same, everything  will  be  in the same memory
         location.

              So, what is our first step.  Well, I suggest picking out
         the right tools to do the job.  In this case,  You  will only
         need PERISCOPE (and  the  addin  program  that  comes with it
         called PSKEY) and a good file editor  (when I say good I mean
         it can edit and search in hex).  So let's get started.

              First, we  load  PERISCOPE (PS from now  on).   This  is
         gonna be the  debugger  we use.  Next, we need a quick way in
         to the debugger.  Since ESCAPE FROM HELL (EFH from now on) is
         not all the picky about how it  keeps  a  crackest out, PSKEY
         will do just fine but not without using a little trick.

              Normally, when using PSKEY (for those of  you who do not
         know what PSKEY does, it allows up to break in to PS usings a
         TSR hotkey) and  you  hit  the  hotkey,  PSKEY does an INT 2h
         (NMI).  This then brings up PS  and  you  are  set.  But, EFH
         revectors INT 2h (NMI) to simply an IRET so this  method does
         not work.  How  do  we  get  around this, well, INT 2h is the
         default used with PSKEY but not the only way to work it.  You
         can also use  INT  3h  (Breakpoint   interrupt)  or  INT  15h
         (Extended services interrrupt) to activate PS.   In this case
         we will use  INT  3h;  so  when  we  invoke  PSKEY we add the
         command line parameter "3" (ie:  "PSKEY  3CAL"  invokes PSKEY
         using INT 3h setting the hotkey to CTRL-ALT-LEFT_SHIFT).

              So, now that we have a way in to EFH, where  do  we want
         to break out.   Well  boys  (and Girls, and BTW: if there are
         any Fems reading this, give me  a ring, I'd like to hear from
         ya) I don't have any formula to give, but remember, I suggest
         that we try  to  break  in  to  the  outermost   loop.    So,
         experiance (and a  good  fucking guess) tells me to break out
         in the title screen before the music begins.

              It just so happens that this time I was right (And noone
         had to get nail to anything -D.A.)   Right  after  the  title
         picture comes up, press your hotkey (oooh).  The PS debugging
         screen should come up and you should see the  follow  section
         of code..

         2309:019C CF            IRET
         2309:019D 3D0085        CMP AX,8500
         etc.

              This is  the exit code from PSKEY.  By usings the J(ump)
         command, and executing the IRET,  you  will be put back right
         to the spot  where  you pressed the hotkey (boy  I'm  getting
         excited).  I would love to give you a code fragment here, but
         each time you press the hotkey you will end up at a different
         point.

              So what  do we do next.  Well, we will just have to keep
         executing code until we find some  reference point.  Remember
         how I said we wanted to break out before we reached  to music
         at the title  screen.   Well,  you can bet that we are in the
         outermost loop since the music comes before the doc check and
         we haven't reached the call to  the music routine yet.  So we
         start executing code.

              Then all  of  the  sudden  BOOM!  you  execute   a  CALL
         instruction and music  bursts  through  the  speaker.  AHa, a
         reference point.  We know we are on the right track.

              Press during the music  so  that  we  can skip the
         stupid intro for now.  After pressing you should regain
         control at the  instruction  after  the  call  to  the  music
         routine.

              From here  on  out,  we  want  to procede rather slowly.
         Each time you reach a CALL instruction you want to write down
         the address where it is located.   Sooner  or  later you will
         execute a CALL instruction and EFH will jump  in  to it's doc
         check routine.  But  damn,  you  have the address of the that
         call WRITTEN DOWN  right.   So   simply   reboot  and  reload
         everything.

              Break out   in  to  PS  at  the  title  picture.    Now,
         unassemble the address   you  wrote  down.   You  should  see
         something like this

         21DD:3EA4 9AA5368132     CALL 3281:36A5  (current line)
         21DD:3EA4 9A522F8132     CALL 3281:2F52
         21DD:3EA4 C706BB070000   MOV WORD PTR [07BB],0000
         21DD:3EA4 8BE5           MOV SP,BP
         21DD:3EA4 5D             POP BP
         21DD:3EA4 CB             RETF

              The first call, is the call  to the doc check, therefore
         it can for  now  be assumed that the second call  is  to  the
         actual game (remember,    most    programmers   follow   good
         programming practice and will exit  the routine that does the
         doc check to  finish the game).  Please NOTE,  from  here  on
         out, if I  say  go back to STEP 1, reboot the machine, reload
         and get to this point.  Ok.

              Our first though in seeing  code like this is shit maybe
         they just check the keyword and exit to dos if  it's bad;  if
         it it's good,  then  they just exit that subroutine and start
         the game.  So having lots of time  on  our hands, we try just
         executing the second CALL and bypass the first  (you  can  do
         that by setting  the IP (instruction pointer) register to the
         offset of the second call [In  our  case 3EA9]).  When you do
         this, the screen clears, and you see the character  (Richard)
         on the screen.   But just as you think it worked, it switches
         back to text mode and prints the message "Hell is HOT".  Shit
         I hate it when that happens.

              So now we know that somewhere  in the doc check routine,
         EFH sets a  flag in memory.  We must figure  out  where  this
         flag is and  figure out a way to fake it.  So go back to step
         1, this time, let's trace (using the T command) in to the doc
         check routine.

              I have included the entire  outerloop  of  the doc check
         routine here.  The   small  subroutines  are   not   of   any
         importants and infact  when I first crack EFH, I never traced
         in to any of them.  It wasn't  until  I  was out getting this
         information that I took a look to see what they did.

              Here is  the  dos check code.  I have place  some  basic
         instructions that should  help you as you go along.  Although
         you address might be different than mine, I will use mine for
         reference.  Also, I have noted some special subroutines along
         the way.

         ( - Unassembled DOC CHECK for ESCAPE FROM HELL [outer loop] )

              First, we start off with  some  initialization routines.
         You don't need to be all to concerned with them.

         3281:36A5 55            PUSH BP
         3281:36A6 8BEC          MOV BP,SP
         3281:36A8 83EC2A        SUB SP,+2A
         3281:36AB C746DE0000    MOV WORD PTR [BP-22],0000
         3281:36B0 B80600        MOV AX,0006
         3281:36B3 50            PUSH AX
         3281:36B4 9AE3169900    CALL 0099:16E3
         3281:36B9 59            POP CX
         3281:36BA 48            DEC AX
         3281:36BB 8946DA        MOV [BP-26],AX
         3281:36BE B80F00        MOV AX,000F
         3281:36C1 50            PUSH AX
         3281:36C2 9AE3169900    CALL 0099:16E3
         3281:36C7 59            POP CX
         3281:36C8 48            DEC AX
         3281:36C9 8946DC        MOV [BP-24],AX
         3281:36CC C706CB070E00  MOV WORD PTR [07CB],000E
         3281:36D2 C746D60000    MOV WORD PTR [BP-2A],0000
         3281:36D7 E9C002        JMP 399A
         3281:36DA C746D80000    MOV WORD PTR [BP-28],0000
         3281:36DF E92501        JMP 3807
         3281:36E2 9A9B479900    CALL 0099:479B
         3281:36E7 B83866        MOV AX,6638
         3281:36EA 50            PUSH AX
         3281:36EB A03407        MOV AL,[0734]
         3281:36EE B400          MOV AH,00
         3281:36F0 50            PUSH AX
         3281:36F1 B80C00        MOV AX,000C
         3281:36F4 50            PUSH AX
         3281:36F5 B8CF00        MOV AX,00CF
         3281:36F8 50            PUSH AX
         3281:36F9 8B46DC        MOV AX,[BP-24]
         3281:36FC BA5800        MOV DX,0058
         3281:36FF F7E2          MUL DX
         3281:3701 8BD8          MOV BX,AX
         3281:3703 8A87F640      MOV AL,[BX+40F6]
         3281:3707 B400          MOV AH,00
         3281:3709 8BD8          MOV BX,AX
         3281:370B 81C39400      ADD BX,0094
         3281:370F D1E3          SHL BX,1
         3281:3711 D1E3          SHL BX,1
         3281:3713 FFB7F25D      PUSH [BX+5DF2]
         3281:3717 FFB7F05D      PUSH [BX+5DF0]
         3281:371B 9AE7019900    CALL 0099:01E7
         3281:3720 83C40C        ADD SP,+0C
         3281:3723 8B46DA        MOV AX,[BP-26]
         3281:3726 3D0500        CMP AX,0005
         3281:3729 7603          JBE 372E
         3281:372B E9B200        JMP 37E0
         3281:372E 8BD8          MOV BX,AX
         3281:3730 D1E3          SHL BX,1
         3281:3732 2E            CS:
         3281:3733 FFA73737      JMP [BX+3737]
         3281:3737 43            INC BX
         3281:3738 37            AAA
         3281:3739 5E            POP SI
         3281:373A 37            AAA
         3281:373B 7837          JS 3774
         3281:373D 92            XCHG DX,AX
         3281:373E 37            AAA
         3281:373F AC            LODSB
         3281:3740 37            AAA
         3281:3741 C637B8        MOV BYTE PTR [BX],B8
         3281:3744 2000          AND [BX+SI],AL
         3281:3746 50            PUSH AX
         3281:3747 B82E01        MOV AX,012E
         3281:374A 50            PUSH AX
         3281:374B B88100        MOV AX,0081
         3281:374E 50            PUSH AX
         3281:374F B87348        MOV AX,4873
         3281:3752 50            PUSH AX
         3281:3753 9AD6029900    CALL 0099:02D6
         3281:3758 83C408        ADD SP,+08
         3281:375B E98200        JMP 37E0
         3281:375E B82000        MOV AX,0020
         3281:3761 50            PUSH AX
         3281:3762 B82E01        MOV AX,012E
         3281:3765 50            PUSH AX
         3281:3766 B88100        MOV AX,0081
         3281:3769 50            PUSH AX
         3281:376A B88648        MOV AX,4886
         3281:376D 50            PUSH AX
         3281:376E 9AD6029900    CALL 0099:02D6
         3281:3773 83C408        ADD SP,+08
         3281:3776 EB68          JMP 37E0
         3281:3778 B82000        MOV AX,0020
         3281:377B 50            PUSH AX
         3281:377C B82E01        MOV AX,012E
         3281:377F 50            PUSH AX
         3281:3780 B88100        MOV AX,0081
         3281:3783 50            PUSH AX
         3281:3784 B8AD48        MOV AX,48AD
         3281:3787 50            PUSH AX
         3281:3788 9AD6029900    CALL 0099:02D6
         3281:378D 83C408        ADD SP,+08
         3281:3790 EB4E          JMP 37E0
         3281:3792 B82000        MOV AX,0020
         3281:3795 50            PUSH AX
         3281:3796 B82E01        MOV AX,012E
         3281:3799 50            PUSH AX
         3281:379A B88100        MOV AX,0081
         3281:379D 50            PUSH AX
         3281:379E B8C748        MOV AX,48C7
         3281:37A1 50            PUSH AX
         3281:37A2 9AD6029900    CALL 0099:02D6
         3281:37A7 83C408        ADD SP,+08
         3281:37AA EB34          JMP 37E0
         3281:37AC B82000        MOV AX,0020
         3281:37AF 50            PUSH AX
         3281:37B0 B82E01        MOV AX,012E
         3281:37B3 50            PUSH AX
         3281:37B4 B88100        MOV AX,0081
         3281:37B7 50            PUSH AX
         3281:37B8 B8E848        MOV AX,48E8
         3281:37BB 50            PUSH AX
         3281:37BC 9AD6029900    CALL 0099:02D6
         3281:37C1 83C408        ADD SP,+08
         3281:37C4 EB1A          JMP 37E0
         3281:37C6 B82000        MOV AX,0020
         3281:37C9 50            PUSH AX
         3281:37CA B82E01        MOV AX,012E
         3281:37CD 50            PUSH AX
         3281:37CE B88100        MOV AX,0081
         3281:37D1 50            PUSH AX
         3281:37D2 B80F49        MOV AX,490F
         3281:37D5 50            PUSH AX
         3281:37D6 9AD6029900    CALL 0099:02D6
         3281:37DB 83C408        ADD SP,+08
         3281:37DE EB00          JMP 37E0
         3281:37E0 B82D00        MOV AX,002D
         3281:37E3 50            PUSH AX
         3281:37E4 B88200        MOV AX,0082
         3281:37E7 50            PUSH AX
         3281:37E8 9A96029900    CALL 0099:0296
         3281:37ED 59            POP CX
         3281:37EE 59            POP CX
         3281:37EF B82849        MOV AX,4928
         3281:37F2 50            PUSH AX
         3281:37F3 9A3F039900    CALL 0099:033F
         3281:37F8 59            POP CX
         3281:37F9 837ED800      CMP WORD PTR [BP-28],+00
         3281:37FD 7505          JNZ 3804

              Here is the first point of interest.  The call on the
         following line will display the "what is xxxx" message. Ä¿
                                                                  ³
         3281:37FF 9A1B019900    CALL 0099:011B <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

         3281:3804 FF46D8        INC WORD PTR [BP-28]
         3281:3807 837ED802      CMP WORD PTR [BP-28],+02
         3281:380B 7D03          JGE 3810
         3281:380D E9D2FE        JMP 36E2
         3281:3810 8B46DA        MOV AX,[BP-26]
         3281:3813 3D0500        CMP AX,0005
         3281:3816 7603          JBE 381B
         3281:3818 E97401        JMP 398F
         3281:381B 8BD8          MOV BX,AX
         3281:381D D1E3          SHL BX,1
         3281:381F 2E            CS:
         3281:3820 FFA72438      JMP [BX+3824]
         3281:3824 3038          XOR [BX+SI],BH
         3281:3826 6E            DB 6E
         3281:3827 38AC38EA      CMP [SI+EA38],CH
         3281:382B 3827          CMP [BX],AH
         3281:382D 396439        CMP [SI+39],SP
         3281:3830 B81000        MOV AX,0010
         3281:3833 50            PUSH AX
         3281:3834 16            PUSH SS
         3281:3835 8D46E2        LEA AX,[BP-1E]
         3281:3838 50            PUSH AX
         3281:3839 9AFB149900    CALL 0099:14FB
         3281:383E 83C406        ADD SP,+06
         3281:3841 8D46E2        LEA AX,[BP-1E]
         3281:3844 50            PUSH AX
         3281:3845 9A0F00B81B    CALL 1BB8:000F
         3281:384A 59            POP CX
         3281:384B 8B46DC        MOV AX,[BP-24]
         3281:384E BA5800        MOV DX,0058
         3281:3851 F7E2          MUL DX
         3281:3853 05F740        ADD AX,40F7
         3281:3856 50            PUSH AX
         3281:3857 8D46E2        LEA AX,[BP-1E]
         3281:385A 50            PUSH AX
         3281:385B 9A0E00661A    CALL 1A66:000E
         3281:3860 59            POP CX
         3281:3861 59            POP CX
         3281:3862 0BC0          OR AX,AX
         3281:3864 7505          JNZ 386B
         3281:3866 C746DEFFFF    MOV WORD PTR [BP-22],FFFF
         3281:386B E92101        JMP 398F
         3281:386E B81000        MOV AX,0010
         3281:3871 50            PUSH AX
         3281:3872 16            PUSH SS
         3281:3873 8D46E2        LEA AX,[BP-1E]
         3281:3876 50            PUSH AX
         3281:3877 9AFB149900    CALL 0099:14FB
         3281:387C 83C406        ADD SP,+06
         3281:387F 8D46E2        LEA AX,[BP-1E]
         3281:3882 50            PUSH AX
         3281:3883 9A0F00B81B    CALL 1BB8:000F
         3281:3888 59            POP CX
         3281:3889 8B46DC        MOV AX,[BP-24]
         3281:388C BA5800        MOV DX,0058
         3281:388F F7E2          MUL DX
         3281:3891 050841        ADD AX,4108
         3281:3894 50            PUSH AX
         3281:3895 8D46E2        LEA AX,[BP-1E]
         3281:3898 50            PUSH AX
         3281:3899 9A0E00661A    CALL 1A66:000E
         3281:389E 59            POP CX
         3281:389F 59            POP CX
         3281:38A0 0BC0          OR AX,AX
         3281:38A2 7505          JNZ 38A9
         3281:38A4 C746DEFFFF    MOV WORD PTR [BP-22],FFFF
         3281:38A9 E9E300        JMP 398F
         3281:38AC B81000        MOV AX,0010
         3281:38AF 50            PUSH AX
         3281:38B0 16            PUSH SS
         3281:38B1 8D46E2        LEA AX,[BP-1E]
         3281:38B4 50            PUSH AX
         3281:38B5 9AFB149900    CALL 0099:14FB
         3281:38BA 83C406        ADD SP,+06
         3281:38BD 8D46E2        LEA AX,[BP-1E]
         3281:38C0 50            PUSH AX
         3281:38C1 9A0F00B81B    CALL 1BB8:000F
         3281:38C6 59            POP CX
         3281:38C7 8B46DC        MOV AX,[BP-24]
         3281:38CA BA5800        MOV DX,0058
         3281:38CD F7E2          MUL DX
         3281:38CF 051941        ADD AX,4119
         3281:38D2 50            PUSH AX
         3281:38D3 8D46E2        LEA AX,[BP-1E]
         3281:38D6 50            PUSH AX
         3281:38D7 9A0E00661A    CALL 1A66:000E
         3281:38DC 59            POP CX
         3281:38DD 59            POP CX
         3281:38DE 0BC0          OR AX,AX
         3281:38E0 7505          JNZ 38E7
         3281:38E2 C746DEFFFF    MOV WORD PTR [BP-22],FFFF
         3281:38E7 E9A500        JMP 398F
         3281:38EA B81000        MOV AX,0010
         3281:38ED 50            PUSH AX
         3281:38EE 16            PUSH SS
         3281:38EF 8D46E2        LEA AX,[BP-1E]
         3281:38F2 50            PUSH AX
         3281:38F3 9AFB149900    CALL 0099:14FB
         3281:38F8 83C406        ADD SP,+06
         3281:38FB 8D46E2        LEA AX,[BP-1E]
         3281:38FE 50            PUSH AX
         3281:38FF 9A0F00B81B    CALL 1BB8:000F
         3281:3904 59            POP CX
         3281:3905 8B46DC        MOV AX,[BP-24]
         3281:3908 BA5800        MOV DX,0058
         3281:390B F7E2          MUL DX
         3281:390D 052A41        ADD AX,412A
         3281:3910 50            PUSH AX
         3281:3911 8D46E2        LEA AX,[BP-1E]
         3281:3914 50            PUSH AX
         3281:3915 9A0E00661A    CALL 1A66:000E
         3281:391A 59            POP CX
         3281:391B 59            POP CX
         3281:391C 0BC0          OR AX,AX
         3281:391E 7505          JNZ 3925
         3281:3920 C746DEFFFF    MOV WORD PTR [BP-22],FFFF
         3281:3925 EB68          JMP 398F
         3281:3927 B81000        MOV AX,0010
         3281:392A 50            PUSH AX
         3281:392B 16            PUSH SS
         3281:392C 8D46E2        LEA AX,[BP-1E]
         3281:392F 50            PUSH AX

              Next point of interest.  When you execute this line, the
         game will pause and wait for you to enter the code word from
         the manual.  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
                                                      ³
                                                      ³
         3281:3930 9AFB149900    CALL 0099:14FB <ÄÄÄÄÄÙ

         3281:3935 83C406        ADD SP,+06
         3281:3938 8D46E2        LEA AX,[BP-1E]
         3281:393B 50            PUSH AX
         3281:393C 9A0F00B81B    CALL 1BB8:000F
         3281:3941 59            POP CX
         3281:3942 8B46DC        MOV AX,[BP-24]
         3281:3945 BA5800        MOV DX,0058
         3281:3948 F7E2          MUL DX
         3281:394A 053B41        ADD AX,413B
         3281:394D 50            PUSH AX
         3281:394E 8D46E2        LEA AX,[BP-1E]
         3281:3951 50            PUSH AX
         3281:3952 9A0E00661A    CALL 1A66:000E
         3281:3957 59            POP CX
         3281:3958 59            POP CX
         3281:3959 0BC0          OR AX,AX
         3281:395B 7505          JNZ 3962
         3281:395D C746DEFFFF    MOV WORD PTR [BP-22],FFFF
         3281:3962 EB2B          JMP 398F
         3281:3964 33D2          XOR DX,DX
         3281:3966 B8B80B        MOV AX,0BB8
         3281:3969 52            PUSH DX
         3281:396A 50            PUSH AX

              Next point of interest.  This call is the final
         evaluation of the entered word (or phrase).  On return, it
         checks a checksum value.  This whole next section of code
         (up to 3281:39Ad) simply test the validity of the keyword you
         entered. I have marked the all jumps that happened when I
         entered my keyword with an " * ".

         3281:396B 9A71139900    CALL 0099:1371
         3281:3970 59            POP CX
         3281:3971 59            POP CX
         3281:3972 8946E0        MOV [BP-20],AX
         3281:3975 8B46DC        MOV AX,[BP-24]
         3281:3978 BA5800        MOV DX,0058
         3281:397B F7E2          MUL DX
         3281:397D 8BD8          MOV BX,AX
         3281:397F 8B874C41      MOV AX,[BX+414C]
         3281:3983 3B46E0        CMP AX,[BP-20]
         3281:3986 7505         *JNZ 398D
         3281:3988 C746DEFFFF    MOV WORD PTR [BP-22],FFFF
         3281:398D EB00          JMP 398F
         3281:398F 837EDE00      CMP WORD PTR [BP-22],+00
         3281:3993 7402         *JZ 3997
         3281:3995 EB0C          JMP 39A3
         3281:3997 FF46D6        INC WORD PTR [BP-2A]
         3281:399A 837ED602      CMP WORD PTR [BP-2A],+02
         3281:399E 7D03         *JGE 39A3
         3281:39A0 E937FD        JMP 36DA
         3281:39A3 837EDE00      CMP WORD PTR [BP-22],+00
         3281:39A7 7504         *JNZ 39AD
         3281:39A9 0E            PUSH CS
         3281:39AA E8E8FC        CALL 3695

              This is the last point of interest.  The next
         instruction is where we set the key (by moving FFFFh to the
         memory location DS:0744h).  This is what we need to fake to
         allow the system to run.  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
                                                              ³
         3281:39AD C7064407FFFF  MOV WORD PTR [0744],FFFF <ÄÄÄÙ
         3281:39B3 B8FFFF        MOV AX,FFFF
         3281:39B6 50            PUSH AX
         3281:39B7 9AC0479900    CALL 0099:47C0
         3281:39BC 59            POP CX
         3281:39BD 8BE5          MOV SP,BP
         3281:39BF 5D            POP BP
         3281:39C0 CB            RETF

              Ok, we have now finished the doc check, and control has
         returned (when the RETF instruction was executed) to
         21DD:3EA9.  We are now ready to continue with the game.


              Notice the instruction at 3281:39AD.  This  is where EFH
         sets that external  flag.   But  how  did  I  determine this.
         Well, by luck.  If you look through  the  entire routine, you
         will not find any other instructions placing  a  value in the
         data segment (DS).   And since I decided a long time ago that
         EFH was written in a higher level  language,  we  can  assume
         that it is writting to some variable.

              So, hoping that we have found the flag,  we  go  back to
         step 1.  This  time,  we manualy edit the word at DS:0744 and
         place the value FFFFh there.  We  then skip over the call the
         the doc check  and execute the game.  Then before  our  eyes,
         shit happenes.  The  game  comes  up, and everything is fine.
         By George you've got it.

              So how do we fix the program to always return a good doc
         check.  Well, we could go about it 2 ways.  The first, is you
         could simple modify the instruction at 3281:3935 to perform a
         long jump to 3281:39AD.  This  would  force  set the value no
         matter what was  typed.  But who the fuck wants  to  have  to
         type anything.  I sure don't so lets think of another way.

              If we  look at the entire doc check routine, we will see
         that it does nothing but handle  the doc check (remember when
         we first bypassed  the  check.   The  screen   came   up  and
         everything looked fine  until  it dropped you out.  So we can
         assume that the actual screen is  not setup in doc check.  So
         I suggest placing a small patch right in the begining  of the
         doc check.

              But what  should  this  patch  do? (BTW: it's late and I
         don't know If I'm using ?s right.   So  if  not  TOO  FUCKING
         BAD).  Well, all  it should do is place the  value  FFFFh  at
         DS:0744h.  Here is the assembly language routine to do it.

                        50       PUSH AX
                        B8FFFF   MOV AX,FFFF
                        3E       DS:
                        A34407   MOV WORD PTR [0744],AX
                        58       POP AX
                        CB       RETF

              This small  routine will place the value FFFFh at DS:744
         and then exit back to the main  loop.   Simple huh (note, you
         don't really need the save AX or load AX with  FFFFh for that
         matter but I did it for clarity).

              So now  that we have the patch, and now where to put it,
         how do we get it there.  Well,  thats  where  the file editor
         comes in, but  first  you  will  need  2  things.    The  hex
         equivlent of out   patch   (in  this  case  the  10  bytes  :
         50,B8,FF,FF,3E,A3,44,07,58,CB) and some string to search for.
         I suggest usings the first 14  bytes  of  the routines we are
         going to write  over (the code at address 3281:36A5).   Those
         bytes are 55, 8B, EC, 83, EC ,2A ,C7, 46, DE ,00 ,00, B8, 06,
         and 00.  When   selecting  the  search  string,  select  only
         instructions that ARN'T call,  jump,  loop or any instruction
         that has a memory address in them.  This value  will  NOT  be
         the same when you do the search.

              Now, using for file editor (I used PCTOOLS, but NORTON's
         will do) search  for  our  string  (55,8B,  etc).  When it is
         found (somewhere near sector 200)  write  down  the sector #.
         Now, go and edit that sector.  Find our search string (55,8B,
         etc) and replace  it  with the patch string (50,B8,FF,  etc).
         Now save the sector.

              Your down.   Try  playing  the game.  It should load up,
         and then go right from the title  page  (or the intro) to the
         game without stopping  at  the doc check.  If  your  doesn't,
         then you fucked  up.   Restart  from  the beginning (NO, this
         file didn't fuck up, and I DON'T MAKE MISTAKES).

              Well, you did it.  You have  now  removed your first doc
         check.  Don't ya feel real good.  With time, you will be able
         to remove any type of doc check.


                                                      -HackerVinoth


                     At this time I would just like to say

                          `ALL CRACKING GROUPS SUCK!'