今天遇到一个需要隐藏动态库符号的需求,记录一下。

因为某些原因需要将定制的OPENSSL库进行封装成一个新的动态库,提供给其他用户使用。并且我们用到的这个OpenSSL库是经过改造的,与系统库里自带的OpenSSL是不相同的。
先贴出Makefile

all:libsgcccrypto.a libsgcccrypto.so test
crypto.o:crypto.h crypto.hgcc -g -o crypto.o -fPIC -I../openssl-1-0-x/include -c crypto.c
libsgcccrypto.a:crypto.o ../openssl-1-0-x/libcrypto.aecho CREATE libsgcccrypto.a > ar.macecho ADDLIB ../openssl-1-0-x/libcrypto.a >> ar.macecho ADDMOD crypto.o >> ar.macecho SAVE >> ar.macecho END >> ar.macar -M < ar.macrm -rf *.mac
libsgcccrypto.so:crypto.o ../openssl-1-0-x/libcrypto.agcc -g -shared -fPIC -o libsgcccrypto.so crypto.o -L../openssl-1-0-x -lcrypto
test: test.c libsgcccrypto.sogcc -g -o test test.c -Wl,-rpath=./ -L. -lsgcccrypto -ldl
clean:rm -rf libsgcccrypto.a *.so *.o *.mac test

从Makefile可以看出我们的目标很简单,就是自己编写了一个crypto.c,实现了一些接口,这些接口会使用到OpenSSL里的一些功能,我们希望将新编写的crypto.c与所使用的OpenSSL库(静态库)合并编译为一个新的动态库libsgcccrypto.so。上面的Makefile可以完成这个功能。

我们来检查一下编译好的so库

[root@localhost crypto]# readelf -s libsgcccrypto.so |grep EVP| more91: 00000000000768cf   197 FUNC    GLOBAL DEFAULT   11 EVP_PKEY_free100: 00000000000e2037    13 FUNC    GLOBAL DEFAULT   11 EVP_des_ede3107: 00000000000e0e8c    13 FUNC    GLOBAL DEFAULT   11 EVP_des_cfb1108: 00000000000e397d    13 FUNC    GLOBAL DEFAULT   11 EVP_rc2_ecb123: 00000000000e0e99    13 FUNC    GLOBAL DEFAULT   11 EVP_des_cfb8430: 0000000000075faf    13 FUNC    GLOBAL DEFAULT   11 EVP_sm3
--More--

好么,OpenSSL库里的符号都导出了,可想而知,如果用户使用了我们封装的动态库,同时又使用了系统的OpenSSL库,这样一定会出问题。
首先想到的是-fvisibility=hidden选项。可惜这个选项只是在编译期间起作用,而我们的OpenSSL库是已经编译好的静态库,这个选项对已经编译好了的静态库起不了作用,但还是可以将我们crypto.c中被默认导出的一些不必要的接口隐藏掉,修改Makefile,给要导出的接口添加attribute,再看看效果。

all:libsgcccrypto.a libsgcccrypto.so test
crypto.o:crypto.h crypto.hgcc -g -o crypto.o -fPIC -fvisibility=hidden -I../openssl-1-0-x/include -c crypto.c
libsgcccrypto.a:crypto.o ../openssl-1-0-x/libcrypto.aecho CREATE libsgcccrypto.a > ar.macecho ADDLIB ../openssl-1-0-x/libcrypto.a >> ar.macecho ADDMOD crypto.o >> ar.macecho SAVE >> ar.macecho END >> ar.macar -M < ar.macrm -rf *.mac
libsgcccrypto.so:crypto.o ../openssl-1-0-x/libcrypto.agcc -g -shared -fPIC -o libsgcccrypto.so crypto.o -L../openssl-1-0-x -lcrypto
test: test.c libsgcccrypto.sogcc -g -o test test.c -Wl,-rpath=./ -L. -lsgcccrypto -ldl
clean:rm -rf libsgcccrypto.a *.so *.o *.mac test
/* crypto.h */
#define EXPORT_API __attribute((visibility("default")))
EXPORT_API SGCC_ENCRYPT_API sgcc_crypto_load_api();
[root@localhost crypto]# readelf -s crypto.o| grep GLOBAL |grep FUNC|more42: 0000000000000000    65 FUNC    GLOBAL HIDDEN    1 check_support_algs43: 0000000000000041    31 FUNC    GLOBAL HIDDEN    1 check_has_init90: 0000000000001397   167 FUNC    GLOBAL HIDDEN    1 sgcc_save_pubkey92: 000000000000143e   167 FUNC    GLOBAL HIDDEN    1 sgcc_save_prikey94: 00000000000014fa   334 FUNC    GLOBAL DEFAULT    1 sgcc_crypto_load_api

可以看到crypto.o中只有sgcc_crypto_load_api接口被导出,其他接口都是隐藏状态。这样用户连接我们的动态库就只能访问这一个接口了。

继续尝试,在链接阶段加入参数 -Wl,–exclude-libs,ALL

all:libsgcccrypto.a libsgcccrypto.so test
crypto.o:crypto.h crypto.hgcc -g -o crypto.o -fPIC -fvisibility=hidden -I../openssl-1-0-x/include -c crypto.c
libsgcccrypto.a:crypto.o ../openssl-1-0-x/libcrypto.aecho CREATE libsgcccrypto.a > ar.macecho ADDLIB ../openssl-1-0-x/libcrypto.a >> ar.macecho ADDMOD crypto.o >> ar.macecho SAVE >> ar.macecho END >> ar.macar -M < ar.macrm -rf *.mac
libsgcccrypto.so:crypto.o ../openssl-1-0-x/libcrypto.agcc -g -shared -fPIC -Wl,--exclude-libs,ALL -o libsgcccrypto.so crypto.o -L../openssl-1-0-x -lcrypto
test: test.c libsgcccrypto.sogcc -g -o test test.c -Wl,-rpath=./ -L. -lsgcccrypto -ldl
clean:rm -rf libsgcccrypto.a *.so *.o *.mac test
[root@localhost crypto]# readelf -s libsgcccrypto.so |grep GLOBAL|grep EVP
[root@localhost crypto]#
[root@localhost crypto]# readelf -s libsgcccrypto.so |grep GLOBAL|more2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fileno@GLIBC_2.2.5 (2)3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND mktime@GLIBC_2.2.5 (2)4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memset@GLIBC_2.2.5 (2)5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND ftell@GLIBC_2.2.5 (2)6: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND close@GLIBC_2.2.5 (2)7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND ioctl@GLIBC_2.2.5 (2)8: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND abort@GLIBC_2.2.5 (2)11: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fseek@GLIBC_2.2.5 (2)12: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __isoc99_sscanf@GLIBC_2.7 (3)13: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __assert_fail@GLIBC_2.2.5 (2)14: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strcasecmp@GLIBC_2.2.5 (2)
[root@localhost crypto]# readelf -s libsgcccrypto.so |grep GLOBAL|grep sgcc80: 0000000000025dc6   334 FUNC    GLOBAL DEFAULT   11 sgcc_crypto_load_api5669: 0000000000025dc6   334 FUNC    GLOBAL DEFAULT   11 sgcc_crypto_load_api

OK,静态库里的符号统统不见,只剩下我们需要的sgcc_crypto_load_api,这样就不怕咱们的动态库污染用户的符号空间了,目标达成!

记一次隐藏动态库符号的探索过程相关推荐

  1. 如何修改动态库符号表

    如何修改动态库符号表 一.ELF 文件和有关术语 Unix 系统的可执行文件和动态库文件是以 ELF 格式存放的.为使下面的叙述 清晰而没有伎义,先简要介绍一下 ELF 文件格式,并约定一些术语.关于 ...

  2. 记录一次C语言调用go生成的动态库的踩坑过程

    记录一次C语言调用go生成的动态库的踩坑过程 问题现象 由于某些特殊原因,需要在C语言中调用go语言生成的so,本来挺顺利,一切都运行的很好.突然某一天,不知道怎么回事,再一个新程序中无法正常运行了, ...

  3. 查看so库中是否有某个定义_论Linux ELF中动态库符号重定义利用 属性/Linker 做隐藏的手法...

    假如libgetthree.so libgetseven.so , 同时这两个so内部都用了internal_do_calculation()函数,并且各自定义了自己的internal_do_calc ...

  4. linux命令之查看动态库符号-nm

    在调用动态库的时候,经常出现由于动态库接口修改或者版本不匹配导致调用动态库找不到函数接口符号的情况. 原因可能有如下几种: 1.由于c++动态库编译没有加extern c导致函数编译时加了c++的前缀 ...

  5. linux动态库符号检查,写 Linux 动态库的最佳实践

    在定义全局变量和函数是,如果我们使用 static 关键字修饰他们,就只能够在同一个文件内引用他们:如果我们不使用 static 关键字,就可以在其他文件中引用他们. 然而,当实现动态库时,问题就变得 ...

  6. 使用 jni加密器对 安卓动态库符号表加密

    android编译动态链接库时,缺省的编译选项下默认所有的符号表都会导出, 这导致别人很容易通过符号表获取动态库里的相关信息. 通过增加-fvisibility=hidden选项有时候能影藏部分符号表 ...

  7. linux下动态库符号表,Linux动态库(.so)符号表

    最近编译libbinder.so发现system/lib/libbinder.so只有358K,但单独编译生成的obj/SHARED_LIBRARIES/libbinder_intermediates ...

  8. 解决Linux多个动态库间的符号冲突问题

    c和c++开发人员或多或少都使用过Linux动态库,但是很多时候我们都不会去深入了解其中的一些细节和原理,直到自己的程序出现莫名其妙的问题后才会去着手解决,我也是在遇到一些动态库的问题后才去深入寻找解 ...

  9. 硬核拆解动态库静态库

    [Github pages] 动态库与静态库是编程中十分常见的玩意儿,但是如此常见的东西在我真正用心去了解梳理过一遍之后才发现原来这里面有这么多的门道.本文就介绍一波 Linux 平台下,特指 GCC ...

  10. Linux 静态库 动态库

    转自:http://blog.chinaunix.net/uid-26833883-id-3219335.html 一.什么是库 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. ...

最新文章

  1. 风控评分模型全流程的开发及应用
  2. ibm3650m2 如何安装linux4,System x3650M2 (Type 7947) Windows Server 2008安装指南
  3. mysql数据剪切到新表_6、MySQL核心DDL语句
  4. linux java 安装配置_类Linux环境安装jdk1.8及环境变量配置详解
  5. kali2020设置root用户登录
  6. swift 雨燕 新手教程
  7. 金蝶kis云+sqlserver报表分析
  8. jQuery 之 $(this) 出了什么问题?
  9. jsp的九大内置对象和作用域
  10. 赶在 2018 年前推荐 30 个最火爆的开源库
  11. Flask项目之手机端租房网站的实战开发(十三)
  12. C语言关于素数个数的求法
  13. 前沿分享|上海市新能源汽车数据平台 王成名: 车联网全景监控数据时空超融合数据库方案
  14. Java获取微信用户昵称时昵称里有特殊符号导致插入数据库失败(解决方案)
  15. 树莓派开始,玩转Linux21:进程的生与死
  16. 年终盘点 | 用Python分析了上千个基金,终于发现了赚钱的秘密!
  17. 私服 php,php私服发布站 代码
  18. colab 跑 deformable-detr 记录:
  19. 在机器学习or深度学习中引入先验知识
  20. r语言kmeans聚类(真实案例完整流程)

热门文章

  1. iOS SceneDelegate使用总结
  2. 初识vbs脚本(简单的逗女孩的记事本炸弹及解除)
  3. 【imx6ul】从头搭建imx6ul开发环境(uboot、内核编译及烧入、mfgtools详细使用方法)
  4. 做量化你需要知道的那些术语!(持续更新)
  5. stm32usb功能设备以及在linux下的USB相关总线、设备驱动笔记
  6. 移远百科 | GNSS定位技术知多少
  7. 使用Origin绘制柱状图(入门)
  8. 单词记忆 词根词缀记忆 总结
  9. android 视频缓存溢出导致视频黑屏,MediaMuxer+MediaCodec生成MP4视频黑屏
  10. 计算机网络安全 的论文,网络安全论文3000字范文参考(3)