home *** CD-ROM | disk | FTP | other *** search
/ Cracking 101 / C101-90.001 < prev    next >
Encoding:
Text File  |  1990-01-01  |  32.3 KB  |  727 lines

  1.                           CRACKING 101 - 1990 edition
  2.  
  3.                                    Lession #1
  4.  
  5.                              ┌────────────────────┐
  6.                              │ CRACKING DOS Files │
  7.                              └────────────────────┘
  8.  
  9.                                By Buckaroo Banzai
  10.  
  11.  
  12.               Today I'm here to about is cracking a dos format (either
  13.          .EXE or .COM) file.  This, in my mind is releativly the
  14.          simplest (in theory although pratice might say otherwise)
  15.          type of crack to do.
  16.  
  17.               There are really 3 steps in cracking a dos file.  Step
  18.          1, is finding where the protection routine is.  How to go
  19.          about it, well, there are several diffrent methods.  Here are
  20.          the steps that I often use.
  21.  
  22.               First, I will run the program under PC-WATCH (PW)
  23.          trapping INT13 all functions and INT21 functions 3Dh and 3Fh.
  24.          Why trap the functions.  This will give (hopefully) a
  25.          starting place to look for the protection.  Once you have set
  26.          the breakpoints, press [F4] to execute and you will drop to
  27.          dos.  When you do, PW should display several calls to INT13.
  28.          What closly at the CS:IP of these calls.  Record it for later
  29.          because these are calls from dos.  We will uses this data to
  30.          recognize what is a call to the protection and what is not.
  31.  
  32.               Next, run the program to be cracked.  As it executes,
  33.          PC-WATCH will show what files are opened (including the file
  34.          you just ran since DOS uses function 3Dh to open a file when
  35.          it executes one) and what (and more improtantly WHERE) data
  36.          is read to.  Makes a list saying what data is read in from
  37.          what file.  Here is an example.  Lets say you ran the program
  38.          "XXX.COM".  While running, "XXX.COM", you noticed that 2
  39.          other files "YYY.BIN" and "ZZZ.BIN" were also opened.  So
  40.          make a list like this:
  41.  
  42.              XXX.COM       YYY.BIN       ZZZ.BIN
  43.              ───────       ───────       ───────
  44.  
  45.               Now, lets say that after "XXX.COM" was opened, PW showed
  46.          that there were 2 reads from "XXX.COM" (the way to tell where
  47.          the data is being read from is by checking the BX register on
  48.          calls to 3Fh and the AX registers after calls to 3Dh.  Yes,
  49.          you should select both INPUT REGISTERS and OUTPUT REGISTERS
  50.          from the PW menu) 1 at aaaa:bbbb and 1 as cccc:dddd.  Right
  51.          after "YYY.BIN" was opened, PW showed data was read to
  52.          eeee:ffff and then after "ZZZ.BIN" was opened, data was
  53.          written to gggg:hhhh and iiii:jjjj.  Now, our list looks like
  54.          this:
  55.  
  56.              XXX.COM       YYY.BIN       ZZZ.BIN
  57.              ───────       ───────       ───────
  58.              aaaa:bbbb     eeee:ffff     gggg:hhhh
  59.              cccc:dddd                   iiii:jjjj
  60.  
  61.               What we have just created in a program load map.  This
  62.          map shows where to program to be cracked is loaded in memory.
  63.          Next, scan though the calls to INT13.  Look for either calls
  64.          that return with errors, calls that have high values in the
  65.          CH ( > 28) or CL ( > 9) registers, or calls not made by dos
  66.          (those calls that have a CS:IP diffrent from the one we
  67.          copied down before we executed the program).  Now, look at
  68.          the CS:IP of the call to INT13.  Match the segment address
  69.          against the program load map.  If only 1 match occurs, then
  70.          you now know what module the check is in so continue on to
  71.          step #2.  If more than 1 match occurs, check the offset (IP).
  72.          Find the one that is closest to one of the write address's
  73.          offset.  Once you find a match, then go on to step #2.  If no
  74.          match occurs after both steps, it's time to track through the
  75.          program.
  76.  
  77.               Tracking your way though the program is a real bitch.  I
  78.          do not like to do because it can just take to long.  But here
  79.          is an overview on how it is done.
  80.  
  81.               The object, is to keep narowing down calls until disk
  82.          access if found.  How to do this.  Well, load the program
  83.          under debug.  Keep tracing through the program in till a
  84.          "CALL" instruction is found.  Jot down you current IP and
  85.          PROCEED (using debug P command) over the instruction without
  86.          tracing in to it.  If you end up at the next instruction
  87.          without access that disk, then you have not found the routine
  88.          you are looking for so keep going.  Search for the next
  89.          "CALL" and then the next and then the next etc.  At some
  90.          point, when you proceed over a call, the disk will either
  91.          check protection or load in a new module.
  92.  
  93.               How to tell the diffrence, well PW is still active and
  94.          will tell you if it was a call to INT13 or INT21 or BOTH.  If
  95.          it was the call to INT13 or a call to BOTH then you have
  96.          found a call to the protection routine (although the actual
  97.          call may be 100 levels deeper, you are on the right track).
  98.          Exit and restart but this time when you reach the call,
  99.          trace into it.  Now do the same process until you get to the
  100.          call to the next level, then again for the next, etc.
  101.          Finally you should find where it is.
  102.  
  103.               But hopefully, you won't have to do that.  As I said, it
  104.          is very time consumming.  Hopefully, you will know which
  105.          module to look in.  If you do, here is how to find the call
  106.          to the protection.  First, try the simple search method.
  107.          Load up the module using DEBUG and simply type:
  108.  
  109.                    S CS:100 FFFF CD 13  (use CS:100 if .EXE)
  110.  
  111.               Debug will hopefully list 1 or more address.  If not,
  112.          try the same command only using CS:0000.  If again you are
  113.          not givin any address, you have some tricky debugging at hand
  114.          (an I suggest rereading the exercise in self-modifying code).
  115.  
  116.               I will explain in detail how to find self-modifying code
  117.          later but for now, lets assume we have found the protection
  118.          routine.  Next, is to figure out what the copy protection is
  119.          trying to do.  First, look to the printout from PW.  Look
  120.          through it until you find the calls the INT13 from the
  121.          protection routine.  Look at the AH register.  If it is 00h
  122.          then the protection routine is probally reading in data from
  123.          the protected tracks.  If not, then the protection is simply
  124.          looking for some KEY (in other words a damaged track or
  125.          sector) that DOS canno't duplicate.
  126.  
  127.               The second choice is much eaiser to defeat.  2 quick
  128.          methods to defeating this type.  First, you can fake the call
  129.          and simply set the registers.  Take the follow check to a
  130.          protection routine:
  131.  
  132.          1:      mov AX,0201h      ; Read 1 sectors using int 13h
  133.          2:      mov CX,2909h      ; Track 29h sector 09h
  134.          3:      xor DX,DX         ; Drive 0, head 0
  135.          4:      int 13h           ; Read sector
  136.          5:      jnc Bad           ; If no error then it's a copy
  137.          6:      cmp AH,10h        ; Was it a CRC error
  138.          7:      jne Bad           ; No, then it's a copy
  139.          8:      mov AX,0h         ; clear error flag
  140.          9:      jmp Done          ; we are done
  141.          Bad:    mov AX,1          ; set error flag
  142.          Done:   ret               ; we are done
  143.  
  144.               What is the above code trying to do.  Well, it's
  145.          checking for a KEY on track 29h.  That key is sector 09h.
  146.          Normally sector 09h would not have an error.  On a read to
  147.          the original disk, after the int13 (line 4) is executed, the
  148.          carry flag (CF) would be set.  The jnc in line 5 would jump
  149.          if CF is not set (indicating no error, which is bad since the
  150.          original disk would have an error there).  The next line
  151.          checks AH to see if it is 10h.  This is checking to see if
  152.          the error was a Bad CRC on the read (the error that should be
  153.          there).  If it was not, then again it is not the protected
  154.          disk.  Only after both of thoses conditions are met, will the
  155.          protection routine return a "GOOD" result.
  156.  
  157.               The key here is the value returned in AX an possibly
  158.          CF.  When the disk is the original, AX would return the value
  159.          of 0000h and CF = 1 but when it was a copy, it would return
  160.          0001h and CF = 0 or 1.  Since on a bad return, CF can be 0 or
  161.          1 then it is preaty safe to assume CF is not used to signal
  162.          the return.  So what must we do to beat the protection
  163.          routine, well, simply return from this CHECK with AX = 0000h.
  164.          Simple.  Just change line 1 to "mov AX,0000h" and line 2 to
  165.          "RET".  This will just bypass the check.
  166.  
  167.               Now, this example is quite simple and would probally
  168.          never be used in a REAL protection routine.  I kept it simple
  169.          to show the point, see the example on how to crack DRAWING
  170.          ASSISTANT for a better example.
  171.  
  172.               The second and more perferd method is to simply bypass
  173.          the call to the protection routine and kill of the section of
  174.          code that test for the check position.  Take the following
  175.          example:
  176.  
  177.          10:     call 1                  ; call the first example
  178.          11:     cmp AX,0                ; Was it the original
  179.          12:     jz  Good2               ; Yes, then good
  180.          13:     ... BAD it was a copy   ; No, then bad
  181.          Good2:
  182.  
  183.               The above example, when used with the last example show
  184.          a typical call to a protection routine.  The perfered method
  185.          to crack this protection would not be to simply fake the
  186.          return, but to remove the call to the protection.  How to do
  187.          it, simple.  Just jump over the check.  Change line 10 to
  188.          "jmp Good2".  This will bypass the protection routine.
  189.  
  190.               Now, you might ask why would you want to take the extra
  191.          step of finding the call to the protection routine rather
  192.          than simply faking an int13 and returning with the proper
  193.          registers set.  2 reasons.  First, What if there wasn't
  194.          enough room to setup the registers the way you needed them.
  195.          Then you would have to take the extra step.  Second, what if
  196.          somewhere down the line, that routine is used for something
  197.          else (like the int13 is modified into an int10 in a game).
  198.          Since you have changed the bytes at that location, the
  199.          modifying routine would create code that wasn't exepcted.
  200.          But as always, if you can fake the return, and the program
  201.          works, leave it.  After all, not to many people go around
  202.          look at other peoples cracks (do they???).
  203.  
  204.               Now, what to do, if the program actually reads in
  205.          important data from the disk.  Well, there are 2 ways to go
  206.          about this (possibly more).  First, you could patch the
  207.          program so that when it calls it's protection routine, it
  208.          jumps to your user routine that opens a file and reads in the
  209.          data to the right place.  This method is preaty simple to add
  210.          to a .COM file but a much harder to patch on to the back of a
  211.          .EXE.  I won't really go in to this method much more than to
  212.          say use your brains.  It's not a difficult concept.
  213.  
  214.               The other method, is to create a LOADER or a TSR.  I
  215.          suggest creating an Interrupt Service Routine (ISR) that
  216.          handles loading in the data.  For example, let say you wrote
  217.          a routine to read in the needed data for a file.  It is not
  218.          to difficult to convert that routine into an ISR.  (For notes
  219.          on ISR and TSRs, try reading The Waite Group's "MS-DOS
  220.          PAPERS".  It has one of the best sections on the subject).
  221.  
  222.                         Consider this following example:
  223.  
  224.  
  225.          A:            call 1           ; test protection
  226.          B:            jnc Good         ; was it successfull
  227.          C:            ... BAD load     ; no then it's a copy
  228.                        ... EXIT TO DOS  ; so exit to dos
  229.          Good:         ... Good load    ; yes then it original
  230.                        call 7C00:0000   ; then jump of protection
  231.                                         ; data
  232.  
  233.          1:            mov ax,0209      ; Read 9 sectors starting from
  234.          2:            mov cx,290a      ; Track 29h Sector 0Ah (10)
  235.          3:            xor dx,dx        ; for drive A: head 0
  236.          4:            mov bx,7c00      ; read to 7c00:0
  237.          5:            mov es,bx        ;
  238.          6:            mov bx,0         ;
  239.          7:            int 13h          ;
  240.          8:            ret
  241.  
  242.  
  243.  
  244.               What the above example dos.  Lines 1-8 try to read in
  245.          sectors 0Ah - 12h for track 29h on drive A:.  This is the
  246.          protection check routine.  Lines A - Good attempt to check
  247.          the protection, and then if the check is good (CF = 0) then
  248.          a call to the loaded in code (the data loaded in by the
  249.          protection check) is made.
  250.  
  251.               What we want to do, is somehow when INT 13h is called,
  252.          load in the needed data for disk.  Well, here is my
  253.          suggestion.  First, I would change line 7 from "int 13h" to
  254.          "int BBh".  Next, I would create a small .COM loader that
  255.          would execute the main program as a child process (read the
  256.          DOS TECH REF on the EXEC function).  But before I did that, I
  257.          would write an ISR (interrupt service routine) for INT BBh.
  258.          Here is the general outline for the ISR
  259.  
  260.               ■ Use dos to open the file containing the needed data
  261.               ■ Read in the data to ES:BX (where int 13h would put it)
  262.               ■ Close the file
  263.               ■ set AX to 0000 and clear CF
  264.               ■ iret
  265.  
  266.               The loader would go like this :
  267.  
  268.               ■ Get current int BBh address (DOS func. 35h)
  269.               ■ Set int BBh address to ours (DOS func. 25h)
  270.               ■ use DOS to EXECUTE (Dos func. 4Bh) the program to be
  271.                 cracked
  272.               ■ Restore the address of BBh
  273.  
  274.               Well, that about all I have to say about cracking a dos
  275.          file.  I hope this section has been usefull to you.  Next I
  276.          will show by example the techinques in this section while
  277.          cracking I.B.M. Drawing Assistance (1.00).
  278.  
  279.               One last thing.  After you have cracked the program, try
  280.          running it from a hard drive with PW set to trap calls to INT
  281.          21h function 1Bh (get fat byte).  If the program make a call
  282.          to here, get the address and find that section of code.  What
  283.          the program is trying to do is check to see if you are
  284.          running from a hard drive (most programs have diffrent
  285.          protection routines for hard drives).  When you find it,
  286.          simply replace the "INT 21h" with a "MOV DS:[BX],FDh".  This
  287.          will fake the program in to thinking you are working on a
  288.          floppy disk.
  289.  
  290.               Ok, for our example we will be removing the code from
  291.          IBM's Drawing assistant.  Now now, I know it's not the best
  292.          program out there, but shit, It's hard to find shit with on
  293.          disk copy protection anymore.  So here we go...
  294.  
  295.               I needed 3 programs in cracking the assist. series.
  296.          Locksmith by Alph Logic, Periscope debugger, and DEBUG
  297.          (supplied with DOS).  By using these three programs together,
  298.          I was able to figure out and remove the copy protection in
  299.          under 30 minutes.
  300.  
  301.               Drawing Assistant (DA) is IBM's answer to colorpaint for
  302.          the Jr.  It is a simple drawing program (a more advanced
  303.          version is included in StoryBoard Deluxe) but easy to learn
  304.          and use.  So far, I have only seen version 1.00 of this
  305.          program.
  306.  
  307.               DA made calls to the copy protection routine in 3
  308.          diffrent modules.  The files "SETDRAW.EXE", "DRAWASST.EXE"
  309.          and "DRAWASST.TWO" all contained calls to the copy
  310.          protection.  Also, "DRAWASST.TWO" and "DRAWASST.EXE" are for
  311.          all intensive puporses then same file.
  312.  
  313.               I first started off by loading DRAWASST.EXE with debug
  314.          and searched for any int 13's by executing the debug command
  315.  
  316.                 s CS:0 FFFF CD 13         Search CS:0 - CS:FFFF for CD
  317.                                           13 (int 13)
  318.  
  319.            I located 2 diffrent calls to int 13h, so I then listed
  320.          them.  Here is what I found...
  321.  
  322.                      { First, some initialization routines }
  323.  
  324.                      18FD:0343 1E            PUSH   DS
  325.                      18FD:0344 B80000        MOV    AX,0000
  326.                      18FD:0347 50            PUSH   AX
  327.                      18FD:0348 B89724        MOV    AX,2497
  328.                      18FD:034B 8ED8          MOV    DS,AX
  329.                      18FD:034D BB1000        MOV    BX,0010
  330.                      18FD:0350 2E            CS:
  331.                      18FD:0351 8A07          MOV    AL,[BX]
  332.                      18FD:0353 3C00          CMP    AL,00
  333.                      18FD:0355 7418          JZ     036F
  334.  
  335.  
  336.                 { This set is called if DA has been installed }
  337.                              { on the hard drive }
  338.                   { When cracked, this will NEVER be called }
  339.  
  340.                      18FD:0357 B419          MOV    AH,19
  341.                      18FD:0359 CD21          INT    21
  342.                      18FD:035B 8AD0          MOV    DL,AL
  343.                      18FD:035D FEC2          INC    DL
  344.                      18FD:035F B41C          MOV    AH,1C
  345.                      18FD:0361 CD21          INT    21
  346.                      18FD:0363 8A07          MOV    AL,[BX]
  347.                      18FD:0365 BB9724        MOV    BX,2497
  348.                      18FD:0368 8EDB          MOV    DS,BX
  349.                      18FD:036A 3CF8          CMP    AL,F8
  350.                      18FD:036C 7475          JZ     03E3
  351.                      18FD:036E CB            RETF
  352.  
  353.             { This set is called if DA is running from the floppy }
  354.  
  355.                      18FD:036F B419          MOV    AH,19
  356.                      18FD:0371 CD21          INT    21
  357.                      18FD:0373 FEC0          INC    AL
  358.                      18FD:0375 B400          MOV    AH,00
  359.                      18FD:0377 A320C6        MOV    [C620],AX
  360.                      18FD:037A 8AD0          MOV    DL,AL
  361.                      18FD:037C B41C          MOV    AH,1C
  362.                      18FD:037E CD21          INT    21
  363.                      18FD:0380 8A07          MOV    AL,[BX]
  364.                      18FD:0382 BB9724        MOV    BX,2497
  365.                      18FD:0385 8EDB          MOV    DS,BX
  366.                      18FD:0387 3CF8          CMP    AL,F8
  367.                      18FD:0389 7408          JZ     0393
  368.  
  369.                  { Here is the called to read in the key disk }
  370.  
  371.                      18FD:038B E8A675        CALL   7934
  372.                      18FD:038E 3D0100        CMP    AX,0001
  373.                      18FD:0391 7450          JZ     03E3
  374.  
  375.            Let's take these code segments 1 at a time.  The fist, is
  376.          some simple initialization routines.  Here is the code, only
  377.          this time full comments are added.
  378.  
  379.          { First, some initialization routines }
  380.          ; Setup for return to DOS
  381.  
  382.          18FD:0343 1E            PUSH   DS
  383.          18FD:0344 B80000        MOV    AX,0000
  384.          18FD:0347 50            PUSH   AX
  385.  
  386.          ; Setup DS to point to the data segment
  387.  
  388.          18FD:0348 B89724        MOV    AX,2497
  389.          18FD:034B 8ED8          MOV    DS,AX
  390.  
  391.  
  392.          18FD:034D BB1000        MOV    BX,0010    ; CS:10 points to
  393.                                                    ; installed flag
  394.          18FD:0350 2E            CS:
  395.          18FD:0351 8A07          MOV    AL,[BX]
  396.  
  397.          18FD:0353 3C00          CMP    AL,00      ; If not installed,
  398.                                                    ; jump to diskette
  399.          18FD:0355 7418          JZ     036F       ; routines
  400.  
  401.            What we are want to do, is fool DA in to thinking that it
  402.          is stilling loading from diskette.  Nothing really needs to
  403.          be changed in this segment, but, just to be safe, we will
  404.          force the jump at 355.  To change the current values, use
  405.          DEBUG's [A]ssembler command.
  406.  
  407.                  A CS:355
  408.                  18FD:355 JMP 36F
  409.  
  410.            Now, we have forced the jump, we can move on to the third
  411.          code segment skipping over the second since it will never be
  412.          called again.  The 3rd code segment checks to see if you are
  413.          using a hard drive.  It does so by first getting the logical
  414.          drive letter, then reading in the FAT descriptor byte for
  415.          that drive.  Here is the commented code.
  416.  
  417.          { This set is called if DA is running from the floppy }
  418.  
  419.          ; First, get the current drive
  420.  
  421.          18FD:036F B419          MOV    AH,19     ; DOS function 19h -
  422.                                                   ; Get Current Drive
  423.          18FD:0371 CD21          INT    21
  424.  
  425.          18FD:0373 FEC0          INC    AL         ; Add 1 for BIOS
  426.          18FD:0375 B400          MOV    AH,00      ; Clear AH
  427.          18FD:0377 A320C6        MOV    [C620],AX  ; Store it at C620
  428.          18FD:037A 8AD0          MOV    DL,AL      ; Store it in DL
  429.          18FD:037C B41C          MOV    AH,1C      ; DOS function 1Ch
  430.                                                    ; Get Fat desc.
  431.          18FD:037E CD21          INT    21         ; returns pointer
  432.                                                    ; in DS:BX
  433.          18FD:0380 8A07          MOV    AL,[BX]    ; Get the actual
  434.                                                    ; byte
  435.          18FD:0382 BB9724        MOV    BX,2497    ; Restore DS
  436.          18FD:0385 8EDB          MOV    DS,BX
  437.  
  438.          18FD:0387 3CF8          CMP    AL,F8      ; Check to see if
  439.                                                    ; it is a H/D
  440.          18FD:0389 7408          JZ     0393       ; Yes, then jump
  441.          abort
  442.  
  443.          { Fall in to the check for the key disk }
  444.  
  445.            As you can see, this section of code is quite straigth
  446.          forward.  It just checks to see if you are using a hard
  447.          drive.  What we want to do is to fake an DOS function 1Ch and
  448.          return the value for a floppy.  This is done by putting the
  449.          value of FDh in AL then NOPing the rest.  Again use the
  450.          Debug's [A] command.
  451.  
  452.  
  453.                  A CS:37C
  454.  
  455.                  18FD:037C MOV AL,FD
  456.                  18FD:0380 NOP
  457.                  18FD:0381 NOP
  458.                  18FD:0382 NOP
  459.                  18FD:0383 NOP
  460.  
  461.            Now, you might ask why I didn't simple force a jump over
  462.          the code.  The answer is what if DA uses the value at C620 at
  463.          a later time (which it doesn't but let's pretend).  If I had
  464.          forced the jump then the value might not have been
  465.          initialized and the crack might not work.  Now that we have
  466.          simulated running from diskette, we must deal for the check
  467.          for the key disk.
  468.  
  469.               This is where Periscope came in to play.  Using
  470.          periscope, I made the above corrections and ran the program
  471.          up till CS:038B (the call to the check). Here is the code,
  472.          including the actual check.  I have indented the check to
  473.          make it easier to read.
  474.  
  475.  
  476.          { Here is the called to read in the key disk }
  477.  
  478.          18FD:038B E8A675        CALL   7934    ; Check key on disk
  479.                                                 ; (track 27h side 0)
  480.  
  481.            18FD:7934 A120C6        MOV   AX,[C620]     ; Get drive
  482.                                                        ; letter
  483.            18FD:7937 FEC8          DEC   AL
  484.            18FD:7939 A23BC6        MOV   [C63B],AL     ; Store it for
  485.                                                        ; later
  486.            18FD:793C 1E            PUSH  DS
  487.            18FD:793D 07            POP   ES
  488.            ; Setup pointers to what sectors to try to read
  489.  
  490.            18FD:793E BB30C6        MOV   BX,C630
  491.            18FD:7941 891E39C6      MOV   [C639],BX
  492.            18FD:7945 C6063CC603    MOV   BYTE PTR [C63C],03
  493.            18FD:794A C6063DC601    MOV   BYTE PTR [C63D],01
  494.  
  495.            ; Reset the disk
  496.  
  497.            18FD:794F B400          MOV   AH,00
  498.            18FD:7951 CD13          INT   13
  499.  
  500.            ; Get address of sector to read an put it in CL
  501.  
  502.            18FD:7953 8B1E39C6      MOV   BX,[C639]
  503.            18FD:7957 8A0F          MOV   CL,[BX]
  504.  
  505.  
  506.            ; Setup the rest of the read information
  507.  
  508.            18FD:7959 BBAE3D        MOV   BX,3DAE
  509.            18FD:795C 81C3D007      ADD   BX,07D0
  510.            18FD:7960 B001          MOV   AL,01
  511.            18FD:7962 B527          MOV   CH,27
  512.            18FD:7964 8A163BC6      MOV   DL,[C63B]
  513.            18FD:7968 B600          MOV   DH,00
  514.            18FD:796A B402          MOV   AH,02
  515.            18FD:796C CD13          INT   13
  516.  
  517.            ; Test for an error and jump if none is present (ie: the
  518.            ; copy protection has been removed)
  519.  
  520.            18FD:796E 80FC00        CMP   AH,00
  521.            18FD:7971 740C          JZ    797F
  522.  
  523.            ; test the bad read (protection is missing) 3 times
  524.  
  525.            18FD:7973 FE0E3CC6      DEC   BYTE PTR [C63C]
  526.            18FD:7977 75D6          JNZ   794F
  527.            18FD:7979 B80000        MOV   AX,0000
  528.            18FD:797C EB13          JMP   7991
  529.  
  530.            ; Get next sector to check.  If finished, set the flag and
  531.            ; return.
  532.  
  533.            18FD:797F FF0639C6      INC   WORD PTR [C639]
  534.            18FD:7983 FE063DC6      INC   BYTE PTR [C63D]
  535.            18FD:7987 803E3DC603    CMP   BYTE PTR [C63D],03
  536.            18FD:798C 75C1          JNZ   794F
  537.            18FD:798E B80100        MOV   AX,0001
  538.            18FD:7991 C3            RET
  539.  
  540.          ; Check to see if the OK flag was set (ax = 0001h means check
  541.          ; was good)
  542.          18FD:038E 3D0100        CMP    AX,0001
  543.          18FD:0391 7450          JZ     03E3
  544.  
  545.  
  546.            The key check used in DA is quite simple.  It simple tries
  547.          to read in the illegaly numbered sectors on Track 27h side
  548.          0h.  If they are missing, it assumes that it is running a
  549.          pirated copy.  What we must do, is to fool the scheme in to
  550.          thinking a good read happened.  I choses to fake the read
  551.          using the easiest method.  Since the protection scheme only
  552.          check to see if AX returns the value > 0000h, I simply
  553.          modified the routine at 1BFD:7934 to set AX to 0000h and then
  554.          return.  Here is the new code (enter using debug's A
  555.          command)...
  556.  
  557.                  A 1BFD:7934
  558.                  1BFD:7934 MOV AX,0000
  559.                  1BFD:7936 RET
  560.  
  561.            Now, this file is unprotected and if you type "G" at
  562.          debug's command prompt, the program will execute, sort-of.
  563.          See DRAWASST.EXE calls DRAWASST.TWO which also has the
  564.          protection scheme.  So both must be changed.  To make to
  565.          changes perement in DRAWASST.EXE, rename the file to
  566.          DRAWASST.DEB and edit it.  To find the address of the start
  567.          of the protection code, use debug's search command...
  568.  
  569.                  S CS:0 FFFF B4 19 CD 21 8A D0
  570.  
  571.            Now, just uses the modified address to change the program
  572.          (the code will still be the same, just all calls and jumps
  573.          will be to diffrent addresses).  Use the same process to stip
  574.          DRAWASST.TWO (it uses the exact same code).  When you have
  575.          both of those files unprotected, you can move on to
  576.          unprotecting the setup program "SETDRAW.EXE"
  577.  
  578.  
  579.               DRAWASST.EXE AND .TWO are not the only programs that
  580.          make calls to the protection routine.  SETDRAW.EXE also makes
  581.          the above calls.  Although the check here is much easier to
  582.          bypass.  Here is the asm listing of SETDRAW with all of the
  583.          calls to the protection.  This time, I will not go in to
  584.          quite as much detail as I did for the other two version.
  585.  
  586.            I will tell you this.  When SETDRAW checks the key disk,
  587.          first it checks to see if the protection exists and then to
  588.          see if the track hasn't been modified.  It again uses AX to
  589.          determine what happeded.  I used Periscope to trace through
  590.          the original version to find out what the correct values are.
  591.            Here is the asm code...
  592.  
  593.          ; Initialization - checks the current mode and saves it.
  594.  
  595.          18FD:0000 1E            PUSH     DS
  596.          18FD:0001 B80000        MOV      AX,0000
  597.          18FD:0004 50            PUSH     AX
  598.          18FD:0005 B8321A        MOV      AX,1A32
  599.          18FD:0008 8ED8          MOV      DS,AX
  600.          18FD:000A B40F          MOV      AH,0F
  601.          18FD:000C CD10          INT      10
  602.          18FD:000E 3C02          CMP      AL,02
  603.          18FD:0010 740D          JZ       001F
  604.          18FD:0012 3C03          CMP      AL,03
  605.          18FD:0014 7409          JZ       001F
  606.          18FD:0016 A28900        MOV      [0089],AL
  607.          18FD:0019 B002          MOV      AL,02
  608.          18FD:001B B400          MOV      AH,00
  609.          18FD:001D CD10          INT      10
  610.  
  611.          ; Gets the current drive
  612.  
  613.          18FD:001F B400          MOV      AH,00
  614.          18FD:0021 B419          MOV      AH,19
  615.          18FD:0023 CD21          INT      21
  616.          18FD:0025 A28700        MOV      [0087],AL
  617.          18FD:0028 8AD0          MOV      DL,AL
  618.          18FD:002A FEC2          INC      DL
  619.  
  620.          ; Checks the FAT descriptor
  621.  
  622.          18FD:002C B41C          MOV      AH,1C
  623.          18FD:002E CD21          INT      21
  624.          18FD:0030 8A07          MOV      AL,[BX]
  625.          18FD:0032 BB321A        MOV      BX,1A32
  626.          18FD:0035 8EDB          MOV      DS,BX
  627.          18FD:0037 C606880000    MOV      BYTE PTR [0088],00
  628.          18FD:003C 3CF8          CMP      AL,F8
  629.          18FD:003E 742A          JZ       006A
  630.  
  631.          ; Read in protection scheme
  632.  
  633.          18FD:0040 8A168700      MOV      DL,[0087]
  634.          18FD:0044 E87E0A        CALL     0AC5
  635.          18FD:0047 C606880000    MOV      BYTE PTR [0088],00
  636.          18FD:004C 3D0000        CMP      AX,0000
  637.          18FD:004F 7419          JZ       006A
  638.  
  639.          ; Read in the dummy scheme
  640.  
  641.          18FD:0051 C606880001    MOV      BYTE PTR [0088],01
  642.          18FD:0056 8A168700      MOV      DL,[0087]
  643.          18FD:005A B84500        MOV      AX,0045
  644.          18FD:005D E8BD0A        CALL     0B1D
  645.          18FD:0060 3D0000        CMP      AX,0000
  646.          18FD:0063 7405          JZ       006A
  647.  
  648.          ; Start of actual routine.
  649.  
  650.          18FD:0065 C606880000    MOV      BYTE PTR [0088],00
  651.  
  652.            There is isn't much to say about the above code.  To bypass
  653.          it, we will change the hard drive check (int 21 function 1c).
  654.          Do the same thing we did for DRAWASST.EXE
  655.  
  656.                 A 18FD:2C
  657.                 18FD:002C mov AL,FD
  658.                 18FD:002E nop
  659.                 18FD:002F nop
  660.                 18FD:0030 nop
  661.                 18FD:0031 nop
  662.  
  663.            Now, just jump over the check to the key disk.
  664.  
  665.                A 18FD:40
  666.  
  667.                18FD:0040 jmp 0065
  668.  
  669.            And thats it.  Now SETDRAW is unprotected.  Drawing
  670.          Assistant may be used, copied or backed up at your pleasure.
  671.  
  672.  
  673.               As you can see, this was a good example although the
  674.          fact that if you only made the changes in DRAWASST.EXE and
  675.          not in DRAWASST.TWO then the program would copy DRAWASST.TWO
  676.          to DRAWASST.EXE to restore the protection was a bit strange.
  677.  
  678.               Well, I hope you are proud.  But be warned, next we take
  679.          on DOC checks, so get a good nights sleep.  Till then, play
  680.          lots of SMASH T.V.
  681.  
  682.                                                       -Buckaroo Banzai
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.                                      page 9
  727.