The Prodigy

[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-файле”

  1. Dimm сказал 15 Апр 2011 at 14:24 #

    Почему нельзя сделать многострочный макрос mycrypt и шифровать строку пока не встретим символ ? Зачем ограничение на размер? Если строка короче - то будет Access Violation…

  2. сказал 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… и т.д.

  3. Max сказал 15 Май 2011 at 16:49 #

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

  4. сказал 18 Май 2011 at 13:37 #

    Max, а можно чуть подробней про “Ресурсы я зашифровал, создав унаследованные от стандартных классов WTL (диалоги, иконки, битмапы и т.д), в которых ресурсы загружаются и расшифровываются динамически”?

  5. Max сказал 19 Май 2011 at 19:25 #

    Ну, к примеру, класс диалога наследуется от CIndirectDialogImpl, и в нем перегружается метод DoInitTemplate, в котором m_Template.m_pData присваивается указатель на загруженную вручную и расшифрованную структуру диалога. В битмапе перегружается метод LoadBitmap, в иконке LoadIcon.
    Тем самым достигается вполне прозрачная работа со всеми ресурсными объектами.

  6. Shakespeare сказал 01 Июн 2011 at 19:32 #

    А для чего может понадобится скрывать какие-либо строки в exe ?

  7. Max сказал 02 Июн 2011 at 13:27 #

    От сигнатурного поиска антивирусов прятаться:-)

  8. сказал 13 Сен 2011 at 17:20 #

    А если вдруг “нужные” строки все равно будут появляться в EXE - убедитесь в отсутствии данной инструкции в коде:

    #pragma optimize( “”, off )

  9. Эрт сказал 26 Янв 2012 at 10:02 #

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

    Я в своё время брал кусок кода (со всякими критичными для работы вызовами-инициализациями-паролями) выносил в функцию. После сборки exe, небольшая утилита эту функцию по маркерам в .exe находит; шифрует (взбивка, замена, шум) файлом-ключиком и записывает обратно. На такой мусор забавно управление передавать :) Автоматизация “one click”. Ломается опять-же отладкой, но без ключика - слишком дорого.

  10. сказал 26 Янв 2012 at 12:23 #

    Эрт, тут вообще тема только про “сбитие” сигнатур. :) Само собой, что от кулхацкеров защита совсем другая.

    А вот на счет поломки сигнатур кода - я ASM-метками почти все функции оборачиваю, а внешним консольным приложением прохожусь по ним и просто ксорю вшитым ключиком все (а после запуска приложение расшифровывает себя уже само).

  11. Max сказал 27 Янв 2012 at 20:05 #

    Очень интересно! Это, выходит, можно прямо в инсталляторе этой консольной прогой шифровать и иметь каждый раз разные экзешники. У меня в NSIS все файлы дополнительно шифруются. Таким образом, антивирю ничего не остается, как делать сигнатуры только на конкретный экземпляр инсталлятора.

MSVC: шифрование строк внутри exe-файла - самый удобный способ






   Прогулка по Москве, фото: красная площадь, московский кремль, ночная москва.

   Случайные записи: поисковая оптимизация WordPress , щенки лабрадора
Другие посты блога: Конференция разработчиков программного обеспечения ISDEF 2011 доклады отзывы,     Система запоминания Джордано (образные коды) - скачать программу,     Как написать бота для игры DirectX. Библиотека opencv для распознавания образов,     Запорожье: покер клуб NetPoint (online),     Биржа Advego отзывы: Как KMiNT21 пытался найти переводчиков (адвего отзывы),     Дайвинг - сертификат PADI OWD,     PES 2012 мастер лига онлайн,