Техническая поддержка :

Современные решения

для защиты Windows программ

и восстановления исходного кода
Автор: [RU].Ban0K!. . Дата публикации: 16.05.2004


Исследование защиты Test Protection 1 by DotFix Software


Введение
Статья, значит, посвящена изучению тестовой защиты созданном на VB без P-CODE... Данный сэмпл подкинул мне автор сайта DotFix Software, скачать его можно с www.dotfix.net. Защита как защита, только вот усложнена она тем что написана на Visual Basic 6.0 :)

Начнём
Открываем OllyDebuger, в нём открываем сэмпл. Запускаем его, вводим всё что попало и выходит сообщение о неправильности кода. Значит ловить будем на MessageBox, но так как в VB не используется такая API, то будем ловить по аналогу... rtcMsgBox.
Нажимаем Ctrl-N, ищем таковую... не находим... дело в том что функции начинающиеся на rtc вызываются по ординате, для нашей функции это будет 595, ставим точку останова, всего их вышло 4. Давайте разберёмся какие в каком случае вызываются.
Первая:
CODE NOW!
Address=0040130C
Disassembly=JMP DWORD PTR DS:[<&MSVBVM60.#595>]

Не в счёт... по ясным причинам...
Вторая:
CODE NOW!
Address=00402D97
Disassembly=CALL DWORD PTR DS:[<&MSVBVM60.#595>]

Заходим на адрес по которому совершается вызов... прокручиваем немного вверх, видим много повторяющейся ерунды, это не что иное как помещение в стэк текста для сообщения, автор хотел зделать некий обман, чтоб строки не видно было... Смотрим ещё выше и натыкаемся на следующее:
CODE NOW!
004028B8 MOV EAX,DWORD PTR SS:[EBP-B4]
004028BE PUSH EAX
004028BF CALL DWORD PTR DS:[MSVBVM60.__vbaLenBstr]
004028C5 XOR ECX,ECX
004028C7 CMP EAX,4
004028CA SETL CL
004028CD NEG ECX
004028CF MOV ESI,ECX
004028D1 LEA ECX,DWORD PTR SS:[EBP-B4]
004028D7 CALL DWORD PTR DS:[MSVBVM60.__vbaFreeStr]
004028DD LEA ECX,DWORD PTR SS:[EBP-C8]
004028E3 CALL DWORD PTR DS:[MSVBVM60.__vbaFreeObj]
004028E9 CMP SI,BX
004028EC JE CRACKME.00402FAF

Краткое описание:
В eax, адрес нашего логина, находим его длину, сравниваем с 4, если меньше то устанавливаем cl в 1, помещаем негатив в esi, освобождаем строку и удаляем объект. Сравниваем esi c 0 (он находится в ebx) если не равно то идём к rtcMsgBox, я думаю всё ясно...
Третья:
CODE NOW!
Address=00403FF4
Disassembly=CALL DWORD PTR DS:[<&MSVBVM60.#595>]

Опять же поднимаемся выше и находим строку на которую совершается прыжок, перед ней безусловный жимп который обходит наш rtcMsgBox. Идём на код который совершает переход на эту строку, посмотрим этот код:
CODE NOW!
00402FFD PUSH EDX
00402FFE CALL DWORD PTR DS:[MSVBVM60.__vbaLenBstr]
00403004 XOR ECX,ECX
00403006 CMP EAX,0A
00403009 SETL CL
0040300C NEG ECX
0040300E MOV ESI,ECX
00403010 LEA ECX,DWORD PTR SS:[EBP-B4]
00403016 CALL DWORD PTR DS:[MSVBVM60.__vbaFreeStr]
0040301C LEA ECX,DWORD PTR SS:[EBP-C8]
00403022 CALL DWORD PTR DS:[MSVBVM60.__vbaFreeObj]
00403028 CMP SI,BX
0040302B JNZ CRACKME.00403CF2

Думаю, этот код не требует объяснений... в отличии от предыдущего сравнивает длину пароля с 10.
Теперь у нас есть два ограничения...
И наконеч рассмотрим четвёртый вызов:
CODE NOW!
Address=004052F6
Disassembly=CALL DWORD PTR DS:[<&MSVBVM60.#595>]

Перейдём по указанному адресу прокрутив вверх мы не увидим ничего :), прокрутив на начало процедуры, увидем следующее:
CODE NOW!
00404480 PUSH EBP
00404481 MOV EBP,ESP
00404483 SUB ESP,0C
00404486 PUSH <JMP.&MSVBVM60.__vbaExceptHandler]
0040448B MOV EAX,DWORD PTR FS:[0]
00404491 PUSH EAX

Делаем вывод... эта процедура, обработчик ошибок...
Вот всё что мы имеем... теперь мы пойдём туда где был безусловный жимп в который обходил rtcMsgBox в прошлый раз... и посмотрим на процедуру после которой он вызывается:
CODE NOW!
00403CB5 CALL DWORD PTR DS:[MSVBVM60.rtcCallByName]
00403CBB LEA EDX,DWORD PTR SS:[EBP-55C]
00403CC1 PUSH EDX
00403CC2 PUSH 0
00403CC4 CALL DWORD PTR DS:[MSVBVM60.__vbaErase]
00403CCA LEA EDX,DWORD PTR SS:[EBP-D8]
00403CD0 LEA ECX,DWORD PTR SS:[EBP-70]
00403CD3 CALL EBX
00403CD5 LEA ECX,DWORD PTR SS:[EBP-B4]
00403CDB CALL DWORD PTR DS:[MSVBVM60.__vbaFreeStr]
00403CE1 LEA ECX,DWORD PTR SS:[EBP-C8]
00403CE7 CALL DWORD PTR DS:[MSVBVM60.__vbaFreeObj]
00403CED JMP CRACKME.0040415F

Только в VB (я имею ввиду компиляторы, так как в PHP тоже есть такая возможность..., но это не компилятор :) ) есть очень интересная возможность :), вызвать процедуру имея строку с её имянем... Это делает процедура: rtcCallByName :).
Поставив точку останова на место её вызова и введя логин и пароль подходящие под найденые границы мы попадаем на это место. Если мы ввели не правельный пароль то пройдя поверх этой процедуры мы попадаем в Exception, а следовательно на четвёртый rtcMsgBox.
Посмотрев во круг я понял что параметр (имя процедуры) это покодированные логин и пароль. Причём имя процедуры 10 символов... По хорошему следовало порыть всю функцию rtcCallByName (как я и зделал) и там найти все процедуры которые есть в проге, но можно поступить легче, т.к. прога у нас маленькая, легче просмотреть весь её код... и найти следующее:
CODE NOW!
00401D58 63 6D 64 52 65 67 69 73 cmdRegis
00401D60 74 65 72 00 74 78 74 50 ter.txtP
00401D68 61 73 73 00 6C 62 6C 50 ass.lblP
00401D70 61 73 73 00 6C 62 6C 54 ass.lblT
00401D78 65 78 74 00 3A 4F AD 33 ext.:O­3
00401D80 99 66 CF 11 B7 0C 00 AA ™fП·..Є
00401D88 00 60 D3 93 46 6F 72 6D .`У“Form
00401D90 00 00 00 00 52 65 67 69 ....Regi
00401D98 73 74 65 72 4F 4B 00 00 sterOK..
00401DA0 44 65 63 6F 64 65 00 00 Decode..
00401DA8 0C 00 58 00 00 00 00 00 ..X.....

Я незнаю правда на сколько легче..., но я сразу это не нашёл :), единственное что я тут увидел их 10 символов и более или менее подходящее по названию это RegisterOK. Поставив опять бряк на rtcCallByName и передав её в параметрах имя найденой процедуры в уникоде... мы получим сообщение что регистрационная информация принята :)
Остаётся найти наш код... я не стал чесно искать процедуру где происходит шифровка, а просто подумал, входные данные 10 символов пароля и выходные 10 символов процедуры... подставив за место пароля RegisterOK и за место логина [RU].Ban0K! я получил фальшивое имя процедуры PgfkstarFN, потом поставив имя процедуры на место пароля... получил имя функции RegisterOK, следовательно шифровка была не иная как простой XOR (или чтото иное, тем ни менее полностью обратимая :) ).
и так имя \"[RU].Ban0K!\", регистрационный код \"PgfkstarFN\"...

[RU].Ban0K!

Распространение и/или размещение статьи на других ресурсах без согласования с автором запрещено!




Комментарии

отсутствуют

Добавление комментария


Ваше имя (на форуме):

Ваш пароль (на форуме):

Комментарии могут добавлять только пользователи,
зарегистрированные на форуме данного сайта. Если Вы не
зарегистрированы, то сначала зарегистрируйтесь тут

Комментарий:





Главная     Программы     Статьи     Разное     Форум     Контакты