【问题标题】:how to hide local symbol for linux static library如何隐藏linux静态库的本地符号
【发布时间】:2020-04-23 05:55:10
【问题描述】:

我将向客户发送一个静态库。 为了最大限度地保护库的隐私,我使用@ypsu Symbol hiding in static libraries built with Xcode提供的技术限制了静态库的符号

但是,上述方法只是限制用户调用隐藏函数,隐藏函数的名称对“nm”或“strings”仍然可见。

隐藏函数的名称非常敏感。如何从静态库中隐藏或删除此信息?

【问题讨论】:

  • 将所有非导出符号设为静态?
  • strip了吗?
  • @bruno "strip -N symbolA lib.a" 不起作用。
  • @KamilCuk "-Wl, --version-script" 仅适用于共享库。
  • objcopy 应该可以解决问题:sourceware.org/binutils/docs/binutils/objcopy.html 在文件中使用您的 API 传递 --keep-symbols=filename

标签: c linux gcc gcc4 gcc4.7


【解决方案1】:

我最近也遇到了同样的问题。我决定将所有公共符号重命名为 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,源文件与ld -relocatable 合并为一个b8c84a861a264dfcb24ebf32892484dd.o 目标文件。我愿意接受有关如何改进此类脚本的更多建议。

显示的模板出现在bigger script ,ar_hide_symbols

【讨论】:

    猜你喜欢
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 2019-09-26
    • 2011-03-17
    • 2010-09-28
    • 2014-04-01
    • 1970-01-01
    相关资源
    最近更新 更多