Как встроить строки в код исполняемого файла? - PullRequest
0 голосов
/ 02 октября 2011

У меня есть строковый литерал, который используется в разных местах моего исполняемого файла.

Скажем, что-то вроде:

const char *formatString = "Something I don't want to make obvious: %d";

int format1(char *buf) { sprintf(buf, formatString, 1); }
int format2(char *buf) { sprintf(buf, formatString, 2); }

//...

Теперь этот строковый литерал становится очень очевидным внутри исполняемого кода, потому что он встроен буквально.

Есть ли способ избежать этого, заставляя компилятор, например, генерировать инструкции по сборке (например, mov [ptr + 4], 0x65) для создания строк вместо буквального встраивания строк?

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

Возможно ли это?

Ответы [ 4 ]

4 голосов
/ 02 октября 2011

Чтобы не вставлять зашифрованные строки в код вручную, вы можете создать макрос, который будет помечать строки, требующие обфускации, и функцию, которая их расшифровывает:

#define OB(s) dec("START_MARK_GUID" s "\0" "END_MARK_GUID")
const char* dec(const char* s) { ... }
...
const char* s = OB("not easily readable"); // on all strings needed
const char* s = OB("either");

Функция должна делать две вещи:

  1. Если параметр начинается с START_MARK_GUID, просто верните исходную строку (без направляющих). Это позволит вам также использовать необсуждаемый исполняемый файл, например, при отладке.

  2. Если он начинается с ENCRYPTED_MARK_GUID, сначала выполните деобфускацию, а затем верните новую строку. В Си вам придется заботиться о времени жизни памяти здесь; в C ++ вы можете просто вернуть std :: string ().

Наконец, создайте программу-обфускатор, которая ищет GUID в скомпилированном двоичном файле и шифрует данные между ними. Это всего лишь несколько строк в Python или подобном языке. Я также рекомендую после этого исправить CRC в EXE, хотя моя программа работала и без этого.

Вы можете изменить направляющие с меньшим количеством уникальных идентификаторов, чтобы сэкономить место. Также вы можете улучшить это, чтобы дешифрование происходило только один раз (например, записать идентификатор строки вместе с ENCRYPTED_MARK_GUID и сохранить расшифрованные строки в словаре по этому идентификатору).

2 голосов
/ 02 октября 2011

Запутывание - это, вероятно, ваш лучший выбор. Используйте простое запутывание (например, XOR) и снимите его в другой переменной в начале вашей программы перед запуском любого кода, которому нужна строка.

0 голосов
/ 02 октября 2011

Довольно скоро с C ++ 11 вы сможете использовать пользовательские литералы.

constexpr const char*
operator"" _decrypto(const char*, size_t len)
{
  //  decrypt input string.
}

const char* formatString = "encrypted gibberish"_decrypto;

int format1(char* buf) { sprintf(buf, formatString, 1); }
int format2(char* buf) { sprintf(buf, formatString, 2); }

int
main()
{
}

GCC яростно работает над этим , и я думаю, что IBM уже это имеет. Не уверен насчет статуса Visual Studio. Это скомпилировано на исправленном gcc.

0 голосов
/ 02 октября 2011

Есть способ не программирования, который я часто использую.Скомпилируйте вашу программу и затем используйте upx для сжатия и запутывания строк.Вы можете найти upx, здесь .

...