[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