Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Пример пропатчивания программы запакованной UPX (редакция)

Обсудить статью на форуме

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

Автор: Alexey <alvolturbo@yandex.ru>

Пример пропатчивания программы запакованной УПХ

Цель: PDF2Word v1.4. (можно взять на www.globalpdf.com, как и остальные подобные программы)
Единственный инструмент: Olly 1.1 с плагинами.

Привет всем! Это небольшая статья для новичков. Хочется поделиться опытом. Меня последнее время занимал вопрос:"Можно ли патчить запакованные программы (хот чем-нибудь), и не маяться с распаковкой?". Очень неудобно, когда после распаковки программы и взлома ее патчем остается большой распакованный экзешник,который неудобно распространять и нет возможности написать к нему компактный автономный патч. Частично на этот вопросмне ответила статья "Патчим программу,
упакованную UPX"
от [RU].Ban0K (спасибо ему и вообще всем авторам полезных статей). В ней достаточно подробно написан подобный взлом крэкмиса (всем советую ознакомится). А мне подвернулся случай сломать настоящую программку. Программка переводит формат PDF в Формат RTF, и при этом настоятельно просит перед каждым запуском купить ее взамен на полную функциональность. А так просто запускается 100 раз и переводит всего 5 страниц.
И так! Загружаем программу в Олли. Перед нами образовывается код на ассемблере и этот код, по-видимому, код программы, запакованной УПХ (это понятно из команды popad и большой кучи нулей в самом конце). Теперь запускаем прогу (даем ей распаковаться, иначе ничего сразу не найдем) и вводим произвольный серийник (можно и вовсе без имени). Ставим точку прерывания bp GetDlgItemTextA на функцию чтения текста из строчного редактора.
Жмем Enter в окне регистрации и вываливаемся в User32 здесь:

77D5274F > 55               PUSH EBP
 77D52750   8BEC             MOV EBP,ESP
 77D52752   FF75 0C          PUSH DWORD PTR SS:[EBP+C]
 77D52755   FF75 08          PUSH DWORD PTR SS:[EBP+8]
 77D52758   E8 4B63FEFF      CALL USER32.GetDlgItem
 77D5275D   85C0             TEST EAX,EAX
 77D5275F   0F84 148F0200    JE USER32.77D7B679
 77D52765   FF75 14          PUSH DWORD PTR SS:[EBP+14]
 77D52768   FF75 10          PUSH DWORD PTR SS:[EBP+10]
 77D5276B   50               PUSH EAX
 77D5276C   E8 C999FFFF      CALL USER32.GetWindowTextA
 77D52771   5D               POP EBP
 77D52772   C2 1000          RETN 10 

и проходим по F8 до retn, жмем заветную клавишу (F8) еще раз и появляемся здесь на 00429BAD :


00429BA7   FF15 1C874400    CALL DWORD PTR DS:[44871C]               ; USER32.GetDlgItemTextA <<---наша точка останова
 
 00429BAD   68 FCA64600      PUSH pdf2rtf.0046A6FC                    ; ASCII "56465" <<--серийничек
 00429BB2   E8 09F8FFFF      CALL pdf2rtf.004293C0                    ; Процедура проверочки
 00429BB7   83C4 04          ADD ESP,4
 00429BBA   85C0             TEST EAX,EAX                             ; Сравнение регистра eax с "1"
 00429BBC   74 39            JE SHORT pdf2rtf.00429BF7                ; Если EAX не равен единице, то прыгаем куда подальше и поглубже:)
 00429BBE   6A 40            PUSH 40
 00429BC0   68 38744600      PUSH pdf2rtf.00467438                    ; ASCII "Thank you registered"
 00429BC5   68 14744600      PUSH pdf2rtf.00467414                    ; ASCII "Thank you registered pdf2word v1.4."
 00429BCA   56               PUSH ESI
 00429BCB   FF15 24874400    CALL DWORD PTR DS:[448724]               ; USER32.MessageBoxA
 00429BD1   68 FCA64600      PUSH pdf2rtf.0046A6FC                    ; ASCII "56465"
 00429BD6   56               PUSH ESI
 00429BD7   E8 54F9FFFF      CALL pdf2rtf.00429530
 00429BDC   83C4 08          ADD ESP,8
 00429BDF   C705 C4A74600 01>MOV DWORD PTR DS:[46A7C4],1
 00429BE9   6A 01            PUSH 1
 00429BEB   56               PUSH ESI
 00429BEC   FF15 20874400    CALL DWORD PTR DS:[448720]               ; USER32.EndDialog
 00429BF2   E9 EB010000      JMP pdf2rtf.00429DE2
 00429BF7   6A 10            PUSH 10
 00429BF9   6A 00            PUSH 0
 00429BFB   68 E0734600      PUSH pdf2rtf.004673E0                    ; ASCII "Series number error, please check it and try again."
 00429C00   56               PUSH ESI
 00429C01   FF15 24874400    CALL DWORD PTR DS:[448724]               ; USER32.MessageBoxA 

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

00429BBC   74 39            JE SHORT pdf2rtf.00429BF7 

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

  00429BB2   E8 09F8FFFF      CALL pdf2rtf.004293C0  

и сделаем там изменения, необходимые нам для успешной работы с программой. Сразу же избавляемся от процедуры проверки так, чтобы нам всегда приходилось иметь дело только с "1" в регистре ЕАХ:
меняем в блоке

004293BE   90               NOP
 004293BF   90               NOP
 004293C0   83EC 30          SUB ESP,30                               ; начиная отсюда несколько команд
 004293C3   55               PUSH EBP
 004293C4   56               PUSH ESI
 004293C5   8B7424 3C        MOV ESI,DWORD PTR SS:[ESP+3C]
 004293C9   57               PUSH EDI 

на

004293BE   90               NOP
 004293BF   90               NOP
 004293C0   B8 01000000      MOV EAX,1                                ; вот это чудо программирования на асме:)
 004293C5   C3               RETN
 004293C6   90               NOP
 004293C7   90               NOP
 004293C8   90               NOP
 004293C9   57               PUSH EDI 

(я привел большие блоки для нахождения соответствия в коде до и после исправления)
Вводим серийник, проверяем--работает!
Да только вот нужно, чтоб этот код каждый раз после распаковки всей программы дописывался в нужное место.
Если посмотреть в конец процедуры распаковки (как раз на переход на EntryPoint), то можно догадаться (а если ознакомиться еще со статьей [RU].Ban0K, то и вовсе знать), что на этот момент программа уже распакована и можно делать наше ДЕЛО:)

00471600   . 83C3 04        ADD EBX,4                                ;  
 00471603   .^EB D8          JMP SHORT pdf2rtf.004715DD
 00471605   > FF96 44270700  CALL DWORD PTR DS:[ESI+72744]            ;  
 0047160B   > 61             POPAD                                    ;  А это восстановление регистров
 0047160C   .-E9 4B36FDFF    JMP pdf2rtf.00444C5C                     ;  А это EntryPoint (точка входа)
 00471611     00             DB 00  

попробуем получить в нужном месте

  B8 01000000      MOV EAX,1                                
   C3               RETN 

Для этого загрузим программу в отладчик еще раз, не доходя до перехода на EntryPoint программы
допишем свой код (просто нажимая пробел на нужной строчке пишем ассемблерные команды, приведенные ниже):

0047160B   > 61             POPAD                                    ;  А это восстановление регистров
 0047160C   . 60             PUSHAD                                   ;  А это EntryPoint (был)
 0047160D   . C705 C0934200 >MOV DWORD PTR DS:[4293C0],1B8
 00471617   . C705 C3934200 >MOV DWORD PTR DS:[4293C3],90C30000
 00471621   . 61             POPAD
 00471622   .-E9 3536FDFF    JMP pdf2rtf.00444C5C
 00471627     00             DB 00 

Мы убедительно просим программу запомнить все регистры в стеке, изменить в коде программы по адресу 4293C0 несколько байт для получения необходимых нам инструкций (надеюсь, какие инструкции нам нужны, все, кто дочитал до этого места, поняли), выгрузить из стека состояние всех регистров обратно.
[RU].Ban0K предлагал написать процедуру в свободном месте и прыгать на нее отдельно, но если проверить, то окажется, что в конце и процедуры распаковки до и после запуска программы достаточно нулей, и это делать не обязательно.
Необходимо помнить про обратный порядок написания байт для добавления их в код программы в нормальном порядке. (Полезно помнить еще и количество байт в переменных типа DWord(4, Word(2), Byte(1) для того, чтобы добить неиспользуемый байт командой NOP с кодом 90).
Мы попросту отсрочиваем переход на ОЕП с добавлением автопропатчиваемых байт. В паре с PUSHAD и POPAD хорошо использовать PUSHFW и POPFW, но по-моему, здесь это не обязательно, т. к. основную прогу не волнует, что до этого делал анпакерский код:)
Кроме того учтя советы великих гуру и опыт предыдущих поколений хочу добавить к статье веское замечание Bi0w0rm’a: для компактности (иногда даже очень полезно) кода можно использовать немного другое решение присвоения регистру EAX единицы, а именно

     33C0           XOR EAX,EAX                       <----обнуление регистра ЕАХ
      40             INC EAX                           <----инкремент ЕАХ (увеоичение на единицу)
      C3             RETN 

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

Я надеюсь, что мой опыт окажется кому-то полезным. Спасибо за внимание. Удачи!

P.S. Если кому что-то непонятно пишите alvolturbo#yandex.ru








Обсуждение статьи: Пример пропатчивания программы запакованной UPX (редакция) >>>


Комментарии к статье: Пример пропатчивания программы запакованной UPX (редакция)

Ara 28.02.2005 02:05:45
Имхо неудачно выбрана прога для статьи - тут проверка серийника сделана тупо и кейген к ней сделать также быстро, как и инлайн...
---
Alexey 01.03.2005 00:25:57
Главное сам принцип и возможность написания инлайн патча, а не то к чему его прикручивать (для данной статьи). А кейгенить я пока не могу:)
---
unodj 20.03.2005 00:55:40
чего то я не понял...
а почему все так сложно то?
она ведь патчится прямо в w32dasm изменением двух переходов на противоположные
вот адреса: 429b51 и 429b11
---
Alexey 27.03.2005 00:55:37
Смотри сам как тебе удобно:)
Эта статья--пример использования отладчика ОЛЛИ для пропатчивания запакованных программ. Тема такая.
:)
---
unodj 28.03.2005 02:07:25
так в том-то и дело, что она не запакованная :)
---
Alexey 29.03.2005 02:25:48
Наверное про разные проги разговор, там на сайте не все запакованые. Видать разные люди писали. Ищи именно ту программу, что в статье. Зря что ли код пакованый у меня?:)
---

Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS