Blog. Just Blog

Исследование защиты программы JPEG Recovery Pro

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы JPEG Recovery Pro
Скриншот программы JPEG Recovery Pro

Программа JPEG Recovery Pro предназначена для восстановления поврежденных изображений в формате JPEG: картинки, разрезанные на несколько файлов, сдвиг блоков изображения, сдвиг цвета. Примеры таких файлов можно посмотреть на офсайте, наверняка вы встречались с чем-нибудь подобным. Незарегистрированной версией полноценно пользоваться нельзя, поверх любой отредактированной картинки накладывается уродливая надпись, что, мол, триальная версия и все такое. Это очень неправильно, а как сделать правильно, я расскажу в этой статье.

Забираем дистрибутив с офсайта, устанавливаем, смотрим. В папке с установленной программой находится два исполняемых файла - JPEGRec.exe и JPEGRec6.exe. Один отвечает за пакетную обработку, а второй - за редактирование. Как подсказывают анализаторы, оба файла упакованы одной из новых версий ASPack. Снимается этот упаковщик или ручками, или каким-нибудь универсальным распаковщиком, смотря какой у вас опыт и предпочтения. Начнем анализ с файла JPEGRec.exe, отправляем его распакованную копию в дизассемблер. Результат придется подождать, файл достаточно объемный.

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

Строка сообщения в ресурсах
Строка сообщения в ресурсах

Сообщение найдено в ресурсах, его индекс 64314 в десятичной системе счисления, или же 0FB3Ah в шестнадцатеричной. Для поиска в дизассемблере нас интересует второе значение. Поиск выводит нас на следующую конструкцию:
  1. .text:00A5B1F0 off_A5B1F0      dd offset hModule
  2. .text:00A5B1F4                 dd 0FB39h
  3. ; DATA XREF: sub_A5D8F8+3A - перекрестная ссылка
  4. .text:00A5B1F8 off_A5B1F8      dd offset hModule
  5. ; Индекс
  6. .text:00A5B1FC                 dd 0FB3Ah
  7. .text:00A5B200 off_A5B200      dd offset dword_A5B204
Это ни что иное, как таблица указателей на строки в ресурсах. Перекрестные ссылки на предваряющий индекс DWORD и есть места в коде, откуда эта строка задействуется. Посмотрим.
  1. .text:00A5D91C                 mov     eax, [ebp+var_4]
  2. .text:00A5D91F                 call    sub_A5F814
  3. .text:00A5D924                 mov     eax, ds:dword_B66A30
  4. ; Проверить значение байта
  5. .text:00A5D929                 cmp     byte ptr [eax+4Ch], 0
  6. ; Если оно ненулевое, то перепрыгнуть вывод сообщения
  7. .text:00A5D92D                 jnz     short loc_A5D95E
  8. ; Вывести сообщение о порче сохраняемой картинки
  9. .text:00A5D92F                 lea     edx, [ebp+var_28]
  10. .text:00A5D932                 mov     eax, offset off_A5B1F8
  11. .text:00A5D937                 call    sub_40BC64
  12. .text:00A5D93C                 mov     eax, [ebp+var_28]
  13. .text:00A5D93F                 mov     [ebp+var_18], eax
  14. .text:00A5D942                 push    0
  15. .text:00A5D944                 push    0FFFFFFFFh
  16. .text:00A5D946                 push    0FFFFFFFFh
  17. .text:00A5D948                 push    0
  18. .text:00A5D94A                 mov     cx, ds:word_A5DAC4
  19. .text:00A5D951                 mov     dl, 2
  20. .text:00A5D953                 mov     eax, [ebp+var_18]
  21. .text:00A5D956                 call    sub_501B08
  22. .text:00A5D95B                 mov     [ebp+var_1C], eax
  23. .text:00A5D95E loc_A5D95E:
Конструкция из двух последовательных команд "mov eax, ds:dword_B66A30" и "cmp byte ptr [eax+4Ch], 0" лично мне напоминает проверку байта из структуры настроек программы. Сама структура находится по указателю dword_B66A30, а 4Ch - индекс байта регистрации в этой структуре. Теперь нам надо найти место, где этот байт инициализируется нулевым или наоборот ненулевым значением. Проще всего это сделать, посмотрев перекрестные ссылки на структуру настроек dword_B66A30:

Перекрестные ссылки на настройки
Перекрестные ссылки на настройки

Нам надо найти такой участок кода, где есть ссылка на настройки и рядом инициализация с байтом. Первое такое место выполняется при старте программы:
  1. .text:00A5BBE4                 mov     eax, ds:dword_B66A30
  2. .text:00A5BBE9                 mov     byte ptr [eax+4Ch], 0
  3. .text:00A5BBED                 mov     eax, ds:dword_B66A30
Здесь патчить бесполезно, это просто начальная инициализация структуры. Ищем дальше.
  1. .text:00A5F967                 mov     eax, [eax+50h]
  2. ; Вызвать функцию проверки
  3. .text:00A5F96A                 call    sub_A18D6C
  4. .text:00A5F96F                 test    al, al
  5. ; Если она вернула AL=0, то записать в байт регистрации 0
  6. .text:00A5F971                 jnz     short loc_A5F996
  7. .text:00A5F973                 mov     eax, ds:dword_B66A30
  8. .text:00A5F978                 mov     byte ptr [eax+4Ch], 0
  9. .text:00A5F97C                 lea     eax, [ebp+var_14]
  10. .text:00A5F97F                 mov     edx, offset off_A5FB70
  11. .text:00A5F984                 call    sub_407FFC
  12. .text:00A5F989                 lea     edx, [ebp+var_10]
  13. .text:00A5F98C                 mov     eax, offset off_A5B1E8
  14. .text:00A5F991                 call    sub_40BC64
  15. .text:00A5F996 loc_A5F996:
Вот, это уже значительно интереснее. Вызывается какая-то функция проверки, по ее результатам в байт регистрации записывается значение 0, то есть программа работает в триальном режиме. Если посмотреть на перекрестные ссылки на функцию проверки по адресу 00A18D6C, то окажется, что их всего три. Наверняка она как-то связана с регистрацией. Патчим ее начало парой команд MOV AL,1 и RET, чтобы она всегда возвращала корректный результат. Сохраняем изменения, запускаем. Программа сразу предлагает ввести серийник, сходить на сайт за покупками или завершить работу. Ок, вводим любые регистрационные данные. Программа благодарит нас за регистрацию.

Программа успешно "зарегистрирована"
Программа успешно "зарегистрирована"

Сообщение о порче картинок при сохранении больше не появляется, впрочем, как и сама триальная надпись, из меню пропал пункт регистрации, в окне "О программе" красуются введенные регистрационные данные. Цель достигнута. Точнее, только половина цели. При запуске второго файла, JPEGRec6.exe, сразу же появляется сообщение:

Сообщение о неправильной регистрации
Сообщение о неправильной регистрации

Ну логично, чо. Пропатчена на предмет приема любых регистрационных данных только одна программа. В принципе, для большинства задач хватит и одного редактора, но лучше довести дело до конца. Отправляем распакованную копию JPEGRec6.exe в дизассемблер и терпеливо ждем, пока он закончит работу.

Строка сообщения в ресурсах
Строка сообщения в ресурсах

Параллельно поковыряемся в ресурсах на предмет каких-нибудь приметных строк. Обнаружится точно такая же строка, как и в первом файле, но только с другим индексом - это 64136 или 0FA88h. Дальше действуем по такой же схеме.
  1. .text:00B13414 off_B13414      dd offset hModule
  2. .text:00B13418                 dd 0FA87h
  3. .text:00B1341C off_B1341C      dd offset hModule
  4. ; DATA XREF: sub_B15B30+32C
  5. .text:00B13420                 dd 0FA88h
  6. .text:00B13424 off_B13424      dd offset hModule
  7. .text:00B13428                 dd 0FA89h
Находим таблицу указателей на строки в ресурсах.
  1. .text:00B15E4B                 mov     eax, ds:dword_123DC00
  2. .text:00B15E50                 cmp     byte ptr [eax+4Ch], 0
  3. .text:00B15E54                 jnz     short loc_B15E8B
  4. .text:00B15E56                 lea     edx, [ebp+var_108]
  5. .text:00B15E5C                 mov     eax, offset off_B1341C
  6. .text:00B15E61                 call    sub_40BF50
  7. .text:00B15E66                 mov     eax, [ebp+var_108]
  8. .text:00B15E6C                 mov     [ebp+var_48], eax
  9. .text:00B15E6F                 push    0
  10. .text:00B15E71                 push    0FFFFFFFFh
  11. .text:00B15E73                 push    0FFFFFFFFh
  12. .text:00B15E75                 push    0
  13. .text:00B15E77                 mov     cx, ds:word_B16AB0
  14. .text:00B15E7E                 mov     dl, 2
  15. .text:00B15E80                 mov     eax, [ebp+var_48]
  16. .text:00B15E83                 call    sub_51A034
  17. .text:00B15E88                 mov     [ebp+var_4C], eax
  18. .text:00B15E8B loc_B15E8B:
Находим код проверки и вывода сообщения, теперь у нас есть адрес структуры с настройками dword_123DC00 и индекс байта регистрации 4Ch.
  1. .text:00B17362                 call    sub_A95120
  2. .text:00B17367                 test    al, al
  3. .text:00B17369                 jnz     short loc_B1738E
  4. .text:00B1736B                 mov     eax, ds:dword_123DC00
  5. .text:00B17370                 mov     byte ptr [eax+4Ch], 0
По перекрестным ссылкам выходим на код инициализации, а с него - на функцию проверки серийника по адресу 00A95120. Патчим ее точно так же, как и первый файл.

Программа успешно "зарегистрирована"
Программа успешно "зарегистрирована"

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

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 1526 | Комментариев: 9

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
pawel97 (30.05.2016 в 21:12):
Всё-таки решил добить, и вот что вышло.
"Здесь патчить бесполезно, это просто начальная инициализация структуры." - а по мне самое то. Сначала меняем там нолик на единицу, а потом вбиваем ret в начало процедуры, из которой вызывается вся свистопляска с проверкой clsid и пр. Она находится по адресу 00A5F814. Теперь программа портативная, зарегистрированная і стартует на долі секунды шустрее. Имени в эбауте не будет, ну и бог с ним. Второй файл лечится аналогично - там процедура по адресу 00B1720C.
ManHunter (20.05.2016 в 22:49):
Иван, там без бутылки не разобраться, и то не факт. Так что это вполне нормальная ситуация :)
Иван (20.05.2016 в 20:31):
Статья познавательная. но прога не о чём, в автомате даже не может восстановить представленные на офсайте файлы для теста, а в ручную я так и не понял, как с ней работать - может я так сильно туп))
VANS (08.04.2016 в 03:04):
Обычно снимаешь протектор, находишь функцию CheckLicense и нопиш её, в результате софт пашет. Кто юзает протекторы - не умеют защищать софт.
ManHunter (03.04.2016 в 14:05):
Я импорт CHimpREC восстанавливал. До OEP и дамп - Olly, всё под Win7.
voffka (03.04.2016 в 13:45):
pawel97, ImpRec вчерашний день, используй Scylla.
Хотя и ImpRec прекрасно справляется, ни в коем случае не используй v1.7
OEP 0072BDE8
RVA 00E3EF44
Size 00000C88
ManHunter (03.04.2016 в 13:34):
Там и без портативки хватает сюрпризов, типа длиннющего списка забаненных регистрационных имен. Если уж стремиться к идеальному взлому, то и это тоже надо подчистить. И регистрация хранится в CLSID в шифрованном виде, ключ реестра отлавливается Process Monitor'ом.
pawel97 (03.04.2016 в 10:46):
p.s. А нет, File Format Identifier распаковал даже под 64-битной десяткой! Спасибо за этот полезный инструмент, впрочем как и за половину всего остального, что есть в арсинале.
pawel97 (03.04.2016 в 10:35):
Наверно руки не из того места - при ручной распаковке не восстанавливается импорт в imprec (738 Unresolved Pointers), QuickUnpack что-то распаковывает, но это что-то не запускается - Runtime Error. Всё делалось под xp в VMware.
И ещё момент - после распаковки файл может в два раза растолстеть, по сравнению с незапакованным оригиналом, этих недостатков лишены разве что caspr и Unpacker by PE_KILL, не справляющиеся с новым аспаком. Поэтому предпочитаю инлайн, а распакованный чисто для анализа.
Софт кстати на дельфи, поэтому imho IDR и ничего кроме IDR. Там из обработчиков форм create, show, в 99% случаев достаётся всё что нужно.
А ещё нельзя забывать про "теперь программа стала портативной и может работать с любого носителя" - тут и на этот счёт есть сюрприз, без установки она даже не запустится - missing installation information.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0049 сек.) / Память: 4.5 Mb
Наверх