Можно ли извлечь константы и другие предопределенные значения из двоичных исполняемых файлов?


Допустим, у нас есть эта программа здесь

class Message{

public static SUPER_SECRET_STRING = "bar";

    public static void Main(){
        string SECRET = "foo";
        Console.Write(sha(SUPER_SECRET_STRING) + "" + sha(SECRET));
    }

}

Теперь, после сборки этой программы, есть ли способ с помощью шестнадцатеричного редактора или какой-либо другой утилиты извлечь значения "foo" и "bar" из скомпилированного двоичного файла?

Также предположим, что Редакторы памяти не допускаются.

Применимо ли это ко всем компилируемым языкам, таким как C++? А как насчет тех, которые выполняются в другой среде, например Java или C#?

2 4

2 ответа:

Да, вы можете легко использовать декомпилятор для извлечения таких констант, особенно строк (поскольку они требуют большего объема памяти). Это будет работать даже в двоичных файлах машинного кода и еще проще для языков виртуальных машин, таких как Java и C#.

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

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

Как вы видите, проблема далеко не тривиальна. И конечно же нет никакого способа дать у вас 100% безопасность (вспомните все взломанные игры и так далее).

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

Ответ от мене верен, но я хотел бы вложить свои два цента, чтобы вы знали, как до смешного легко извлекать строки из скомпилированных двоичных файлов (независимо от языка). Если у вас есть Linux, все, что вам нужно сделать, это выполнить команду strings <compiled binary>, и у вас есть извлеченные строки. Вам не нужно быть каким-то обратным инженером, чтобы осуществить это. Я просто запустил его против двоичного файла eclipse на моей машине Ubuntu и проверил (усеченный) вывод:

> strings eclipse
ATSH
0[A\
8.uCH
The %s executable launcher was unable to locate its 
companion shared library.
There was a problem loading the shared library and 
finding the entry point.
setInitialArgs
-vmargs
-name
--launcher.library
--launcher.suppressErrors
--launcher.ini
eclipse

Обратите внимание, как строка " исполняемая программа запуска %s не смогла найти свою сопутствующую общую библиотеку. Возникла проблема с загрузкой общей библиотеки и поиском точки входа."появляется в выходных данных. Эта строка, без сомнения, жестко закодирована в программе.

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