[ILUG-BOM] [OT] How copy protection schemes are implemented

S. Krishnan sri_krishnan@[EMAIL-PROTECTED]
Wed Jul 18 23:27:03 IST 2001

There was a thread about how to protect CDs etc
against copying - basic copy protection techniques. 
When checking one of my ancient archives before
blowing it away entirely, I happened upon the
following piece of code that was written to circumvent
a basic key-disk floppy based copy protection scheme. 
I had written it to show someone how easy these
schemes were to get around (actually, some, based on
hardware hasps and self-modifying code are pretty
tough, so beware!).

I reproduce the code here for anyone who is interested
in the guts of a fairly trivial copy protection scheme
and its antidote.  The code is pretty heavily
commented, since it was in the nature of a tutorial,
so that you should not have any trouble following it
if you are at all familiar with x86 architecture and
the DOS/ BIOS system call scheme.

Old timers like me who date back to the days of the 2
x 360 KB FDD based PCs may wax nostalgic at the
mention of Central Point Software's CopyIINokey

Incidentally, although this code works, it probably
will render your PC's floppy unusable without a
reboot, since it does not do any process based
vaildation. Also, although it circumvents a copy
PIRACY!  It is intended for use as an educational
exercise for people to learn about program design and
the PC's architecture, and not as a cracker shortcut. 
I am definitely not a cracker!

Here goes:

; kundli key disk buster program
; v 1.2 coded 1.6.98
; Copyleft (sic) S. Krishnan, 1998
; This software is freely copyable and distributable
provided the above
; version and copyright info are retained in whole. 
Send your comments, 
; questions, flames et al to sri_krishnan at yahoo.com.
; You will find kundli, a multilingual MS-DOS Indian
astrology program, on the 
; infamous Installer 4 CD that is a part of every
hardware assembler's armoury.
; Incidentally, kundli is coded in MS QuickBasic.
; Written for MS-DOS and NASM; will NOT assemble under
MASM or TASM or A86
; Anyone who wants to assemble under the latter
programs will have to do a little rewriting.
; The kundli program is copy protected through a key
disk scheme. 
; It checks for a key disk in drive a: by issuing a
BIOS int 13h
; disk read using service 02h, for reading one sector.
 This sector
; presumably exists on the key disk as follows:
; Track No. 19, Sector No. 01, Head No. 0, Drive No. 0
; No. of sectors to be read: 1; results to be placed
as usual in es:bx
; The result is one word read into the buffer pointed
to by es:bx
; This word is compared with 434Bh, using a cmp
operation, as follows, 
; by the kundli.exe program:
; cmp wo ptr es:[bx], 434Bh
; jne exit
; Eureka!  If the word pointed to by es:bx !=0x434B,
then exit.
; Incidentally I got this information by disassembling
kundli.exe in
; bxd 2.6 (the BrandX debugger by Sonam S. Gyato; you
can download it
; off simtel.net if you want).
; The scheme may therefore be broken if one intercepts
int 13h, function
; 02h. If the read request for Function 02h is for
Track No. 19, Sector No.1,
; then we can be sure it is for kundli.  Hence one
performs an iret with all
; the details that the program expects, including
placing 434Bh at the
; location pointed to by es:bx.  It is also essential
to clear the carry flag,
; since a set carry flag means error, and kundli.exe
incorporates processing
; to ; check for the results of the carry flag after
the int.
; On to programming, then!

org 100h                ; align psp for com program

segment .text           ; standard for bin files under

jmp start


nokey:				; far procedure for interrupt servicing
				; named in memory of Central Point Software

cs pop	word [useraddr]		; save caller's ip return
cs pop	word [useraddr+2]		; save caller's cs

popf					; get rid of old flags

push	ax				; save caller's registers
push	bx				; -do-
push	cx				; -do-
push	dx				; -do-
push	es				; -do-

pushf					; simulate int call by pushing flags on
cs call far [old_int13]			; call the original int 13h

; after servicing the original int 13h request, our
ISR is reentered at
; this point.  First we save the old ax since int 13h
returns the results
; in ah or ax, and then restore the registers to what
they were when our isr
; was entered.  We then check to see if the call
conditions were that of
; kundli.exe : service no.2, 1 sector to be read,
track no. 19, drive 0, etc.
; if so we return with the preset reply of 434Bh, else
we jump to exit, which
; restores the ax returned by the original int 13h
isr, pushes the flags,
; caller's cs: and caller's ip: on to the stack and
executes an iret to
; return to the calling program

mov	word [cs:temp], ax		; save ax contents returned by
old int 13 call

pop	es				; restore caller's registers
pop	dx				;  -do-
pop	cx				;  -do-
pop	bx				;  -do-
pop	ax				;  -do-

cmp	ah, 02h			; cmp. al - is the request for service
jnz	exit			; no - then return to caller

cmp 	dl, 00h			; cmp dl - is request for FDD No.1
jnz	exit

cmp	ch, 19h			; cmp ch - is track no.==19h
jnz	exit

cmp	cl, 01h			; cmp cl - is sector no.==01
jnz	exit

; Now that we've come this far, it appears that the
request is indeed by the
; kundli program  Hence we stuff 434Bh into the buffer
pointed to by es:bx

mov	word [es:bx], 434Bh	; stuff the code into kundli's
disk read buffer

clc					; clear the carry flag
mov	ah, 00h				; disk read sucessful
mov	al, 01h				; 1 sector read
jmp 	far [cs:useraddr]		; return to kundli.exe with
pseudo-disk read

exit:					; normal exit if caller is not kundli.exe

mov	ax, word [cs:temp]	; restore ax returned by old
int 13 isr
pushf				; save the flags rtd. by original int 13h
push word [cs:useraddr+2]	; push caller's saved cs on
stack for iret
push word [cs:useraddr]		; push push caller's ip on
stack for iret

iret				; return to calling program

temp dw 0
old_int13 dd 0
useraddr dd 0


start:				; initialization code for loading the int

; get and save the vector for int 13h

xor	ax, ax				; set ax to 0
mov 	ah, 35h				; Int 21h function 35h
mov	al, 13h				; Int 13h vector to be obtained
int 	21h				; go for it

mov 	word [old_int13], bx		; save old int 13h offset
mov	word [old_int13+2], es		; save old int 13h segment

; next, install our new handler for int 13h

push	ds				; save data seg.
mov	ax, cs				; code seg to be loaded into ds for seg
add of
mov	ds, ax				; new interrupt handler
mov	dx, nokey			; offset of our new int 13h ISR
mov	ah, 25h				; Func. 25h for setting int. vect.
mov	al, 13h				; vector to substitute with our isr
int 	21h

pop	ds				; restore ds

mov	ah, 09h				; display line
mov	dx, msg1			; address of message
int 	21h				; sign on message

mov	ax, tsr_end
shr	ax, 4
add	ax, 01h
mov	dx, ax
mov	ax, 3100h
int 	21h		; terminate and stay resident

msg1 db '          The Kundli Buster program: written
by S. Krishnan, 1998$'
last db 0

Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail

More information about the Linuxers mailing list