[C/C++, шифрование] Самый удобный способ скрыть строку в EXE-файле
Чаще всего такая необходимость возникает тогда, когда в программе приходится хранить пароли в открытом виде. Лично у меня задача была несколько другая - получить возможность простым изменением одной-двух циферок в коде на выходе получить файл с новыми сигнатурами без использование пакеров и протекторов.
Строк в коде много, потому объявлять их в виде массива байт, предварительно закодировав внешним инструментом, - не вариант. А попытаться автоматизировать этот процесс - слишком хлопотно и чревато глюками.
И тут нам на помощь приходят макросы. Не знаю как в других компиляторах (кто дополнит?), но в MSVC все решается вот так (немного упростил код для примера):
//Ключ, которым будем XOR-ить
#define K1 77
// Макс. допустимая дл. строки тут 10 байт
#define MYCRYPT10(str) { MYCRYPT10_(str “\0\0\0\0\0\0\0\0\0\0″) }
#define MYCRYPT10_(str) (str)[0] ^ K1, (str)[1] ^ K1, (str)[2] ^ K1, (str)[3] ^ K1, (str)[4] ^ K1, (str)[5] ^ K1, (str)[6] ^ K1, (str)[7] ^ K1, (str)[8] ^ K1, (str)[9] ^ K1, ‘\0′
// Пример объявления
char szMyPlainTextPassword[] = MYCRYPT10(”superpass”);
Теперь в EXE строки будут уже в зашифрованном виде. Перед использованием этих строк в коде их необходимо расшифровать. Функция дешифровки:
void decrypt(char * buf) {
for (int i=0; i<10; i++)
buf[i]^=K1;
}
Перед обращением к строке (или сразу после загрузки приложения) делаем вызов: decrypt(szMyPlainTextPassword).В чем преимущество данного метода? Все строки (ключи реестра, ссылки, сообщения и т.д.) остаются в читабельном виде. Такой код удобно поддерживать и изменять.
Но еще остался вопрос - как удобней всего организовать шифрование ресурсов внутри EXE? Причем так, чтоб при каждой сборке набор байт был новый. У кого какие мысли будут?
Апрель 15th 2011 in Безопасность, Обо всем
Комментариев: 11 к записи “[C/C++, шифрование] Самый удобный способ скрыть строку в EXE-файле”
MSVC: шифрование строк внутри exe-файла - самый удобный способ
Прогулка по Москве, фото: красная площадь, московский кремль, ночная москва.
Случайные записи: поисковая оптимизация WordPress , щенки лабрадора
Dimm сказал 15 Апр 2011 at 14:24 #
Почему нельзя сделать многострочный макрос mycrypt и шифровать строку пока не встретим символ ? Зачем ограничение на размер? Если строка короче - то будет Access Violation…
сказал 15 Апр 2011 at 15:24 #
Этот макрос всего лишь разворачивает “хитрое” определение строки:
MYCRYPT10(”superpass”);
MYCRYPT10_(“superpass\0\0\0\0\0\0\0\0\0\0″)
char szMyPlainTextPassword[] = “superpass\0\0\0\0\0\0\0\0\0\0″[0]^K1, “superpass\0\0\0\0\0\0\0\0\0\0″[1]^K1, “superpass\0\0\0\0\0\0\0\0\0\0″[2]^K1… и т.д.
Max сказал 15 Май 2011 at 16:49 #
Интересный способ. Правда, не радует ограничение на размер строки.
Ресурсы я зашифровал, создав унаследованные от стандартных классов WTL (диалоги, иконки, битмапы и т.д), в которых ресурсы загружаются и расшифровываются динамически. А зашифровываются они после линковки специальной прогой. Прога генерит случайный пароль и вписывает его в ресурсы, после чего шифрует все ресурсы(кроме иконки программы и пароля) этим паролем.
сказал 18 Май 2011 at 13:37 #
Max, а можно чуть подробней про “Ресурсы я зашифровал, создав унаследованные от стандартных классов WTL (диалоги, иконки, битмапы и т.д), в которых ресурсы загружаются и расшифровываются динамически”?
Max сказал 19 Май 2011 at 19:25 #
Ну, к примеру, класс диалога наследуется от CIndirectDialogImpl, и в нем перегружается метод DoInitTemplate, в котором m_Template.m_pData присваивается указатель на загруженную вручную и расшифрованную структуру диалога. В битмапе перегружается метод LoadBitmap, в иконке LoadIcon.
Тем самым достигается вполне прозрачная работа со всеми ресурсными объектами.
Shakespeare сказал 01 Июн 2011 at 19:32 #
А для чего может понадобится скрывать какие-либо строки в exe ?
Max сказал 02 Июн 2011 at 13:27 #
От сигнатурного поиска антивирусов прятаться:-)
сказал 13 Сен 2011 at 17:20 #
А если вдруг “нужные” строки все равно будут появляться в EXE - убедитесь в отсутствии данной инструкции в коде:
#pragma optimize( “”, off )
Эрт сказал 26 Янв 2012 at 10:02 #
К сожалению дебаггером любое такое шифрование по месту использования данных или вызова функции ловится и там пароль уже в чистом виде. Поэтому шифрование данных без шифрования кода - отсекает, но только неопытных кулхацкеров.
Я в своё время брал кусок кода (со всякими критичными для работы вызовами-инициализациями-паролями) выносил в функцию. После сборки exe, небольшая утилита эту функцию по маркерам в .exe находит; шифрует (взбивка, замена, шум) файлом-ключиком и записывает обратно. На такой мусор забавно управление передавать Автоматизация “one click”. Ломается опять-же отладкой, но без ключика - слишком дорого.
сказал 26 Янв 2012 at 12:23 #
Эрт, тут вообще тема только про “сбитие” сигнатур. Само собой, что от кулхацкеров защита совсем другая.
А вот на счет поломки сигнатур кода - я ASM-метками почти все функции оборачиваю, а внешним консольным приложением прохожусь по ним и просто ксорю вшитым ключиком все (а после запуска приложение расшифровывает себя уже само).
Max сказал 27 Янв 2012 at 20:05 #
Очень интересно! Это, выходит, можно прямо в инсталляторе этой консольной прогой шифровать и иметь каждый раз разные экзешники. У меня в NSIS все файлы дополнительно шифруются. Таким образом, антивирю ничего не остается, как делать сигнатуры только на конкретный экземпляр инсталлятора.