C: обфусцирование целого числа - PullRequest
2 голосов
/ 07 февраля 2010

Если у меня в коде есть целое число, подобное этому ...

int my_secret = 42;

... возможно ли затруднить поиск этого целого числа в скомпилированной программе? Я видел, как это делалось со строками, например, сдвигая каждую букву на x символов, а затем снимая их во время выполнения, но я сомневаюсь, что этот метод будет хорошо работать с числами.

Ответы [ 9 ]

14 голосов
/ 07 февраля 2010

Это никогда не работает. Секретные ключи никогда не должны быть в коде. Создание их во время выполнения работ. Обфускация, безусловно, заманчиво провидение.

3 голосов
/ 07 февраля 2010

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

Конечно, проблема в том, что ни один из этих типов вещей не остановит решительного человека.

Можно также утверждать, что вам действительно не нужно беспокоиться. Запутывание строки имеет большой смысл, потому что есть множество простых в использовании инструментов, которые будут выгружать строки из исполняемого файла. Однако ваш 42 будет просто закодирован как двоичное число. Весь исполняемый файл - это просто длинная последовательность двоичных чисел, и нет простого инструмента для поиска 42-х. Вам придется разобрать исполняемый файл и понять сборку. Любой, кто переживет столько неприятностей, может выяснить это число независимо от того, что вы делаете.

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

2 голосов
/ 07 февраля 2010

Я слышал о людях, использующих самоизменяющийся код в целях запутывания. Как уже говорили другие, кто-то решительно настроенный может все же взломать его, но это усложнит жизнь потенциальному злоумышленнику, если он даже не увидит окончательный код в разобранном виде или установит в нем контрольные точки. (Установка точки останова равносильна замене байта памяти инструкцией INT 3; если эта память модифицируется как часть операции самоизменяющегося кода, точка останова исчезнет, ​​что может повредить инструкции там и привести к еще большему веселью. )

Все еще возможно пошаговое выполнение кода в отладчике. Чтобы частично противодействовать этому, вы можете время от времени проверять IsDebuggerPresent () и вести атакующего на погоню за диким гусем, если это так. Конечно, этому тоже можно противодействовать, например, с помощью DLL-шимминга или даже при необходимости создания низкоуровневого драйвера устройства.

2 голосов
/ 07 февраля 2010

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

Самый простой способ сделать это - применить одноразовые планшеты, такие как XOR.

int pad = 322;
int secret = 360;
int value = pad ^ secret; // This is 42

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

Обратите внимание: несмотря на то, что злоумышленникам становится труднее получить ключ, взглянув на скомпилированный код, они все равно могут подключить отладчик к запущенному процессу и извлечь вычисленный ключ прямо из памяти. На самом деле, есть отладчики (такие как IDA pro), которые делают подобные вещи почти тривиальными.

Вам также придется беспокоиться о том, что ОС подкачает ваш ключ на диск после того, как он был вычислен, что можно извлечь довольно тривиально. (Использование чего-то вроде mlock () для блокировки страниц в памяти может помочь вам в этом.)

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

2 голосов
/ 07 февраля 2010

Первоначальный вопрос в комментарии Хасана является критическим.Это зависит от того, что вы держите в секрете и почему, сколько работы стоит.Вообще говоря, скрыть что-то от того, кто использует программу, которая (в какой-то момент) объединяет эти значения, невозможно навсегда.Однако вы можете усложнить задачу для атакующего.

Тогда возникает вопрос, сколько работы вы хотите выполнить, чтобы усложнить задачу для атакующего.Затем вы можете делать что угодно: от обфускации кода (не очень надежно, но может удержать очень случайного злоумышленника и сделать это относительно легко, особенно если исходный источник можно прокомментировать с тем, что происходит) до полного шифрования и некоторых «черных»методы типа "box", которые использовались для защиты от копирования (хотя даже те, которые в конечном итоге могут быть взломаны), чтобы, если это достаточно критично, предоставлять это как эффект веб-службы, где код не передается конечному пользователю.Даже это не всегда безопасно.

Итак, насколько секрет вы хотите, чтобы ваш секрет, и сколько работы вы готовы потратить, пытаясь сохранить его таким образом?

2 голосов
/ 07 февраля 2010

Вы можете сделать это, разделив это значение между двумя переменными. Например, как это:

volatile int my_secret_1 = 20;
volatile int my_secret_2 = 22;

, а затем используйте my_secret_1 + my_secret_2 вместо my_secret.

Ключевое слово volatile необходимо, потому что большинство (если не все) компиляторов c оптимизируют его в противном случае. В любом случае лучше посмотреть, какой ассемблерный код выдает компилятор.

1 голос
/ 07 февраля 2010

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

1 голос
/ 07 февраля 2010

Как использовать дополнения

int secret = ~42;
printf("%0X %0x" , secret , ~secret );

отпечатки

FFFFFFD5 42

РЕДАКТИРОВАТЬ: Или с помощью макроса

#define OBFUSCATE(X) (~(X)^0xdeadbeef)

int secret = OBFUSCATE( 42 );
printf("%0X %d" , secret ,OBFUSCATE( secret ));

2152413A 42
0 голосов
/ 07 февраля 2010

В программе нет способа скрыть только целое число, так как кто-то может просто пройти через отладчик, чтобы определить его окончательное значение.

Лучше всего использовать автообфускатор, чтобы запутать всю процедуру / программу.

...