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

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

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

и восстановления исходного кода
Автор: bi0w0rM. Дата публикации: 05.08.2004

Исследование P-Code Visual Basic

[ Исследование P-Code Visual Basic ]

Эхх!! Я очень часто слышу отрицательные отзывы типа: ненавижу ломать VB-программы, там не код, там какая-то помойка вообще! И многие, видать не из большой любви к языку Visual Basic, который считают почему-то ламерским, забрасывают исследовние. Часто из-за того, что их любимый w32dasm не может найти UNICODE-строк. Тут бы я посоветовал юзать IDA Pro и, если поможет, прогу VBREF. Но код и вправду превращается в набор недизассемблируемых байтов, если прога собрана... в P-Code. Именно такой тип сборки я указал в опциях проекта, когда писал свой P-Code crackme. Всего у VB два типа компиляции: Native и P-Code. Native легко дизассемблировать, так как это обычные команды процессора intel x86, а вот P-Code(псевдокод) представляет нечто другое: команды записаны в виде номер функций и их аргументов; эти команды читаются Dll-кой MSVBVM60.DLL(ну или у кого какая версия). Так что можно считать псевдокод неломаемым, если... не иметь нормального декомпилятора псевдокода, который бы преобразовывал байт-коды в нормальный для восприятия вид. Таких прог я знаю две: EXDEC и VBParser. Последний мне не очень нравится, потому что весь GUI сделан на китайском и сама прога порой виснет при декомпиляции больших программ(листинг хоть и сохраняется в файл, но не весь) :( Хотя VBParser более подробно описывает команды, нежели EXDEC, который типа находится в стадии разработки :)) Итак, я написал крякмис, по которому сегодня будем учиться ломать псевдокод, его можно скачать здесь: http://bioworm.narod.ru/soft/bio_keygenme.rar . Сам EXDEC есть у меня же на сайте.

1) При нажатии на кнопку "Check your lamerizm" форма некоторое покрывается красными точками. такую херь я организовал естественно при помощи цикла, и мы постараемся избежать этот цикл, чтоб побыстрее шло дело. Запустим EXDEC и дизасмим там наш exe’шник. В первой же процедуре такой код:

Proc: 40479c
404548: 28 LitVarI2: ( local_00C4 ) 0x64 (100)
40454D: 25 PopAdLdVar
40454E: 28 LitVarI2: ( local_00B4 ) 0x64 (100)
404553: 25 PopAdLdVar
404554: 28 LitVarI2: ( local_00A4 ) 0x0 (0)
404559: 25 PopAdLdVar
40455A: 28 LitVarI2: ( local_0094 ) 0x0 (0)
40455F: 25 PopAdLdVar
404560: f4 LitI2_Byte: 0x4 4 (.)
404562: 08 FLdPr local_param_0008
404565: 0d VCallHresult ?$
40456A: f5 LitI4: 0xff 255 (....)
40456F: 05 ImpAdLdRf: 406008
404572: 24 NewIfNullPr 401b4c (MainForm)
404575: 0d VCallHresult put_FORECOLORFORM

LitVarI2 в псевдокодах что-то вроде push. А в исходнике первые строчки у меня были такие: Scale (0, 0)-(100, 100).

40456A: f5 LitI4: 0xff 255 (....)
40456F: 05 ImpAdLdRf: 406008
404572: 24 NewIfNullPr 401b4c (MainForm)
404575: 0d VCallHresult put_FORECOLORFORM

А вот из этого кода можно судить, что здесь меняется цвет на красный(#FF0000). Попробуем поменять цвет. В HIEW делаем Go To: ".40456A". Длина команды 5 байтов(40456A-404565). Там стоит: F5 FF 00 00 00. Меняем на F5 FF 22 FF 00. Теперь красный поменялся на фиолетовый :) Далее наблюдаем в EXDEC такой код:

40457A: f4 LitI2_Byte: 0x0 0 (.)
40457C: eb CR8I2
40457D: 08 FLdPr local_param_0008
404580: 06 MemLdRfVar local_param_0034
404583: f5 LitI4: 0x4e200 320000 (....)
404588: ec CR8I4
404589: Lead3/65 ForR4
40458F: 04 FLdRfVar local_00DC
404592: 0a ImpAdCallFPR4: 
404597: 04 FLdRfVar local_00DC
40459A: 0a ImpAdCallFPR4: 
40459F: 73 FStFPR4
4045A2: 04 FLdRfVar local_00EC
4045A5: 0a ImpAdCallFPR4: 
4045AA: 04 FLdRfVar local_00EC
4045AD: 0a ImpAdCallFPR4: 
4045B2: 73 FStFPR4
4045B5: f5 LitI4: 0x0 0 (....)
4045BA: 6e FLdFPR4
4045BD: f4 LitI2_Byte: 0x64 100 (d)
4045BF: eb CR8I2
4045C0: b3 MulR8
4045C1: 37 PopFPR4
4045C2: 6e FLdFPR4
4045C5: f4 LitI2_Byte: 0x64 100 (d)
4045C7: eb CR8I2
4045C8: b3 MulR8
4045C9: 37 PopFPR4
4045CA: f4 LitI2_Byte: 0x0 0 (.)
4045CC: 08 FLdPr local_param_0008
4045CF: 0d VCallHresult meth__imethPSET
4045D4: 36 FFreeVar
4045DB: 08 FLdPr local_param_0008
4045DE: 06 MemLdRfVar local_param_0034
4045E1: 68 NextStepR4: (continue) 40458F
4045E6: 21 FLdPrThis
4045E7: 0d VCallHresult meth__imethCLS

meth__imethPSET - это поставить точку, PSET в VB. meth__imethCLS - очистить, CLS в VB. NextStepR4 - это элемент цикла. В начале видно, что цикл пойдет от 0 до 0x4e200(320000). Также в HIEW меняем 0x4e200 на 000000. Теперь нормально :) Дальше можно наткнуться на такой код:

4045F9: 0d VCallHresult get__ipropTEXTEDIT
4045FE: 6c ILdRf local_00FC
404601: 4a FnLenStr
404602: f5 LitI4: 0x6 6 (....)
404607: db GtI4
404608: 2f FFree1Str local_00FC
40460B: 1a FFree1Ad local_00F8
40460E: 1c BranchF: 404772

Надеюсь, что делает get__ipropTEXTEDIT, объяснять не надо. И что такое FnLenStr тоже с виду понятно :) Здесь происходит сравнение на длину, можете проверить, поменяв 6 на другие числа. BranchF: 404772 - условный переход на 404772. Как они работают в VB, расскажу позже. Дальше видим такой код:

40468F: 08 FLdPr local_00F8
404692: 0d VCallHresult get__ipropTEXTEDIT
404697: 27 LitVar_Missing
40469A: 27 LitVar_Missing
40469D: 27 LitVar_Missing
4046A0: f5 LitI4: 0x10 16 (....)
4046A5: 1b LitStr: Hey
4046A8: 6c ILdRf local_00FC
4046AB: 2a ConcatStr
4046AC: 23 FStStrNoPop local_0100
4046AF: 1b LitStr: ! it’s a BAD C0DE >:))
4046B2: 2a ConcatStr
4046B3: 23 FStStrNoPop local_0104
4046B6: 1b LitStr:
4046B9: 2a ConcatStr
4046BA: 23 FStStrNoPop local_0108
4046BD: 1b LitStr: Try again!
4046C0: 2a ConcatStr
4046C1: 46 CVarStr local_00DC
4046C4: 0a ImpAdCallFPR4: 

ImpAdCallFPR4 - вызов функции. Тут непонятно, какой именно. Но по строчкам it’s a BAD C0DE >:)) можно догадаться, что это тот MsgBox :)) LitVar_Missing - это push аргумента, который программист опустил. Я например могу в VB написать просто: MsgBox "pizka", упустив остальные аргументы. ConcatStr - это соединение строк в одну. Тут я просто формировал обращение по введенному имени :)) А чуть выше такой код:

404648: 08 FLdPr local_param_0008
40464B: 06 MemLdRfVar local_param_0048
40464E: 4d CVarRef: ( local_0094 ) 4008
404653: 3e FLdZeroAd local_00FC
404656: 46 CVarStr local_00DC
404659: 0a ImpAdCallFPR4: 40520c
40465E: 1a FFree1Ad local_00F8
404661: 35 FFree1Var local_00DC
404664: 08 FLdPr local_param_0008
404667: 06 MemLdRfVar local_param_0038
40466A: 08 FLdPr local_param_0008
40466D: 8a MemLdStr
404670: 46 CVarStr local_0094
404673: 5d HardType
404674: Lead0/40 NeVarBool
404676: 1c BranchF: 4046E5

ImpAdCallFPR4 - снова вызов функции/процедуры, но уже 40520c. Раскрою секрет - это моя процедура GetCode. Чтоб написать нормальный кейген к этому крякмису, копайте ее. В листинге EXDEC есть такой код:

Proc: 40520c

404AC8: Lead2/16 ILdRfDarg local_param_000C
404ACE: Lead0/eb FnLenVar
404AD2: 28 LitVarI2: ( local_0254 ) 0x1 (1)
404AD7: Lead0/9c SubVar
...........................................

Хех, а почему процедура зовется 40520c, а начинается с 404AC8?? Потому что названия процедур даются по их концу, здесь это 40520c.

Теперь надо бы запатчить, что все время выдавалось сообщение о правильности кода(как мы патчили JE на JMP и т.д.:)). Только тут способ немного извращенней.
Команда BranchF - условный переход, начинается на 1C
Команда Branch - безусловный переход, начинается на 1E

Следовательно в HIEW меняем 1C на 1E по VA ".404676". И все нормально :)0
А вот если бы нам надо было вбить что-то вроде асмовского nop?? Вроде бы где-то в листингах псевдокодов я встречал подобную команду, но сейчас забыл :( тогда можно поставить безусловный переход на следующую команду! Как? Полностью команда у нас такая: 1C 9D 01. Где 019D - длина перехода, а 1C номер p-code функции. Длина перехода считается от начала процедуры. То есть 404548+19D. А для перехода на следующую процедуру нам нужна длина... 404679 - 404548 = 0131. Пропишем это в HIEW: 1E 13 01. И теперь всегда будет сообщение BAD C0DE, в независимости от правильности кода... Вот так.

Удачного исследования P-Code программ!

bi0w0rM[AHT]
22 июня 2004.

Комментарии

Добавил: andzol Дата: 04.12.2005

Hi!
Натолкнулся на эту статью по необходимости анализа VBasic программы. Нашел много полезного в статье, но возник вопрос:
-какой прогой можно Pcod представить в ассемблере.
-выбранный (вырезанный) кусок кода как вставлять в VB форму.

Добавил: Admin Дата: 08.01.2007

Для разбора P-Code качай VB Decompiler: http://www.vb-decompiler.org
Pro версия позволяет декомпилировать P-Code почти в исходный код


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


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

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

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

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





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