Как скрыть литералы в коде

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

Например, вместо того, чтобы кодировать это:

    static final int MY_VALUE = 100;

У нас могло быть:

    static final int MY_VALUE = myFunction1();

    private int myFunction1(){
        int i = 23;
        i += 8 << 4;
        for(int j = 0; j < 3; j++){
            i-= (j<<1);
        }
        return myFunction2(i);
    }

    private int myFunction2(int i){
        return i + 19;
    }

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

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


person Mister Smith    schedule 29.09.2011    source источник
comment
Ваш пример достаточен, чтобы скрыть фактическое значение. Другая половина решения состоит в том, чтобы удалить исполняемый файл для удаления символов, что усложняет обратное проектирование (но также и труднее отлаживать), или, по крайней мере, использовать имена функций, которые не показывают, что вы пытаетесь что-то скрыть.   -  person Simon C    schedule 29.09.2011
comment
Ваш примерный код сложен, но безоговорочен. Добавление условий на (очевидно) внешние факторы может быть полезным дополнительным методом запутывания. Например, установить глобальное значение в ноль глубоко внутри некоторого кода инициализации, затем проверить, четно ли оно, а если нет, выполнить другое (бесполезное, никогда не достигнутое) вычисление на i.   -  person tripleee    schedule 10.10.2011


Ответы (3)


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

Подробные инструкции:

  1. Посетите ROT47.com и закодируйте свой текст в Интернете. Вы также можете использовать этот веб-сайт для более общей кодировки ROTn.
  2. Замените содержимое строковых констант закодированным текстом.
  3. Используйте декодер в своем коде, чтобы преобразовать текст обратно в исходную форму, когда он вам понадобится. Статья в Википедии о ROT13 содержит некоторые примечания о реализации, а вот Javascript-реализация ROTn в StackOverflow. Его легко адаптировать к любому языку, который вы используете.

Зачем использовать ROT47, который является заведомо слабым шифрованием?

В итоге ваш код будет выглядеть примерно так:

decryptedData = decryptStr (MY_ENCRYPTED_CONSTANT)
useDecrypted (decryptedData)

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

  1. Вы можете кодировать свой текст онлайн, не нужно писать специализированную программу для кодирования вашего текста.
  2. Расшифровку очень легко реализовать, поэтому вы не тратите время на то, что не приносит пользы вашим клиентам.
  3. Любой, кто читает ваш код (ваш коллега или вы через 5 лет), сразу поймет, что это не настоящая безопасность, а безопасность через неизвестность.
  4. Ваш текст по-прежнему будет казаться тарабарщиной для любого, кто просто заглянет внутрь вашей скомпилированной программы, так что миссия выполнена.
person haimg    schedule 05.10.2011
comment
Я думал о тексте, а не о int. Rot13 мне кажется слишком стандартным. - person Mister Smith; 05.10.2011
comment
Поскольку вы не можете действительно скрыть эти строки от кого-то, у кого есть отладчик, вы скрываете их от случайных любопытных глаз. Так что здесь подойдет любое слабое шифрование. Не хотите стандартный Rot13? Добавьте дополнительный XOR или что-то в этом роде ... - person haimg; 05.10.2011
comment
Думаю, это единственное универсальное решение. Применение преобразования к текстовым литералам, например RotN или подобным. То же самое с ints. - person Mister Smith; 10.10.2011

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

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

person phs    schedule 08.10.2011
comment
Интересная идея, было бы неплохо реализовать какой-нибудь пример. - person Rob; 10.10.2011

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

person mateusz.fiolka    schedule 29.09.2011
comment
Нет, только прочитать какую-то инструкцию или аргумент операции (вопрос был в том, чтобы скрыть данные в программе). Самомодификация кода также будет запутана, но это не связано с вопросом. - person mateusz.fiolka; 29.09.2011