2013-06-12 2 views
3

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

class Message{ 

public static SUPER_SECRET_STRING = "bar"; 

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

} 

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

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

Это применимо ко всем скомпилированным языкам, таким как C++? Что можно сказать о тех, которые запускаются в других средах, таких как Java или C#?

+1

Да; это, безусловно, возможно. Какой язык? – SLaks

+0

Существует стандартная программа 'strings', которая будет печатать распечатанные данные из объектных файлов - ее можно использовать для поиска строк в исполняемых файлах и чрезвычайно полезны. Возможно, вам понадобится использовать опцию '-a', чтобы получить максимальную выгоду. –

ответ

4

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

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

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

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

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

+2

Связанный вопрос http://stackoverflow.com/questions/7435980/protect-string-constant-against-reverse-engineering – wonton

4

Ответ от Mene верен, но я хотел поставить в свои два цента, чтобы вы знали, как смешно легко извлекать строки из скомпилированных двоичных файлов (независимо от языка). Если у вас Linux, все, что вам нужно сделать, это запустить команду strings <compiled binary>, и у вас есть извлеченные строки. Вам не обязательно быть каким-то реверсным инженером, чтобы это сделать. Я просто побежал против затмения двоичном на моей машине 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 в исполняемый файл запуска не смог найти его компаньон разделяемой библиотеки Был проблема загрузки разделяемой библиотеки и поиска точки входа. " появляется на выходе. Эта строка, без сомнения, жестко закодирована в программе.

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