Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #48, НОЯБРЬ 2004 г.

Немой укор за компьютерный хардкор

Крис Касперски

Спецвыпуск: Хакер, номер #048, стр. 048-058-6


Сформированный линкером файл пока не пригоден для запуска, ведь защищенная функция еще не зашифрована! Чтобы ее зашифровать, запустим HIEW, переключимся в HEX-режим и запустим контекстный поиск маркерной строки (<F7> , "KPNC", <ENTER> ). Вот она! (см. рисунок 6). Теперь остается лишь зашифровать все, что расположено внутри маркеров "KPNC". Нажимаем <F3> и переходим в режим редактирования, затем давим <F8> и задаем маску шифрования (в данном случае она равна 66h). Каждое последующее нажатие на <F8> зашифровывает один байт, перемещая курсор по тексту. <F9>  сохраняет изменения на диске. После того как файл будет зашифрован, потребность в маркерах отпадает, и при желании их можно затереть бессмысленным кодом, чтобы защищенная процедура поменьше бросалась в глаза.

Вот теперь наш файл готов к выполнению. Запускаем его и… он, понятное дело, отказывает в работе. Что ж, первый блин всегда комом, особенно если тесто замешено на самомодифицирующемся коде. Призвав на помощь отладчик, здравый смысл и дизассемблер, попытаемся определить, что именно мы сделали не так.

Добившись успеха, загрузим исполняемый файл в IDA PRO и посмотрим, как выглядит зашифрованная функция. Бред сивой кобылы, да и только:

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

API-функция VirtualProtect позволяет манипулировать атрибутами страниц по нашему усмотрению. С ее помощью мы можем присваивать атрибут Writeable только тем страницам, которые реально нуждаются в модификации, и сразу же после завершения расшифровки отбирать его обратно.

Обновленный вариант функции crypt_it может выглядеть так:

crypt_it(unsigned char *p, int c)

{

int a;

// отключаем защиту от записи

VirtualProtect(p, c, PAGE_READWRITE, (DWORD*) &a);

// расшифровываем функцию

for (a = 0; a < c; a++) *p++ ^= 0x66;

// восстанавливаем защиту

VirtualProtect(p, c, PAGE_READONLY, (DWORD*) &a);

Назад на стр. 048-058-5  Содержание  Вперед на стр. 048-058-7