如何为linux静态库隐藏本地符号
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何为linux静态库隐藏本地符号相关的知识,希望对你有一定的参考价值。
我将向静态库发送给客户。为了最大化图书馆的隐私,我使用@ypsu Symbol hiding in static libraries built with Xcode
提供的技术对静态图书馆的符号进行了限制。但是,上述方法仅限制用户调用隐藏函数,隐藏函数名称的名称对于“ nm”或“ strings”仍然可见。
隐藏功能的名称非常敏感。如何隐藏或从静态库中删除此信息?
答案
我最近也遇到过同样的问题。我决定将所有公共符号重命名为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
目标文件。我愿意就如何改进此类脚本提供更多建议。
以上是关于如何为linux静态库隐藏本地符号的主要内容,如果未能解决你的问题,请参考以下文章
使用 Clang 作为编译器构建 Android 项目时从静态库中隐藏符号
Facebook iOS SDK - 如何为 Xcode 4.3 构建静态库?