RCE.SU - реверсинг, кодинг, выделенные сервера, ICQ, proxy

Декомпилинг FoxPro на примере RostBif 4.2 Общепит.

[Исследование]

Subject: Cracking
Target: RostBif 4.2 Общепит
URL: rostbif.hypermart.net.
Author: aSL!
Date: 11.07.2001

Before starting!
Все ниже изложенное предназначено только для образовательных целей.

I. Вступление

Здравствуйте мои маленькие любители прекрасного! :)

Тут недавно наткнулся я на такую прогу, как RostBif 4.2 Общепит. Точнее, меня опросили ее поломать на предмет нахождения валидного ключа. Посмотрел я на нее и мне стало немножко не по себе. Почему? Дело в том, что она написана на Visual FoxPro 6.0, что является еще большим геморроем, чем небезызвестный VB. (Не, ну чего тянет MS на интерпретируемые продукты в P-коде?). Но как известно, невозможного не бывает.
"If program runs, it can be defeated?" (c) by +ORC. Не так ли? Но и многочасовое ковыряние с отладчиком меня тоже не прельщало. Тут я немного почесал то место, откуда волосы растут (Это голова, а не то, что вы подумали :)). И вспомнил я об одной замечательной проге, а именно о FoxPro decompiler'е. Единственным рабочим с VFP 6.0 мне вспомнился ReFox 8.0. Правда, в сети он доступен как Demo версия, также оччень много для него различных кряков, но, если честно, реально и полностью работающим является только один из всех мне известных. :)

II. Постановка задачи
  1. Необходимо сделать кейген, поскольку патчить P-код. (а он еще и оказался закриптованным) мне не прельщало.
III. Исследование

Необходимые инструменты:

  1. ReFox 8.0
  2. Драйвера hands.sys и bright_brain.vxd последних версий.

Итак, приступим...

Загружаем жертву в ReFox... Опа! ReFox, умная девочка, сама нашла нам код стартера:

Заходим туда. (Кстати, забыл сказать, что необходимо поставить в Options->Table View в Record, иначе у нас ничего не получится. И видим такой код:

IF .F.
_ANIPROG_ = (1E+45)
_REFOX_ = (1E+46)
ENDIF
_SCREEN.WINDOWSTATE = 2
_SCREEN.CAPTION = 'Ростбиф 4.2'
_PROGNAM = 'rostbif'
DO FORM start
*-eof

Что все это значит? А то, что автор оказался умным и попытался отключить ReFox. Но если версия целиком пропатчена, то это не страшно. Что же мы видим? А то, что в самом начале вызывается форма Start. Ищем ее. И скроллируем по компонентам:

Что это? А это событие Click у кнопки "Пуск", т.е. то, что происходит при клике на нее. Смотрим этот код внимательно. Меня в первую очередь интересуют следующие строки:

SET LIBRARY TO donlibr.prg
= USTSET()
SET CLASSLIB TO Kronos

Первым делом здесь выполняется функция USTSET из donlibr.fxp, а потом активным устанавливается класс Kronos.vcx. Смотрим дальше:

IF THISFORM.IEDICT()
THISFORM.ROS.LOADING
THISFORM.VISIBLE = .F.
LOCAL LRET
DO FORM getpassw TO LRET
IF LRET=.F.
THISFORM.VISIBLE = .T.
RETURN
ENDIF

Ага! тут значит из Kronos'а выполняется LOADING, а затем уже появляется форма "Введите пароль". Значит, именно в LOADING где-то и происходит проверка рег. кода. Ну что же. пора сдампить объект ROS из kronos.vcx. Ага: а вот и LOADING. А какие тут есть интересные строки, вы не находите?:

IF CHESTRU(LCHES,LCKEY)=.F.
DO FORM inckey WITH LCHES
LCKEY = ALLTRIM(CVAL)
IF CHESTRU(LCHES,LCKEY)=.F.
= MESSAGEBOX('Неверный ключ регистрации, узнайте в Rostbif Soft истинный ключ'+CHR(13)+'(http://rostbif.hypermart.net Email: support@rostbif.hypermart.net)'+CHR(13)+' А пока работает триал-режим', 64, 'Сообщение системы')
Хех! Так вот ты какой, северный олень :) Значит всем тут заправляет функция CHESTRU, если она возвращает TRUE (.T.), то все пучком, а вот если FALSE (.F.), то все ...
А что за CHESTRU и что за LCHES и LCKEY. Смотрим чуть выше:
IF FILE('uconfig.dbf')
...

Если существует uconfig.dbf, то продолжаем... Дальше идут функции открытия именно этого файла и т.д. Смотрим дальше:

GOTO TOP
LOCATE FOR UPPER(CVALNAM)='CHES'
IF FOUND()
REPLACE CVAL WITH RECHES(CNAME)
LOCAL LCHES
LCHES = ALLTRIM(CVAL)
PUBLIC PCCHES
PCCHES = LCHES

Угу. Идем в начало базы данных, ищем строку, в поле CVALNAM которого записано 'CHES', после этого пишем в поле CVAL результат функции RECHES от имени организации (Справочники->Константы). Не забываем записать в LCHES и PCCHES этот результат. Смотрим дальше... Чуть ниже:

GOTO TOP
LOCATE FOR UPPER(CVALNAM)='CKEY'
IF FOUND()
LOCAL LCKEY
LCKEY = ALLTRIM(CVAL)

Идем в начало. Ищем строчку, в поле CVALNAM которой записано CKEY. Читаем в LCKEY значение поля CVAL. Вот мы и выяснили откуда LCHES и LCKEY. Из базы данных. Дальше.
А откуда же функции RECHES и CHESTRU? А вернемся в start.scx. Там был загружен модуль donlibr.fxp. Сдампим и его. Что же мы видим? Опа!

FUNCTION reches
PARAMETER CNAM
LOCAL RT
RT = SYS(2007, CNAM)
RT = CHRTRAN(RT, '0123456789', '1726354908')
RETURN RT
ENDFUNC

FUNCTION chestru
PARAMETER CHES, CKEY
LOCAL RT, LCVAL
RT = .F.
LCVAL = CHRTRAN(CHES, '1726354908', '0123456789')
IF VAL(LCVAL)+VAL(CKEY)=1000000
RT = .T.
ENDIF
RETURN RT
ENDFUNC

Вот и ответ на все наши вопросы. Рассмотрим сначала функцию reches. Дано CNAM. От нее берется контрольная сумма (к сожалению, я не знаю алгоритма, если кто знает - напишите). После этого над контрольной суммой делаются нехитрые преобразования, а именно функция CHRTRAN. Что она делает? Да элеметарно. Привожу вырезку из FoxPro HELP:


CHRTRAN( ) Function

Replaces each character in a character expression that matches a character in a second character expression with the corresponding character in a third character expression.

Syntax

CHRTRAN(cSearchedExpression, cSearchExpression, cReplacementExpression)

[Skipped]

Remarks

CHRTRAN( ) translates the character expression cSearchedExpression using the translation expressions cSearchExpression and cReplacementExpression and returns the resulting character string.


Т.е. это ни что иное, как шифр подстановкой (aka шифр Цезаря).
Объясняю:
Берется символ из исходной строки и заменяется по следующему правилу:
'0'->'8'; '1'->'0'; '3'->'4'; '4'->'6'; '6'->'3'; '7'->'1'; '8'->'9'; '9'->'7';
Все! После этого функция RECHES возвращает это число, которое впоследствии становится LCHES.
Далее. Рассмотрим функцию CHESTRU. Вот она! Самая главная функция проверки. Что она делает? Во-первых, ей передаются два параметра, а она возвращает BOOLEAN типа TRUE, то все нормально, FALSE - нет. Опять также транслирует LCHES только в обратную сторону. А LCKEY, оказывается должен быть простым дополнением оттранслированного LCHES до 1000000. И все!
Получаем следующиа алгоритм действия:

  1. Читаем LCHES из uconfig.dbf. Это можно делать как на душу положит.
  2. Транслируем по приведенной выше таблице (только стрелочки в другую сторону).
  3. Вычитаем полученное число из 1000000
  4. Это и есть пресловутый LCKEY! Можно его сразу записать в таблицу, можно просто ввести в программу.
IV. Подводим итоги:

Принцип генерации серийника мы раскрыли. Но не могу же оставить все это просто так, без домашнего задания? Нееет. Не дождетесь. Ловите!
Если зайти в программу с паролем CAMRAD, то в меню "Сервис" будет такой пункт меню как "Регистрационный код", который, как оказалось позволяет делать все, что мы уже делали выше, только автоматом. Но вот незадача, просит какой-то пароль :)

Задача: найти этот пароль. (Кстати, с этим паролем можно заходить в программу и его нельзя сменить :)

HINT: Проанализировать функцию retckey из модуля donlibr.fxp и места ее вызова.

Вот собственно и все! :)

Endnote:
© 2001 aSL! (asl@aslsoft.com )
This essay can be freely distributed/ published/ printed etc... as long as no modifications are made in any way.
Greets to: Everyone in UOFG www.uofg.com.ua.


<= Вернуться к статьям

Rambler's Top100