Исследование защиты программы PDF to EXE Converter
Скриншот программы PDF to EXE Converter
Утилита PDF to EXE Converter от ApinSoft позволяет конвертировать PDF-документы в исполняемые файлы, которые не требуют наличия дополнительных инструментов для открытия PDF. Кроме этого можно выбрать большое количество дополнительных настроек типа ограничения по времени, отображения собственного сплеш-скрина, ограничения количества печати и просмотров, регистрации с привязкой к компьютеру и еще много чего интересного. Короче, реально полезный инструмент для издателей своих материалов в PDF-формате, даже если учесть, что может обработать не все файлы. На сайте доступен дистрибутив демо-версии, доступ к полной дается только после оплаты. Лишнего зеленого полтинника у меня не завалялось, будем работать с тем, что есть.
Забираем триальный дистрибутив, устанавливаем, смотрим.
Ограничения триальной версии
Из триальных ограничений в основном исполняемом файле я нашел только невозможность установить пользовательский пароль для регистрации. На попытку ввести серийник через меню программы никаких действий не происходит, это просто демонстрационная пустышка.
Файл ничем не упакован, беглым осмотром можно выяснить, что он написан на Дельфи. Для работы с Дельфи есть очень хороший инструмент - IDR (Interactive Delphi Reconstructor). Загружаем исполняемый файл в него и ждем, когда декомпиляция будет завершена. Затем переходим к более внимательному осмотру.
Элементы формы в ресурсах
Даже если разблокировать поля ввода какими-нибудь внешними инструментами, поменять в них текст все равно не получится. В главной форме приложения, которая имеет название TFORMMAIN заблокированные поля ввода пароля имеют названия "Edit9" и "Edit12" соответственно. Теперь надо найти код, в котором происходит работа с этими полями.
Сохраняем проект Дельфи
Чтобы иметь полную картину происходящего, я обычно сохраняю весь проект, так по комментариям с названиями элементов форм, а также самих форм, можно легко найти интересующий код. Так я делал при декомпиляции файлов в DeDe, так же поступаю и в IDR. Строка обнаружится в файле описания формы FormMain.dfm и в файле _Unit94.pas, в котором содержится код.
Code (Assembler) : Убрать нумерацию
- 006BC087 lea eax,[ebp-10]
- 006BC08A mov ecx,0
- 006BC08F call @LStrFromUStr
- 006BC094 mov eax,dword ptr [ebp-8]
- 006BC097 mov edx,dword ptr [ebp-10]
- ; Сравнить какие-то строки
- 006BC09A call @LStrEqual
- ; Если они равны, то вычистить из интерфейса все связанное с триалом
- 006BC09F je 006BC0D3
- ; Показать кнопку "Buy now"
- 006BC0A1 mov eax,dword ptr [ebp-4]
- 006BC0A4 mov eax,dword ptr [eax+7FC];TFormMain.BitBtn1:TBitBtn
- 006BC0AA mov dl,1
- 006BC0AC call TControl.SetVisible
- ; Установить режим "только для чтения" на два поля ввода
- 006BC0B1 mov eax,dword ptr [ebp-4]
- 006BC0B4 mov eax,dword ptr [eax+65C];TFormMain.Edit9:TEdit
- 006BC0BA mov dl,1
- 006BC0BC call TEdit.SetReadOnly
- 006BC0C1 mov eax,dword ptr [ebp-4]
- 006BC0C4 mov eax,dword ptr [eax+660];TFormMain.Edit12:TEdit
- 006BC0CA mov dl,1
- 006BC0CC call TEdit.SetReadOnly
- 006BC0D1 jmp 006BC143
- ; Очистка интерфейса
- 006BC0D3 mov eax,dword ptr [ebp-4]
- 006BC0D6 mov eax,dword ptr [eax+7FC];TFormMain.BitBtn1:TBitBtn
- 006BC0DC xor edx,edx
- ; Спрятать кнопку покупки "Buy now"
- 006BC0DE call TControl.SetVisible
- 006BC0E3 mov eax,dword ptr [ebp-4]
- ; Удалить пункты меню о покупке и регистрации
- 006BC0E6 mov eax,dword ptr [eax+844]
- ;TFormMain.Buynow1:TMenuItem
- 006BC0EC xor edx,edx
- 006BC0EE call TMenuItem.SetVisible
- 006BC0F3 mov eax,dword ptr [ebp-4]
- 006BC0F6 mov eax,dword ptr [eax+840]
- ;TFormMain.EnterregistrationKey1:TMenuItem
- 006BC0FC xor edx,edx
- 006BC0FE call TMenuItem.SetVisible
- ; Разблокировать поля ввода
- 006BC103 mov eax,dword ptr [ebp-4]
- 006BC106 mov eax,dword ptr [eax+65C];TFormMain.Edit9:TEdit
- 006BC10C xor edx,edx
- 006BC10E call TEdit.SetReadOnly
- 006BC113 mov eax,dword ptr [ebp-4]
- 006BC116 mov eax,dword ptr [eax+660];TFormMain.Edit12:TEdit
- 006BC11C xor edx,edx
- 006BC11E call TEdit.SetReadOnly
Программа успешно "зарегистрирована"
Можно сгенерить тестовый исполняемый файл из какого-нибудь PDF, защитив его регистрацией. Указанный произвольный серийник работает. Таким образом, в программе все триальные ограничения получаются сняты. Первая цель достигнута, едем дальше. Дело в том, что собранный exe-файл при запуске и завершении работы вываливает вот такое окно.
Триальное окно
Самозапускающийся PDF формируется следующим образом: программа берет из своих ресурсов хранящийся там стаб, затем дописывает к нему исходный PDF в слегка зашифрованном виде, настройки и всякие вспомогательные файлы. Стаб представляет собой exe-файл, но он хранится в ресурсах как минимум в упакованном виде, а может быть еще и в шифрованном. То есть проблематично извлечь стаб, пропатчить каким-то образом, избавившись от назойливых сообщений, а потом затолкать его обратно в ресурсы. Не невозможно, но потребует несоизмеримых трудозатрат. Поэтому будем работать с уже собранными файлами.
Соберем исполняемый файл с любыми настройками, затем отправим его на декомпиляцию в IDR. И точно так же, как мы делали с основным файлом, сохраним проект. Заодно посмотрим список форм. Триальное окно в ресурсах имеет название "Form2". Запускаем поиск этой строки по файлам проекта, найдутся три файла: _Unit74.pas - обработчик триального окна, Form2.dfm с описанием формы и главный обработчик приложения - mainformUnit.pas. Он-то нас и интересует. Как мы помним, триальное окно открывается два раза. Первое вхождение:
Code (Assembler) : Убрать нумерацию
- 0067AD57 mov eax,ebx
- 0067AD59 call 006804AC
- 0067AD5E mov eax,[0069E0F0];gvar_0069E0F0:TForm1
- 0067AD63 mov eax,dword ptr [eax+46C]
- 0067AD69 mov edx,67AEA8;'2'
- ; Выполнить какое-то сравнение
- 0067AD6E call @UStrEqual
- ; Прыжок в обход триального окна
- 0067AD73 je 0067AD9C
- 0067AD75 mov ecx,dword ptr ds:[695C8C]
- ;^Application:TApplication
- 0067AD7B mov ecx,dword ptr [ecx]
- 0067AD7D mov dl,1
- ; Создать триальное окно и отобразить его
- 0067AD7F mov eax,[0064D398];TForm2
- 0067AD84 call TCustomForm.Create;TForm2.Create
- 0067AD89 mov esi,eax
- 0067AD8B mov eax,esi
- 0067AD8D mov edx,dword ptr [eax]
- 0067AD8F call dword ptr [edx+168];TCustomForm.ShowModal
- 0067AD95 mov eax,esi
- 0067AD97 call TObject.Free
- 0067AD9C mov eax,dword ptr [ebx+834];TForm1.pMem:Pointer
- 0067ADA2 test eax,eax
- 0067ADA4 je 0067ADAC
- 0067ADA6 push eax
Code (Assembler) : Убрать нумерацию
- 0067D5E1 call @UStrAsg
- 0067D5E6 mov eax,dword ptr [ebp-4]
- 0067D5E9 mov eax,dword ptr [eax+480];TForm1.m_cc:string
- 0067D5EF mov edx,67EBF8;'1'
- 0067D5F4 call @UStrEqual
- ; Прыжок в обход триального окна
- 0067D5F9 je 0067D622
- 0067D5FB mov ecx,dword ptr ds:[695C8C]
- ;^Application:TApplication
- 0067D601 mov ecx,dword ptr [ecx]
- 0067D603 mov dl,1
- ; Создать триальное окно и отобразить его
- 0067D605 mov eax,[0064D398];TForm2
- 0067D60A call TCustomForm.Create;TForm2.Create
- 0067D60F mov ebx,eax
- 0067D611 mov eax,ebx
- 0067D613 mov edx,dword ptr [eax]
- 0067D615 call dword ptr [edx+168];TCustomForm.ShowModal
- 0067D61B mov eax,ebx
- 0067D61D call TObject.Free
- 0067D622 mov dl,1
- 0067D624 mov eax,[00444334];TStringList
- 0067D629 call TStringList.Create;TStringList.Create
- 0067D62E mov dword ptr [ebp-30],eax
- 0067D631 mov dl,1
- 0067D633 mov eax,[00447970];TMemoryStream
- 0067D638 call TObject.Create;TMemoryStream.Create
- 0067D63D mov ebx,eax
Просмотров: 383 | Комментариев: 2
Метки: исследование защиты, PDF
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(11.09.2024 в 12:40):
Ну вот, век живи - век учись :) За offzip спасибо, классная утилита, не знал про такую.
pawel97
(08.09.2024 в 19:35):
Занопить переход .663246 - и стаб можно не патчить. Выйти на код можно, как по строке 21obk12, фигурирующей в стабе в проверке показывать ли стартовое окно, так и по длиннющей строке из цифр, один-в-один как в проверке реги при запуске проги. Кстати, idr не определяет последнее как код, hiew наше всё.
Но если бы безвариантно пришлось заменять стаб (тут он просто упакован zlib) - то есть удобный консольный тул offzip и его ключи -a (достать) и -a -r (упаковать обратно). Что-то на qt/qml так пролечивал: распаковать сорцы, поправить блокнотом и затолкать назад.
Но если бы безвариантно пришлось заменять стаб (тут он просто упакован zlib) - то есть удобный консольный тул offzip и его ключи -a (достать) и -a -r (упаковать обратно). Что-то на qt/qml так пролечивал: распаковать сорцы, поправить блокнотом и затолкать назад.
Добавить комментарий
Заполните форму для добавления комментария