Сейчас на форуме: asfa, _MBK_, Rio (+7 невидимых)

 eXeL@B —› Вопросы новичков —› Помогите влезть в шифрованную базу данных через DLL
Посл.ответ Сообщение

Ранг: 2.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 25 декабря 2008 20:52 · Поправил: [Oleg]
· Личное сообщение · #1

У меня есть виндовая программа (специфичная в моей отрасли), которая является каталогом-справочником и на диске лежит как куча шифрованных файлов. Рядом лежит небольшое число нешифрованных DBF файлов. Если "походить" в программе (мышкой), то в памяти возникают небольшие расшифрованные куски базы. Сами таблицы крайне примитивны - тот же DBF или иной формат с простой фиксированной длиной строк.


За работу с данными отвечает отдельный bhdb.dll. Список его функций и назначение очевидны:


Code:
  1. 003B1000            .text      Export     a64l_W
  2. 003B58D0            .text      Export     DbErrorText_W
  3. 003B59D0            .text      Export     DbGetContext_W
  4. 003B59E9            .text      Export     DbSetContext_W
  5. 003B5A58            .text      Export     DbInitAndSize_W
  6. 003B5C18            .text      Export     DbInit_W
  7. 003B5C34            .text      Export     DbSetCat_W
  8. 003B5D38            .text      Export     DbLoad_W
  9. 003B5E9F            .text      Export     DbSelect_W
  10. 003B5F1F            .text      Export     DbGet_W
  11. 003B5FF0            .text      Export     DbGetSeq_W
  12. 003B60F2            .text      Export     DbSetRec_W
  13. 003B6139            .text      Export     DbCloseCat_W
  14. 003B61E1            .text      Export     DbDeinit_W
  15. 003B629A            .text      Export     DbRetrieveIndex_W
  16. 003B758B            .text      Export     DbLength_W
  17. 003B7627            .text      Export     DbLengths_W
  18. 003B7779            .text      Export     DbGetFieldNames_W
  19. 003B78DE            .text      Export     DbOffset_W
  20. 003BD6C1            .text      Export     <ModuleEntryPoint>                      3 arguments



Суть в том, как утащить эти шифрованные данные? Понимаю (в меру своих способностей) следующие варианты:


1. Как бы написать свою DLL, подсунуть вместо оригинала, а bhdb.dll подгрузить и вызывать функции прозрачно для самой проги. Тогда бы моя DLL, как прокси, все бы скинула в текстовые файлы на диске и готово. Писать в Borland C++ свои DLL и в коде загружать чужие, используя их функции (если иметь документацию по параметрам) - умею.

2. Я иду в Олю, руками смотрю адреса функций (либо прога сама вычислит адрес, поискав код DLL функций) и далее из своей проги вызываю у чужой программы функции bhdb.dll. Определять ID процесса и читать чужую память - умею. Вызывать чужие функции и получать результат - нет. Дописывать сложный код в чужие программы - не умею (если только пяток простых строк в пустых местах, забитых нулями). Внедрять в чужие запущенные процессы свои потоки - не умею.

3. Из своей софтины на С++ подгрузить bhdb.dll и прочитать базу. Затрудняет отсутствие документации по параметрам и не ясный до конца алгоритм оригинальной программы, как она сама вызывает функции.

4. Узнать алгоритм функцию чтения шифрованного файла базы данных и воспроизвести его на любом языке программирования. Слишком сложно для меня, много кода. Элементарно не отделить полезный код, когда библиотека ищет нужные строки по базе, от собственно алгоритма расшифровки. Как-то трейсил все подряд от момента открытия по CreateFile до выдачи текста - ничего не понял.

По поводу пунктов 1-2. Например, есть функция SELECT (bhdb.dll), которая по условиям основной программы читает и ищет нужные строки.


Code:
  1. bhdb.DbSelect_W    /$  55                PUSH EBP
  2. 003B5EA0            |.  8BEC              MOV EBP,ESP
  3. 003B5EA2            |.  83EC 08           SUB ESP,8
  4. 003B5EA5            |.  C745 F8 00000000  MOV DWORD PTR SS:[EBP-8],0
  5. 003B5EAC            |.  8B45 1C           MOV EAX,DWORD PTR SS:[EBP+1C]
  6. 003B5EAF            |.  C700 00000000     MOV DWORD PTR DS:[EAX],0
  7. 003B5EB5            |.  8B4D 08           MOV ECX,DWORD PTR SS:[EBP+8]
  8. 003B5EB8            |.  8379 28 00        CMP DWORD PTR DS:[ECX+28],0
  9. 003B5EBC            |.  75 04             JNZ SHORT bhdb.003B5EC2
  10. ....
  11. 003B5F0E            |.  8B55 1C           MOV EDX,DWORD PTR SS:[EBP+1C]
  12. 003B5F11            |.  8B45 FC           MOV EAX,DWORD PTR SS:[EBP-4]
  13. 003B5F14            |.  8B48 1C           MOV ECX,DWORD PTR DS:[EAX+1C]
  14. 003B5F17            |.  890A              MOV DWORD PTR DS:[EDX],ECX
  15. 003B5F19            |.  33C0              XOR EAX,EAX
  16. 003B5F1B            |>  8BE5              MOV ESP,EBP
  17. 003B5F1D            |.  5D                POP EBP
  18. 003B5F1E            \.  C3                RETN


Она вызывается из базовой программы кода с 6-ю параметрами:


Code:
  1. 00428DBB            |.  8B55 18           MOV EDX,DWORD PTR SS:[EBP+18]
  2. 00428DBE            |.  52                PUSH EDX                                ; /Arg6
  3. 00428DBF            |.  8B45 14           MOV EAX,DWORD PTR SS:[EBP+14]           ; |
  4. 00428DC2            |.  50                PUSH EAX                                ; |Arg5
  5. 00428DC3            |.  8B4D 10           MOV ECX,DWORD PTR SS:[EBP+10]           ; |
  6. 00428DC6            |.  51                PUSH ECX                                ; |Arg4
  7. 00428DC7            |.  8B55 0C           MOV EDX,DWORD PTR SS:[EBP+C]            ; |
  8. 00428DCA            |.  52                PUSH EDX                                ; |Arg3
  9. 00428DCB            |.  8B45 08           MOV EAX,DWORD PTR SS:[EBP+8]            ; |
  10. 00428DCE            |.  50                PUSH EAX                                ; |Arg2
  11. 00428DCF            |.  68 50154400       PUSH zpw.00441550                   ; |Arg1 = 00441550 ASCII "ZPW"
  12. 00428DD4            |.  FF15 80934300     CALL DWORD PTR DS:[<&btdb.DbSelect_W>] ; \DbSelect_W



Подскажите, что делать, в каком направлении изучать тему? Как внедриться в софт, чтобы заставить чужую DLL выдать данные?



Ранг: 123.7 (ветеран)
Активность: 0.10
Статус: Участник
1nn0$/100

Создано: 26 декабря 2008 10:16
· Личное сообщение · #2

Я правильно понимаю, что в приведенном примере функция Select лезет в шифрованую базу и в каком-то одном параметре на выходе получается расшифрованная строка? Или же строка зашифрована?

Я бы делал так: нашел бы интересующий параметр (если он визуально определяется) и дальше такой код в своей дллке:

func DbSelect
{
call DbSelect_Original
mov EAX, DWORD PTR [EBP-X] //где X увидели на предыдущем шаге перед передачей управления оригинальной функе
sprintf("%s", EAX)
return
}
Очень сорри за комбинацию языков =) смысл надеюсь понятен.

-----
Blame the victim!




Ранг: 2.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 26 декабря 2008 11:40
· Личное сообщение · #3

DbSelect - это аналог SQL запроса. Функция записыват в выделенный кусок памяти блок строк из базы. Строки из базы выбираются на основе самого запроса поиска. Кусок в памяти расшифрован и ищется в памяти программы. Расшифка базы происходит на этапе чтения файла из bhdb.dll, иначе поиска по параметрам не сделать. Основная программа получает чистые данные по запросу.

sprintf - это хорошо, но куда его писать? Если в свою сишную прогу, то нужно подключить bhdb.dll. С этим сложности. Ведь чтобы вызвать DbSelect, нужно правильно инициализировать систему: DbInit_W(), DbSetContext_W(), только потом DbSelect(). И самое главное - нужно же в функции передавать правильные указатели на какие-то блоки памяти!

Просто так отловить параметры одного запроса и посмотреть их в Оле не составляет никакого труда - бряк на функцию и в стеке (или в окне вызова функций) все видно. Допустим, я знаю один типичный запрос, чтения одной заданной таблицы, по одной строке по порядковому номеру. Как мне автоматизированно вызвывать DbSelect() и сохранять в своем файле очередной считанный кусок?

Наиболее простой для меня вариант в данной ситуации. Запустили Олю, поставили бряк на функцию и далее нужно
а) последовательно вызвать функцию со всем перечнем строк (от 0 до 999999)
б) сохранить результат в файл после отработки функции (указатель на нужный блок останется в стеке по фиксированному месту)



Ранг: 2.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 29 декабря 2008 14:09
· Личное сообщение · #4

граждане, неужели никто не умеет из своего процесса вызывать процедуры чужого процесса?

или метода, как написать свою DLL-прокси для замена оригинальной и сброса в лог всех передаваемых данных?

кто может обучить сему процессу в Питере на платной основе? В детстве, когда ходил на курсы асма, такому увы не учили



Ранг: 284.8 (наставник), 6thx
Активность: 0.150
Статус: Участник

Создано: 29 декабря 2008 18:02
· Личное сообщение · #5

счас думаю у народа сессия, поэтому мало кто отвечает.

ИМХО я бы сделал так:
1) написал длл-фильтр, т.е. пишешь свою длл bhdb.dll оригинал переименовываешь в bhdb_.dll
2) в своей длл создаешь точно такие же экспортируемые функции как и в оригинале bhdb.dll.
3) все функции работают как фильтр. т.е. имеют след. вид:

int MydbSelect(....// параметры которые передаются )
{
typedef int (WINAPI *OrignFunSelet)(... );

dll = LoadLibrary( "bhdb_.dll" );

Fun = GetProcAddress( dll , "DbSelect );

return Fun(...);
}

это грубый пример, но думаю будет понятно.

4) делаешь подмену и проверяешь что прога нормально работает, не глючит не и падает.

5) в код нужных функции добавляешь логику прохода по всем индексам таблицы или т.п. в общем делаешь что захочешь. инициализацию и раскриптовку базы сделает сама прога!!!!


 eXeL@B —› Вопросы новичков —› Помогите влезть в шифрованную базу данных через DLL
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати