Я недавно подошел к той же проблеме. Я решил переименовать все символы 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 .