JIT SPRAY ÃÂÃÂÃÂÛØ× TDSS - Xakep Online
JIT SPRAY ÃÂÃÂÃÂÛØ× TDSS - Xakep Online
JIT SPRAY ÃÂÃÂÃÂÛØ× TDSS - Xakep Online
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
MALWARE<br />
невыявляем путем сканирования памяти, поскольку ее модификация<br />
здесь не происходит.<br />
int SetDebugBreak(FARPROC address)<br />
{<br />
int status = -1;<br />
HANDLE thSnap = CreateToolhelp32Snapshot(<br />
TH32CS_SNAPTHREAD, NULL);<br />
THREADENTRY32 te;<br />
te.dwSize = sizeof(THREADENTRY32);<br />
Ïåðåõâàò IAT - íîðìà<br />
целевого приложения в памяти и заменить целевой адрес функции в IAT<br />
адресом hook-функции. Тогда, когда перехватываемая функция будет<br />
вызвана, твоя hook-функция будет выполнена вместо первоначальной<br />
функции. Чуть более редкий вариант, встречающий в природе, реализованный<br />
по приниципу «Если гора не идет к Магомеду...» — перехват<br />
Export Address Table (EAT), когда патчится, наоборот, таблица экспорта Dll,<br />
которая экспортирует целевую функцию.<br />
STELTH-ÕÓÊÈ: ÏÎÉÌÀÉ ÌÅÍß,<br />
ÅÑËÈ ÑÌÎÆÅØÜ<br />
Как я уже писал выше, главный недостаток вышеуказанных методов<br />
перехвата — это вынужденная модификация памяти, что неизбежно ведет<br />
к ее детекту со стороны аверов. Есть ли выход? Как ни странно, есть. Даже<br />
два. Первый из них — это зарегистрировать свой обработчик исключений,<br />
затем добиться, чтобы он получил управление. Это можно сделать,<br />
например, потерев какой-либо участок памяти. Второй способ представляет<br />
собой несколько видоизмененный первый. То есть, ты, как и раньше,<br />
регистрируешь обработчик исключений, но для их генерирования ты<br />
используешь прием, известный среди дебаггеров. Как ты знаешь, дебагрегистры<br />
процессора используются для отладки приложений и доступны,<br />
как правило, из кернелмода. Однако их можно устанавливать и из юзермодных<br />
приложений путем использования функций GetThreadContext/<br />
SetThreadContext. Используются дебаг-регистры для установки точек<br />
останова (Breakpoints) на доступе к участку памяти или исполнении.<br />
Всего имеется восемь регистров, их назначение следующее:<br />
• DR0 - DR3 — Каждый из этих регистров содержит линейный адрес одной<br />
из четырех контрольных точек. Если подкачка страниц разрешена, то их<br />
значения транслируются в физические адреса по общему алгоритму;<br />
• DR4 - DR5 — Регистры зарезервированы и в процессоре i486 не используются;<br />
• DR6 — Отладочный регистр состояния. Он сообщает об условиях, выявленных<br />
во время генерирования отладочного исключения (номер 1). Биты<br />
регистра устанавливаются аппаратно, а сбрасываются программно;<br />
• DR7 — Регистр задает вид доступа к памяти, связанный с каждой контрольной<br />
точкой.<br />
Итак, все, что тебе нужно сделать — это установить хардварный бряк<br />
(hardware breakpoint, он же int 1) на начало функции, чтобы процессор<br />
сгенерировал так называемое «одношаговое исключение» (single step<br />
exception) и затем, путем установки своего обработчика исключения:<br />
AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_<br />
HANDLER)DebugHookHandler), ïåðåõâàòèòü ýòîò ñàìûé<br />
EXCEPTION_SINGLE_STEP.<br />
При его генерации твой обработчик получит управление желанной функцией.<br />
Несомненное достоинство такого метода в том, что он абсолютно<br />
088<br />
}<br />
Thread32First(thSnap, &te);<br />
do<br />
{<br />
if(te.th32OwnerProcessID != GetCurrentProcessId())<br />
continue;<br />
HANDLE hThread = OpenThread(<br />
THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);<br />
CONTEXT ctx;<br />
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;<br />
GetThreadContext(hThread, &ctx);<br />
if(!ctx.Dr 0)<br />
{<br />
ctx.Dr0 = MakePtr( ULONG, address, 0);<br />
ctx.Dr7 |= 0x00000001;<br />
status = 0;<br />
}<br />
else if(!ctx.Dr1)<br />
{<br />
ctx.Dr1 = MakePtr( ULONG, address, 0);<br />
ctx.Dr7 |= 0x00000004;<br />
status = 1;<br />
}<br />
else if(!ctx.Dr2)<br />
{<br />
ctx.Dr2 = MakePtr( ULONG, address, 0);<br />
ctx.Dr7 |= 0x00000010;<br />
status = 2;<br />
}<br />
else if(!ctx.Dr3)<br />
{<br />
ctx.Dr3 = MakePtr( ULONG, address, 0);<br />
ctx.Dr7 |= 0x00000040;<br />
status = 3;<br />
}<br />
else<br />
status = -1;<br />
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;<br />
SetThreadContext(hThread, &ctx);<br />
CloseHandle(hThread);<br />
}<br />
while(Thread32Next(thSnap, &te));<br />
return status;<br />
ÇÀÊËÞ×ÅÍÈÅ<br />
Как ты видишь, даже в самых сложных ситуациях можно найти возможность<br />
исполнить свой код. Уверен, что при этом твой код нацелен исключительно<br />
на решение задач по защите твоей системы. Удачи тебе и удачного<br />
компилирования! z<br />
XÀÊÅÐ 09 /140/ 10