Эта статья посвящена новому способу защиты БД 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