Прозрачное шифрование баз данных Access
Эта статья посвящена новому способу защиты БД Access. Он имеет ряд преимуществ над существующими методами, которые я описал в статье Защита и взлом баз данных Access
Введение
Известно, что на сегодняшний день не существует способа защитить значения, хранимые в таблицах БД Access от прямого доступа. Либо защита удаляется с помощью программ типа dbRecowery, либо она накладывает серьёзные ограничения на производительность приложений работающих с БД и всё равно взламываются, но с большими трудозатратами.
Вот достоинства предлагаемого способа:
- защита устанавливается и снимается нажатием одной кнопки
- добавление защиты в код - добавление одной строки при подключении БД и изменить строку с паролем в коде.(больше ни чего менять не надо)
- её нельзя снять программами типа dbRecowery
- её использование почти не сказывается на производительности
- можно использовать ADO или DAO
- защищающий код можно интегрировать в VB проект (2 класса и 2 модуля)
- не надо платить за программы и электронные ключи
Вот его недостатки:
- реализовано в виде Active-X dll на Visual Basic 6 (не удалось сделать на VBA)
- работает только на чтение данных (запись не реализована)
- работает под WinXP; должно работать под 2k; под 98 - не работает (надо доделывать)
О тестовом проекте
- data.mdb - защищенная БД с двумя таблицами и одним запросом
- user.mdb - БД с формой 'main' в которую выводятся данные из data.mdb с помощью Protect.dll
- Protect.dll - ищет data.mdb в той же директории, где и сама и возвращает ADODB.Recordset
для регистрации необходимо выполнить в командной строке 'regsvr32.exe [Ваш путь к]\Protect.dll'
Описание способа защиты
Данный способ основан на использовании прозрачного шифрования. При таком подходе работающая с данными программа не замечает, что данные зашифрованы. Иными словами, когда библиотеки ADODB нашей программы обращаются к файлу БД - они видят самый обычный файл. Но если с этими данными начинает работать чужая программа - она видит зашифрованные данные. Подобный подход используется в HASP Envelope. Но с его помощью шифруется весь файл, что сильно снижает производительность. Между тем, достаточно зашифровать только заголовок БД чтобы получить приемлемый уровень защиты.
Для работы с БД Access в настоящее время используется ADODB. Сначала создаётся подключение к файлу БД (ADODB.Connection). Когда заданы все параметры подключения - вызывается метод Open, который открывает БД. При этом, происходит чтение первых &H10000 байт файла БД. Здесь и срабатывает защита. Мы эти &H10000 байт предварительно зашифруем. Программа перехватывает вызов API функции ReadFile, сама считывает заголовок БД, и возвращает дешифрованные данные.
Чтобы перехватить вызов API функции ReadFile необходимо сделать следующее:
- получить идентификатор процесса с помощью функции GetCurrentProcessId
- получить описатель процесса, используя OpenProcess
- получить адрес замещающей функции, используя AddressOf
- получить описатель модуля kernel32 с помощью GetModuleHandle
- получить адрес функции ReadFile с помощью GetProcAddress
- прочитать и сохранить первые оригинальные 6 байт стандартной API функции ReadFile с помощью ReadProcessMemory
- записать с помощью WriteProcessMemory вместо этих 6 байт код ASM инструкции push и ret, указав в качестве аргумента инструкции push адрес замещающей функции
Таким образом, сначала мы меняем код API функции ReadFile на вызов нашей замещающей функции. Поле вызова метода Open объекта Connection - одна из библиотек ADODB начинает читать файл БД, используя ReadFile. Так как эта функция была нами модифицирована - она обращается к замещающей функции.
Замещающая функция имеет тот же набор аргументов, что и оригинальная ReadFile. Таким образом, получив управление в свои руки, мы знаем - откуда и сколько надо считать и куда результат поместить. При вызове замещающеё функции происходит следующее:
- возвращаем оригинальные 6 байт стандартной API функции ReadFile на место с помощью WriteProcessMemory
- вызываем ReadFile с теми же аргументами, с какими её вызывала библиотека ADODB
- так как нам известен размер считанных данных и адрес, куда они были прочитаны - мы дешифруем эти данные
- всё. библиотека ADODB получает управление обратно, даже не заметив наших действий. С её точки зрения - она просто вызвала функцию ReadFile, которая считала блок данных из файла. Повторное чтение файла функцией ReadFile будет происходить как обычно, так как мы вернули её в исходное состояние
Развитие проекта
- Этот материал ранее был опубликован на sql.ru в форуме по Access
- Предлагаю поучаствовать в дальнейшем совершенствовании этой технологии. На мой взгляд, она достаточно эффективна в плане защиты, проста в использовании и пригодна для добавления в существующие проекты
- Может, кому удастся перевести код на VBA. Основная проблема в использовании AddressOf. В таком случае можно будет интегрировать код в mde файл, и избежать той глупой ошибки, которую я допустил, возвращая Recordset из Active-X dll
- Также можно реализовать не только чтение, но и запись заголовка и сделать возможной работу под win98
Скачать пример Sample.zip 131 КБ