Хакерские трюки или как поставить бряк на jmp eax
Хакерские трюки или как поставить бряк на jmpeax
крис касперски ака мыщъх, no e-mailкодокопатели достаточно часто сталкиваются с необходимостью установить точку останова на произвольную машинную команду (например, jmp eax). форумы буквально пестрят вопросами, но x86-процессоры не предоставляют такой возможности и приходится действовать обходим путем, о существовании которого догадываются многие, но находит далеко не каждый
Первые шаги или установка точки останова на одну команду
Начнем с простого. Возьмем демонстрационный пример TF.exe и попытаемся брякнуться на команду PUSHFD. Загружаем программу в отладчик, в меню "debug" выбираем "set condition" или нажимаем
Рисунок 1 диалоговое окно отладчика OllyDbg, позволяющее устанавливать точки останова на произвольные машинные команды
Вводим в окно редактирования "PUSHD" (ес-но без кавычек), взводим соседствующию с ним галочку и говорим "OK". Диалоговое окно исчезает и мы возвращаемся в OllyDbg. Если теперь нажать

Рисунок 2 надпись в строке статуса, свидетельствующая о том, что отладчик работает в режиме трассировки
Если во время трассировки нажать

Рисунок 3 в режиме трассировки OllyDbg сильно загружает осевое ядро
Если вместо

Рисунок 4 анимированная трассировка в OllyDbg (в правом нижнем углу строки статуса горит "animating")
Если же вести трассировку до победоносного конца, то спустя некоторое время (определяемое в первую очередь мощностью вашего ЦП), отладчик остановится на инструкции PUSHFD (см. рис. 5). Это и есть "сердце" защитного механизма, который нам предстоит проанализировать и обезвредить.

Рисунок 5 остановка отладчика по срабатыванию точки останова на команду PUSHFD
Антиотладочный код предельно прост и укладывается всего в четыре строки (см. листинг 1):
0040100E |. 9C PUSHFD
0040100F |. 58 POP EAX
00401010 |. 25 00010000 AND EAX,100
00401015 |. 75 03 JNZ SHORT TF.0040101A
Листинг 1 антиотладочный код, основанный на чтении регистра флагов
Защита заталкивает в стек регистр флагов командой PUSHFD и тут же выталкивает его в EAX, проверяя бит трассировки логической операцией AND EAX 100h. Только никакого бита трассировки в стеке ни хрена не окажется — OllyDbg автоматически удалит его, но чтобы программа работала и под другими отладчиками, необходимо заменить JNZ на NOP/NOP или AND EAX, 100h на AND EAX, 0h.
Если немного потрассировать программу, мы выйдем из антиотладочной процедуры и попадем в довольно типичный для высокоуровневых программ машинный код, проверяющий значение, возращенное функций, с помощью пары инструкций TEST EAX,EAX/Jx (см. листинг 2):
0040102A |. E8 D1FFFFFF CALL TF.00401000
0040102F |. 85C0 TEST EAX,EAX
00401031 |. 74 0F JE SHORT TF.00401042
00401033 |. 68 30604000 PUSH TF.00406030; ASCII "debugger was not been detected"
00401038 |. E8 6C000000 CALL TF.004010A9
0040103D |. 83C4 04 ADD ESP,4
00401040 |. EB 0D JMP SHORT TF.0040104F
00401042 |> 68 50604000 PUSH TF.00406050 ; ASCII "debugger has been detected!"
00401047 |. E8 5D000000 CALL TF.004010A9
0040104C |. 83C4 04 ADD ESP,4
Листинг 2 обработка результата работы функции
Давайте попробуем установить точку останова на комбинацию команд CALL XXX\TEST EAX,EAX\JX. А вот не получается! В окно "condition to pause run trace" ясно сказано "command is one of" (одна из следующий команд), то есть если ввести "call const; test eax,eax; jСС const", отладчик будет останавливаться на _каждой_ из перечисленных команд, что совсем не входит в наши планы, но такой уж у OllyDbg синтаксис!
Кстати, о синтаксисе. Отладчик поддерживает шаблоны, позволяющие составлять простейшие регулярные выражения. Например, R32 обозначает любой 32-разрядный регистр общего назначения и "TEST R32, R32" – останавливает трассировку при выполнении команд TEST EAX, EAX; TEST ESI, EDX и т. д. "RA" – любой регистр общего назначения не такой как "RB", поэтому, шаблон "TEST RA, RA" будет останавливаться на инструкции "TEST EAX, EAX", но проскочит мимо "TEST EAX, EBX". Соответственно, "TEST RA, RB" останется равнодушным к "TEST EAX, EAX". Ключевое слово "CONST" заменяет любой непосредственный операнд, например, "MOV RA, CONST" останавливается на "MOV AL, 69h" и "MOV ESI, 666h", а "CALL CONST" – на всяком прямом вызове процедуры.
Выражение "JCC CONST" соответствует любому условному (но _не_ безусловному!) переходу по непосредственному адресу. Остальные ключевые слова перечислены в таблице 1.
|
ключевое слово |
назначение |
|
R8 |
любой 8-битный регистр (AL,BL, CL, DL, AH, BH, CH, DH) |
|
R16 |
любой 16-битный регистр (AX, BX, CX, DX, SP, BP, SI, DI) |
|
R32 |
любой 32-битный регистр (EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI) |
|
FPU |
любой регистр математического сопроцессора (ST0..ST7) |
|
MMX |
любой MMX-регистр (MM0..MM7) |
|
CRX |
любой регистр управления (CR0..CR7) |
|
DRX |
любой отладочный регистр (DR0..DR7) |
|
CONST |
любая константа |
|
OFFSET |
любое смещение (равнозначно константе) |
|
JCC |
любой условный переход (JE, JC, JNGE...) |
|
SETCC |
любая инструкция условной установки байт (SETE, SETC, SETNGE... ) |
|
CMOVCC |
любая условная пересылка (CMOVE, CMOVC, CMOVNGE...) |
Все это, конечно, замечательно и немного потренировавшись мы сможем брякаться на любой машинной команде (за исключением адресации типа mem, которую Olly не поддерживает), но нам-то нужны не отдельные команды, а сочетания _нескольких_ команд. Как быть, что делать?
Программирование шаблонов в машинных кодах
Главный недостаток поиска поКонкретно, нас будут интересовать мнемоники инструкций CALL CONST, TEST EAX, EAX и JNZ/JZ. Оттуда, мы в частности, узнаем, что команда CALL имеем опкод E8h за которым следуют четыре байта относительного адреса. Команда TEST EAX, EAX в машинном виде выглядит как 85h С0h, ну а JZ/JNZ представляются хорошо известными двухбайтовыми инструкциями 74h XXh/75h XXh, где XXh – относительное смещение адреса перехода, отсчитываемое от начала команды.

Рисунок 7 матрица опкодов машинных инструкций в электронном справочнике TECH HELP!
Обобщив все вышесказанное, можно составить выражение, срабатывающее на заданной последовательности команд. Мы будем отталкиваться от содержимого регистра EIP — если одно равно E8h, то это команда CALL const. Увеличив EIP на 5 байт (длина CALL const) мы получаем указатель на следующую команду, сверяя его с опкодом инструкции TEST EAX, EAX, равным 85h C0h или C085h с учетом обратного порядка байт в x86.
; ß CALL const à ß TEST EAX, EAX à ß JZ const OR JNZ const à
([BYTE EIP]==0E8) & ([WORD EIP+5]==0C085) & (([BYTE EIP+7]==74) | ([BYTE EIP+7]==75))
Листинг 4 выражение, устанавливающее точку останова на последовательность команд CALL const/TEST EAX, EAX/Jx const
Нажимаем

Рисунок 8 установка точек останова на последовательность машинных команд
Составлять сложные выражения непосредственно в строке редактирования очень неудобно и ненаглядно. Постоянно путаешься в скобках и забываешь, что уже написано, а что нет. Наконец, однажды написанное (и отлаженное!) выражение необходимо как-то сохранять с комментариями, что оно, собственно, делает, а всего этого OllyDbg не умеет, поэтому выражения лучше составлять в своем любимом редакторе (например, FAR'е по
Реализация ANY на языке выражений — очень сложная задача, которую можно осуществить только написав свой собственный дизассемблер длин, а это... уже настоящий монстр получается! Такие вещи лучше писать на Си и цеплять к отладчику как плагин, тем более, что исходные тексты дизассемблера распространяются вместе с OllyDbg (http://www.ollydbg.de/srcdescr.htm), а, значит, основная часть работы уже сделана за нас.
Остальное доделает… Perl. А почему бы и нет? Лучшего "движка" для составления регулярных выражений, пожалуй, и не придумаешь! Соединив Perl с дизассемблером воедино, мы получим могучий инструмент. На вход плагина подается поток команд, "добываемый" трассером OllyDbg, дизассемблер превращает его в текст, ну а Perl ищет в этом тексте все, что мы ему скажем. Маленький нюанс — для борьбы с самомодифицирующимся кодом, необходимо отказаться от опережающего просмотра вперед и анализировать только выполненные инструкции, которые OllyDbg помещает в лог трассировки, однако, это слишком амбициозные цели. Просто прикрутите Perl к дизассемблеру и наслаждайтесь возможностью устанавливать точки останова на любую комбинацию команд.
Это поможет нам обходить все антиотладочные приемы, какие только есть. Ведь любой антиотладочый прием по сути задается той или иной комбинацией машинных команд, и количество возможных вариаций достаточно ограничено. Встретившись с защитой, которая разваливает отладчик, мы находим где он гробится и добавляем этот антиотдочный прием в свой плагин. В конечном счете, получится аналог IceExt для OllyDbg только более мощный, правда, и более тормозной за счет использования неповоротливого Perl'а.
Секреты пошаговой трассировки
Отладчик OllyDbg поддерживает условные точки останова, позволяющие в том числе брякаться и на команду (чего не умеет soft-ice), но... как именно он это делает? Очень просто — трассирует программу и на каждом шаге проверяет истинность одного или нескольких условий, заданных хакером. Это очень мощный механизм (Olly зовет его "condition to pause run trace" – условие прекращения трассировки), позволяющий устанавливать точки останова на любую комбинацию команд, регистров и/или данных, однако, страдающей целой кучей побочных эффектов и ограничений. В режиме трассировке скорость выполнения программы замедляется в сотни (!) раз, к тому же факт трассировки очень легко обнаружить, чем защитные механизмы и занимаются.Среди множества антиотладочных приемов, чаще всего встречается чтение регистра флагов конструкцией PUSHFD/POP REG с последующей проверкой бита трассировки (TF) – взведен он или нет. Отладчик Microsoft Visual Studio Debugger выдает свое присутствие сразу, но OllyDbg за просто так не проведешь! Если в процессе трассировки программы он обнаруживает инструкцию PUSHFD, он очищает бит трассировки после ее выполнения, скрывая свое присутствие. Однако, этот трюк разваливает самотрассирующие программы, к тому же существуют и другие антиотладочные приемы, с которыми Olly не справляется, поэтому, защитный код приходится разминировать ### обезвреживать вручную, а для этого необходимо уметь ставить точки останова на определенные комбинации машинных команд. Атиотладочных приемов не так уж и много, они хорошо известны как хакерам и разработчикам и если только разработчики не выдумают чего-то принципиального нового (что навряд ли), мы легко победим любую защиту, какой бы сложной и навороченной они ни была.
Шаблонный поиск в дизассемблерном тексте
Нажимаем
Рисунок 6 последовательность команд, найденная OllyDbg в дизассемблерном текстеы
Теперь мы можем нажать
Оптимизирующие компиляторы могут "разрывать" стандартный шаблон, помещая между инструкциями TEST EAX, EAX другие машинные команды (см. листинг 3). Это увеличивает производительность, за счет устранения простоя конвейера, но затрудняет шаблонный поиск.
004013E4 |. E8 9F180000 CALL TF.00402C88
004013E9 |. 85C0 TEST EAX,EAX
004013EB |. 59 POP ECX
004013EC |. 8907 MOV DWORD PTR DS:[EDI],EAX
004013EE |. 75 13 JNZ SHORT TF.00401403
Листинг 3 оптимизирующий компилятор "разорвал" шаблон, внедрив между TEST EAX, EAX и JNZ две команды: POP ECX и MOV [EDI], EAX
К счастью, OllyDbg поддерживает замечательное количество слово "ANY n", позволяющее пропускать от нуля до n машинных команд. В частности, "ANY 2" эквивалентно любым двум машинным командам, любой одной машинной команде или же отсутствию команд в данном месте. Новая версия шаблона, учитывающая особенности оптимизирующих компиляторов выглядит так: "CALL CONST\TEST EAX,EAX\ANY 3\JCC CONST". Правильный выбор величины n очень важен. Слишком большое значение приведет к ложным срабатываниям, слишком маленькое — к пропуску шаблонов. По своему опыту могу сказать, что оптимальное значение — три. Не слишком больше и не слишком маленькое. Короче, три это в самый раз.
Услышав дурацкий вопрос не спешите
Услышав дурацкий вопрос не спешите давать категоричный ответ. Установить точку останова на команду все-таки возможно! Пускай, это не совсем точка останова (в традиционном понимании этого слова), зато она работает (правда, очень медленно) и это главное! Эмулирующие отладчики и программы-эмуляторы PC такие как BOCHS или QEMU открывают большие перспективы, однако, достойных отладчиков под них что-то не наблюдается, но, учитывая открытость исходного кода, такой отладчик любой хакер может написать и самостоятельно.Проблема в том, что не существует никакого "отладочного" сообщества, которое бы координировало усилия и работу разобщенного племени программистов, многократно дублирующих работу друг друга, и "концентрировало" их вокруг одного отдельно взятого отладчика. Многие хакеры пишут плагины для OllyDbg, но это закрытый проект энтузиаста-одиночки, который может забросить его в любой момент. Поддержка soft-ice уже прекращена и он обречен на медленное, но неотвратимое вымирание. Microsoft Kernel Debugger поддерживает документированный интерфейс расширений и можно надеяться, что он не погибнет в ближайшие десять лет, но лить воду на мельницу Microsoft это... Последние версии IDA Pro так же обзавелись собственным отладчиком, все еще далеким от идеала, но по крайней мере работающим.
Короче говоря, ассортимент широк, а выбирать не из чего.
Работа с информацией: Безопасность - Защита - Софт - Криптография
- Информационная безопасность
- Аспекты информационной безопасности
- Системы информационной безопасности
- Софт и информационная безопасность
- IInternet Information Services
- Защита и безопасность
- Защита с Firewall
- Атаки и информационная безопасность
- Информационная безопасность в интернет
- Борьба с вирусами
- Антивирусы против вирусов
- Хакеры и информационная безопасность
- Криптография