R0 CREW

Скриптиз в летнюю ночь

Автор: AbreC (special for r0 Crew)
Уровень: Для всех
Программа:
Размер инсталлятора: 2,08 МБ (2 189 373 байт)
Инструменты: OllyDBG, DiE, PeiD, ResHacker, DLL Export Viewer

Введение

Наконец-то нашел несколько свободных минут на свободное творчество.

Мог бы конечно сидеть рисовать, или там программки сочинять, но все это не так интересно. Иногда хочется большего. Хочется похачить чего-нибудь, по решать сложненькие задачки, отточить зубики, собаку съесть на каком-то деле и т.д.

И вот, на этот раз мои руки поднялись на одну прогму, которая была замечена мной несколько лет назад.

А все из-за того, что она очень хорошо подходит для всяких экспериментов.

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

Здесь же я не буду прямолинейно и неотступно (как это часто бывает) ломать программу одним самым правильным путем, а буду всячески извращаться, показывая, что можно делать стандартным средствами ОС. Буду показывать, что не всегда обязательно полностью вскрывать защиту (что потребует очень глубоких знаний) — иногда достаточно ограничиться несколькими простыми шажками (что под силу даже начинающим) и пользоваться плодом почти без ограничений.

Вопрос
По своему обыкновению, я приведу вопрос, который возможно задает себе каждый из Вас, читателей, смотря на эту статью:

Если Вы немец — это приказ!
Если Вы американец — это патриотично!
Если Вы японец — это повышает потенцию!
А если Вы русский (или из СНГ) — Вам запрещено это читать!!!

Перенос на виртуальную машину
Чтобы не рисковать различными частями своего молодого тела (угадайте от кого) я решил перенести инсталлятор на виртуальную машину. Впрочем, я всегда так делаю. И Вам советую.

На первый взгляд, не должна работа инсталлятора зависеть от того, где конкретно она работает, на реальной машине или нет. Но этот инсталлятор (самый странный из всех, что я видел за свою жизнь) иногда выдает странные сообщения.

Если при установке выдается такое сообщение:

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

Если же все равно выдается сообщение, то можете посмотреть главу “Установка под дебаггером”.

Установка под дебаггером
Если Вы читаете эту главу, значит у Вас инсталлятор отказывается работать. Что ж, читайте далее - мы Вам поможем =)

Нас смущает сообщение, которые выводится посредством API-функции MessageBox, но в user32.dll их несколько. Разнятся они тем, что одни работают с кодировкой ASCII, а другие с UNICODE.

По логике, это сообщение вообще не должно появляться (по крайней мере, у меня), но…

Ведь нужна какая-то проверка, которая в зависимости от результатов выдавала бы это сообщение.

Вот эту проверку мы должны с Вами найти.

А на проверку можно выйти двумя способами: либо поставить бряк на функцию и прыгая по ретурнам вернутся на вызывающий код, а вместе с тем найти процедуру проверки, либо, начиная с точки входа гонять программу кнопкой F8 до тех пор, пока не вылетит сообщение. Как вылетит сообщение - записываем адрес вызывающего кода (это будет CALL) в блокнот (или еще куда-нибудь), перезапускаем прогму, ставим бряк на предыдущий адрес, заходим в него кнопкой F7 и уже внутри него опять искать вызов сообщения, записывать адрес, перезапускать ставить бряк и так до полного садо-мазо :grin:.

Первый вариант лучше. Я делал и так и эдак. Решайте сами. Здесь же я буду описывать первый вариант =)

Для начала давайте проверим, запакован ли чем-нибудь инсталлятор.
Я попробую проверить посредством D.i.E и PEiD.

Вот что они мне поведали:

D.i.E

Compiler: Borland Delphi [ver: x] | Object Pascal
Heurestic: UPX 1.20
Status: UPX v0.89.6 - v1.02 / v1.05 -v1.22 (Delphi) stub
PEiD

UPX 0.89.6 - 1.02 / 1.05 - 2.90 (Delphi) stub -> Markus & Laszlo [Overlay]

Короче говоря, имеем дело с простейшим пакером - UPX.

Можно сразу тем же Юпиксом распаковать инсталлер, но я не буду этого делать.

Итак, загужаем прогму в Олю и наблюдаем следующую картину (у Вас будет нечто аналогичное):

Прокручиваем листинг немного вниз и видим последний JMP перед нулями. Это и есть так называемый “Magic Jump” - волшебный прыжок. Прыгает он на точку входа распакованного кода инсталлятора, а весь код перед этим джампом - код распаковщика (т.е. код UPX’а).

Ставим бряк на этот волшебный прыжок (нажатием F2 или двойным кликом по коду).

Запускаем нашу программу и ждем остановки на бряке.

Видим картину:

Дальше жмем один раз F7 и мы на точке входа.

Так как дальше мы будем иметь дело с только что распакованным кодом, анализ которого отладчиком не проводился, мы многого просто не увидим.

Чтобы облегчить себе жизнь жмем CTRL+A или же RMB --> Analysis -->Analyse Code.

Анализ проведен - можно мутить дальше.

Сейчас самое время ставить бряки на наши функции.

Для этого (как обычно) пользуясь меню, панелью инструментов или же комбинацией ALT+E открываем окно “Executable modules”.

Здесь находим библо user32.dll, ставим на него курсор и жмем CTRL+N или же RMB --> View names.

В окне “Names in USER32” можно сразу с клавиатуры набрать “MessageBox” для нахождения функций.

Таких функций здесь несколько. Я не знаю, какой из них используется, поэтому решил поставить бряк на четырех:
MessageBoxA
MessageBoxExA
MessageBoxExW
MessageBoxW

Бряки ставить просто - ставишь курсор на функцию, жмешь F2.

Теперь можно запускать программу. Жмем F9.

Заработал первый бряк — MessageBoxA.

Остальные бряки можно убирать.

Дальше жмем ALT+F9 дабы выйти на код программы.

Выводиться сообщение. Нажимаем ОК чтобы закрыть его.

Ага, теперь мы на одну команду ниже (в Оле) кода, вызывающего MessageBoxA.

Здесь правильно будет осмотреться на предмет наличия какой-нибудь проверки. В общем, ищем какой-нибудь Jxx, который мог бы перепрыгнуть вызов функции.

Искать надо вверх до ближайшей конструкции RETN. Надеюсь, вы и сами это знаете.

Как видите, никаких джампов здесь нет. Значит проверка где-то в другом месте.

Нажимая на F8 налетаем на RETN 4 и вылезаем на код “верхнего уровня”:

Здесь также ищем прыжки, но не находим… Опять не здесь.

Ладно, продолжаем жать на F8.

По адресу 0043F567 у меня есть инструкция RETN, которая выкинула меня на код еще выше.

Здесь еще раз осматриваемся… И находим чуть выше прыжок JE, который как раз может перепрыгнуть вызов.

Прыжок этот у меня находится по адресу 004274C4. Я записал этот адрес в блокнот - он еще пригодится (еще бы ;-)).

Как Вы сами понимаете (а если нет, можете попробовать) дальше трассировать прогму не имеет, смыла - она просто закроется.

Поэтому заново открываем эту же программу, ставим также бряк на волшебном прыжке и прыгаем на точку входа.

Еще раз анализируем и ставим бряк на тот джамп, который мы долго искали.

Повторюсь, это у меня:
004274C4 JE SHORT 004274D7

Ставим бряк, и жмем F9.

Отладчик брякнулся, теперь меняем инструкцию JE на JMP. Делается это двумя кликами по инструкции.

А теперь еще раз жмем F9, дабы запустить программу и устанавливаем =)

Но те тут-то было! У меня выскочило сообщение:

А потом еще и:

---------------------------
???

I/O error 145

ОК
---------------------------

И закрылся инсталлятор…

Ладно. Еще раз открываем инсталлятор в отладчике, еще раз проводим предыдущие процедуры, но на этот раз после замены JE SHORT 004274D7 на JMP не запуская программу, а нажимая только F8 найдите вызов, который отвечает за сообщение “Expression evaluation error”.

Вы можете избежать этот вызов разными способами. Лично я просто ее перепрыгнул =) Можно затереть NOP’ами - дело Ваше.

А теперь запускаем прогму на выполнение и спокойно устанавливаем.

В конце у меня выдало следующее:

---------------------------
???

I/O error 145

ОК
---------------------------

Ну, не проблема. Запускаем еще раз инсталлятор (уже не под отладчиком), выбираем пункт Repair и жмем Next.

Во и все.

Показ ограничений
Раз уж программа установлена, грех не посмотреть на ее ограничения. Запускаем программу и видим большой наг с инфой о том, сколько нам осталось юзать триал.

Это было первое ограничение.

Теперь в меню Help --> Contents смотрим справку, а вернее ищем инфу об ограничениях, наложенных на программу.

Я нашел их (ограничения) в разделе “Trial Versus Registered”:

В том же разделе говорится о полнофункциональности триалки. А это очень хорошо =)

А тем, что из Вас не сильны в буржуйском, я объясню доходчивее.

Вот это и есть “a trial notification screen upon startup”:

Вот и “a message stating you are running in evaluation mode in the main window title bar”:

А вот “a screen on exit” я не видел…

Зато видел кое-что больше - сейчас покажу:

Запускаем нашу программу и выполняем:
File --> New --> Batch file (bat)

В окне пишем любой скрипт. Я написал следующее:

И сохранил под именем:
C:\Documents and Settings\AbreC\Мои документы\PAUSE.BAT

А потом скомпилировал как:
C:\Documents and Settings\AbreC\Мои документы\PAUSE.EXE

Запустил и увидел вот что:

Потом делаем вот это:
File --> New --> HTA file

Пишем какой-нибудь код. Например:

Сохраняем. У меня это:
C:\Documents and Settings\AbreC\Мои документы\INDEX.HTA

Компилую и получаю:
C:\Documents and Settings\AbreC\Мои документы\INDEX.EXE

Запускаю и вижу:

Кроме того, по команде Help --> About можно увидеть еще кое-какие неприятные вещи.

Вот такие вот ограничения… Может я что-то упустил? Если так, то напишите - вместе рассмотрим =)

Постановка задачи
Теперь, когда мы рассмотрели основные ограничения прогмы, мы можем составить план по их преодолению.

План:

  1. Сносим “[…]a trial notification screen upon startup[…]”;
  2. Прячем “[…]a message stating you are running in evaluation mode in the main window title bar[…]”;
  3. Убираем прочие “[…]You must purchase the software to remove this[…]”.

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

Первая задача может быть решена загрузчиком, который будет запускать подопытную программу, искать наг-скрин и закрывать его.
Вторую задачу вроде тоже можно списать на загрузчик.

Нужно записать на листочек хэндлы лэйблов на эбаутБоксе, затем вставить в код на лету пару СендМесиджей скрывающих эти самые лэйблы.

Затем записать все изменения в формате РискПроцПатчера.

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

Но загрузчик оставим программистам, а мы займемся исследованием прогмы.

Зайдем в папку установки.

У меня это:
X:\bin</B>

Сразу можно заметить папку UPX. Переименовав эту папку или удалив можно лишить “компилятор” способности к сжатию своей “продукции”.

Я переименовал сам экзешник (upx.exe --> bak_upx.exe).

У меня стоит 7-zip, которым я обычно исследую непонятные файлы. Этот архиватор поддерживает не только различные форматы архивов, но и позволяет просматривать внутренности PE-файлов (а может и ELF и прочих - не проверял).

Так, порывшись в ресурсах некоторых исполняемых (и не очень) файлов, я обнаружил носитель текстов “нехороших сообщений”:

Можно сразу поправить файл, дабы “зарегистрировать” прогму. Каждый решает сам. Мое решение было такое - не трогать библиотеку, а написать свою и скопировать туда ресурсы (чтобы не модифицировать ПО и не нарушать закон).

Смотрим на экспорт библиотеки:

Как Вы видите, экспортируется только одна функция. Посмотрим на функцию в отладчике:

Таким образом, функция возвращает указатель на UNICODE-строку.

Написание библиотеки
Не скажу, что то, что я написал (код ниже) полностью соответствует действительности, но... это избавляет меня от некоторой ответственности.

Библиотеку написал на fasm’е:

Скомпилировал…

Какая-никакая, но библиотека :grin:

Подсунул это дело программе, но та не запустилась в полной мере… хотя пыталась… Угадайте, чего ей не хватало для полного счастья?

Копирование оригинальных ресурсов
Может Вы угадали, а может быть и нет - уже не важно.

Ответ: Не хватало ресурсов.

Мне всегда было интересно, какая прогма используется чаще: ResHacker, Restorator или PE Explorer.

Долгое время я пользовался только первым, потом ощутил кое-какие недостатки (нельзя сохранить все ресурсы в один res-файл) и SDI-интерфейс (а может еще что-то, не помню). Пришлось пересаживаться на второй. Второй не справился с починкой ресурсов (грубо говоря) одной программки после АсПака - пришлось юзать последнюю прогму.

Вот такая история.

Но потом обнаружилось, что ResHacker не такой простенький, как казался. Потом сами увидите:

Оригинальный english.dll переименовал в _english.dll

Свою библиотеку подставил вместо оригинальной

Закинул всю папку ResHacker в папку X:\bin

Будучи заядлым скриптизером, замутил следующее:

Опять я за свое:

Запустил командную строку из рабочей папки и выполнил скриптики:

В результате все ресурсы оригинальной библиотеки перекочевали в мою.

Запустил программу - все работает. Надо же =)

Для чего я все это делал?

Для того чтобы наконец добраться до ресурсов и “зарегистрировать” программу.

Не буду дальше обсуждать эту тему, ибо нахождение нужных ресурсов и их правка - задача очень простая.

Покопавшись в ресурсах, я решил все поставленные выше задачи, кроме…

Реверс компилятов
Заменой надписей/подписей и прочей байтщины дело не кончилось - компилированные скрипты (далее компиляты) все НАГлеют и НАГлеют.

Много ли я писал скриптов, мало ли, но таки пришел к выводу, что на моей машине (виртуальной) компиляты содержат условные прыжки по адресам:
0040B263
0040B2b8

Конечно, изучив работу программы я узнал, что можно раз пропатчить кое-какие файлы и оставшуюся жизнь получать компиляты без всяких нагов, но уже говорил, что по возможности не буду трогать компоненты ПО.

Не лишним будет объяснить Вам, что и как я собираюсь сейчас делать.

Решено мною подменить upx.exe на свою прогму, которая сразу патчила компилят, а потом, быть может, еще и запускал настоящий ЮПИКС со всеми вытекающими отсюда последствиями.

Необходимо узнать какие вообще параметры получает ЮПИКС при запуске.
Для этого сделал подмену upx.exe прогмой msswchx.exe из %systemroot%\system32</B> и попытался скомпилировать скрипт:

Как Вы можете видеть, параметры командной строки выводятся в заголовке сообщения.

Вместо msswchx.exe можно подставить и что-нибудь другое, ну а я предпочитаю делать так.

ЮПИКСу передается только имя файла на паковку и ничего больше. Чтобы применять к паковщику какие-либо опции, девелопер заботливо оставил upx_options.txt в папке с программой - может кому и пригодится.

Когда я начал писать эту статью, я пообещал себе, что в ней будет как минимум пара другая настоящих хаков.

Первый хак - просмотр внутренностей PE-файлов 7-zip’ом.

Второй хак - скрипты для ResHacker. Не в том смысле, что это никому не известно, а в том, что лично мне не было известно о возможности сохранения всех ресурсов в res-файле (для этого я пользовался Restorator). Видимо, недочитал документацию. Чтож, будем знать.

Третий хак - это то, как я сейчас собираюсь патчить компиляты.

Я решил не качать какие-то специализированные утилиты для патчинга, а воспользоваться стандартными средствами ОС.

Для начала небольшой план действий:

  1. Перехватываем имя скомпилированного файла при передачего его в качестве параметра UPX;
  2. Проверяем, в каком месте компилята затаился наш условный прыжок;
  3. Меняем условный прыжок на безусловный и сохраняем изменения.

Сидеть, смотреть по каким адресам какие оптокоды висят, писать скрипты для проверки, изменения и прочьего дело не легкое. По крайней мере убивает кучу времени. Посидев пару десятков минут над отлаживанием скрипта-патча я решил избавиться от одной трудности.

Вместо того, чтобы изменять несколько байт в коде компилятов, я решил изменить лишь одну.

В результате вместо того, чтобы условный прыжок менять на безусловный, я просто подменил само условие проверки.

TEST EAX, EAX поменял на TEST ECX, ECX

Если EAX пустовал (а он пустовал), то TEST устанавливал Zero-флаг, после чего JNZ не перепрыгивал НАГлый код. А ECX редко когда пустует…

Подкорректируем план:

  1. Перехватываем имя скомпилированного файла при передачего его в качестве параметра UPX;
  2. Проверяем, в каком месте компилята затаился наш TEST EAX, EAX;
  3. Меняем TEST EAX, EAX на TEST ECX, ECX и сохраняем изменения.

Первое - проще простого.

Второе - надо написать скриптик, который будет проверять диапазон B262-B2B7 на наличие TEST EAX, EAX. Результат выносим в файл.

Третье - выдираем адрес из файла и… правим код по этому адресу, пишем лог.

Пока писал статью, я несколько десятков раз переписывал патч, что-то удалял, что-то добавлял, объединял и, в конце концов…

Философствовать по поводу, как и почему больше не буду - и так дело затянулось. Привожу свой скрипт:

Данному скрипту достаточно передать имя компилята чтобы лишить последнего НАГлости.

На счет кода - я специально не стал ничего комментировать, ибо это подогреет Ваш интерес (надеюсь) и заставит немного поломать голову.

Здесь нет обработки исключений или еще чего-то, что могло бы сделать код более устойчивым - это минимальный рабочий вариант, но уверяю Вас, в коде достаточно интересных моментов.

В конце концов, в любой момент Вы можете все это изменить в свою пользу =)

Можно скомпилировать этот скрипт, обработать патчем и переименовать в upx.exe.

После этого Ваша “регистрация” будет за-вер-ше-на!

Заключение
Эххххх... Чего бы сказать в заключении? Конечно, хочется сказать, что данная тема весьма и весьма обширна и я не смог, имхо, описать даже половину из того что собирался. Но я и не собирался все разжевывать и разносить по полочкам - моя цель заставить Вас шуршать мозгами в некоторых направлениях, показать, что стандартными средствами ОС тоже можно что-то сделать.

Возможно я маньяк-скриптизер =) Да, я не отрицаю, но это же интересно!

AbreC © r0 Crew

P.S. Оу, чуть не забыл - архив прилагается =)

СКАЧАТЬ

Пароль на архив (base64):
aGFwcHlfYmlydGhkYXlfMl9V

Отличная статья! Молодец! Я уж было подумал, что мы в этом месяце статей ни от кого не увидим. Продолжай в том же духе! good

Offtop

Завтра дам доступ к нашему ФТП, для файлов к статьям и личного пользования.

Не смотря на время года, большинство форумчан работает и… похоже, что в “усиленном” режиме.

Времени реально нет…