Всем привет. Сегодня займёмся Delphi, а точнее одним её компонентом.
Исключительно в целях повышения образованности ;-)
Понадобилось тут для одной программки создать стиль - и вспомнил, что как то давно использовал alphaControls, довольно удобная штука. Пошёл на офф-сайт alphaControls, скачал версию 17.1, установил и получаю
при загрузке проекта в IDE и при запуске скомпилированной программы. Компонент перестал быть бесплатным. Понятно - что человек трудился и достоин вознаграждения за довольно удобный компонент, но автор гражданин украины, а оплата в ту сторону может быть превратно истолкована. По этому мы от-патчим триальные сообщения. Достаточно много статей описывающих исправление своей скомпилированной программы отладчиком уже после сборки, но мы пропатчим исходники и будем собирать программы не требующие пропатчивания. Понадобятся X64Dbg , hex-редактор и скорее всего обойдёмся без - IDA, так как IDA Free 8 отказывается открывать что либо кроме экзешников.
Установили alphaControls по инструкции из Install.txt.
Пусть файлы компонента находятся в c:\Program Files (x86)\Embarcadero\acnt\
После установки компонента в radStudio - заменяем (всё в acnt содержимым из acnt_dx11alexandria_x64.zip - не обязательно), а содержимое c:\Program Files (x86)\Embarcadero\acnt\DX11Alexandria\ содержимым из acnt_dx11alexandria_x64.zip\DX11Alexandria_x64\ иначе приложения x64 с alphaControls не собирались.
Запускаем IDE и наблюдаем "триальное сообщение", создаём тестовый проект. Кидаем на форму AlphaTools\TsSkinManager , накидываем какие нибудь alphaControls - компоненты. В свойствах sSkinManager1 в SkinName выбираем тему оформления и убедимся - что в SkinDirectory верный путь к папке со скинами. Собираем проект. И при его запуске тоже наблюдаем триал-сообщение.
Посмотрим на КОТд вблизи. ;-)
Чтобы добраться до кода триал-сообщения, нам понадобится обойти isDebuggerPresent. Можно установить в x64Dbg плагин ScyllaHide и не париться, а можно в целях практики обезвредить isDebuggerPresent вручную. Запустим сначала приложение , а потом присоединимся x64Dbg. Иначе мы не найдём динамически загружаемые isDebuggerPresent. Присоединились, на вкладке карта памяти мышкой по секции кода (в секциях нашего приложения) - она же .text , перейти к дизассемблерному коду.
Там Поиск в->Все пользовательские модули->Межмодульные вызовы , на вкладке Ссылки в строке поиск пишем isDebuggerPresent и получаем три результата. Поставим бряки на все, в параметрах X64Dbg укажем останавливаться на точке входа и перезагрузим приложение в отладчик уже нормально.
Адреса на скриншотах могут меняться ввиду перезагрузок.
Запустим выполнение и посмотрим какие вызовы проходят и сколько раз.
Один раз вызывается самая нижняя mov qword ptr ds:[C4BB88],rax , а далее несколько раз вторая
call qword ptr ds:[<&IsDebuggerPresent>] | <--
jmp project1.BACC98 |
mov al,1 |
add rsp,28 |
ret | ->
после возврата из которой попадаем на проверку
call <project1.sub_BACC80> | call IsDbg (вызывает код описанный выше)
test al,al | <- проверка
jne project1.BA00EE | <- запудривание мозга
И так как isDebuggerPresent оставляет в ax единицу - то jne любезно нас уводит в сторону от реального кода. Поставим на jne бряк в качестве метки и деактивируем его. Если jne занупать, всё встанет на свои места. Всё это и другие антиотладочные приёмы, исправляют антиАнти-отладочные плагины вроде ScyllaHide. Сохраняем исправленное приложение и открываем его в X64Dbg.
Находясь на точке входа, Поиск в->Все пользовательские модули->Ссылки на строки и в строке фильтра Поиск: пишем Trial
Находим два результата.
поставим бряк на втором и запустим выполнение и остановимся тут
lea rcx,qword ptr ds:[5D018C] | <- загружает строку "Trial version of "
call project1_2.5DCC00 | вызов триал-сообщения |
а выше - наблюдаем переходы, красная стрелка указывает на переход ведущий нас к триал-сообщению, оранжевые стрелки - проверки каких то условий - при которых сообщение не будет выводится, они обходят его, а значит - если в строке с красной стрелкой написать безусловный переход на адрес от оранжевых стрелок, то сообщение выводится не будет.
А ещё выше видим нупы (nop) синяя стрелка, это занупленный нами ранее переход isDebuggerPresent
и он как не странно обходил триал-сообщение - но только под отладчиком. И если бы мы исправили его на безусловный переход - то обход триал сообщения был бы пропатчен раньше, но тогда мы не знали этого ;-) Но нас интересует не пропатчивание приложения а сама структура кода.
Запустим каким нибудь файловым менеджером (тотал) - поиск файлов в c:\Program Files (x86)\Embarcadero\ содержащих текст ( Trial version of the AlphaControls ) в кодировке UTF-16 Тотал выдаст два результата : sCommonData.dcu и sConst.dcu находящиеся в папке ..\DX11Alexandria\
Нам понадобится плагин x64Dbg SigMake для определения уникальности куска кода ( сигнатуры ) для поиска, скачали, установили. Откроем наше не патченное от isDebuggerPresent приложение , перейдём на бряк с jne и выделим часть кода как на скриншоте, начало - строкой выше нашего jne и три строки после него.
Теперь в меню Модули->SigMake->Create signature и в окне SigMake Scan . Если в статус строке результат Found 1 reference - значит выбранный отрезок кода уникален и его можно искать через - например WinHex. Не снимая выделения щёлкаем правой мышкой по нему и Двоичные операции -> Копировать Вставим в какой нибудь блокнот и удалим разделяющие пробелы. Получится 84C07548488B8580000000488B98A80000004889D9
Не обязательно чтоб искомый фрагмент входил в сигнатуру, важно найти уникальную часть зная сколько байт нужно отсчитать от него до нужного места.
Теперь запустим hex-редактор (winHex) способный искать hex-строки, и найдём расположение нашей сигнатуры. Сделаем резервную копию файла c:\Program Files (x86)\Embarcadero\acnt\DX11Alexandria\sCommonData.dcu и откроем его в winHex. Теперь меню Поиск->Найти хекс значение
в окне поиска вставляем нашу строку с байтами и она находится
Давайте глянем - как в x64Dbg выглядит код нашего jne , это - 75 48 сразу за (84 С0)
ткнём пробелом на строке с jne , исправим его на jmp и посмотрим код
это EB 48 , то есть на нужно изменить один байт 75 на EB Возвращаемся в winHex, исправляем 84C07548 на 84C0EB48 и сохраняем исправление. Заменяем файл c:\Program Files (x86)\Embarcadero\acnt\DX11Alexandria\sCommonData.dcu исправленным и пересобираем проект в RadStudio. Триал-сообщения нет, можно посмотреть в x64Dbg , как работает наш патч. Сама RadStudio ещё не исправлена, сейчас этим займёмся.
Запустим RadStudio_Delphi и откроем в ней наш тестовый проект. Запустим 32-битную версию отладчика x32Dbg и присоединимся к процессу RadStudio - bds
и из контекстного меню запустим поиск строк во всех модулях. На вкладке результатов Ссылки - в строке Поиск напишем Trial version и получим результат
Двойной щёлк по строке переносит в окно дизассемблера ( CPU ) , в верху, в заголовке видим - что это содержимое файла c:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\acntDX11Alexandria_R.bpl , сделаем его резервную копию. И что мы видим чуть выше
практически один в один код триал-сообщения из нашего тестового приложения. Синяя - переход после isDebuggerPresent , красная - переходы после анализа каких то значений, зелёная - загрузка строки "Trial version of the AlphaControls ..." и последующий вызов триал-окна. Но в отличии от патча sCommonData.dcu - сейчас мы можем патчить прямо здесь. Изменим все четыре перехода на безусловный, обходящий вызов триал-сообщение, гулять так гулять.
Сохраняем исправления проверив правильность имени сохраняемого файла acntDX11Alexandria_R.bpl
Сохраним его с именем acntDX11Alexandria_R_2.bpl , удалим старый acntDX11Alexandria_R.bpl , переименуем acntDX11Alexandria_R_2.bpl в acntDX11Alexandria_R.bpl , запускаем RadStudio и наблюдаем отсутствие триал-сообщения.
Для Delphi7 ( alphaControls 16 ) всё делается таким же способом.
***
К стати, при сборке приложения с alphaControls, по умолчанию скин не вшивается в приложение и будет работать при наличии пути до папки со скинами. То есть на другой машине оформления не будет. Для внедрения скинов в ресурсы приложения: правой мышкой по компоненту sSkinManager на форме -> Internal skins.. и в окне через кнопку +Add добавляем нужные скины и Exit. Теперь скин вшит в приложение и будет работать всегда.
***
---------- ERROR -----------------------
Попробовал AlphaControls_v17.10_Stable установить на
RADStudio 12.1 61.7529, не ставится, ни для delphi, ни для Си. ;-\
На RADStudio 12.0 29.0.51511.6924 всё норм.
----------------------------------------
Порядок, всем удачи.