Защита игр от взлома

         

типичный представитель стартового кода


Точка останова на GetModuleHandleA.

Вызов API-функции GetModuleHandleA сразу же бросается в глаза. Если хакер установит сюда точку останова, отладчик/дампер "всплывет" в start-up коде, еще до передачи управления WinMain (так же можно поставить точки останова на GetVesion/GetVersionEx, GetCommandLine, GetStartupInfo и т. д.). Если точка останова программная, распаковщик может обнаружить ее по наличию ССh в начале API-функции, и, с некоторой долей риска, снять. Если второй байт функции равен 8Bh, то это, очевидно, стандартный пролог, первый (оригинальный) байт которого равен 55h. Получаем права на запись через VirtualAlloc, меняем CCh на 8Bh и продолжаем распаковку в обычном режиме. Пусть хакер крякнет! Правда, в последующих версиях Windows пролог API-функций может быть модифицирован и тогда этот трюк не сработает.

Отладочные регистры. Аппаратную точку останова можно обнаружить через чтение регистров Drx. Команда mov eax,DrX на прикладном уровне приводит к исключению, кроме того, отладчик (теоретически) может отслеживать обращение к отладочным регистрам, чтобы маскировать свое присутствие – все необходимое для этого x86 процессоры предоставляют, но! Если распаковщик прочитает свой контекст, он сможет дотянуться и до Drx, причем не только на чтение, но и на запись! То есть, можно не только обнаружить точки останова, но и обезвредить их! Весь вопрос в том, как получить контекст. Чтение SDK выявляет API-функцию GetThreadContext, которая как раз для этого и предназначена, однако, пользоваться ей нельзя, иначе хакер установит сюда точку останова и защита проиграет войну! Надо действовать так: регистрируем из распаковщика собственный обработчик SEH, возбуждаем исключение (делим на ноль, обращаемся по недействительному указателю) и... получаем контекст в одном из аргументов структурного обработчика. Что остается делать хакеру? Правильно! Устанавливать точку останова на fs:0, где и хранится указатель на SEH обработчик (только до этого додумается не каждый хакер).


Структурные исключения. Кстати, о fs:0. Первое, что делает стартовый код, это регистрирует собственный SEH-обработчик, поэтому установка точки останова на fs:0 позволяет хакеру всплыть сразу же после завершения распаковки, следовательно, распаковщик должен обращаться к этой ячейке как можно чаще. Десятки или даже тысячи раз, причем ложить туда не абы что, а именно ESP, иначе хакер установит условную точку останова (soft-ice это позволяет) и легко обойдет защиту.

Поиск по сигнатуре. Козырный хакерский трюк — взломщик снимает дамп с работающей программы, находит там стартовый код по сигнатуре, определяет его адрес и ставит на его начало аппаратную точку останова (программную ставить нельзя, она будет затерта при распаковке). Разработчику защиты необходимо либо распознавать аппаратные точки останова и снимать их, действия по методике, описанной выше, либо использовать модифицированный стартовый код, который не сможет распознать хакер.

Контроль за $PC. А вот еще один трюк. Большинство распаковщиков располагаются в стороне после распакованного кода и при передаче управления на оригинальную точку входа прыгают куда-то далеко. Хакер может использовать этот факт как сигнал, что распаковка уже завершена. Конечно, установить аппаратную точку останова на это условие уже не удастся и придется прибегнуть к пошаговой трассировке (которой легко противостоять), но ради этого случая хакер может написать и трейсер нулевого кольца. Это не сложно. Сложно определить когда же заканчивается распаковка. Контроль на $pc (в терминологии x86 – eip) – это единственный универсальный способ, который позволяет это сделать без особых измен и чтобы обломать хакера, распаковщик должен как бы "размазывать" себя вдоль программы, тогда он победит!


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