Техника защиты компакт-дисков от копирования

Способы разоблачения защитных механизмов


Защита, нуждающаяся в низкоуровневом доступе кс CD, обязательно выдаст себя наличием функций DeviceIoControl и/или SendASPI32Command в таблице импорта. Если же защитный механизм загружает эти функции динамически, "поймать его за хвост" можно установкой точек останова на LoadLibrary/GetProcAddress

[Y148][n2k149] (однако опытные программисты могут отважиться на самостоятельный поиск требуемых им функций в памяти, –— и это отнюдь не такая трудная задача, какой она кажется).

Также в теле программы могут присутствовать строки: "\\.\", "SCSI", "CdRom", "Wnaspi32.dll" и другие. Установив точку останова на первый байт строки, мы сможем мгновенно локализовать защитный код при первом его к ним обращении. Чтобы этого не произошло, разработчики часто шифруют все текстовые строки, однако большинство из них ограничивается примитивной статической шифровкой (которая обычно осуществляется программой ASPack'ом или подобныподобнойми ейму программами), а потому, если дождаться завершения расшифровки и вызвать отладчик после, а не до запуска программы, все текстовые строки предстанут перед нами в прямом виде! Динамическая шифровка намного надежней. В этом случае текстовые строки расшифровываются непосредственно перед их передачей в соответствующую API-функцию, а потом зашифровываются вновь. Но и динамическую шифровку при желании можно преодолеть! Достаточно поставить условную точку останова на функцию CreateFile, которой эти текстовые строки и передаются, всплывая в том и только в том случае, если первые четыре байта имени файла равны "\\.\". Пример ее вызова может выглядеть, например, так: "bpx CreateFileA if (*esp->4=='\\\\.\\')", после чего останется только "пожинать урожай".

Естественно, под "урожаем" понимается, во-первых, имя самого открываемого файла, а точнее –— драйвера (это уже многое что дает), и, во-вторых, возращенный функцией CreateFile дескриптор.
Какие же фокусы используют разработчики, чтобы затруднить анализ драйверов? Ну, вот, например: шифруют текстовую строку с символьным именем устройства, которое создает драйвер при своей загрузке. В результате, хакер точно знает, что защитный код открывает устройство "\\.\MyGoodDriver", но не может быстро установить: какому именно драйверу это имя соответствует. Если же шифровка отсутствует, то задача решается простым контекстным поиском. Вот, например, захотелось нам узнать: какой именно драйвер создает устройство с именем MbMmDp32 –— заходим при помощи файлового менеджера [n2k150] FAR'ом в папку WINNT\System32\Drivers, нажимаем <ALT>+<-F7> и в строку поиска вводим "MbMmDp32", не забыв установить флажок "Use all installed character tables" (в противном случае менджер FAR ничего не найдет, т. к. строка должна задаваться в Unicodeуникоде). Прошуршав некоторое время диском, файловый менеджер FAR выдаст единственно правильный ответ: ASPI32.SYS. Это и есть тот самый драйвер, который нам нужен! А теперь представьте, что строка с именем зашифрована… Если драйвер загружается динамически, то это еще полбеды: просто ставим точку останова на функциюи IoCreareDevice и ждем "всплытия" отладчика. Затем даем команду P RET и по карте загруженных моделей (выдаваемых командой mod) смотрим –— кто "проживает" в данном регионе памяти. С драйверами, загружающимися вместе с самой операционной системой, справиться значительно сложнее и, как правило, отыскивать нужный драйвер приходится методом "тыка". Часто в этом помогает дата создания файла, –— драйвер, устанавливаемый защищенным приложением, должен обычно имееть ту же самую дату создания, что и остальные его файлы. Однако защитный механизм может свободно манипулировать датой создания по своему усмотрению, так что это не очень-то надежный прием. Хороший результат дает сравнение содержимого каталогадиректории WINNT\System32\Drivers до и после инсталляции защищенного приложения, –— очевидно, защита может скрываться только среди вновь появившихся драйверов.


Содержание раздела