Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #89, МАЙ 2006 г.

Дао универсальной распаковки

Крис Касперски

Хакер, номер #089, стр. 089-114-5


Посмотрим на карту памяти еще раз:

[две секции упакованной программы]

MAP32

NOTEPAD-fsg 0001 001B:01001000 00010000 CODE RW

NOTEPAD-fsg 0002 001B:01011000 00008000 CODE RW

Мы видим две секции, принадлежащие упакованной программе. Непонятно, которая из них — секция кода, а какая — данных, тем более что должна быть еще одна секция — секция ресурсов, но коварный упаковщик каким-то образом скомбинировал их друг с другом, впрочем код самого упаковщика, как мы уже видели, сосредоточен в пространстве 10001xxh и отдельной секции для себя создавать не стал.

Чтобы отсеять лишние всплытия отладчика, мы сосредоточимся на диапазоне адресов, принадлежащих упакованной программе, то есть от начала первой секции до конца последней, автоматически контролируя значение регистра EIP на каждом срабатывании точки останова.

В данном случае это выглядит так:

["магическая" последовательность, приводящаяся нас к OEP]

bpm esp-4 if eip >= 0x1001000 && eip < 0x1011000

Невероятно, но после продолжительного молчания (а он и будет молчать, ведь стек распаковщиком используется очень интенсивно) отладчик неожиданно всплывает непосредственно в OEP!

[отсюда начинается распакованный код исходной программы]

01006420 PUSH EBP

01006421 MOV EBP,ESP

01006423 PUSH FF

01006425 PUSH 1001888

0100642A PUSH 10065D0

0100642F MOV EAX,FS:[00000000]

01006435 PUSH EAX

01006436 MOV FS:[00000000],ESP

Фантастика!!! А ведь FSG далеко не самый слабый упаковщик — фактически граничит с протекторами. Однако методика поиска OEP во всех случаях та же самая. Выделяем секции, принадлежащие упакованной программе, и устанавливаем точку останова на esp-4 в их границах. Даже если стартовый код использует оптимизированный пролог, первый же регистр вызовет срабатывание отладчика. Ничего страшного не случится, если мы не попадем в саму OEP, так как найти начало оптимизированного пролога можно и автоматом!

Таким образом, мы получаем в свои руки мощное оружие многоцелевого действия, которое легко реализовать в виде плагина к LordPE, IDA Pro или самостоятельной утилиты, о которой мы еще поговорим в будущем.

[заключение]

Вот мы и научились находить OEP. Остается самая малость — сбросить дамп программы на диск. Но здесь не все так просто, как может показаться сначала, и многие упаковщики/проекторы этому всячески сопротивляются. В следующей статье этого цикла мы покажем, как реализовать универсальный дампер, распаковывающий, в том числе и DLL, и обходящий продвинутый механизм динамической шифровки, известный под именем CopyMemII, — это когда вся программа зашифрована, и отдельные страницы памяти расшифровываются непосредственно перед их употреблением, а потом зашифровываются вновь. Также мы коснемся вопросов восстановления таблицы импорта. В итоге получится нехилый универсальный распаковщик, обходящий своих конкурентов.

[что делать, если отладчик проскакивает в распаковщике точку входа?]

Берем исполняемый файл, загружаем его в NuMega SoftICE Symbol Loader, внимательно убедившись, что горячая лампочка опции "Start at WinMain, Main, DllMain" активирована, но при попытке загрузки программы SoftICE коварно проскакивает точку входа, полностью утрачивая управление и контроль. Это известный глюк SoftICE, с которым постоянно борются. Вот только один способ: загружаем (неправленную) программу в hiew, переходим в hex-режим, жмем <F8> и вычисляем адрес точки входа путем сложения Entrypoint RVA (в нашем случае — 10001) с Image Base (в нашем случае - 1000000). Получается 1010001. Если считать лень, то можно просто нажать <F5>, чтобы hiew перенес нас в точку входа, сообщив ее адрес (однако это не срабатывает на некоторых защищенных файлах с искаженной структурой заголовка). ОК, адрес EP получен. Вызываем SoftICE путем нажатия на <Ctrl-D> и устанавливаем точку останова на любую API-функцию, которую в какой-то момент вызывает наша программа. Это может быть и GetModuleHandleA ("bpx GetModuleHandleA") и CreateFileA — неважно! Выходим из SoftICE и запускам нашу программу. Отладчик всплывает. Убедившись, что правый нижний угол отражает имя нашего процесса (если нет, то выходим из SoftICE и ждем следующего всплытия), устанавливаем аппаратную точку останова на EP, отдавая команду "bpx 010001 X", где 1010001 - адрес точки входа в PE-файл. Выходим из SoftICE и перезапускаем программу. hint: SoftICE запоминает установленные точки в контексте данной программы и не удаляет их даже после ее завершения. При повторном перезапуске SoftICE будет послушно останавливаться на EP в точке останова. Разве это не здорово?!

Назад на стр. 089-114-4  Содержание