(неизвестно)
Польза:
0
|
Добавлено: 2006-10-27, 12:05 Заголовок сообщения: Взлом защиты на cd/dvd |
|
|
Наконец, я решился на написание этой статьи, идея пришла давно, но
полностью систематизировать решился только сегодня. Сегодня мы не будем
рассматривать конкретного взлома. На это есть две причины:
1) У меня начал глючить CD-ROM, пора менять
2) Статья получилась бы слишком длинной
В принципе вторая причина меня волнует мало, но первая встала доста-
точно остро.
Хотя сдесь и будет в основном теоретический материал, о способах за-
щиты от копирования с CD и методах устранения такой нехорошести, но я
буду приводить и примеры игр, к сожалению, многое ломается на ходу и не
обременяешь себя запоминанием, поэтому примеры игры в основном одни и
те же.
Принципы и методы защиты
Сейчас я постараюсь написать все, когда либо встреченные методы за-
щиты:
1) Проверка на наличие диска
2) Проверка на метку тома
3) Проверка на наличие места
5) Проверка на наличие файла и его аттрибуты
5) Проверка на запись файла
6) Другие виды проверки
7) Некоторые общие моменты
1) Проверка на наличие диска
Я разделяю эти проверки на два класса:
1) Функцией GetDriveTypeA
Теория: Функция GetDriveTypeA возвращает в eax тип диска по его имени
Вот список возвращаемых значений.
0 -- - Невозможно определить тип
1 -- - Диск не найден
2 DRIVE_REMOVABLE - Гибкий (возможна замена)
3 DRIVE_FIXED - Жесткий (замена невозможна)
4 DRIVE_REMOTE - Сетевой диск
5 DRIVE_CDROM - CD-ROM
6 DRIVE_RAMDISK - RAM - Диск
Как часто встречается:
Такая проверка стоит на абсолютном большинстве ИГР.
Методы взлома:
1) Используя Soft-Ice/TRW2000 поставить бряк на эту функцию командой
bpx GetDriveTypeA и если после выхода в вызывающую программу, недалеко
стоит cmp eax, 00000005, то следует 5 исправить на 3, т.е. программа будет
искать не CD-ROM, а жесткий диск.
2) Дизассемблировать перейти к месту вызова функции, посмотреть, есть ли
сравнение. Это несколько модернизированный вариант пункта 1.
3) На эту идею я натолкнулся в статье Vadim M. "Как отучить игры от про-
верки CD-ROM (на примере Hellfire)". Краткое описание: поскольку функция
GetDriveTypeA вызывается из kernel32.dll будем править там, смысл, чтобы
все жесткие диски в системе были бы как CD-ROM'ы, этого легко достичь пере-
правив результат возвращаеммый функцией с 3 на 5, правдо это не всегда про-
ходит.
Примеры игр:
Project IGI, Deadly Dozen, и многие другие
2) Запись имя диска в реестр или файл
Как часто встречается:
Достаточно часто
Метод взлома:
Я использую такой метод, т.к. программа где-то сохранила имя CD-ROM'a,
значит, если мы изменим имя, то программа откажется запускаться, даже если
диск будет торчать в CDюке. Изменяем имя и если запускаться перестанет, то
ищем с помощью RegMon и FileMon, куда программа его запрятала.
Примеры игр:
Shockman (Шокмэн), записывала в файл WINDOWSfacked.ini
2) Проверка на метку тома
Теория: Метка тома проверяется с помощи функции GetVolumeInformation,
если эта функция вызывается, то почти однозначный вывод проверка метки
тома. Функция очень часто используется с категорией 1.
Как часто встречается:
Очень часто
Методы взлома:
1) Используя Soft-Ice/TRW2000 поставить бряк на эту функцию командой
bpx GetVolumeInformation. После этой процедуры скорее всего идет
процедура сравнения правильной метки с вашей. После процедуры переправить
переход.
2) Дизассемблировать перейти к месту вызова функции, посмотреть, есть ли
сравнение и т.д.. Это несколько модернизированный вариант пункта 1.
3) Если категорию 1 вы уже правили. Посмотреть метку тома на компакт-ди-
ске, и установить такую же на любом жестком диске.
4) Если категорию 1 не правили. Берем любой свой компакт с длинной метки
тома меньшей, либо равной длинне метки на ломаемом компакте. Ищем в испол-
няемых файлах программы, настоящую метку и заменяем ее нашей. Вывод если
Вы вставляете свой компакт, игра думает, что это ее родной.
Примеры игр:
Deadly Dozen
3) Проверка на наличие места
Теория: Наличие свободного места на диске проверяется функцией
GetDiskFreeSpace. Функция вызывается для того, чтобы проверить
что это за диск, ведь на CD свободного места нет.
Как часто встречается:
Бывает
Методы взлома:
Аналогичны методам 1 и 2 из 1 и 2 категории, только на другую функцию.
Примеры игр:
Была какая-то, но не помню названия.
4) Проверка на наличие файла и его аттрибуты
Теория: Один из распространившихся в последнее время приемчиков,
часто это используется для проверки видео. Которое не копируется на ЖД.
В основном используются такие функции:
GetFileAttributesA - Проверка аттрибутов файла
ReadFile - Чтение файла
GetFileSize - Получение размера файла
FindFirstFile - Поиск файла.
Как часто встречается:
Иногда
Метод взлома:
Я использую такой метод, запускаем FileMon. Затем запускаем игру, со
вставленным компактом. Потом сразу же выходим и смотрим, к каким файлам
шло обращение. Если файлы не большие можно скопировать их на ЖД, если есть
большие видео, то их можно заменить любыми другими видаками маленького
размера. В других случая придется править переходы. Если используются все
эти функции придется попотеть.
Примеры игр:
Project IGI, в этой игре были два файла по 1 байту, я их скопировал на
диск C: в корневой, изменил после GetDriveTypeA сравнение и все.
5) Проверка на запись файла
Теория: Для этого используются функции WriteFile и GetLastError.
Одна для записи файла другая для проверки ошибки, если они стоят подряд, то
это явно она.
Как часто встречается:
Ни разу не встречал
Метод взлома:
Чуть-чуть исправленный метод из предыдущей категории.
Примеры игр:
Я же сказал: "Не встречал!"
6) Другие виды проверки
Теория: Бывают и другие сильно замусоленные проверки
Как часто встречается:
На дисках компании "Русобит"
Метод взлома:
подробное инфо извлечения ключей
Примеры игр:
Казаки, Star Force.
7) Некоторые общие моменты
Часто в играх проверки объединены в одну общую процедуру. И удалив ее,
программа начинает работать.
Практически всегда программа защищена совокупностью защит, которые здесь
представлены в разных категориях.
8)
Прошел почти год с выхода первых Казаков, год как я полагаю не сидения сложа руки, и вот перед нами очередная игра от компании Russobit-M - Venom. Codename: Outbreak, также использующая систему защиты Star-Force.
Что представляет из себя защита?
По сравнению с Казаками налицо следующие усовершенствования: защита прочно обосновалась уже на трех прерываниях - INT0, INT1, INT3, соответственно затруднена не только отладка, но запуск игры с SoftICE, отладочные регистры DRx стали не только обнуляться, но и использоваться(!) самой защитой, часть данных одной из DLL настраиваются самой Star-Force, функции, сокрытые в _DllDispatch теперь тоже выполняются на своеобразном псевдокоде.
Запуск с SoftICE
Для запуска игры с SoftICE необходимо перед передачей управления собственно игре вернуть отладчику обработку INT1 и INT3. Для этого мы воспользуемся той же методикой, что и в прошлый раз: добавим к импорту файла Venom.exe свою DLL (vnm.dll), которая получив управление после starforce.dll (а так теперь называется главная DLL с защитой) перенастроит необходимые прерывания (см. исходник). Причем старые обработчики, принадлежащие Star-Force нужно сохранить, они нам еще пригодятся.
Снятие дампа
Дамп исполняемого файла в этой версии Star-Force удобно получить с помощью той же самой vnm.dll - когда управление будет у нее надо просто зациклить программу. Все, можно снимать дамп, например PEditor'ом.
Восстановление импорта
Импорт Venom'a защищен так же, как и импорт Казаков, только вот защищенных функций стало на порядок больше. Становится очевидно, что процесс восстановления нужно автоматизировать. Наиболее очевидное решение: написать программу, преобразующую код из импорта к первоначальному виду, и идентифицирующую его. Наиболее простое решение: преобразовать системные DLL таким образом, чтобы после всех видоизменений, внесенных Star-Force, код оставался элементарно идентифицируемым. Вот этим путем мы и пойдем.
Добавим к следующим системным DLL (т.к. Star-Force защищает только их функции) kernel32.dll, user32.dll, advapi32.dll по новой секции, и заменим в них таблицу экспорта. Экспорт ссылается на нашу секцию, а она в свою очередь содержит переходы на реальные функции.
Например:
push real_addr
ret
Когда Star-Force этот код преобразует, он станет выглядеть примерно так:
mov eax,real_addr
xchg eax,[esp]
То есть реальный адрес перед нами, и нам совершенно безразлично, какими ухищрениями защита видоизменяла код.
Важно!
Чтобы Windows загрузилась с видоизмененными библиотеками, следует помнить что
1) размер добавляемых секций должен быть обязательно выровненным
2) user32.dll и advapi32.dll сначала грузятся в память kernel32.dll по адресу, отличному от ImageBase, поэтому в процедуре перехода на реальный адрес нужно это предусмотреть, например так:
call $+5
pop eax
xor ax,ax
add eax,real_addr
push eax
ret
Настроив таким образом весь импорт на реальные адреса путем простого копирования из одной ячейки памяти в другую ;) , снова воспользуемся утилитой ImportList by Boris и получим нормальную секцию импорта. Помещаем ее в дамп.
Восстановление данных .BSS
Получив казалось бы нормальный дамп с восстановленным импортом, обнаруживаем, что дальше показа фона главного меню он не идет. Сравнение с оригиналом показало, что в нашем дампе не инициализировались некоторые значения секции .BSS библиотеки verender.dll, т.к. по всей видимости их должна была инициализировать Star-Force. Поскольку эти значения - это различные константы, адреса конкретных функций этой DLL и т.п., то мы можем безболезненно скопировать их (32h*4 байт) и жестко вшить в дамп. Для этого добавим к нему новую секцию (VA=548000h), содержащую в начале эти 30h*4 байт, а затем код (который теперь является новым EntryPoint'ом) такого вида:
mov edi,0200A7EB0 ; Листинг из Hiew ;)
mov esi,000548000
mov ecx,000000030
repe movsd ; Копирование 30h*4 байт
mov eax,020109688
mov d,[eax],0200FB438 ; Оставшиеся 2*4 байт
mov eax,02010954C
mov d,[eax],02026EF0C
push 00048DC04
retn
Теперь мы имеем практически полностью работоспособный дамп. Можно загружать игру, играть, выбирать в меню. Нельзя только стартовать новую миссию. На нашем пути вновь встал _DllDispatch.
Восстановление кода _DllDispatch
Идея перехвата сокрытого кода в памяти осталась прежней - ловушка на обращение к секции кода. Только реализация будет иная. В момент вызова _DllDispatch INT1 и INT3 обрабатываются SoftICE'ом; для корректной работы _DllDispatch возвращаем обработку этих прерываний Star-Force. Поскольку INT3 использовать мы уже не можем, станем обрабатывать INT6 (Invalid Opcode), а секцию кода будем перезаписывать значением 0FFh. Когда ловушка сработает, обработку INT1 и INT3 можно вновь вернуть SoftICE'у для удобства дальнейшей отладки.
Все, код найден? Найден псевдокод! В этом состоит одно из главных отличий от Казаков - защищаемая функция (а в Venom'е защищается всего лишь одна функция) выполняется на псевдокоде. Псевдокод несложный: отдельные его операции размежеваны значением 0F4h, значения между ними после нескольких преобразований в движке псевдокода превращаются в адрес памяти, содержащий элементарные операции, например mov ebx,[eax] или push dword ptr [ebx], т.е. регистры не используются напрямую в тех местах, где это касается логики работы защищенной функции - такая вот виртуальная минимашина. Если очередной разделитель отличен от 0F4h, идет call в основной код игры.
Наиболее очевидное решение: написать декомпилятор для этого псевдокода. Наиболее простое решение: встроить в дамп прямо сам псевдокод с его движком. Так мы и сделаем. Добавляем найденные 2 Kb псевдокода к нашей секции в дамп.
Понаблюдав за работой псевдокодового движка, мы замечаем, что
1) указатель на текущую интерпретируемую инструкцию псевдокода передается через стек
2) переход на интерпретирующую процедуру стоит непосредственно перед самым первым 0F4h псевдокода
Таким образом, чтобы корректно передать управление на псевдокод мы должны положить в стек адрес первого 0F4h псевдокода и прыгнуть на jmp стоящий перед ним, благо у нас есть ~10 байт. Значит пишем по адресу 473E48h нашего дампа (где раньше стоял вызов _DllDispatch) код:
mov eax,548116h ; Адрес первого 0F4h в нашем дампе
push eax
sub al,5
jmp eax
И пара штрихов в самом псевдокоде: подкорректируем значение указателя стека, хранящееся по адресу 549065h на 98F19Ch, и запретим пересылки в регистр DS, чтобы не получить сюрпризов на других операционных системах. Для этого ставим два nop'а по адресу 548772h и три по адресу 5486A2h.
Все, EXE-файл готов. И не забудьте пожалуйста удалить starforce.dll, зачем занимать лишнее место на диске? ;))
Исходный текст vnm.dll
vnm.asm (5K) - исходный текст, предназначен для компилирования как DLL в TASM 5.0
Заключение
Я очень надеюсь, что разработчики Star-Force уже приготовили для нас новые подарки, и нам не придется скучать, купив новые игры от Russobit-M. |
|