COMMENT /*
Here is the code for a MBR password protection
A few remarks
- this one stealths itself, so windows 32 bits access will yell
- there is a backdoor built in for de-iinstallation
- comments are partly in french, sorry
- there is a break point to debug the MMBR loading process in our debugger
- CRTL-ALT-DEL is hooked, regardless off the national keyboard driver
- supports three users and passwords
- crashing the floppy boot is easily acchieved when you know that "circular
partitions" will crash DOS > 3 at load time
Pierre
*/
page 60,200
.286
;*************************************************************************
; sac - simple access control
; public domain version
; (c) 1995-1996 datarescue sprl
; 110, route du condroz
; 4121 neupre
; belgium
; tel : +32 41 729 110
; fax : +32 41 729 114
; bbs : +32 41 720 237
; http://www.datarescue.com
; h.carette and p.vandevenne
;*************************************************************************
; segment bidon pour un saut far
farseg segment at 00000h
org 07c00h
farlabel label far
farseg ends
;**************************************************************************
cseg segment public byte 'code'
assume cs:cseg,ds:cseg,ss:cseg
org 0000h
SECTEUR_MBR equ 0002h
ctrl equ 0100b ; pour masquer alt-ctrl-del
alt equ 1000b ; pour masquer alt-ctrl-del
buffer equ 0200h ; adresse du buffer de saisie
start: jmp short debut
passe db 39,24,20,32,18,25,16,31 ; mots de passe
db 39,24,20,32,18,25,16,31
db 39,24,20,32,18,25,16,31
ID_nom db 25,23,18,19,19,18,0,0 ; utilisateurs
db 35,18,19,47,18,0,0,0
db 32,18,38,25,35,23,49,18
login db 'Nom?',0ah,0dh,00h ; 1 er message
mdpasse db 'Passe?',0ah,0dh ; 2 iŠme message
; le z‚ro de asciiiz = flag
stealthflag db 00 ; quand ce flag est a 0
; on stealthe
debut: int 3 ; pour soft-ice
xor CX , CX ; bx = 0
mov DS , CX ; ds = 0
mov AX , DS:[0413h] ; taille m‚moire var bios
dec AX ; r‚server 1 ko
mov DS:[0413h], AX ;
shl AX , 6 ; 80x86 -> 3 octets
mov ES , AX ; segment du k r‚serv‚
mov SI , 7C00h ; offset du mbr en m‚moire
xor DI , DI ; offset z‚ro
mov CH , 01h ; 100 words
cld ; dans le bon sens
rep movsw ; on d‚place
mov AX , OFFSET ici ; offset de retour
push ES ; pousser segment de retour
push AX ; pousser offset de retour
retf ; y aller
ici: cli
; d‚tourne l'interruption 15h
LES AX , DS:054h ; offset du vecteur de l'int 15
mov CS:word ptr [adresse15h],AX
mov CS:word ptr [adresse15h+2],ES
mov DS:word ptr 054h, OFFSET int15
mov DS:word ptr 056h, CS
; d‚tourne l'interruption 13h
LES AX, DS:04Ch ; offset du vecteur de l'int 13
mov CS:word ptr [adresse13h],AX
mov CS:word ptr [adresse13h+2],ES
mov DS:word ptr 04Ch, OFFSET int13
mov DS:word ptr 04Eh, CS
push CS ; le ds est ici maintenant
pop DS ; demander id et mot de passe
mov AX , 0003h ; pour effacer l'‚cran
int 10h ;
push DS ; ds=es=ss=cs pour les cmp
pop ES ;
; (premier = 0)
mov DL , 03
push DX
next_essai: mov BP , 0002h ; nombre d'utilisateurs - 1
mov SI , offset login ; pointer le login
call printasciiz ; l'afficher
call saisie ; saisir l'id
next_ID: mov DI , offset ID_nom ; pointer les utilisateurs
call newID ; pointer nom courant
call verification ; v‚rifier id
jnc ID_OK ; pas d'erreur tout est ok
dec BP ; id suivant
jns next_ID ; ce n'est pas le cas
dec DL
jnz next_essai ; essai suivant
call hang ; arrˆt
ID_OK:
pop DX
next_essai_mdp: mov SI , offset mdpasse ; pointer passe?
call printasciiz ; l'afficher
mov DI , offset passe ; pointer les mots de passe
call newID ; pointer le mot de l'id
call saisie ; saisir le mot de passe
call verification ; v‚rifier le mot de passe
jnc tout_ok ; bon mot de passe
mov AX , 0E08h ; beep
int 10h
dec DL
jnz next_essai_mdp ; essai suivant
call hang ; arrˆt
tout_ok: xor BX, BX ; charger le mbr et l'ex‚cuter
mov ES , BX ; es = 0000
mov BX , 7C00h ; offset buffer pour int 13h
mov DX , 0080h ; disque dur 1, tˆte 0
mov CX , SECTEUR_MBR ; cylindre 0 , secteur ?
mov DI , 0004h ; nombre d'essai ( lecture )
loop_1: xor AX , AX ; ax = 0000
int 13h
mov AX , 0201h ; lecture d'un secteur
int 13h
jnc lecture_ok ; pas de problŠme
dec DI ; d‚cr‚menter le cpt d'essai
jnz loop_1 ; si pas z‚ro, alors recommencer
int 18h ; appel de la rom basic
lecture_ok: push CS
pop ES
jmp farlabel
; gestionnaire int13h
int13: cmp AH, 0CFh ; notre appel ?
jnz int13_1 ; non, on continue
not CS:byte ptr [stealthflag]; inverse le flag
iret ; retour
int13_1: cmp CS:byte ptr [stealthflag], 0 ; stealth
jnz real_int13 ; non, on laisse aller
cmp DX , 0080h ; disque c , tˆte 0
jne real_int13 ; non
test CX , 11111111000000b ; cylindre 0 ?
jnz real_int13 ; non, on laisse aller
test CL , 00111110b ; secteur 1 ?
jnz real_int13 ; non, on laisse aller
mov CL , SECTEUR_MBR ; modifier l'appel
real_int13: db 0EAh ; jmp far
adresse13h dd 0 ; adresse handler int 13
; gestionnaire int15h
int_15 proc ; nouveau gestionnaire
; de l'int 15
int15:
push AX ;
push DS ; save registers
cmp AH, 04Fh ;
jne go_ahead ;
xor AX,AX ;
mov DS,AX ;point ds to bios data area
mov AL,DS:(417h) ;get keyboard flags
and al,ctrl+alt ;clear non relevant bits
cmp al,ctrl+alt ;compare to our map
jne go_ahead ;no ctrl+alt keys pressed
and byte ptr ds:(417h),not alt ;ctrl+alt pressed
;clear alt key bit to simulate
;alt key is not pressed
go_ahead:
pop DS
pop AX
db 0EAh
adresse15h dd 0
int_15 endp
; ************* hang **********************************************************
hang proc
boucle: cli ; no interruptions
jmp short boucle
hang endp
; ************* printasciiz ***************************************************
Printasciiz proc
pusha
cld ; memory up
Print: lodsb
OR AL,AL
JZ ExitPrint ;jmp to ret instr.
call print_one
JMP short Print
ExitPrint:
popa
ret
Printasciiz endp
; ************* newid *********************************************************
newID proc
push BP ; sauver le compteur d'id
shl BP , 03
add DI , BP ; ajouter
pop BP ; r‚cup‚rer le cpt d'id
ret
newID endp
;************** saisie ********************************************************
saisie proc
xor BX , BX ; bx = 0
next_char: xor AX , AX ; lire caractŠre
push BX
int 16h ;
pop BX
mov [ buffer ] [ BX ] , AH ; stocker le caractŠre
cmp AL , 0Dh ; cr ?
jz fin_saisie ; oui
mov AL , '*' ; star
call print_one
inc BX ; next char
cmp BX , 0008 ; buffer plein ?
jnz next_char ; non, alors char suivant
fin_saisie: mov AL , 0Dh
call print_one
ret
saisie endp
; ************* print_one *****************************************************
print_one proc
mov AH , 0Eh
int 10h
ret
print_one endp
; ************* verification **************************************************
verification proc
mov SI , buffer
mov CX , 0008 ; nbr de char
repz cmpsb ; comparer buffer et id/mdp
jcxz fin_verif ; 8 char et = tous
cmp byte ptr [ SI - 0001 ] , 28 ; = jusqu'au cr ?
jz cr_only ; oui, alors tester si cr seul
iz_no_goud: stc ; non, alors erreur
ret
cr_only: cmp CL , 07 ; un char = cr ?
jz iz_no_goud ; oui
fin_verif: clc ; pas d'erreur
ret
verification endp
; *****************************************************************************
db 84 dup (01h)
db 055h
db 0aah
cseg ends
end start ;end of program