Немой укор за компьютерный хардкор Крис Касперски Спецвыпуск: Хакер, номер #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); |