Как я удаляю строки из / запутывают скомпилированный двоичный файл? Цель состоит в том, чтобы не читать людей названия функций/методов внутри.
Это - динамическая библиотека (.so) скомпилированный из кода C++ для Android с инструментами NDK (включает GCC),
Я компилирую с -O3
и уже используйте arm-eabi-strip -g mylib.so
удалить отладочную информацию, но когда я делаю strings mylib.so
все названия функций/методов все еще читаемы.
Эти строки находятся в таблице динамических символов , которая используется, когда библиотека загружается во время выполнения. readelf -p .dynstr mylib.so
покажет эти записи.
strip -g
удалит отладочные символы, но не может удалить записи из динамической таблицы символов, так как они могут понадобиться во время выполнения. Ваша проблема в том, что у вас есть записи в динамической таблице символов для функций, которые никогда не будут вызываться извне вашей библиотеки. Если вы не сообщите об этом, компилятор / компоновщик не имеет возможности узнать, какие функции являются частью внешнего API (и, следовательно, нуждаются в записях в динамической таблице символов), а какие функции являются частными для вашей библиотеки (и поэтому записи в таблица динамических символов), поэтому он просто создает записи динамической таблицы символов для всех нестатических функций.
Есть два основных способа сообщить компилятору, какие функции являются частными.
Отметьте частные функции статическими
. Очевидно, это работает только для функций, необходимых только в пределах одной единицы компиляции, хотя для некоторых библиотек этого метода может быть достаточно.
Используйте атрибут gcc «visibility», чтобы пометить функции как видимые или скрытые. У вас есть два варианта: либо пометить все частные функции как скрытые, либо изменить видимость по умолчанию на скрытую с помощью параметра компилятора -fvisibility = hidden
и отметить все общедоступные функции как видимые. Последнее, вероятно, лучший вариант для вас, поскольку это означает, что вам не нужно беспокоиться о том, что вы случайно добавите функцию и забудете пометить ее как скрытую.
Если у вас есть функция:
int foo(int a, int b);
, то синтаксис для пометки ее скрытой:
int foo(int a, int b) __attribute__((visibility("hidden")));
, а синтаксис для пометки ее видимой:
int foo(int a, int b) __attribute__((visibility("default")));
Для получения дополнительных сведений см. этот документ , который является отличным источником информации по этому вопросу.
Есть некоторые коммерческие обфускаторы, которые достигают этого. По сути, они переписывают все символы на ходу. Что-то вроде этого:
void foo()
становится
void EEhj_y33() // usually much, much longer and clobbered
Имена переменных также подвергаются такой же обработке, как и члены структур / союзов (в зависимости от того, какой уровень обфускации вы установили).
Большинство из них работают, сканируя вашу кодовую базу, создавая словарь, а затем заменяя беспорядочную путаницу на имена символов в выходных данных, которые затем могут быть скомпилированы как обычно.
Я не рекомендую их использовать, но они доступны. Простая обфускация значимых имен символов не остановит того, кто решил узнать, как работает ваша библиотека/программа. Кроме того, вы ничего не сможете сделать с тем, кто отслеживает системные вызовы. Действительно, в чем смысл? Некоторые утверждают, что это помогает держать "случайного наблюдателя" на расстоянии, я же утверждаю, что тот, кто выполняет ltrace
strace
и strings
, обычно является кем угодно, только не случайным наблюдателем.
Если только вы не имеете в виду строковые литералы , а не символы ? С ними ничего нельзя поделать, если только вы не храните литералы в зашифрованном формате, который ваш код должен расшифровать перед использованием. Это не просто трата, а вопиющая трата, не приносящая никакой пользы.
Они неизбежны. Эти строки являются средством, с помощью которого загрузчик связывает разделяемые библиотеки во время выполнения.
Предполагая, что вы правильно указали скрытую видимость для g ++ для всех ваших исходных файлов (как рекомендовали другие авторы), есть вероятность, что вы столкнулись с этой ошибкой GCC: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38643
Попробуйте сбросить отображаемые символы в вашем двоичном файле ( readelf -Wa mylib.so | c ++ filter | less
); Если после разборки вы видите только символы vtable и VTT, то ошибка gcc может быть вашей проблемой.
Изменить: если можете, попробуйте GCC 4.4.0 или более позднюю версию, поскольку она там исправлена.