Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #57, АВГУСТ 2005 г.

Крутой протектор – не беда

Ms-Rem (Ms-Rem@yandex.ru)

Спецвыпуск: Хакер, номер #057, стр. 057-056-3


void Set2kSyscallHook()

{

TIdt Idt;

__asm

{

cli

sidt [Idt]

mov esi, NewSyscall

mov ebx, Idt.Base

xchg [ebx + 0x170], si

rol esi, 0x10

xchg [ebx + 0x176], si

ror esi, 0x10

mov OldSyscall, esi

sti

}

}

Для многопроцессорных систем, в том числе для процессоров Hyper Threading, этот код существенно усложняется, но рассматривать его сейчас не будем. Если интересно, залезь в исходники IceExt.

Адрес обработчика sysenter вызова определяется содержимым 32-битного MSR-регистра с номером 176h. Читать или записывать в такие регистры мы можем с помощью команд RDMSR/WRMSR, предварительно поместив в ECX номер регистра, а EAX используя как источник или приемник нового значения. Код, перехватывающий обработчик sysenter, будет выглядеть примерно так:

void SetXpSyscallHook()

{

__asm

{

mov ecx, 0x176

rdmsr

mov OldSyscall, eax

mov eax, NewSyscall

wrmsr

}

}

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

Что ж, с методами перехвата разобрались. Осталось научиться бороться с ними. Тут все очень просто. Нужно определить адреса оригинальных обработчиков и самостоятельно пропатчить SDT, убрав перехват, либо заменить участок кода, измененный при сплайсинге, аналогичным участком из оригинального файла ядра системы (ntoskrnl.exe). При этом ты можешь столкнуться с проверкой наличия перехвата протектором, и если ты не знаешь, как бороться с такими вещами, значит, тебе рано браться за ring0-проекторы - потренируйся лучше на аспаке.

Второе, с чем ты обязательно столкнешься в ring0-протекторах - это перехват отладочных прерываний (int 1 и int 3). Этот прием не дает нам трассировать код в отладчике и ставить бряки. Реакция защит на срабатывание этих прерываний банальна - синий экран! Нужно что-то делать с этим, если ты хочешь пользоваться отладчиком.

Если отладочные прерывания просто заблокированы, но не несут при этом никакой смысловой нагрузки, то можно восстановить их оригинальные векторы, отключить проверки целостности перехватов (если они будут) и радоваться жизни. Но, к сожалению, в современных протекторах отладочные прерывания не просто вырублены, а используются для какой-либо работы, без которой защищенная программа функционировать не будет. Здесь есть три варианта: 1) перевести протектор на другие прерывания; 2) перевести отладчик на другие прерывания; 3) заставить и протектор, и отладчик работать на общих прерываниях.

В первом случае нужно разобраться в том, как протектор использует отладочные прерывания, и попробовать заменить их другими, не конфликтующими с отладчиком. Например, если в коде протектора встречается int 1, то заменим его на int 20 и модифицируем вектор 20 прерывания так, чтобы он указывал на обработчик протектора, после этого int 1 можно будет использовать для отладчика.

Второй подход несколько сложнее, так как аппаратная трассировка и точки останова работают только на стандартных отладочных прерываниях. Поэтому нам придется писать плагин к SoftIce'у, который будет вешать всплытие отладчика на свободное прерывание (например 20), а при установке бряка будет пихать в код не CC, а СD20.

Назад на стр. 057-056-2  Содержание  Вперед на стр. 057-056-4