powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как быть с таблицами?
15 сообщений из 15, страница 1 из 1
Как быть с таблицами?
    #32772792
Finale!!!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот попала на сопровождение программа - судя по экранчику запуска = Fox Pro 2.6X for DOS все данные в dbf, fpt-файлах, индексы idx
но как открыть такие таблицы???
в аттаче примерчик одной из таблиц.. хитро разработчик зашифровал блин...
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32772801
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
рефокс исходник и ищи где есть раскриптование, ибо DBF имхо зашифровано
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32772807
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Finale!!!Вот попала на сопровождение программа - судя по экранчику запуска = Fox Pro 2.6X for DOS все данные в dbf, fpt-файлах, индексы idx
но как открыть такие таблицы???
в аттаче примерчик одной из таблиц.. хитро разработчик зашифровал блин...
Что тебе сказать... Зашифровано хорошо...
Вообще-то разработчик, если уж шифрует данные, должен был дать инструмент (утилиты) для администратора по работе со всем набором файлов внутри программы (просмотр, редактирование и т.д.)
Самое простое, что можно в этой ситуации сделать (если конечно нет утилиты для работы с файлами) - взломать программу при помощи ReFox'a (если она на самом деле Фоксовая) и посмотреть как в ней изнутри организована работа с подобными файлами. После этого, пишется процедура конвертации (шифрования/дешифрования) файла и запускается по мере надобности...
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32772859
Finale!!!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вот забыл сразу написать.. дык если бы РеФокс (у меня MMII) ее взял - я бы не мучил Вас вопросами.. но в том-то и дело что ни Рефокс не берет, ни ДеРефокс9 не берет
То что на ФПД 2,6 - сделал вывот из того, как выглядит экран запуска...
точно как бы запустили FoxPro.exe без параметра -T
+ ко всему в каталоге программы присутствуют
Foxd2600.esl, Foxd2600.eso, Foxuser.dbf, Foxuser.fpt
Ну да и сам не 1-й год на фоксе пишу...
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32772893
Alex Sheff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Давай мыло - скину рефокс для доса.
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32772976
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Finale!!!вот забыл сразу написать.. дык если бы РеФокс (у меня MMII) ее взял - я бы не мучил Вас вопросами.. но в том-то и дело что ни Рефокс не берет, ни ДеРефокс9 не берет
То что на ФПД 2,6 - сделал вывот из того, как выглядит экран запуска...
точно как бы запустили FoxPro.exe без параметра -T
+ ко всему в каталоге программы присутствуют
Foxd2600.esl, Foxd2600.eso, Foxuser.dbf, Foxuser.fpt
Ну да и сам не 1-й год на фоксе пишу...
А РеФокс пропатченный? Я имею ввиду, что не пропатченные могут не читать файлы с защитой типа Brand Level I, в то время как пропатченные - читают...
Если, однако, у тебя защищенный файл (защита типа Brand Level I+,II), то тебе можно только посочувствовать. Придется искать разработчика, выпрашивать у него исходники... Либо локально заняться хакерством, изучить на хорошем уровне ассемблер и таким способом найти процедуры кодирования/декодирования таблиц...
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32773046
XAndy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторЧто тебе сказать... Зашифровано хорошо...

Судя по примеру, не то чтобы хорошо - скорее совсем плохо :)
Если присмотреться к содержимому dbf, то невооруженным глазом видно кучу повторяющихся последовательностей, т.е. все "шифрование" наверняка свелось к наложению через xor короткой последовательности, может даже по записям. Смешно. Зная формат заголовка или наличие в конце текстовых полей пробелов, вычислить саму последовательность... Короче, детский лепет.
Но и этого не нужно - индекс то не зашифрован! А там тег по адресам есть, адреса в открытом виде лежат... Бери - не хочу :)
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32773056
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
единственное ч:е можна сказать - есть поле UL а таблица скорей фсего справочник улиц ;) Может уже лутше собрать этот справочник занова из Инета или как у нас в НиНо - их фсе можна выдрать из телефонного справочника 09 (:)

а то што пофторяющихся символоф в этой табличке нет - это уже имхо проверено ;))
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32773382
Finale!!!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
( = Судя по примеру, не то чтобы хорошо - скорее совсем плохо :)
Если присмотреться к содержимому dbf, то невооруженным глазом видно кучу повторяющихся последовательностей, т.е. все "шифрование" наверняка свелось к наложению через xor короткой последовательности, может даже по записям. Смешно. Зная формат заголовка или наличие в конце текстовых полей пробелов, вычислить саму последовательность... Короче, детский лепет.
Но и этого не нужно - индекс то не зашифрован! А там тег по адресам есть, адреса в открытом виде лежат... Бери - не хочу :) =

если б я знал как.. я ж хакерством не ханимаюсь.. разработчика даже нашел - но там разговор короток - "пшел ты на..."
то что это улицы я и так знаю :-)
но просто интересен сам метод + все же данные надо бы вытянуть ибо исходников не дают = пасить с начала придется...
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32773802
Maltsev Max
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так как IDX не зашифрован, то для использования базы он ее расшифровывает

Надо найти куда.

1) Смотри все файлы которые создаются на момент работы проги (в каталоге проги, в TEMP)
2) забирай их к себе :-))
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32773854
Finale!!!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TMP файлов там уйма... но в них тоже ничего нету...
да ладно все равно писать с нуля...
просто интересовался КАк реалишуется такая защита.. ибо сталкиваться с этим не приходилось до сих пор...
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32774560
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Maltsev Max!
Так как IDX не зашифрован, то для использования базы он ее
расшифровывает
Не факт - запросто можно построить индекс по уже расшиврованному полю (а
значит имеется UDF, которая расшифровывает таблицу).
Всё это можно увидеть в заголовке idx-а...
Скачаю файлик, посмотрю... Ибо по NNTP тока линк пока вижу.

Posted via ActualForum NNTP Server 1.1
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32776447
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Finale!!!

Да, dbf-ка зашифрована полностью (я думал что лишь сами поля будут
зашифрованы).
Это с одной стороны не очень хорошо, но с другой - это значит что во время
работы программы табличка скорее всего расшифровывается, и доступна в
совершенно открытом виде. Потому скачай с инета FileMon, и запустив
программу, отследи к каким файлам она обращается, какие создаёт - в общем
найди где же появляется расшифрованная dbf-ка. Я сильно сомневаюсь что тот
товарищ смог так обойтись с фоксом, что табличка расшифровывается только в
памяти... наличие незашифрованного idx также наводит на такие мысли.
Возможно что расшифровывается dbf в ту-же папку, где и лежит зашифрованная.
Если найдёшь где лежит раскрытая dbf, то можно попробовать после запуска
программы её (уже расшифрованную) скопировать в безопасное место - т.к.
скорее всего этот нехороший человек её сразу-же после расшифровки блокирует,
то надо пользоваться какими-либо средствами позволяющими копировать
блокированные файлы. Это проги из разряда Backup-оделателей. Вроде как даже
Rar имеет опцию открывать такие файлы.
Также как вариант - после запуска проги удушить её через TaskManager (убив
сам процесс! чтоб он не успел "нормально" завершиться и снова "закрыть"
dbf).
Ессно что всё это нужно делать, имея копию программы и всех файлов.
Также можно воспользоваться каким-либо Win32 отладчиком, и снять таблицу
прямо из кэша фокса (из памяти) - это конечно жутко мутурно, но если данные
нужны позарез...
Опять-же можно восстановить часть данных по индексам (при соблюдении конечно
ряда условий - типа индекс без FOR и не UNIQUE - ибо тогда просто не всё
будет в индексном файле).
Если у тебя есть более менее свежий фокс (я на VFP8 рисовал, но вроде должно
и на более старых работать - если что - подправь по надобности - ну там
FILETOSTR замени на FOPEN+FREAD...), то можешь ради прикола посмотреть вот
эту программульку - если не пропадёт желание, я её возможно доделаю до
более-менее приличного вида, пока она понимает лишь compact idx файлы и
текстовые ключи.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
LPARAMETERS tcIDXName
IF PCOUNT() <  1  OR VARTYPE(m.tcIDXName) # "C" OR ;
  EMPTY(m.tcIDXName) OR !FILE(m.tcIDXName)
 tcIDXName = GETFILE("Index:idx")
ENDIF
IF EMPTY(m.tcIDXName) OR !FILE(m.tcIDXName)
 ReportError(PROGRAM(), "Файл индекса не найден")
 RETURN .F.
ENDIF
PRIVATE lcIDX, lnKeyLen
LOCAL lnType, llIsCompact, lnRootPointer, lnLen, lcKey
* Считаем весь файл в переменную
lcIDX = FILETOSTR(m.tcIDXName)
* Определим/проверим тип IDX-а
lnType = ASC(SUBSTR(m.lcIDX,  15 ,  1 ))
IF BITTEST(m.lnType,  0 )
 ReportError(PROGRAM(), "UNIQUE индекс - можем восстановить лишь часть 
записей")
ENDIF
IF BITTEST(m.lnType,  6 )
 ReportError(PROGRAM(), "COMPOUND индексный файл  - временно не 
подерживается")
 RETURN .F.
ENDIF
* COMPACT индекс
llIsCompact = BITTEST(m.lnType,  5 )
IF !m.llIsCompact
 ReportError(PROGRAM(), "Не COMPACT индексный файл  - временно не 
подерживается")
 RETURN .F.
ENDIF
* Определим длинну ключа
lnRootPointer = Char2DWord(SUBSTR(m.lcIDX,  1 ,  4 ))
lnKeyLen = Char2Word(SUBSTR(m.lcIDX,  13 ,  2 ))
* Длинна ключевого выражения (учитывая нуль-терминатор)
lnLen = Char2Word(SUBSTR(m.lcIDX,  511 ,  2 ))
* Достанем само ключевое выражение
lcKey = SUBSTR(m.lcIDX,  513 , lnLen -  1 )
? "Key expression : " + m.lcKey
* Тут потом добавим извлечение FOR-выражения

* В данном курсоре мы и будем собирать извлекаемую информацию
CREATE CURSOR Result (nRecno I, cKey C(m.lnKeyLen))
ProcessNode(SUBSTR(m.lcIDX, m.lnRootPointer +  1 ,  512 ))
RETURN .T.

PROCEDURE ProcessNode
 LPARAMETERS tcNode AS String, m.tcKey AS String
  * Собственно пытается разобрать указанный узел
  * Заполняет курсор Result если это leafe-узел
  * Рекурсивно вызывает процедуру, если это промежуточный узел
  LOCAL lnType, lnKeyCnt
  lnType = Char2Word(SUBSTR(m.tcNode,  1 ,  2 ))
  lnKeyCnt = Char2Word(SUBSTR(m.tcNode,  3 ,  2 ))
  IF BITTEST(lnType,  1 )
   LOCAL lnRNMask, lnDupMask, lnTrailMask, ;
     lnRNBits, lnDupBits, lnTrailBits, lnEntrySize, lcPrevKey, ;
     lnPos, ln1, lcKey, lnRN, lnTrail, lnDup
   * leafe - заполним курсор
   * Предполагаем COMPACT стуктуру!
   lnRNMask = Char2DWord(SUBSTR(m.tcNode,  15 ,  4 ))
   lnDupMask = ASC(SUBSTR(m.tcNode,  19 ,  1 ))
   lnTrailMask = ASC(SUBSTR(m.tcNode,  20 ,  1 ))
   lnRNBits = ASC(SUBSTR(m.tcNode,  21 ,  1 ))
   lnDupBits = ASC(SUBSTR(m.tcNode,  22 ,  1 ))
   lnTrailBits = ASC(SUBSTR(m.tcNode,  23 ,  1 ))
   lnEntrySize = ASC(SUBSTR(m.tcNode,  24 ,  1 ))
   * Цикл по каждой из "запией" в данном узле
   lcPrevKey = m.tcKey
   lnPos =  0 
   FOR ln1 =  0  TO m.lnKeyCnt -  1 
    lcKey = SUBSTR(m.tcNode,  25  + m.ln1 * m.lnEntrySize, m.lnEntrySize)
    lnRN = BITAND(Char2DWord(SUBSTR(m.lcKey,  1 , CEILING(m.lnRNBits/ 8 ))), 
lnRNMask)
    lnTrail = BITRSHIFT(Char2DWord(SUBSTR(m.lcKey, FLOOR(m.lnRNBits/ 8 ) +  1 , 
 3 )), m.lnRNBits %  8 )
    lnDup = BITAND(m.lnTrail, m.lnDupMask)
    lnTrail = BITAND(BITRSHIFT(m.lnTrail, m.lnDupBits), m.lnTrailMask)
    lnPos = m.lnPos - (m.lnKeyLen - m.lnDup - m.lnTrail)
    lcKey = LEFT(m.lcPrevKey, m.lnDup) + ;
      SUBSTR(m.tcNode,  513  + m.lnPos, m.lnKeyLen - m.lnDup - m.lnTrail) + ;
      SPACE(m.lnTrail)
    INSERT INTO Result (nRecno, cKey) VALUES (m.lnRN, CPCONVERT ( 866 ,  1251 , 
m.lcKey))
    lcPrevKey = m.lcKey
   ENDFOR
  ENDIF
  IF BITTEST(lnType,  0 )
   LOCAL ln1, lcKey, lnRN, lnNextNode
   * промежуточный узел - заполним курсор
   * и рекурсовно вызовем эту же процедуру для узлов нижнего уровня
   * Предполагаем REGULAR (не compact) структуру!
   FOR ln1 =  0  TO m.lnKeyCnt -  1 
    lcKey = SUBSTR(m.tcNode,  13  + m.ln1 * (m.lnKeyLen +  8 ), m.lnKeyLen)
    lnRN = Char2DWord(SwapString(SUBSTR(m.tcNode,  13  + m.lnKeyLen + m.ln1 * 
(m.lnKeyLen +  8 ),  4 )))
*    INSERT INTO Result (nRecno, cKey) VALUES (m.lnRN, m.lcKey)
    lnNextNode = Char2DWord(SwapString(SUBSTR(m.tcNode,  17  + m.lnKeyLen + 
m.ln1 * (m.lnKeyLen +  8 ),  4 )))
    IF m.lnNextNode +  512  <= LEN(m.lcIDX)
     * Ссылка на следующий узел верна (узел существует)
     ProcessNode(SUBSTR(m.lcIDX, m.lnNextNode +  1 ,  512 ), m.lcKey)
    ENDIF
   ENDFOR
  ENDIF
 RETURN .T.
ENDPROC
FUNCTION Char2Word(tcInput AS String) AS Integer
 * Преобразует строку представляющую WORD (intel-порядка, т.е. big-endian)
 RETURN ASC(SUBSTR(m.tcInput,  1 ,  1 )) +  256  * ASC(SUBSTR(m.tcInput,  2 ,  1 ))
ENDFUNC
FUNCTION Char2DWord(tcInput AS String) AS Integer
 * Преобразует строку представляющую DWORD (intel-порядка, т.е. big-endian)
 RETURN ASC(SUBSTR(m.tcInput,  1 ,  1 )) +  256  * ASC(SUBSTR(m.tcInput,  2 ,  1 )) + 
;
    256 ^ 2  * ASC(SUBSTR(m.tcInput,  3 ,  1 )) +  256 ^ 3  * ASC(SUBSTR(m.tcInput,  4 , 
 1 ))
ENDFUNC
FUNCTION SwapString(tcInput AS String) AS String
 * Переворачивает строку (меняет порядок байт на обратный)
 LOCAL lcOutput, lnLen, ln1
 lcOutput = ""
 lnLen = LEN(m.tcInput)
 FOR ln1 =  0  TO m.lnLen -  1 
  lcOutput = m.lcOutput + SUBSTR(m.tcInput, m.lnLen - ln1,  1 )
 ENDFOR
 RETURN m.lcOutput
ENDFUNC
Запути, укажи idx файл, по завершении смотри в курсоре Result
восстановленные данные. Поле nRecno - это номер записи в исходной таблице.
На твоём idx-е оно вполне работает. Записи с "точкой" и "квадратиком" -
скорее всего были удалены из исходной таблицы, и названия в них "затёрты".
Если к таблице было несколько idx-ов, то можно восстановить все поля
входившие в индексные выражения (ну если ещё и декодирование для числового
формата сделать :) ).
В принципе зная структуру dbf-а (а заодно и добавив туда извлечённую из idx
информацию) можно организовать атаку KnownPlainText и выяснить каким паролем
закрыта таблица... У меня нету для этого достаточного образования, но если
есть знакомый математик (а лучше сразу узкий специалист - криптоаналитик),
то можешь попробовать...
На первый взгляд не видно, чтобы алогритм шифрования был совсем уж дубовый -
возможно применён один из известных нормальых алгоритмов - DES, наш ГОСТ
(сорри номера не помню)...

Posted via ActualForum NNTP Server 1.1
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32777237
XAndy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет, Игорь!

Ну ты молодец! А на счет этого:
авторвозможно применён один из известных нормальых алгоритмов - DES, наш ГОСТ
исключено. Там прослеживается явная периодичность, т.е. побайтовая замена даже без перестановки.
...
Рейтинг: 0 / 0
Как быть с таблицами?
    #32778594
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi XAndy!

Я не увидел последовательности. Как я понимаю тебе не нужно рассказывать как
примерно выглядит начало DBF-а, т.е. ты сам представляешь что там скажем
байты c 16 по 31 все нулевые, потом в блоке перечисления полей опять должны
идти довольно длинные последовательности из нулей...
Я уже сказал, что используя знания полученные из idx можно восстановить (с
некоторой долей вероятности конечно - порядка и числа прочих полей мы не
знаем) довольно большой кусок dbf-а и уж имея PlainText попытаться атаковать
шифр. Конечно если ты уверен что это именно простой шифр замены (XOR)...
Было-бы любопытно посмотреть результат.

Posted via ActualForum NNTP Server 1.1
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как быть с таблицами?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]