Если вы хотите защитить базу данных, которая используется в вашей программе, то эта информация окажется вам полезной. Возможно нужно улучшить защиту, например, шифруя значения базы данных и расшифровывая их при выводе.
Итак. Есть программа с папкой DATA, данные из которой очень хочется получить.
Есть несколько вариантов.
Для начала нужно узнать в каком формате хранятся данные в программе. Можно воспользоваться бесплатной программой TrID. Пробуем ...
Печаль. Что-то не известное. Похоже на какой-то собственный формат на основе ole datastore. Если это действительно так и разработчики решили заморачиваться и писать собсвенную СУБД то извлечь данные будет очень сложно и долго. Проще будет воспользоваться вариантом 1.
Но, все программисты ленивые и скорее всего это какой то известный формат. Например Access или Firebird. Я бы так сделал. Поискал в каталоге с программой, нет никаких библиотек.
Исследуем дальше. Скачиваем очень полезную бесплатную утилиту с Process explorer, которая показывает все обращения программы к реестру, файлам и всему что возможно.
Запускаем, настраиваем, чтобы моиторила только один процесс catalog.exe — главный исполняемый файл программы.
Запускаем программу и смотрим, куда она обращается.
О! Она использует ODBC источник данных. Скорее всего используемая бд это access! Ставим себе плюсик. Смотрим дальше. Есть интересный ключ в реестре TraceSQLMode. Погуглив выясняется, что все запросы можно писать в файл. Меняем ключик и ищем файл. Нашли:
Смотрим запросы:
Табличка называется spare, что в переводе означает запасная часть. Значит это не вспомогательня БД и там действительно хранятся наименования деталей. Отлично. Смотрим дальше.
Идет обращение к файлу БД не в каталоге с программой. Значит он временно туда копируется. Пробуем открыть в access — без результата, не понимает.
Делаем действие в программе, переключаемся ну другую позицию в каталоге, смотрим более внимательно на лог:
Перед запросом происходят модификации файла, что-то в него пишется. Вероятно он или расшифровывается или меняется заголовок файла. Теперь это уже не важно, т.к понимаем, что если до запроса скопировать этот файл, то с большей долей вероятности он окажется рабочим.
Значит нужно как-то приостановить выполнение программы до запроса, пока файл рабочий. Правильно, трассировкой в дебаггере. Скачиваем дебаггер, например, бесплатный OllyDbg весом 1.3МБ.
Запускаем в режиме администратора, если у вас windows vista и выше.
Присоединяемся к запущенному процессу (attach)
Выбираем наш процесс:
Возвращаемся в Process Explorer и смотрим стек вызова функции (в контекстном меню события):
Точку останова можно поставить на вызове закрытия файла CloseHandle в системном модуле kernel32.dll.
Переходим в этот модуль в дебаггере:
Находим нужную функцию:
Ставим точку остановки (Breakpoint) — F2.
Дальше запускаем выполнение программы, нажав F9. И делаем какое либо действие в подопытной программе. Программа остановится на брекпоинте.
Трассируем (F8) в дебаггрере, пока не появятся записи обращения к реестру перед выполнением запроса. Это будет означать, что файл БД модифицирован для подключения к нему и он пригоден для чтения.
После этого переходим к файлу и копируем его в другое место:
Смотрим, что за файл теперь:
100% mdb! Это файл MS Access. Переименовываем, открываем, убеждаемся, что все хорошо.
Мы успешно получили БД, пригодную для дальнейших модификаций или конвертирования в другой формат.
Раз уж начал писать, то выложу скрипт на groovy для конвертирования данных из MS Access в PostgreSQL БД.
вот он:
Запускается интерпретатором:
Выводы: Чтобы защитить базу нужно либо (самое надежное) писать данные в собственном формате, либо шифровать значения в базе данных и разархивировать непосредственно при отображении, а так же использовать вспомогательные методы защиты, например шифровать сам файл, менять сигнатуру файла, использовать встроенные средства шифрования бд.
P.S. Автор этой статьи — Александр Суровцев. Если материал вам понравился, помогите ему пожалуйста получить инвайт на Хабр. Свои инвайты я, к сожалению, все раздал. Адрес его электронной почты — surovtsev.alex на gmail.com, твиттер — mobal1 Большое спасибо!
Итак. Есть программа с папкой DATA, данные из которой очень хочется получить.
Есть несколько вариантов.
- Превый вариант. Можно пойти сложным путем, снимая скриншоты и экспортируя заявки по одной в excel. Но это долгий способ и неинтересный.
- Второй вариант. Подумать и раскодировать данные.
Для начала нужно узнать в каком формате хранятся данные в программе. Можно воспользоваться бесплатной программой TrID. Пробуем ...
Печаль. Что-то не известное. Похоже на какой-то собственный формат на основе ole datastore. Если это действительно так и разработчики решили заморачиваться и писать собсвенную СУБД то извлечь данные будет очень сложно и долго. Проще будет воспользоваться вариантом 1.
Но, все программисты ленивые и скорее всего это какой то известный формат. Например Access или Firebird. Я бы так сделал. Поискал в каталоге с программой, нет никаких библиотек.
Исследуем дальше. Скачиваем очень полезную бесплатную утилиту с Process explorer, которая показывает все обращения программы к реестру, файлам и всему что возможно.
Запускаем, настраиваем, чтобы моиторила только один процесс catalog.exe — главный исполняемый файл программы.
Запускаем программу и смотрим, куда она обращается.
О! Она использует ODBC источник данных. Скорее всего используемая бд это access! Ставим себе плюсик. Смотрим дальше. Есть интересный ключ в реестре TraceSQLMode. Погуглив выясняется, что все запросы можно писать в файл. Меняем ключик и ищем файл. Нашли:
Смотрим запросы:
SELECT
…
FROM spare LEFT JOIN photo ON photo.serial = spare.serial
Табличка называется spare, что в переводе означает запасная часть. Значит это не вспомогательня БД и там действительно хранятся наименования деталей. Отлично. Смотрим дальше.
Идет обращение к файлу БД не в каталоге с программой. Значит он временно туда копируется. Пробуем открыть в access — без результата, не понимает.
Делаем действие в программе, переключаемся ну другую позицию в каталоге, смотрим более внимательно на лог:
Перед запросом происходят модификации файла, что-то в него пишется. Вероятно он или расшифровывается или меняется заголовок файла. Теперь это уже не важно, т.к понимаем, что если до запроса скопировать этот файл, то с большей долей вероятности он окажется рабочим.
Значит нужно как-то приостановить выполнение программы до запроса, пока файл рабочий. Правильно, трассировкой в дебаггере. Скачиваем дебаггер, например, бесплатный OllyDbg весом 1.3МБ.
Запускаем в режиме администратора, если у вас windows vista и выше.
Присоединяемся к запущенному процессу (attach)
Выбираем наш процесс:
Возвращаемся в Process Explorer и смотрим стек вызова функции (в контекстном меню события):
Точку останова можно поставить на вызове закрытия файла CloseHandle в системном модуле kernel32.dll.
Переходим в этот модуль в дебаггере:
Находим нужную функцию:
Ставим точку остановки (Breakpoint) — F2.
Дальше запускаем выполнение программы, нажав F9. И делаем какое либо действие в подопытной программе. Программа остановится на брекпоинте.
Трассируем (F8) в дебаггрере, пока не появятся записи обращения к реестру перед выполнением запроса. Это будет означать, что файл БД модифицирован для подключения к нему и он пригоден для чтения.
После этого переходим к файлу и копируем его в другое место:
Смотрим, что за файл теперь:
100% mdb! Это файл MS Access. Переименовываем, открываем, убеждаемся, что все хорошо.
Мы успешно получили БД, пригодную для дальнейших модификаций или конвертирования в другой формат.
Раз уж начал писать, то выложу скрипт на groovy для конвертирования данных из MS Access в PostgreSQL БД.
вот он:
import groovy.sql.Sql
java.util.Properties prop = new java.util.Properties();
prop.put(“charSet”, “cp1251”);
sourceSql = Sql.newInstance(‘jdbc:odbc:catalog2’,prop)
targetSql = Sql.newInstance(“jdbc:postgresql://localhost:5432/catalog”,”catalog”,”catalog”, “org.postgresql.Driver”)
def images = targetSql.dataSet(“image”);
sourceSql.eachRow(‘select * from image’) {
def id = it.id
images.add(id:id,block:it.block);
def image=it.getProperty(“image”)
if (image) {
File f = new File(“D:/trid_w32/images/” + id + “.png”);
f.append(image);
}
}
def coords = targetSql.dataSet(“coord”);
sourceSql.eachRow(‘select * from coord’) {
coords.add(id:it.id,block:it.block,x:it.x,y:it.y,r:it.r);
}
def spares = targetSql.dataSet(“spare”);
sourceSql.eachRow(‘select * from spare’) {
spares.add(id:it.id,parent:it.parent,num:it.num,serial:it.serial,count:it.count,spec:it.spec,apply:it.apply,ru:it.ru,cn:it.cn);
}
Запускается интерпретатором:
groovy имя_скрипта.groovy
Выводы: Чтобы защитить базу нужно либо (самое надежное) писать данные в собственном формате, либо шифровать значения в базе данных и разархивировать непосредственно при отображении, а так же использовать вспомогательные методы защиты, например шифровать сам файл, менять сигнатуру файла, использовать встроенные средства шифрования бд.
P.S. Автор этой статьи — Александр Суровцев. Если материал вам понравился, помогите ему пожалуйста получить инвайт на Хабр. Свои инвайты я, к сожалению, все раздал. Адрес его электронной почты — surovtsev.alex на gmail.com, твиттер — mobal1 Большое спасибо!