cseg segment
assume cs:cseg
org 100h
first: jmp init
olint label WORD
old8 dd ?
newint:
push ax
push bx
push cx
push dx
push bp
push si
push di
push ds
push es
push ss
mov ah,1
xor cx,cx
xor dx,dx
int 1ah
pushf
call old8
pop ss
pop es
pop ds
pop di
pop si
pop bp
pop dx
pop cx
pop bx
pop ax
iret
init:
mov ax,3508h
int 21h
mov olint,bx
mov olint[2],es
mov ax,2508h
lea dx,newint
int 21h
mov ax,ds:[2ch]
mov es,ax
mov ah,49h
int 21h
lea dx,init
int 27h
cseg ends
end first
When time stood still
Once upon a time, when few were online, a common copy protection scheme for DOS computer games was to ask the player to enter some word from the printed manual, or a code from a table. The assumption was that disks were easy to copy, but printed materials were not, which was fairly accurate.
Sometimes the challenge was easy to bypass. Some games chose from a small set of multiple choice questions which obviously could be defeated with trial-and-error. Others would store their secret words in plaintext in the binary, which a simple utility would reveal. Yet others would always ask the same question if you held down a key as soon as the game loaded, presumably because they incremented a counter that determined the question while waiting for the first keypress.
I’m proud that to have found an easy but less trivial workaround in my early
teens. I noticed C tutorials often contained the call srand(time(0)), which
seeds a pseudo-random number generator using the system clock.
I suspected that game developers might have adopted this practice, so I wrote a Terminate-and-Stay-Resident (TSR) program that intercepted the timer interrupt (INT 8h) and set the time to midnight. In other words, it would always be midnight for the computer.
Sure enough, I’d set the date to 01-01-1981 and run my utility, and several games would ask the same copy protection question every time!
Here’s the source to W.ASM:
Hold still for a moment
Other games froze up if the clock failed to change, so I wrote a second TSR utility that also intercepted the keyboard interrupt (INT 9h). On detecting Alt-B, on the next 96 timer interrupts, it would reset the time to midnight. Since the timer interrupt went off 18.2 times a second, it would be midnight for about 5 seconds, then the clock would tick again.
A well-timed Alt-B was enough to force some of these games to issue the same challenge every time.
Here’s the source to TIMESTOP.ASM:
cseg segment
assume cs:cseg
org 100h
first: jmp init
hotkey equ 30h ;Scan code for "B"
shftmsk equ 00001000b ;Shift mask
old8 label word
oldloc8 dd ?
old9 label word
oldloc9 dd ?
count db 0
newint9 proc near
push ax
in al,60h
cmp al,hotkey
je keygood
exit9:
pop ax
jmp oldloc9
keygood:
mov ah,2
int 16h
test al,shftmsk
jz exit9
inc count
jmp exit9
newint9 endp
newint8 proc near
cmp count,0
je exit8
push ax
push bx
push cx
push dx
xor cx,cx
xor dx,dx
mov ah,1
int 1ah
inc count
cmp count,60h
jne all_done
mov count,0
all_done:pop dx
pop cx
pop bx
pop ax
exit8:
jmp oldloc8
newint8 endp
init proc near
mov ax,3508h
int 21h
mov old8,bx
mov old8[2],es
mov ax,3509h
int 21h
mov old9,bx
mov old9[2],es
mov ax,2508h
lea dx,newint8
int 21h
mov ax,2509h
lea dx,newint9
int 21h
mov ax,ds:[2ch]
mov es,ax
mov ah,49h
int 21h
lea dx,init
int 27h
init endp
cseg ends
end first
Downloads:
Tempus Fugit
A decade later, I was a PhD student studying cryptography. Although the tiny tools I built in my youth are now obsolete, I was obliged to continue thinking about exploits involving pseudo-randomness. For example:
-
Wikipedia lists prominent incidents involving pseudo-randomness, such as improper seeding leading to predictable OpenSSL keys in Debian.
-
The NSA chose the seemingly random numbers in the S-boxes used in the DES cipher. Years later, differential cryptanalysis was (publicly) discovered, and DES was surprisingly resistant thanks to these choices, though it remains unknown if DES is weakened in some other way.
-
The NSA chose mysterious constants for Dual_EC_DRBG, but this time it was clear they intended to insert a backdoor.
-
The NSA chose mysterious constants for elliptic curves in NIST, ANSI, and other standards. Jerry Solinas claimed they were seeded by the SHA1 hash of an ostensibly innocent phrase such as "Give Bob and Jerry a raise", but forgot the details. There’s now a $12000 prize for finding it.
-
Random constants for things like hash algorithms should be nothing-up-my-sleeve numbers.