[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
(nokey.com).

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
protection scheme, PLEASE DO NOT USE IT FOR SOFTWARE
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
(FDD)
; 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
NASM

jmp start

tsr_start:

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

cs pop	word [useraddr]		; save caller's ip return
address
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
stack
cs call far [old_int13]			; call the original int 13h
ISR

; 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
No.2
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
call
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

tsr_end:

start:				; initialization code for loading the int
vector

; 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


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






__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail
http://personal.mail.yahoo.com/



More information about the Linuxers mailing list