Исследование компонентов Delphi
Я работаю кем-то наподобие системного программиста, и вот увидел в Сети
некий Компонент для Delphi, грозящийся сильно облегчить мне жизнь. Чтобы быть
"канкретным", Компонент этот зовётся ODAC и означает сиё Oracle Data Access Components,
версия 1.20, скопировать можно отсюда.
Компонент этот выделяется среди прочих тем, что позволяет подключаться к Oracle-
базам минуя BDE. Очень удобно, ибо не нужно на каждого клиента ставить BDE и теоретически
должно работать раза в два быстрее.
Скачал я его, инсталлировал в палитру компонентов, скомпилировал примеры,
которые с ним поставляются (настоятельно рекомендую всегда это делать). Казалось бы всё совсем уже работает, но вот на исходе рабочего дня выяснилось, что оно не
хочет работать без Delphi IDE в данной версии, а чтобы такого не было, предлагается
купить нормальную версию всего за каких-то 69$ (и даже просто за 00 cents, что
совсем уже удивительно). Я, конечно, не то чтобы уж какой-нибудь патологический
жмот, но это сумма сейчас составляет половину моего monthly salary, так что эту
мысль я отверг сразу.
И стал я думать - как бы мне обойти сию неприятность. Было два подхода:
поправить непосредственно рабочий код
написать некий эмулятор "Delphi IDE"
Обнаружились сразу две неприятности:
IDA Pro 3.76 ни за что на свете не хотела признавать в .dcu файлах что-либо
малознакомое и норовила подсунуть мне его как "binary file". Поискав
с пол-часика в Сети (например, Wotsit неплохое
место при встрече с новым форматом файлов) и так ничего и не найдя, я отказался
от идеи править Delphi Compiled Units (кстати, если кто-либо из читающих победил
данную проблему, pls, свяжитесь с автором)
В комплект поставки входил ещё и .dpl файл - динамически загружаемый модуль.
С ним тоже ничего не вышло, ибо сначала Delphi не могла найти файл .dpk, а когда
я его сваял вручную, благополучно не смогла найти файл .dcp (кстати, тоже может
быть кто-нибудь объяснит мне тёмному и дремучему, что это такое и как его можно
сделать, если это возможно ?). Вобщем, вследствие моего плохого знания прикладного
инструмента решить задачу красиво не получилось
Тогда стал я думать, а как бы это всё могло быть так устроено, что при живой
Delphi всё работает, а иначе - пишет "ODAC trial version requires Delphi IDE" и не работает.
Простейшее решение - дизассемблировать бесполезный .dpl. Довольно скоро я нашёл
выдаваемую строку и отловил обращение к ней по адресу 410FC0:
...
410FC0: push 0
410FC2: push offset loc_4110E8
410FC7: call j_FindWindowA
410FCC: test eax, eax
410FCE: jnz short loc_410FE6
410FD0: mov ecx, offset aOdacTrialVersi ; грузим указатель на искомую строку
410FD5: mov dl,1
410FD7: mov eax, ds:SysUtils__Exception
...
Понятно, что после выдачи Exception ничего хорошего случится не может, поэтому нужно
смотреть, отчего так происходит. Вызывается функция FindWindow с двумя аргументами:
первый (второй в C - помните, что параметры передаются через стек в обратном порядке)
- указатель на строку с названием окна (или с Caption)
второй (первый в C)- указатель на строку с именем класса окна.
В данном случае передаётся вторым параметром указатель на строку "TAppBuilder",
и если такого окна не найдено, программа свято уверена, что IDE не запущена.
И вот - лампочка в голове засияла - а что если написать маленькую программу,
которая будет делать лишь одно полезное действие - при старте создаст окно с
искомым классом (его при этом даже не обязательно показывать - нужен лишь
вызов CreateWindow) и будет висеть себе тихонько, эмулируя таким образом
замечательную и большую (я бы даже добавил, чересчур большую :-) Delphi.
Что и было исполнено в течение 20 минут. Исходный текст и саму программу можно взять здесь. Чтобы программу можно было таки принудить
закончить без насилия, я добавил tray icon для индикации и выхода - достаточно
щёлкнуть по нему два раза правой кнопкой мыши. Для полноты ощущения счастья
можно поместить shortcut на сей шедевр в папку Startup системного меню.
Вот, собственно, и всё. Я полагаю, что таким способом можно снять защиту со
всех 32-битных компонентов Delphi, работающих только в IDE и проверяющих её наличие
простым нахождением окна (я имею под рукой только Delphi 2, но и там класс главного
окна называется точно так же, осмелюсь предположить, что это справедливо и для Delphi 4)
|