как скрыть локальный символ для библиотеки linux stati c - PullRequest
2 голосов
/ 23 апреля 2020

Я собираюсь отправить клиенту библиотеку Stati c. Чтобы максимизировать конфиденциальность библиотеки, я ограничил символы для библиотеки stati c, используя метод, предоставленный @ypsu Символ, скрывающийся в библиотеках stati c, созданных с помощью Xcode

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

Имена скрытых функций очень чувствительны. Как скрыть или удалить эту информацию из библиотеки stati c?

1 Ответ

2 голосов
/ 23 апреля 2020

Я недавно подошел к той же проблеме. Я решил переименовать все символы publi c в md5sum, чтобы имена не были видны пользователю, включая имена файлов. Следующий пример пытается продемонстрировать это:

cat >priv.c <<EOF
#include <stdio.h>
void priv() { printf("Hello, private function\n"); }
EOF

cat >interface.c <<EOF
void priv();
void interface() { priv(); }
EOF

cat >main.c <<EOF
void interface();
int main() {
    interface();
}
EOF

cat >compile.sh <<EOF3
#!/bin/bash   

namespace="namespace_"

# compile to object files
gcc -c -o priv.o priv.c
gcc -c -o interface.o interface.c

# rename the object file so the names of files are not visible
nofilename="$(echo "nofilenames" | md5sum | cut -d' ' -f1).o"
ld -relocatable priv.o interface.o -o "$nofilename"

# create the static library
ar rcs static.a "$nofilename"

# list of interface symbols    
public_symbols=( interface )

# list of private symbols - all symbols except interface symbols
private_symbols=($(
    nm static.a | sed '/^[0-9]\+ T /!d; s///' |
    sort | comm -13 <(printf "%s\n" "${public_symbols[@]}" | sort) -
))

# strip unused symbols, leave only interface symbols
strip_args=($(printf " -K %s " "${public_symbols[@]}"))
strip --strip-unneeded --strip-debug "${strip_args[@]}" static.a

# rename all private symbols with it's md5sum
objcopy_args=($(
    printf "%s\n" "${private_symbols[@]}" |
    while IFS= read -r sym; do
        new="${namespace}$(echo "$sym" | md5sum | cut -d' ' -f1)"
        # replace the symbol with it's md5sum
        echo --redefine-sym "$sym=$new"
        # make the symbol local
        echo -L "$new"
    done
))
objcopy "${objcopy_args[@]}" static.a

gcc main.c static.a 

# testing    
set -x
nm static.a
strings static.a
./a.out
EOF3

Сценарий ./compile.sh выведет:

+ nm static.a

b8c84a861a264dfcb24ebf32892484dd.o:
                 U _GLOBAL_OFFSET_TABLE_
0000000000000013 T interface
0000000000000000 t namespace_6b2f60f631c17ca910498adb47387adf
                 U puts
+ strings static.a
!<arch>
/               0           0     0     0       18        `
interface
//                                              36        `
b8c84a861a264dfcb24ebf32892484dd.o/
/0              0           0     0     644     1744      `
Hello, private function
GCC: (Arch Linux 9.3.0-1) 9.3.0
GCC: (Arch Linux 9.3.0-1) 9.3.0
namespace_6b2f60f631c17ca910498adb47387adf
puts
interface
_GLOBAL_OFFSET_TABLE_
.symtab
.strtab
.shstrtab
.rela.text
.rodata
.rela.eh_frame
.data
.bss
.comment
.note.GNU-stack
+ ./a.out
Hello, private function

Символ priv был переименован в namespace_6b2f60f631c17ca910498adb47387adf, а исходные файлы были объединены в один объектный файл b8c84a861a264dfcb24ebf32892484dd.o с ld -relocatable. Я открыт для дополнительных предложений о том, как улучшить такой скрипт.

Показанный шаблон появился в большем скрипте, ar_hide_symbols .

...