Распаковка конверта HASP/HASP HL/HARDLOCK при наличии ключа или эмулятора

Внимание: Данная статья предназначена только для эмулирования легально купленных ключей, которые по каким-либо причинам не могут быть использованы в компьютере (отсутствие порта, его некорректная работа или занятость). Автор не несет никакой ответственности за нецелевое использование нижеизложенного материала.

Автор: s0cpy
e-mail: s0cpy.store@gmail.com

Содержание

1. Пролог.
2. Анализ подопытного файла.
3. Таблица импорта и ОЕР.
4. Таблица релоков.
5. Эпилог.


1. Пролог


Используемые инструменты: OllyDbg (by Oleh Yuschuk) + плагин для скрытия от анти-отладки (я использую Olly Advanced 1.26 beta 12 by MaRKuS TH-DJM), LordPE deluxe (by yoda) или PE Tools (v1.5.700.2005 RC6 , by NEOx/[uinC]).
Так получилось, что мне довольно-таки часто приходится встречаться с данным типом защиты, хотя при наличии ключа/эмулятора, назвать Aladdin Envelop (назову ее так, потому что ключей разных много, а суть одна, включая защиту HASP HL). Единственное что изменилось в корне между старыми и новыми версиями конверта (т.е. от версии к версии, envelop не претерпевает каких-либо существенных изменений, поэтому я и разделил версии на старые и новые) так это количество спертых функций импорта. В старых версия в спирались в основном GetProcAddress, GetModuleHandleA и ExitProcess, а в новых же версиях, разработчики из Aladdin продвинулись в этом плане ;) и стали спирать кучу функций из разных dll.
Почитав топик "И снова HASP Envelop" на CRACKL@B, честно говоря немного удивился по поводу того, что присутствует какая-то фича обнаружения OllyDbg. Когда я тока начинал пробовать распаковывать Aladdin Envelop, мне вполне хватало OllyDbg + какого-то из самых первых плагинов анти-детекта (сейчас уже и не припомню). Для интереса скачал свежую версию HASP Envelop (вроде как 11.0), посмотрел и ничего нового не увидел.
Процедура распаковки была проведена на dll-ке. Почему именно на ней, а не на exe…? Просто распаковка и того и другого ничем не отличается кроме того, что при распаковке динамической библиотеки, сразу затронем тему восстановления reloc`ов, если процедуру восстановления вообще можно так назвать… ;)

2. Анализ подопытного файла.

Итак, грузим исследуемое тело в любимый редактор РЕ. Смотрим что у нас в "Sections"…

[Скриншот]

и Directories…

[Скриншот]

EntryPoint и адреса импорта и релоков принадлежат секции .protect, ImageBase = 2A400000. По названиям секций похоже на что-то типа Microsoft Visual C++, а импорт для данного типа обычно (или всегда…?) располагается в секции .rdata. В данном случае, можно заострить внимание на RVA ExportTable (ниже объясню почему).

3. Таблица импорта и ОЕР.

Импорт.
Грузим тело в OllyDbg, включаем игнор всех эксепшенов, открываем карту памяти, ставим memory breakpoint on access на секцию .rdata нашего файлика и отпускаем OllyDbg на волю (F9)…
Тормознули на бряке…:

[Скриншот]

Смотрим в окно регистров. Адрес в регистре EAX принадлежит секции .rdata. Скажу сразу, 2A589C24 - это и есть нужный нам VirtualAddress таблицы импорта. Значит RVA=VA-ImageBase (2A589C24-2A400000=00189C24).
Дампим тело[!!!] (я использую PE Tools, настройки приведены ниже)…:

[Скриншот]

Теперь идем к ОЕР.
Убираем memory breakpoint on access с секции .rdata и ставим еe на секцию .text, отпускаем OllyDbg. Остановились…:

[Скриншот]

Ну вот собственно и ОЕР
2A54CD48-2A400000=0014CD48


4. Таблица релоков.

Открываем наш дамп в LordPE (тут удобнее именно он, потому как имеет встроенный HEX-редактор),
Адрес начала секции релоков - 001CF000. Его и прописываем в Directory Editor`е в поле RVA для Base Relocation Table и давим кнопочку Save. Осталось только определить размер этой самой Base Relocation Table.

[Скриншот]

Далее, давим кнопочку [H] напротив Relocation и скролим вниз до появления кучи нулей, ставим курсор на первый из них и смотрим внизу окошка адрес Offset: 0x001E8872. Вычисляем размер: 0x001E8872 - 0x001CF000 (адрес начала секции релоков) = 00019872. Вписываем полученное число в поле Size для Relocation. Попутно вписываем полученный ранее RVA для ImportTable, давим Save. Ну и для интереса заглядываем что же у нас с импортом --> […]…:

[Скриншот]

А там очень даже ничего… ;)
Ну и перед выходом из редактора PE, прописываем OEP, сохраняем……….
Вот собственно говоря и все…


5. Эпилог.

В этой части тутора попытаюсь дать пояснения некоторых моментов.

1) Почему нужно обратить внимание на RVA ExportTable…?
Насколько я знаю, директории импорта и экспорта лежат не далеко друг от друга (пусть знающие люди меня поправят). В разных версиях конверта, VirtualAddress таблицы импорта при срабатывании бряка на доступ к секции содержащей эту самую таблицу может появиться не только в регистре EAX, но и в других регистрах. А так же кроме нужного адреса, проскакивают и не нужные. Я считаю что тот который ближе к RVA ExportTable и есть нужный нам адрес..

2) На какую секцию поставить бряк на доступ, если не похоже на "что-то типа Microsoft Visual C++" …?
Доходим до ОЕР, ищем любой валидный вызов/прыжок в системные библиотеки, смотрим по какому адресу хранится ячейка содержащая этот валидный вызов/прыжок. Смотрим к какой из секций файла принадлежит адрес ячейки.

3) Почему дампим на первом бряке на доступ к секции импорта, а не на ОЕР…?
Все секции файла уже расшифрованы и на своем месте. Не нужно использовать ImpRec.

Ну вот кажется и все. Все вопросы на форум в топик, в ПМ или на мыло…

;) Спасибы…:

Всем авторам инструментов использованных в статье и не только.
CRACKL@B и его основателю Bad_guy`ю.
Всем , кто пишет интересные и познавательные статьи на тему RE, и тем кто дает знания на форуме и т.д.
Отдельное спасибо SSX. Это человек, никогда не отказывающий мне в помощи и просто хороший парень.

З.Ы. Просьба сильно не пинать. Это моя первая статья. Сори за возможные ошибки и неточности в тексте.

19 september 2006
s0cpy