weird. I can't find any DOS file interrupts. I know this is for DOS 2.x, but it's gotta load files somehow... there's a high score file!
oh wait I searched on "int 21h". but there's a generic interrupt mechanism here, I just described it. I'm an idiot
rather than hack my way into having a disk that'll work when mounted in DOSBox, I'm just going to make it work properly if the files are copied to DOS? I'll stick the information from those sectors into a file, and swap the raw-sector interrupts out for a simple DOS read-file-data routine.
in fact, I might be able to steal one from elsewhere in the EXE
weird. I can't find any DOS file interrupts. I know this is for DOS 2.x, but it's gotta load files somehow... there's a high score file!
so I have a hack that works: I don't think I trust it though. I'm going to change it so the right memory gets into RAM at the right places, just to make sure there's no additional side effects.
There's random values in this sector, after all: what if the game is using them to multiple enemy damage or something?
rather than hack my way into having a disk that'll work when mounted in DOSBox, I'm just going to make it work properly if the files are copied to DOS? I'll stick the information from those sectors into a file, and swap the raw-sector interrupts out for a simple DOS read-file-data routine.
in fact, I might be able to steal one from elsewhere in the EXE
so, step 3: The checksums.
I hack out the checksum function so that when it's called, it just writes the "correct" answer into the return value.
I do it at the point where checksum_memory() is implemented, not where it's called, as there's two visible calls to the checksumming function, there may be more. this way it'll always return the right value.
(assuming they always checksum the same part of memory! a fun trick would be doing different chunks of RAM... but not here)
so I have a hack that works: I don't think I trust it though. I'm going to change it so the right memory gets into RAM at the right places, just to make sure there's no additional side effects.
There's random values in this sector, after all: what if the game is using them to multiple enemy damage or something?
but luckily for everyone, the call_interrupt function is at 1000:e3b6 so it's outside the checksummed 16kb
so, step 3: The checksums.
I hack out the checksum function so that when it's called, it just writes the "correct" answer into the return value.
I do it at the point where checksum_memory() is implemented, not where it's called, as there's two visible calls to the checksumming function, there may be more. this way it'll always return the right value.
(assuming they always checksum the same part of memory! a fun trick would be doing different chunks of RAM... but not here)
fun fact: this code is self modifying! not for copy-protection reasons, but for generic-interrupt reasons.
x86 doesn't have an INT r8 instruction, only INT imm8. So to generically call an interrupt, you have to either:
1. do a lookup to a bunch of INT 00h, INT 01h, INT 02h, INT 03h instructions, OR...
2. just rewrite your own code at runtime. overwrite the second byte of the "INT 00" instruction and bam, dynamic interrupts
but luckily for everyone, the call_interrupt function is at 1000:e3b6 so it's outside the checksummed 16kb
that's because the checksum failed. it checksums the the code segment, starting at 1000:0082 and going to 1000:4082 (16 kilobytes)
fun fact: this code is self modifying! not for copy-protection reasons, but for generic-interrupt reasons.
x86 doesn't have an INT r8 instruction, only INT imm8. So to generically call an interrupt, you have to either:
1. do a lookup to a bunch of INT 00h, INT 01h, INT 02h, INT 03h instructions, OR...
2. just rewrite your own code at runtime. overwrite the second byte of the "INT 00" instruction and bam, dynamic interrupts
But at the end of the game, it'll change your tombstone, and not save your score:
It'll call you "Software Pirate" and say you were killed by the "Copy Protection Mafia"
that's because the checksum failed. it checksums the the code segment, starting at 1000:0082 and going to 1000:4082 (16 kilobytes)
but if you apply these two patches, it'll STILL not work!
But it won't work silently. It'll pretend to work.
But at the end of the game, it'll change your tombstone, and not save your score:
It'll call you "Software Pirate" and say you were killed by the "Copy Protection Mafia"
okay, tracked it down: it's just coming from the same sector 113 as loaded in step one. Anyway, if this isn't loaded properly, we'll trigger a "Diskette/Version out of phase" error. I fix this by just never checking if it's loaded: I NOP'd that part out
but if you apply these two patches, it'll STILL not work!
But it won't work silently. It'll pretend to work.