LESSON 5 (1) - HOW TO CRACK, HANDS ON - Disk/CDROM access (plus
  bypasses "on the fly")
Somewhere I have to put the bypasses (loader programs) in this
  tutorial, allow me to put them here:
Preparing a loader to bypass a protection [MARIO ANDRETTI]
  At time the protectionists hook vectors in order to impose
  a particular protection. In this (and similar) cases a good
  crack-way is to prepare a "loader" program, that "de-hooks" 
  the
  vector used for the protection. This kind of crack can be used
  also for internet cracking (on some firewall configurations, see
  lesson A.2).
  As example let's take "Mario andretti racing challenge", a
  stupid game that uses the SAME (!) protection scheme you'll still
  find to day on some access routines of military servers around
  the witlessly called "free" world.
In order to crack this cram you would prepare a loader on the
  following lines:
loc code instruction what's going on
  -------------------------------------------------------
  :0100 EB44 JMP 0146
  ...
  :0142 0000 <- storing for offset of INT_21
  :0144 5887 <- storing for segment of INT_21
  :0146 FA CLI
  :0147 0E PUSH CS
  :0148 1F POP DS
  :0149 BCB403 MOV SP,03B4
  :014C FB STI
  :014D 8C1EA901 MOV [01A9],DS <- save DS
  :0151 8C1EAD01 MOV [01AD],DS three
  :0155 8C1EB101 MOV [01B1],DS times
  :0159 B82135 MOV AX,3521 <- get INT_21
  :015C CD21 INT 21 in ES:BX
  :015E 891E4201 MOV [0142],BX <- store offset
  :0162 8C064401 MOV [0144],ES <- store segment
  :0166 BA0201 MOV DX,0102
  :0169 B82125 MOV AX,2521 <- set INT_21 to
  :016C CD21 INT 21 DS:0102
  :016E 0E PUSH CS
  :016F 07 POP ES <- ES= current CS
  :0170 BBB403 MOV BX,03B4
  :0173 83C30F ADD BX,+0F
  :0176 B104 MOV CL,04
  :0178 D3EB SHR BX,CL <- BX= 3C
  :017A B8004A MOV AX,4A00 <- Modify memory block
  :017D CD21 INT 21 to 3C paragraphs
  :017F BA9E01 MOV DX,019E <- ds:dx=program name
  :0182 BBA501 MOV BX,01A5 <- es:bx = param. block
  :0185 B8004B MOV AX,4B00 <- load ma.com
  :0188 CD21 INT 21
  :018A 2E8B164201 MOV DX,CS:[0142] <- reset old int_21
  :018F 2E8E1E4401 MOV DS,CS:[0144]
  :0194 B82125 MOV AX,2521
  :0197 CD21 INT 21
  :0199 B8004C MOV AX,4C00 <- terminate with return
  :019C CD21 INT 21 code
  :019E 6D612E636F6D00 "ma.com"
  0000 fence
  :01A7 B2015887
  :01AB B2015887
  :O1AF B2015887
  0000 fence
let's now prepare a routine that hooks INT_21:
push all
  CMP AX,2500 <- go on if INT_21 service 25
  JNZ ret
  CMP Word Ptr [0065], C00B <- go on if location 65 = C00B
  JNZ ret
  MOV Byte Ptr [0060], EB <- crack instructions
  MOV Byte Ptr [0061], 3C
  MOV Byte Ptr [0062], 40 <- INC AX
  MOV Byte Ptr [0063], 90 <- NOP
  MOV Byte Ptr [0064], 48 <- DEC AX
  pop all
  JMP FAR CS:[0142] <- JMP previous INT_21
 From now on this loader will work every time that a program
  with location [0065] containing an 0R AX,AX instruction (0BC0:
  it's the case of ma.com) calls INT_21 service 25 (hook a vector),
  the target program will be modified on the fly and will get, at
  location [0060], the instruction JMP 3C locations ahead, despite
  the fact that it has routines capable of self checking in order
  to make sure it has not been modified.
  The most important thing is the routine that YOU write that
  will precede the call to INT_21 (or any other INT) service 25 (or
  any other service) in order to crack on the fly the offending
  program. I'll show you another one, this one for [Reach for the
  skies] (reach.com):
push all
  CMP AH,3D <- is it service 3D? (open file)
  JNZ ret <- no, so ret
  CMP DX,13CE <- you wanna open file at 13CE?
  JNZ ret <- no, so ret
  MOV AX,[BP+04] <- in this case
  MOV DS,AX
  CMP Byte Ptr [B6DA],74 <- old instructions
  JNZ 015B
  CMP Byte Ptr [B6DB],0F <- ditto
  JNZ 015B
  CMP Byte Ptr [B6DC],80 <- ditto, now we now where we are
  JNZ 015B
  MOV Byte Ptr [B6DA],EB <- crack
  MOV Byte Ptr [B697],40 <- camouflaged no-opping
  MOV Byte Ptr [B698],48 <- cam nop
  MOV Byte Ptr [B699],90 <- cam nop
  MOV Byte Ptr [B69A],40 <- cam nop
  MOV Byte Ptr [B69B],48 <- cam nop
  MOV DX,CS:[0165]
  MOV DS,CS:[0167]
  MOV AX,2521 <- set hook
  INT 21
  POP all
  JMP FAR CS:[0165]
  Here you did change the instruction 740F in the instruction EB0F,
  and you did "noop" the instructions at B697-B69B. (Well, more
  elegantly than "noop" them with "90" bytes, you choose a 
  INC AX,
  DEC AX, NOP, INC AX, DEC AX sequence instead! There are sound
  reasons to use a sequence of "working" instructions instead of
  NOPs: recent protection schemes "smell" patched nops inside the
  program and trash everything if they find more than -say- three
  consecutive NOPs! You should always try to choose THE LESS
  INTRUSIVE and MORE "CAMOUFLAGED" solution when you crack!)
  You can apply this kind of crack, on the same lines, to many
  programs that perform self checking of the code and hook the
  vectors.
REAL DISK ACCESS STUFF
  Now we may come to the subject of this lesson:
  As usual, let's begin from the beginning: history is always
  the key that allows an understanding of present and future, in
  cracking matters too. As the older 5 1/4 inch big black floppy
  disks were still used (the 320K/8 tracks or 360K/9 tracks ones,
  that were really "floppy" and have nowadays almost disappeared)
  one of the more common methods to protect a program, was to
  format the "master" (key) disk in a weird way. Old floppy disk
  for the PC did usually store 360K at 9 sectors per track.
  Some basics for those of you that do not know anything: in
  order to defeat this kind of cracks you need to know two things:
  the floppy disk parameter block (FDPB) and the interrupt routines
  dealing with format/read disk (basically INT_13).
  Most often, the protection scheme is to either format one
  or more sectors or tracks with sector sizes other than the
  standard 512 bytes, or to either give one of the sectors a wild
  sector number like 211 or just not format a whole track of
  eight/nine/15 sectors. If you, for instance, have got the same
  (very old) copy of VisiCalc master I do, you'll find that sector
  8 on track 39 is missing entirely. The interrogation with
  assembly or with an "ad hoc" utility (I use the tools I wrote
  myself, but you 'll be able to find many such utilities in public
  domain, the oldest one, from 1984 (!) being the seasoned [U-ZAP]
  an "Ultra utility" from the "Freesoft company") will tell 
  you
  which sector numbers were altered, their size in bytes, and if
  they were formatted with a CRC error (another not so fancy
  trick).
  The floppy disk parameters are stored in the BIOS: interrupt
  vector 1E contains the address of the floppy disk parameter
  block. The FDPB's contents are the following:
  Offset Function crackworthy? Example
  0 Step rate & head unload no DF
  1 head load time no 02
  2 Motor on delay no 25
  3 Number of bytes per sector yes 02
  4 Last sector number yes 12
  5 Gap length yes 1B
  6 Data track length yes FF
  7 Format gap length yes 54
  8 Format byte no F6
  9 Head settle time no 0F
  A Motor start time no 02
0) Offset #0: the left "nybble" (single digit) of this value
  is the step rate time for the disk drive head. The right
  nybble is the disk head unload time. These values are best
  left alone.
  1) Offset #1: again, don't fool around with these values. The
  left nybble is the disk head load time, and the right
  nybble is the direct memory access mode select.
  2) Wait time until motor is turned off. Not normally of use.
  3) Bytes-per-sector value: AH-HAH! If you place a "0" in this
  value, the PC expects all sectors to be 128 bytes long. A
  "1" means a sector size of 256 bytes, a "2" means 512
  bytes (this is the standard DOS value), and a "3" means
  1024 bytes per sector.
  4) Highest sector number on a track: this is used for
  formatting and tells DOS how many sectors there are on each
  track.
  5) Gap length for diskette reads: this is what you fool around
  with if you keep getting CRC errors when you try to read a
  non-standard size sector. Normally, you can just leave this
  alone except when formatting with a U-Format tool.
  6) Data length: This contains the number of bytes in a sector
  when the value in table byte #4 doesn't contain a 0, 1, 2,
  or 3.
  7) Number of bytes in the gap between sectors: this is also
  only used when formatting special tracks.
  8) Format fill byte: When formatting, this is the
  initialization byte that will be placed in all new sectors.
  9) Head settle time: leave this alone.
  A) Motor start time: don't fool with this either.
  In order to modify globally the number of tracks on a given disk
  and the number of sectors per track you can always format with
  the DOS command switches "/t:" and "/n:"
  FORMAT /t:tracks /n:sectors
 If you want to find out what the existing parameters are,
  run [Debug.exe] or [Symdeb.exe] and enter the following commands:
  - d 0:78 l 4 <- get FDPB address
  0000:0070 22 05 00 <- debugger's likely response
  - d 0:522 l a <- get 10 FDPB values
  0000:520 DF 02 25 02 12 1B FF... <- see preceding table
 Remember that all standard disk formats under DOS support
  a sector size of 512 bytes, therefore, for one-sided 5.25 inch
  floppies:
  40t*8s*512b=163.840 bytes (160Kb)
  40t*9s*512b=184.320 bytes (180Kb)
  and for two-sided 5.25 inch floppies:
  40t*8s*512b*2sides=327.680 bytes (320Kb)
  40t*9s*512b*2sides=368.640 bytes (360Kb)
  Beginning with DOS version 3.0 (Yeah, more and more
  history!) a new floppy disk format has been supported: The IBM
  AT (80286 CPU) introduced the so called "high capacity" 5.25 u-
  inch floppy, capable of storing 1.2M at 15 sectors per track:
  80t*15s*512b*2sides=1.228.800 bytes (1.2Mb)
  Later on were introduced the to-day universally used 3.5
  inch floppies, the ones inside a rigid small plastic cartridge,
  and we have, similarly:
  3.5-inch double sided/double density 720K
  3.5-inch double sided/quad density (HD) 1440K
  3.5-inch double sided/high density 2880K
  [INT_13, AH=18, Set media type for format]
  In order to create weird layouts, the protectionists use
  interrupt 13h, service 18h, that specifies to the formatting
  routines the number of tracks and sectors per track to be placed
  on the media:
  * Registers on entry: AH=18h; CH=Nø of tracks; CL= Sectors
  per track; DL= Drive number (A=0; B=1;C=2... bit 7 is set
  if the drive is an hard disk)
  * Registers on Return: DI: Offset address of 11-byte
  parameter table; ES: Segment address of 11-byte parameter
  table.
[INT_13, AH=2, Read disk sectors]
  In order to read them, they have to use INT_13, service 2, read
  disk sectors, with following layout:
  * Registers on entry: AH=2h; AL= Nø of sectors; BX= Offset
  address of data buffer; CH=track; CL= Sector; DH= Head
  (side) number; DL= Drive number; ES: Segment address of
  data buffer.
  * Registers on Return: AH= return code. If the carry flag is
  not set, AH=0, therefore the weird sector has been read, if
  on the contrary the carry flag is set, AH reports the
  status byte as follows:
  76543210 HEX DEC Meaning
  1 80h 128 Time out - drive crazy
  1 40h 064 Seek failure, could not move to track
  1 20h 032 Controller kaputt
  1 10h 016 Bad CRC on disk read
  1 09h 009 DMA error - 64K boundary crossed
  1 08h 008 DMA overrun
  1 04h 004 Bad sector - sector not found
  11 03h 003 Write protect!
  1 02h 002 Bad sector ID (address mark
  1 01h 001 Bad command
[Return code AH=9: DMA boundary error]
  One of the possible errors should be explained, coz it is
  used in some protection schemes: AH=9 DMA boundary error, means
  that an illegal boundary was crossed when the in formation was
  placed into RAM. DMA (Direct memory access) is used by the disk
  service routines to place information into RAM. If a memory
  offset address ending in three zeros (ES:1000, ES: 2000...) falls
  in the middle of the area being overlaid by a sector, this error
  will occur.
[INT_13, AH=4 Verify disk sectors]
  Another possible protection interrupt is interrupt 13H,
  service 4, Verify disk sectors. Disk verification takes place on
  the disk and DOES NOT involve verification of the data on the
  disk against data in memory! This function has no buffer
  specification, does not read or write a disk: it causes the
  system to read the data in the designated sector or sectors and
  to check its computed cyclic redundancy check (CRC) against data
  stored on the disk. See INT_13, AH=2 registers and error report.
[CRC]
  The CRC is a checksum, that detects general errors. When a
  sector is written to disk, an original CRC is calculated AND
  WRITTEN ALONG with the sector data. The verification service
  reads the sector, recalculates the CRC, and compares the
  recalculated CRC with the original CRC.
 We saw that some protection schemes attempt to disguise
  interrupt calls. This is particularly frequent in the disk access
  protection schemes that utilize INT_13 (the "disk" interrupt).
  If you are attempting to crack such programs, the usual
  course of action is to search for occurrences of "CD13", which
  is machine language for interrupt 13. One way or another, the
  protection scheme has to use this interrupt to check for the
  special sectors of the disk. If you examine a cross section of
  the program, however, you'll find programs which do not have
  "CD13" in their machine code, but which clearly are checking the
  key disk for weird sectors. How comez?
  There are several techniques which can be used to camouflage
  the protection scheme from our nice prying eyes. I'll describe
  here the three such techniques that are more frequent:
  1) The following section of code is equivalent to issuing an
  INT 13 command to read one sector from drive A, side 0, track
  29h, sector ffh, and then checking for a status code of 10h:
  cs:1000 MOV AH,02 ;read operation
  cs:1002 MOV AL,01 ;1 sector to read
  cs:1004 MOV CH,29 ;track 29h
  cs:1006 MOV CL,FF ;sector ffh
  cs:1008 MOV DX,0000 ;side 0, drive A
  cs:100B XOR BX,BX ;move 0...
  cs:100D MOV DS,BX ;...to DS register
  cs:100F PUSHF ;pusha flags
  cs:1010 PUSH CS ;pusha CX
  cs:1011 CALL 1100 ;push address for next
  instruction onto stack and branch
  cs:1014 COMP AH,10 ;check CRC error
  cs:1017 ... rest of verification code
  ...
  ...
  cs:1100 PUSHF ;pusha flags
  cs:1101 MOV BX,004C ;address of INT_13 vector
  cs:1104 PUSH [BX+02] ;push CS of INT_13 routine
  cs:1107 PUSH [BX] ;push IP of INT_13 routine
  cs:1109 IRET ;pop IP,CS and flags
  Notice that there is no INT 13 command in the source code, so if
  you had simply used a debugger to search for "CD13" in the
  machine code, you would never have found the protection routine.
2) Another technique is to put in a substitute interrupt
  instruction, such as INT 10, which looks harmless enough, and
  have the program change the "10" to "13 (and then back to "10")
  on the fly. A search for "CD13" would turn up nothing.
3) The best camouflage method for interrupts I have ever
  cracked (albeit not on a INT 13) was a jump to a section of the
  PROGRAM code that reproduces in extenso the interrupt code. This
  elegant (if a little overbloated) disguise mocks every call to
  the replicated interrupt.
LOADING ABSOLUTE DISK SECTORS
  Old good [debug.com] has been called the "swiss army knife" of
  the cracker. It allows a lot of nice things, inter alia the
  loading, reading, modifying and writing of absolute sectors of
  the disks. The sector count starts with the first sector of track
  0, next sector is track 0, second side (if double sided), then,
  back to the first side, track 1, and so on, until the end of the
  disk. Up to 80h (128) sectors can be loaded at one time. To use
  you must specify starting address, drive (0=A, 1=B, etc...),
  starting sector and number of sectors to load.
  - l 100 0 10 20
  This instruction tells DEBUG to load, starting at DS:0100, from
  drive A, sector 10h for 20h sectors. This allows at times the
  retrieval of hidden and/or weird formatted data. If you get an
  error, check the memory location for that data. Often times, part
  of the data has been transferred before the error occurs, and the
  remainder can be manually entered or gathered through repetitive
  retries.
Bear all this in mind learning the following cracks.
  Let's now crack an "oldie" primitive:
  MS Flight simulator (old version 2.12, from 1985!)
  This old program used -in 1985!- following beautiful protection
  scheme: on the disk you had only a "stub", called FS.COM with few
  bytes, which had following instructions:
loc code instruction what's going on
  -------------------------------------------------------
  :0100 FA CLI ;why not?
  :0101 33C0 XOR AX,AX ;ax=0
  :0103 8ED0 MOV SS,AX ;ss=0
  :0105 BCB0C0 MOV SP,C0B0 ;SP=C0B0
  :0108 8EC0 MOV ES,AX ;ES=0
  :010A 26C70678003001 MOV Wptr ES:[0078],0130 ;Wp 0:78=130
  :0111 268C0E7A00 MOV ES:[007A],CS ;0:7A=Segment
  :0116 BB0010 MOV BX,1000 ;BX=1000
  :0119 8EC3 MOV ES,BX ;ES=1000
  :011B 33DB XOR BX,BX ;BX=0
  :011D B80102 MOV AX,0201 ;AH=2 AL=1 sector
  :0120 BA0000 MOV DX,0000 ;head=0 drive=0
  :0123 B96501 MOV CX,0165 ;track=1 sector=65 (!)
  :0126 CD13 INT 13 ;INT 13/AH=2
  :0128 B83412 MOV AX,1234 ;AX=1234
  :012B EA00000010 JMP 1000:0000 ;JMP to data we just read
  :0130 CF IRET ;Pavlovian, useless ret
 You see what's happening in this old protection scheme,
  don't you? Herein you can watch the same snap that happens in
  more recent (much more recent) protection schemes (as you'll see
  in the next lesson): the protection searches for a weird
  formatted sector and/or for particular data.
  That should be no problem for you any more: you should just
  reverse engineer everything (and that goes on pretty quickly:
  just watch and break on the INT_13 calls), fetch the "weird"
  data, tamper the whole crap and have your soup as you like it.
  One more word about "old" protection schemes. Be careful not
  to spurn them! Some of them are
  --CLEVER
  --STILL USED
  --DIFFICULT TO CRACK... I mean, this older DOS programs had
  nice protections... it's pretty annoying to crack windows
  programs that require a registration number: as you saw in Lesson
  3, you just type your name and a serial number of your choice in,
  say "666666666", break into the program with WINICE, search the
  "666666666" and search too, for good measure, your own name, set
  a memory read breakpoint where the number dwells and look at the
  code that manipulates your input. As [Chris] rightly pointed out,
  you can even rip the code straight out of the program and create
  a key generator which will produce a valid code. This code will
  work for any name you typed in only in the "pure maths
  manipulation" protection schemes, and will on the contrary be
  specific, following the name you typed in, the "alpha-maths
  manipulation" protection schemes (like MOD4WIN, see the Windows
  lessons), watch in this case the "pseudo-random xoring" of the
  letters that compose your name.
  --STUNNING, coz new ideas have always been infrequent, and
  they are getting more and more rare in this objectionable world
  of lazy, incapable programmers patronizing us with ill-cooked
  outrages like Windows'95... yeah, as usual there is no
  "development" at all, quite the contrary, I would say. Take a
  step backward, sip a good Martini-Wodka (please remember that
  only Ice cubes, Dry Martini, Wodka Moskovskaja, Schweppes'
  "Indian tonic" a green olive from Tuskany and a maltese lemon
  zest will really be perfect) and watch from your balcony, with
  unsullied eyes, your town and the people around you: slaves
  everywhere, leaving home at 7.30 in the morning, stinking in a
  progression of identical cars, forced to interminably watch
  advertisement panels and endlessly listen to boorish publicity,
  happy to go to work (if they happen to have the "luck" to work,
  in this inequitable society) the whole day long in order to
  produce other cars in order to buy, one day, a new car with a
  different colour...
  Why people don't look at the stars, love each other, feel
  the winds, ban the stinking cars from the places where they live
  and eat, study colours... name yourself a not-consumistic
  activity? Why don't they read any poems any more? No poetry any
  more, in the grey society of the publicity-spots slaves...poetry
  will soon be forbidden, coz you cannot CONSUME as you read poems,
  and in this farce of a society you are BOUND to consume, that's
  the only thing they want you to do... you are CULTIVATED to
  consume... no books worth to read any more... stupid american
  conventional cram everywhere... boy, at times I'm missing some
  well placed neutron bombs, the ones that would kill all these
  useless zombies and leave noble books and good Wodka untouched.
  It's difficult to believe in democracy any more... if I ever
  did... all the useless zombie do -unfortunately- vote, and they
  do vote for "smiling semblances", for "conventionally minded
  idiots" that so act as if they would "really" be like what they
  "look" like and could not care less about anything else than
  making bucks and defend intolerant and petty patterns. The slaves
  choose the people they have "seen" on TV... as if the egyptians
  would VOTE for their pharaohs, exhilarated under the whips of
  publicity... sorry, at times I forget that you are here for the
  cracks, and could not care less about what I think...
 You 'll obtain the OTHER missing lessons IF AND ONLY IF you
  mail me back (via anon.penet.fi) with some tricks of the trade
  I may not know that YOU discovered. Mostly I'll actually know
  them already, but if they are really new you'll be given full
  credit, and even if they are not, should I judge that you
  "rediscovered" them with your work, or that you actually did good
  work on them, I'll send you the remaining lessons nevertheless.
  Your suggestions and critics on the whole crap I wrote are also
  welcomed.
+ORC an526164@anon.penet.fi