simonh@hpopd.pwd.hp.com (Simon Hunt) (04/11/91)
Over the last few evenings, I have been trying to discover how the copy protection works on one of the disk-based games I have. The game loads itself in several stages, to display a title screen whilst the rest of the program loads... Using a monitor/disassembler program, which allows you to read/write selected disk sectors to a specified buffer, I eventually disassembled enough code to discover how the program loaded itself in. Apart from the usual "unformatted sectors" method, the program used a really neat trick which goes something like this: : : (set colours & display list pointers etc.) : * Read Sector <N> into buffer [$600-$67F] * Read the SAME Sector into buffer [$680-$7FF] * For X = #$00 to #$7F do.. * EOR $600,X with $680,X and store in $2800,X : : (more stuff) : * JSR $2800 : The point is, on a normal disk (ie. a "copy" of the original) the values loaded into the destination buffer [$2800-$287F] all equal #$00, since <n> EOR <n> = #$00 so the JSR encounters the BRK instruction and stops. However, on closer inspection of the original disk, I discovered that reading sector <N> several times in a row produced one of TWO sets of data in the buffer. When I EOR'd the two sets of data together and disassembled the result, there was the "missing" subroutine. Does anyone know how the disk was manufactured such that reading the same sector gave TWO different, but CONSISTANT, sets of data? Observations: 1. The two sets of data NEED to be consistant to produce the correct code when EOR'd together. 2. It doesn't matter which order the data sets arrive in as EOR is commutative. 3. Reading the sector several times did not guarantee alternation of the two data sets. 4. There wasn't any provision for checking that the second read of the sector had produced the OTHER data set. What puzzles me is 3. and 4. Together they seem to imply that occasionally, two consecutive reads of the sector would produce the same result which when EOR'd together would, of course, produce a zero filled buffer. This in turn would halt the program with the JSR call. However, in the numerous times I have loaded and played the game in the past, I have NEVER seen this happen.. it's always loaded fine. Any ideas? Simon Hunt.
simonh@hpopd.pwd.hp.com (Simon Hunt) (04/11/91)
Erratum: : * Read Sector <N> into buffer [$600-$67F] * Read the SAME Sector into buffer [$680-$7FF] ^^^^----- This should read "$6FF" Apologies. Simon Hunt.
ken@hpcupt3.cup.hp.com (Kenneth M. Sumrall) (04/12/91)
> * Read Sector <N> into buffer [$600-$67F] > * Read the SAME Sector into buffer [$680-$7FF] > * For X = #$00 to #$7F do.. > * EOR $600,X with $680,X and store in $2800,X > [... Stuff deleted...] >Does anyone know how the disk was manufactured such that reading the same >sector gave TWO different, but CONSISTANT, sets of data? > Excellent hack work Simon. I did this on Choplifter way back in 1981. Very difficult to figure out when I never knew more than one sector could have the same sector number. (10th grade == not very bright :-) >Observations: > 1. The two sets of data NEED to be consistant to produce the correct code > when EOR'd together. > 2. It doesn't matter which order the data sets arrive in as EOR is > commutative. > Correct. > 3. Reading the sector several times did not guarantee alternation of the > two data sets. > If you read them with a sector editor, of course not. However, if read in rapid succesion by an assembly program, the computer generates the first read. It is satisfied as soon as a sector with the correct number passes under the disk drive head. Then, immediately ask for the same sector again. The computer will send the request to the disk drive before the other sector with the same number passes under the head, and now the disk drive will satisfy the read request with the other sector. > 4. There wasn't any provision for checking that the second read of the > sector had produced the OTHER data set. > Not needed because the way the sectors are read in guarantees the correct data. >What puzzles me is 3. and 4. Together they seem to imply that occasionally, >two consecutive reads of the sector would produce the same result which when >EOR'd together would, of course, produce a zero filled buffer. This in >turn would halt the program with the JSR call. However, in the numerous >times I have loaded and played the game in the past, I have NEVER seen this >happen.. it's always loaded fine. > >Any ideas? > Choplifter used a slightly different scheme, if I remember correctly. It seems that three sectors had the same number. The loading routine would read the same sector 10 times into two different locations alternatively. Some how, this produced the correct data in the right locations. I never figured out why. Anyway, I copied the two neccesary sectors to two DIFFERENT sectors on my copy, changed the loader to read one sector into one location, and the other sector into another, and jump to it. Luckily, the boot loader didn't checksum itself before running the program. I believe that Way Out did this. Made it a little more difficult to hack. Of course, now that I have a Happy Drive, backups aren't so difficult! >Simon Hunt. | Ken Sumrall | Internet: ken%hpda@hplabs.hp.com | | HP California Language Labs | UUCP: ...!hplabs!hpda!ken | | "I'd stomp desert dope heads for some gas in my moped!" - Bill the Cat | | "What a stupid world" -Calvin (speaking to Hobbes) |
smb@cs.purdue.EDU (Scott M. Ballew) (04/12/91)
In article <40060005@hpopd.pwd.hp.com> simonh@hpopd.pwd.hp.com (Simon Hunt) writes: >Does anyone know how the disk was manufactured such that reading the same >sector gave TWO different, but CONSISTANT, sets of data? >Observations: > 1. The two sets of data NEED to be consistant to produce the correct code > when EOR'd together. > 2. It doesn't matter which order the data sets arrive in as EOR is > commutative. > 3. Reading the sector several times did not guarantee alternation of the > two data sets. > 4. There wasn't any provision for checking that the second read of the > sector had produced the OTHER data set. >What puzzles me is 3. and 4. Together they seem to imply that occasionally, >two consecutive reads of the sector would produce the same result which when >EOR'd together would, of course, produce a zero filled buffer. This in >turn would halt the program with the JSR call. However, in the numerous >times I have loaded and played the game in the past, I have NEVER seen this >happen.. it's always loaded fine. This is a very old copy protection scheme that relies on some timing properties of disk drives. Consider a single track of data which contains 18 sectors. These are normally numbered from 0 to 17 but are NOT in order around the disk surface. I forget what the optimal format is but basically, sector 1 is almost 180 degrees around the disk from sector 0 and then sector 2 is almost 180 degrees from sector 1, etc. This is because while the computer and disk drive transfer the data across the SIO cable, the disk is still spinning and it just so happens that it is almost 180 degrees later when the drive and computer are ready to read the next sector. Now, in the case you mention above, if you labeled two sectors with the same sector number in a track, which one you got would now depend on the timing of other reads around you. Various methods have used the idea that if you read the sectors in the order of say 0 - 1 - 3 - 1, then you got two different reads for sector 1. With what you describe, they are counting on the following fact: If I read a sector "1" from the track and immediately read another sector "1" from the track and these two sector "1"s are approx 180 degrees apart, I am all but guaranteed that I will get two different sets of data, ie., I will read both of the sector "1"s on the disk. As to how they did it, it is simply a matter of reprogramming the drive (not possible on a stock 810 or 1050) to format the disk in a different manner than the normal way. It turns out that Happy enhanced drives have been able to do this for some time and have absolutely no problem duplicating the format on the destination disk. By the way, you probably do not really have as many "unformatted" sectors as you think since if you have 18 sectors and renumber one of them to be a duplicate number, one of the 18 sector numbers will not exist so the drive will treat it as if it were unformatted. Scott M. Ballew