Friday, 29 August 2014

CRACKING 101 - 1990 edition-2


                          CRACKING 101 - 1990 edition

                                    Lesson 2

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

                               by Buckaroo Banzai


              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 <ESC> during the music  so  that  we  can skip the
         stupid intro for now.  After pressing <ESC> 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.


                                                      -BUCKAROO BANZAI


                     At this time I would just like to say

                          `ALL CRACKING GROUPS SUCK!'

CRACKING 101 - 1990 edition-1

                          CRACKING 101 - 1990 edition

                                   Lession #1

                             ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
                             ³ CRACKING DOS Files ³
                             ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

                               By Buckaroo Banzai


              Today I'm here to about is cracking a dos format (either
         .EXE or .COM) file.  This, in my mind is releativly the
         simplest (in theory although pratice might say otherwise)
         type of crack to do.

              There are really 3 steps in cracking a dos file.  Step
         1, is finding where the protection routine is.  How to go
         about it, well, there are several diffrent methods.  Here are
         the steps that I often use.

              First, I will run the program under PC-WATCH (PW)
         trapping INT13 all functions and INT21 functions 3Dh and 3Fh.
         Why trap the functions.  This will give (hopefully) a
         starting place to look for the protection.  Once you have set
         the breakpoints, press [F4] to execute and you will drop to
         dos.  When you do, PW should display several calls to INT13.
         What closly at the CS:IP of these calls.  Record it for later
         because these are calls from dos.  We will uses this data to
         recognize what is a call to the protection and what is not.

              Next, run the program to be cracked.  As it executes,
         PC-WATCH will show what files are opened (including the file
         you just ran since DOS uses function 3Dh to open a file when
         it executes one) and what (and more improtantly WHERE) data
         is read to.  Makes a list saying what data is read in from
         what file.  Here is an example.  Lets say you ran the program
         "XXX.COM".  While running, "XXX.COM", you noticed that 2
         other files "YYY.BIN" and "ZZZ.BIN" were also opened.  So
         make a list like this:

             XXX.COM       YYY.BIN       ZZZ.BIN
             ÄÄÄÄÄÄÄ       ÄÄÄÄÄÄÄ       ÄÄÄÄÄÄÄ

              Now, lets say that after "XXX.COM" was opened, PW showed
         that there were 2 reads from "XXX.COM" (the way to tell where
         the data is being read from is by checking the BX register on
         calls to 3Fh and the AX registers after calls to 3Dh.  Yes,
         you should select both INPUT REGISTERS and OUTPUT REGISTERS
         from the PW menu) 1 at aaaa:bbbb and 1 as cccc:dddd.  Right
         after "YYY.BIN" was opened, PW showed data was read to
         eeee:ffff and then after "ZZZ.BIN" was opened, data was
         written to gggg:hhhh and iiii:jjjj.  Now, our list looks like
         this:

             XXX.COM       YYY.BIN       ZZZ.BIN
             ÄÄÄÄÄÄÄ       ÄÄÄÄÄÄÄ       ÄÄÄÄÄÄÄ
             aaaa:bbbb     eeee:ffff     gggg:hhhh
             cccc:dddd                   iiii:jjjj

              What we have just created in a program load map.  This
         map shows where to program to be cracked is loaded in memory.
         Next, scan though the calls to INT13.  Look for either calls
         that return with errors, calls that have high values in the
         CH ( > 28) or CL ( > 9) registers, or calls not made by dos
         (those calls that have a CS:IP diffrent from the one we
         copied down before we executed the program).  Now, look at
         the CS:IP of the call to INT13.  Match the segment address
         against the program load map.  If only 1 match occurs, then
         you now know what module the check is in so continue on to
         step #2.  If more than 1 match occurs, check the offset (IP).
         Find the one that is closest to one of the write address's
         offset.  Once you find a match, then go on to step #2.  If no
         match occurs after both steps, it's time to track through the
         program.

              Tracking your way though the program is a real bitch.  I
         do not like to do because it can just take to long.  But here
         is an overview on how it is done.

              The object, is to keep narowing down calls until disk
         access if found.  How to do this.  Well, load the program
         under debug.  Keep tracing through the program in till a
         "CALL" instruction is found.  Jot down you current IP and
         PROCEED (using debug P command) over the instruction without
         tracing in to it.  If you end up at the next instruction
         without access that disk, then you have not found the routine
         you are looking for so keep going.  Search for the next
         "CALL" and then the next and then the next etc.  At some
         point, when you proceed over a call, the disk will either
         check protection or load in a new module.

              How to tell the diffrence, well PW is still active and
         will tell you if it was a call to INT13 or INT21 or BOTH.  If
         it was the call to INT13 or a call to BOTH then you have
         found a call to the protection routine (although the actual
         call may be 100 levels deeper, you are on the right track).
         Exit and restart but this time when you reach the call,
         trace into it.  Now do the same process until you get to the
         call to the next level, then again for the next, etc.
         Finally you should find where it is.

              But hopefully, you won't have to do that.  As I said, it
         is very time consumming.  Hopefully, you will know which
         module to look in.  If you do, here is how to find the call
         to the protection.  First, try the simple search method.
         Load up the module using DEBUG and simply type:

                   S CS:100 FFFF CD 13  (use CS:100 if .EXE)

              Debug will hopefully list 1 or more address.  If not,
         try the same command only using CS:0000.  If again you are
         not givin any address, you have some tricky debugging at hand
         (an I suggest rereading the exercise in self-modifying code).

              I will explain in detail how to find self-modifying code
         later but for now, lets assume we have found the protection
         routine.  Next, is to figure out what the copy protection is
         trying to do.  First, look to the printout from PW.  Look
         through it until you find the calls the INT13 from the
         protection routine.  Look at the AH register.  If it is 00h
         then the protection routine is probally reading in data from
         the protected tracks.  If not, then the protection is simply
         looking for some KEY (in other words a damaged track or
         sector) that DOS canno't duplicate.

              The second choice is much eaiser to defeat.  2 quick
         methods to defeating this type.  First, you can fake the call
         and simply set the registers.  Take the follow check to a
         protection routine:

         1:      mov AX,0201h      ; Read 1 sectors using int 13h
         2:      mov CX,2909h      ; Track 29h sector 09h
         3:      xor DX,DX         ; Drive 0, head 0
         4:      int 13h           ; Read sector
         5:      jnc Bad           ; If no error then it's a copy
         6:      cmp AH,10h        ; Was it a CRC error
         7:      jne Bad           ; No, then it's a copy
         8:      mov AX,0h         ; clear error flag
         9:      jmp Done          ; we are done
         Bad:    mov AX,1          ; set error flag
         Done:   ret               ; we are done

              What is the above code trying to do.  Well, it's
         checking for a KEY on track 29h.  That key is sector 09h.
         Normally sector 09h would not have an error.  On a read to
         the original disk, after the int13 (line 4) is executed, the
         carry flag (CF) would be set.  The jnc in line 5 would jump
         if CF is not set (indicating no error, which is bad since the
         original disk would have an error there).  The next line
         checks AH to see if it is 10h.  This is checking to see if
         the error was a Bad CRC on the read (the error that should be
         there).  If it was not, then again it is not the protected
         disk.  Only after both of thoses conditions are met, will the
         protection routine return a "GOOD" result.

              The key here is the value returned in AX an possibly
         CF.  When the disk is the original, AX would return the value
         of 0000h and CF = 1 but when it was a copy, it would return
         0001h and CF = 0 or 1.  Since on a bad return, CF can be 0 or
         1 then it is preaty safe to assume CF is not used to signal
         the return.  So what must we do to beat the protection
         routine, well, simply return from this CHECK with AX = 0000h.
         Simple.  Just change line 1 to "mov AX,0000h" and line 2 to
         "RET".  This will just bypass the check.

              Now, this example is quite simple and would probally
         never be used in a REAL protection routine.  I kept it simple
         to show the point, see the example on how to crack DRAWING
         ASSISTANT for a better example.

              The second and more perferd method is to simply bypass
         the call to the protection routine and kill of the section of
         code that test for the check position.  Take the following
         example:

         10:     call 1                  ; call the first example
         11:     cmp AX,0                ; Was it the original
         12:     jz  Good2               ; Yes, then good
         13:     ... BAD it was a copy   ; No, then bad
         Good2:

              The above example, when used with the last example show
         a typical call to a protection routine.  The perfered method
         to crack this protection would not be to simply fake the
         return, but to remove the call to the protection.  How to do
         it, simple.  Just jump over the check.  Change line 10 to
         "jmp Good2".  This will bypass the protection routine.

              Now, you might ask why would you want to take the extra
         step of finding the call to the protection routine rather
         than simply faking an int13 and returning with the proper
         registers set.  2 reasons.  First, What if there wasn't
         enough room to setup the registers the way you needed them.
         Then you would have to take the extra step.  Second, what if
         somewhere down the line, that routine is used for something
         else (like the int13 is modified into an int10 in a game).
         Since you have changed the bytes at that location, the
         modifying routine would create code that wasn't exepcted.
         But as always, if you can fake the return, and the program
         works, leave it.  After all, not to many people go around
         look at other peoples cracks (do they???).

              Now, what to do, if the program actually reads in
         important data from the disk.  Well, there are 2 ways to go
         about this (possibly more).  First, you could patch the
         program so that when it calls it's protection routine, it
         jumps to your user routine that opens a file and reads in the
         data to the right place.  This method is preaty simple to add
         to a .COM file but a much harder to patch on to the back of a
         .EXE.  I won't really go in to this method much more than to
         say use your brains.  It's not a difficult concept.

              The other method, is to create a LOADER or a TSR.  I
         suggest creating an Interrupt Service Routine (ISR) that
         handles loading in the data.  For example, let say you wrote
         a routine to read in the needed data for a file.  It is not
         to difficult to convert that routine into an ISR.  (For notes
         on ISR and TSRs, try reading The Waite Group's "MS-DOS
         PAPERS".  It has one of the best sections on the subject).

                        Consider this following example:


         A:            call 1           ; test protection
         B:            jnc Good         ; was it successfull
         C:            ... BAD load     ; no then it's a copy
                       ... EXIT TO DOS  ; so exit to dos
         Good:         ... Good load    ; yes then it original
                       call 7C00:0000   ; then jump of protection
                                        ; data

         1:            mov ax,0209      ; Read 9 sectors starting from
         2:            mov cx,290a      ; Track 29h Sector 0Ah (10)
         3:            xor dx,dx        ; for drive A: head 0
         4:            mov bx,7c00      ; read to 7c00:0
         5:            mov es,bx        ;
         6:            mov bx,0         ;
         7:            int 13h          ;
         8:            ret



              What the above example dos.  Lines 1-8 try to read in
         sectors 0Ah - 12h for track 29h on drive A:.  This is the
         protection check routine.  Lines A - Good attempt to check
         the protection, and then if the check is good (CF = 0) then
         a call to the loaded in code (the data loaded in by the
         protection check) is made.

              What we want to do, is somehow when INT 13h is called,
         load in the needed data for disk.  Well, here is my
         suggestion.  First, I would change line 7 from "int 13h" to
         "int BBh".  Next, I would create a small .COM loader that
         would execute the main program as a child process (read the
         DOS TECH REF on the EXEC function).  But before I did that, I
         would write an ISR (interrupt service routine) for INT BBh.
         Here is the general outline for the ISR

              þ Use dos to open the file containing the needed data
              þ Read in the data to ES:BX (where int 13h would put it)
              þ Close the file
              þ set AX to 0000 and clear CF
              þ iret

              The loader would go like this :

              þ Get current int BBh address (DOS func. 35h)
              þ Set int BBh address to ours (DOS func. 25h)
              þ use DOS to EXECUTE (Dos func. 4Bh) the program to be
                cracked
              þ Restore the address of BBh

              Well, that about all I have to say about cracking a dos
         file.  I hope this section has been usefull to you.  Next I
         will show by example the techinques in this section while
         cracking I.B.M. Drawing Assistance (1.00).

              One last thing.  After you have cracked the program, try
         running it from a hard drive with PW set to trap calls to INT
         21h function 1Bh (get fat byte).  If the program make a call
         to here, get the address and find that section of code.  What
         the program is trying to do is check to see if you are
         running from a hard drive (most programs have diffrent
         protection routines for hard drives).  When you find it,
         simply replace the "INT 21h" with a "MOV DS:[BX],FDh".  This
         will fake the program in to thinking you are working on a
         floppy disk.

              Ok, for our example we will be removing the code from
         IBM's Drawing assistant.  Now now, I know it's not the best
         program out there, but shit, It's hard to find shit with on
         disk copy protection anymore.  So here we go...

              I needed 3 programs in cracking the assist. series.
         Locksmith by Alph Logic, Periscope debugger, and DEBUG
         (supplied with DOS).  By using these three programs together,
         I was able to figure out and remove the copy protection in
         under 30 minutes.

              Drawing Assistant (DA) is IBM's answer to colorpaint for
         the Jr.  It is a simple drawing program (a more advanced
         version is included in StoryBoard Deluxe) but easy to learn
         and use.  So far, I have only seen version 1.00 of this
         program.

              DA made calls to the copy protection routine in 3
         diffrent modules.  The files "SETDRAW.EXE", "DRAWASST.EXE"
         and "DRAWASST.TWO" all contained calls to the copy
         protection.  Also, "DRAWASST.TWO" and "DRAWASST.EXE" are for
         all intensive puporses then same file.

              I first started off by loading DRAWASST.EXE with debug
         and searched for any int 13's by executing the debug command

                s CS:0 FFFF CD 13         Search CS:0 - CS:FFFF for CD
                                          13 (int 13)

           I located 2 diffrent calls to int 13h, so I then listed
         them.  Here is what I found...

                     { First, some initialization routines }

                     18FD:0343 1E            PUSH   DS
                     18FD:0344 B80000        MOV    AX,0000
                     18FD:0347 50            PUSH   AX
                     18FD:0348 B89724        MOV    AX,2497
                     18FD:034B 8ED8          MOV    DS,AX
                     18FD:034D BB1000        MOV    BX,0010
                     18FD:0350 2E            CS:
                     18FD:0351 8A07          MOV    AL,[BX]
                     18FD:0353 3C00          CMP    AL,00
                     18FD:0355 7418          JZ     036F


                { This set is called if DA has been installed }
                             { on the hard drive }
                  { When cracked, this will NEVER be called }

                     18FD:0357 B419          MOV    AH,19
                     18FD:0359 CD21          INT    21
                     18FD:035B 8AD0          MOV    DL,AL
                     18FD:035D FEC2          INC    DL
                     18FD:035F B41C          MOV    AH,1C
                     18FD:0361 CD21          INT    21
                     18FD:0363 8A07          MOV    AL,[BX]
                     18FD:0365 BB9724        MOV    BX,2497
                     18FD:0368 8EDB          MOV    DS,BX
                     18FD:036A 3CF8          CMP    AL,F8
                     18FD:036C 7475          JZ     03E3
                     18FD:036E CB            RETF

            { This set is called if DA is running from the floppy }

                     18FD:036F B419          MOV    AH,19
                     18FD:0371 CD21          INT    21
                     18FD:0373 FEC0          INC    AL
                     18FD:0375 B400          MOV    AH,00
                     18FD:0377 A320C6        MOV    [C620],AX
                     18FD:037A 8AD0          MOV    DL,AL
                     18FD:037C B41C          MOV    AH,1C
                     18FD:037E CD21          INT    21
                     18FD:0380 8A07          MOV    AL,[BX]
                     18FD:0382 BB9724        MOV    BX,2497
                     18FD:0385 8EDB          MOV    DS,BX
                     18FD:0387 3CF8          CMP    AL,F8
                     18FD:0389 7408          JZ     0393

                 { Here is the called to read in the key disk }

                     18FD:038B E8A675        CALL   7934
                     18FD:038E 3D0100        CMP    AX,0001
                     18FD:0391 7450          JZ     03E3

           Let's take these code segments 1 at a time.  The fist, is
         some simple initialization routines.  Here is the code, only
         this time full comments are added.

         { First, some initialization routines }
         ; Setup for return to DOS

         18FD:0343 1E            PUSH   DS
         18FD:0344 B80000        MOV    AX,0000
         18FD:0347 50            PUSH   AX

         ; Setup DS to point to the data segment

         18FD:0348 B89724        MOV    AX,2497
         18FD:034B 8ED8          MOV    DS,AX


         18FD:034D BB1000        MOV    BX,0010    ; CS:10 points to
                                                   ; installed flag
         18FD:0350 2E            CS:
         18FD:0351 8A07          MOV    AL,[BX]

         18FD:0353 3C00          CMP    AL,00      ; If not installed,
                                                   ; jump to diskette
         18FD:0355 7418          JZ     036F       ; routines

           What we are want to do, is fool DA in to thinking that it
         is stilling loading from diskette.  Nothing really needs to
         be changed in this segment, but, just to be safe, we will
         force the jump at 355.  To change the current values, use
         DEBUG's [A]ssembler command.

                 A CS:355
                 18FD:355 JMP 36F

           Now, we have forced the jump, we can move on to the third
         code segment skipping over the second since it will never be
         called again.  The 3rd code segment checks to see if you are
         using a hard drive.  It does so by first getting the logical
         drive letter, then reading in the FAT descriptor byte for
         that drive.  Here is the commented code.

         { This set is called if DA is running from the floppy }

         ; First, get the current drive

         18FD:036F B419          MOV    AH,19     ; DOS function 19h -
                                                  ; Get Current Drive
         18FD:0371 CD21          INT    21

         18FD:0373 FEC0          INC    AL         ; Add 1 for BIOS
         18FD:0375 B400          MOV    AH,00      ; Clear AH
         18FD:0377 A320C6        MOV    [C620],AX  ; Store it at C620
         18FD:037A 8AD0          MOV    DL,AL      ; Store it in DL
         18FD:037C B41C          MOV    AH,1C      ; DOS function 1Ch
                                                   ; Get Fat desc.
         18FD:037E CD21          INT    21         ; returns pointer
                                                   ; in DS:BX
         18FD:0380 8A07          MOV    AL,[BX]    ; Get the actual
                                                   ; byte
         18FD:0382 BB9724        MOV    BX,2497    ; Restore DS
         18FD:0385 8EDB          MOV    DS,BX

         18FD:0387 3CF8          CMP    AL,F8      ; Check to see if
                                                   ; it is a H/D
         18FD:0389 7408          JZ     0393       ; Yes, then jump
         abort

         { Fall in to the check for the key disk }

           As you can see, this section of code is quite straigth
         forward.  It just checks to see if you are using a hard
         drive.  What we want to do is to fake an DOS function 1Ch and
         return the value for a floppy.  This is done by putting the
         value of FDh in AL then NOPing the rest.  Again use the
         Debug's [A] command.


                 A CS:37C

                 18FD:037C MOV AL,FD
                 18FD:0380 NOP
                 18FD:0381 NOP
                 18FD:0382 NOP
                 18FD:0383 NOP

           Now, you might ask why I didn't simple force a jump over
         the code.  The answer is what if DA uses the value at C620 at
         a later time (which it doesn't but let's pretend).  If I had
         forced the jump then the value might not have been
         initialized and the crack might not work.  Now that we have
         simulated running from diskette, we must deal for the check
         for the key disk.

              This is where Periscope came in to play.  Using
         periscope, I made the above corrections and ran the program
         up till CS:038B (the call to the check). Here is the code,
         including the actual check.  I have indented the check to
         make it easier to read.


         { Here is the called to read in the key disk }

         18FD:038B E8A675        CALL   7934    ; Check key on disk
                                                ; (track 27h side 0)

           18FD:7934 A120C6        MOV   AX,[C620]     ; Get drive
                                                       ; letter
           18FD:7937 FEC8          DEC   AL
           18FD:7939 A23BC6        MOV   [C63B],AL     ; Store it for
                                                       ; later
           18FD:793C 1E            PUSH  DS
           18FD:793D 07            POP   ES
           ; Setup pointers to what sectors to try to read

           18FD:793E BB30C6        MOV   BX,C630
           18FD:7941 891E39C6      MOV   [C639],BX
           18FD:7945 C6063CC603    MOV   BYTE PTR [C63C],03
           18FD:794A C6063DC601    MOV   BYTE PTR [C63D],01

           ; Reset the disk

           18FD:794F B400          MOV   AH,00
           18FD:7951 CD13          INT   13

           ; Get address of sector to read an put it in CL

           18FD:7953 8B1E39C6      MOV   BX,[C639]
           18FD:7957 8A0F          MOV   CL,[BX]


           ; Setup the rest of the read information

           18FD:7959 BBAE3D        MOV   BX,3DAE
           18FD:795C 81C3D007      ADD   BX,07D0
           18FD:7960 B001          MOV   AL,01
           18FD:7962 B527          MOV   CH,27
           18FD:7964 8A163BC6      MOV   DL,[C63B]
           18FD:7968 B600          MOV   DH,00
           18FD:796A B402          MOV   AH,02
           18FD:796C CD13          INT   13

           ; Test for an error and jump if none is present (ie: the
           ; copy protection has been removed)

           18FD:796E 80FC00        CMP   AH,00
           18FD:7971 740C          JZ    797F

           ; test the bad read (protection is missing) 3 times

           18FD:7973 FE0E3CC6      DEC   BYTE PTR [C63C]
           18FD:7977 75D6          JNZ   794F
           18FD:7979 B80000        MOV   AX,0000
           18FD:797C EB13          JMP   7991

           ; Get next sector to check.  If finished, set the flag and
           ; return.

           18FD:797F FF0639C6      INC   WORD PTR [C639]
           18FD:7983 FE063DC6      INC   BYTE PTR [C63D]
           18FD:7987 803E3DC603    CMP   BYTE PTR [C63D],03
           18FD:798C 75C1          JNZ   794F
           18FD:798E B80100        MOV   AX,0001
           18FD:7991 C3            RET

         ; Check to see if the OK flag was set (ax = 0001h means check
         ; was good)
         18FD:038E 3D0100        CMP    AX,0001
         18FD:0391 7450          JZ     03E3


           The key check used in DA is quite simple.  It simple tries
         to read in the illegaly numbered sectors on Track 27h side
         0h.  If they are missing, it assumes that it is running a
         pirated copy.  What we must do, is to fool the scheme in to
         thinking a good read happened.  I choses to fake the read
         using the easiest method.  Since the protection scheme only
         check to see if AX returns the value > 0000h, I simply
         modified the routine at 1BFD:7934 to set AX to 0000h and then
         return.  Here is the new code (enter using debug's A
         command)...

                 A 1BFD:7934
                 1BFD:7934 MOV AX,0000
                 1BFD:7936 RET

           Now, this file is unprotected and if you type "G" at
         debug's command prompt, the program will execute, sort-of.
         See DRAWASST.EXE calls DRAWASST.TWO which also has the
         protection scheme.  So both must be changed.  To make to
         changes perement in DRAWASST.EXE, rename the file to
         DRAWASST.DEB and edit it.  To find the address of the start
         of the protection code, use debug's search command...

                 S CS:0 FFFF B4 19 CD 21 8A D0

           Now, just uses the modified address to change the program
         (the code will still be the same, just all calls and jumps
         will be to diffrent addresses).  Use the same process to stip
         DRAWASST.TWO (it uses the exact same code).  When you have
         both of those files unprotected, you can move on to
         unprotecting the setup program "SETDRAW.EXE"


              DRAWASST.EXE AND .TWO are not the only programs that
         make calls to the protection routine.  SETDRAW.EXE also makes
         the above calls.  Although the check here is much easier to
         bypass.  Here is the asm listing of SETDRAW with all of the
         calls to the protection.  This time, I will not go in to
         quite as much detail as I did for the other two version.

           I will tell you this.  When SETDRAW checks the key disk,
         first it checks to see if the protection exists and then to
         see if the track hasn't been modified.  It again uses AX to
         determine what happeded.  I used Periscope to trace through
         the original version to find out what the correct values are.
           Here is the asm code...

         ; Initialization - checks the current mode and saves it.

         18FD:0000 1E            PUSH     DS
         18FD:0001 B80000        MOV      AX,0000
         18FD:0004 50            PUSH     AX
         18FD:0005 B8321A        MOV      AX,1A32
         18FD:0008 8ED8          MOV      DS,AX
         18FD:000A B40F          MOV      AH,0F
         18FD:000C CD10          INT      10
         18FD:000E 3C02          CMP      AL,02
         18FD:0010 740D          JZ       001F
         18FD:0012 3C03          CMP      AL,03
         18FD:0014 7409          JZ       001F
         18FD:0016 A28900        MOV      [0089],AL
         18FD:0019 B002          MOV      AL,02
         18FD:001B B400          MOV      AH,00
         18FD:001D CD10          INT      10

         ; Gets the current drive

         18FD:001F B400          MOV      AH,00
         18FD:0021 B419          MOV      AH,19
         18FD:0023 CD21          INT      21
         18FD:0025 A28700        MOV      [0087],AL
         18FD:0028 8AD0          MOV      DL,AL
         18FD:002A FEC2          INC      DL

         ; Checks the FAT descriptor

         18FD:002C B41C          MOV      AH,1C
         18FD:002E CD21          INT      21
         18FD:0030 8A07          MOV      AL,[BX]
         18FD:0032 BB321A        MOV      BX,1A32
         18FD:0035 8EDB          MOV      DS,BX
         18FD:0037 C606880000    MOV      BYTE PTR [0088],00
         18FD:003C 3CF8          CMP      AL,F8
         18FD:003E 742A          JZ       006A

         ; Read in protection scheme

         18FD:0040 8A168700      MOV      DL,[0087]
         18FD:0044 E87E0A        CALL     0AC5
         18FD:0047 C606880000    MOV      BYTE PTR [0088],00
         18FD:004C 3D0000        CMP      AX,0000
         18FD:004F 7419          JZ       006A

         ; Read in the dummy scheme

         18FD:0051 C606880001    MOV      BYTE PTR [0088],01
         18FD:0056 8A168700      MOV      DL,[0087]
         18FD:005A B84500        MOV      AX,0045
         18FD:005D E8BD0A        CALL     0B1D
         18FD:0060 3D0000        CMP      AX,0000
         18FD:0063 7405          JZ       006A

         ; Start of actual routine.

         18FD:0065 C606880000    MOV      BYTE PTR [0088],00

           There is isn't much to say about the above code.  To bypass
         it, we will change the hard drive check (int 21 function 1c).
         Do the same thing we did for DRAWASST.EXE

                A 18FD:2C
                18FD:002C mov AL,FD
                18FD:002E nop
                18FD:002F nop
                18FD:0030 nop
                18FD:0031 nop

           Now, just jump over the check to the key disk.

               A 18FD:40

               18FD:0040 jmp 0065

           And thats it.  Now SETDRAW is unprotected.  Drawing
         Assistant may be used, copied or backed up at your pleasure.


              As you can see, this was a good example although the
         fact that if you only made the changes in DRAWASST.EXE and
         not in DRAWASST.TWO then the program would copy DRAWASST.TWO
         to DRAWASST.EXE to restore the protection was a bit strange.

              Well, I hope you are proud.  But be warned, next we take
         on DOC checks, so get a good nights sleep.  Till then, play
         lots of SMASH T.V.

                                                      -Buckaroo Banzai











































                                     page 9

CRACKING 101 - 1990 edition

                          CRACKING 101 - 1990 edition

                                ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
                                ³ INTRODUCTION ³
                                ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

                               by Buckaroo Banzai


              A long time a go, in a galaxy far far away, a great
         adventure took ... What, oh sorry, wrong textfile.


              Hello my children.  Let me introduce myself, I am the
         great cracking guru BUCKAROO BANZAI (the original) and I'm
         back after a couple of years of hiding (from the Feds? from
         the IRS? No, from this girl MaryLou.  Let me tell you, she
         could ... oh well let's get back to the textfile).

              Let me tell you a little history about cracking on the
         IBMpc.  It all started about 11 years ago with an apple IIe.
         See, I owned one and always wanted to learn how to crack (I
         was already a good pirate).  Unfortunately, I just never
         could get the hang of it.

              Well anyway, then I got my PC, and right away started to
         learn to program.  Soon, I had pick up oh 4 languages one of
         which was assemble language.  So I started down the long road
         to becoming a crackist.

              But the road was hard since unlike the apple, there were
         NO textfiles on cracking the PC.  Several unprotects, but
         nothing that really told you what to do.  But thanks to some
         of the better known crackists of the day (Thanks SPI for the
         help) I got through.

              It was at that point I decided to give something back.
         And thus, after a long (and I mean long) night of sex, drugs
         and rock and roll I started on my first cracking textfile.
         (Ok, so there really wasn't any drugs)

              Since then, I have written about 10 different textfiles,
         4 utilities and cracked several dozen programs.  So, why the
         long pause, well I never really stopped cracking.  I just
         basicly stuck to myself.  I never released any of my cracks
         cause I was never first but several of my cracking programs
         (most known is SECTOR-C) reached the pirate world.

              So, why am I back.  3 reasons.  First is because now DOC
         CHECKS have taken over the scene and nobody has really
         written about them (plus I'm tired of seeing my old textfiles
         butchered in "CRACKING" mags).  Second is because I have some
         free time, and third, because it was there.

              It feels kinda funny.  I have written this intro file
         several times, and the whole series has been rewritten.  What
         started off as 4 simple textfiles has grown.  I have givin up
         trying to write a book.  What I'm doing is as a new game
         reaches me, I will crack it, and then tell how it was done,
         highlight the odd quirks about the crack.

              I have also compiled a preaty good reference on INT 13h.
         I have included it with this series.  And in the near future,
         I hope to release several utilities that I use to help me
         crack.

              As of this writing, I have 2 actual lessons done, and 2
         ready to be written.  For the first 2 lessons I touch on both
         types on copy protection (On disk copy protection with
         I.B.M.'s DRAWING ASSISTANT and dos checks with EOA's ESCAPE
         FROM HELL).  I still have to compose 2 more files, 1 more on
         each type (usings STAR CONTROL and CHAMBER OF THE SCI-MUNTANT
         PREISTEST).  From there, who the hells knows.

              So anyway, sit back, watch, listen, learn and if that
         doesn't work, kick a small kid in the head...

              -Buckaroo Banzai
               -the cracking guru

Saturday, 4 January 2014

how to develop your blog

Many people ask me, how should you go about developing your blog ? How should you start to attract visitors and how can you keep those visitors. It’s best to look at this in stages or phases, you need to have a plan of action as how you are going to bring your blog to the masses. So for this article I will assume that you have your blog setup completed and you have some visitors and commentators and you are listed on google, and that you know what niche/theme your blog is about.

Developing Your Blog

One of the toughest things in having a blog is getting visitors. Once you have a steady stream of visitors you are indeed presented with another types of problems, but this is something that I will cover at a later stage. So we are in search of visitors and we are wondering what we can do to increase the number. Blog visitors mean that you have traffic on your site, and traffic can be turned into revenue, by using some of the programs listed on the main blogging page.

Blog Preparation & Research

Alas, this point sounds easy, but it is indeed all about preparation & research. Before you go to the hard work of trying to attract your visitors, it is a good idea to have at least 1 months worth of blog posts ready. Of this 1 months worth of posts, I would post about 1/2 of these. This should be roughly 10 to 15 good articles, which should be well research and thoroughly check for such silly things like grammar mistakes and typos. As for research, you should check out and make a list of other blogs that cover similar topics to you. You can use tools like google’s blog search. Type in your keywords and see what is out there in the blogosphere. Another good place to find blogs is on Technorati.com.

Finding Interested Readers

By posting a few comments on these, and possibly contacting the author of the blogs, you will gain some extra exposure. People will see your link and they might visit your site, and blog authors may link to one of your posts, and you will get visitors that way. This is a great way to get visitors, as you are contacting your target audience. People who like to read and comment on blogs and are interested in the topic you are blogging about. If you read and comment on other blogs (this is pretty likely seeing as you are motivated to start your own blog) it would advantageous if you could squeeze a link on their blog roll, or a mention on those blogs.
Blogging is all about networking, and getting the word out that you exist and that you are producing something worth while. Keeping this as your mantra to blog by

Keeping your Visitors

Now for the second part of the plan, this is where the other half of your one month’s posts come into play. I would publish these every day or every second day, with these 10 t 15 posts your visitors will start to add you into their regular reading patterns. People will start to comment more and more, and you will also see that other bloggers are likely to link to your posts.

It is in giving that you receive

Don’t be afraid to link to other (worthy) blogs in your posts. If you find something interesting and you think deserves a link then share it with your readers. State and reference your sources of ‘inspiration‘. This will have a two fold benefit, 1) your readers will think that your have a little bit more creditability for showing your sources, 2) the blogs or pages you link to might return the favour and give you a link back or a mention in return.

df