写过win32程序的朋友对dll导出函数名都很熟悉,大家都可以通过.def文件或者__declspec(dllexport)来指定导出的函数名。在android下,可执行文件或者动态链接库用的是elf格式,和win32的pe格式有所不同。当编译动态链接库时,缺省的编译选项下默认所有的符号表都会导出。以android-ndk下的san-angeles例子为例,用ndk编译之后生成的jni动态库导出的符号表可以用下面命令看到(默认开发环境为win32 cygwin):

$ /path/to/ndk/buid/prebuilt/windows/arm-eabi-4.4.0/bin/arm-eabi-nm libs/armeabi/libsanangeles.so

00003600 T Java_com_example_SanAngeles_DemoGLSurfaceView_nativePause

00003638 T Java_com_example_SanAngeles_DemoRenderer_nativeDone

0000367c T Java_com_example_SanAngeles_DemoRenderer_nativeInit

000035b4 T Java_com_example_SanAngeles_DemoRenderer_nativeRender

00003644 T Java_com_example_SanAngeles_DemoRenderer_nativeResize

00007334 a _DYNAMIC

0000740c a _GLOBAL_OFFSET_TABLE_

复制代码

这里可以看到几乎所有的函数名全局变量名都会被导出。其中有Java_com_example_SanAngeles_为前缀的JNI接口函数,有importGLInit这些普通函数,有freeGLObject这些局部(static)函数,还有sStartTick等全局变量名。其实在这个动态发布的时候,只需要导出java_com_开头的jni函数就可以了,里面这些细节函数名完全不需要暴露出来。

如何做到这一点呢?首先,我们需要了解gcc新引进的选项-fvisibility=hidden,这个编译选项可以把所有的符号名(包括函数名和全局变量名)都强制标记成隐藏属性。我们可以在Android.mk中可以通过修改LOCAL_CFLAGS选项加入-fvisibility=hidden来做到这一点,这样编译之后的.so看到的符号表为:

000033d0 t Java_com_example_SanAngeles_DemoGLSurfaceView_nativePause

00003408 t Java_com_example_SanAngeles_DemoRenderer_nativeDone

0000344c t Java_com_example_SanAngeles_DemoRenderer_nativeInit

00003384 t Java_com_example_SanAngeles_DemoRenderer_nativeRender

00003414 t Java_com_example_SanAngeles_DemoRenderer_nativeResize

00007104 a _DYNAMIC

000071dc a _GLOBAL_OFFSET_TABLE_

0000554c T _Unwind_Backtrace

00004748 T _Unwind_Complete

0000474c T _Unwind_DeleteException

00005528 T _Unwind_ForcedUnwind

00004740 T _Unwind_GetCFA

000055d0 T _Unwind_GetDataRelBase

复制代码

这里可以看到所有源代码里出现的函数名和全局变量名(符号名)都变成了't',也就是说都是局部符号(类似于static),这样这些函数名主程序是看不到的。我们还需要把jni的入口函数变成'T'类型才行,我们可以修改jni入口函数的属性来导出这些入口函数,比如app-android.c中的Java_com_example_SanAngeles_DemoRenderer_nativeInit函数,可以改为:

void __attribute__ ((visibility ("default")))

Java_com_example_SanAngeles_DemoRenderer_nativeInit ( JNIEnv*  env )

{

importGLInit();

appInit();

gAppAlive    = 1;

sDemoStopped = 0;

sTimeOffsetInit = 0;

}

复制代码

其他几个Java_com_example_SanAngeles_开头的函数也这样修改一下即可。这样编译之后我们看到的符号表里所有Java_com_example_SanAngeles_开头的函数又变成'T'类型了。

最后我们还有一个问题就是如何隐藏那些局部符号名呢(t类型的符号)?我们可以调用strip -x来去掉这些局部的符号名。我们可以通过修改Android.mk重定义cmd-strip这个命令来实现,修改后的Android.mk如下:

LOCAL_PATH := $(call my-dir)

cmd-strip = $(TOOLCHAIN_PREFIX)strip --strip-debug -x $1

include $(CLEAR_VARS)

LOCAL_MODULE := sanangeles

LOCAL_CFLAGS := -DANDROID_NDK \

-DDISABLE_IMPORTGL \

-fvisibility=hidden

LOCAL_SRC_FILES := \

importgl.c \

demo.c \

app-android.c \

LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog

include $(BUILD_SHARED_LIBRARY)

复制代码

这样每次编译之后会自动strip掉这些局部的符号名,如下:

00003540 T Java_com_example_SanAngeles_DemoGLSurfaceView_nativePause

00003578 T Java_com_example_SanAngeles_DemoRenderer_nativeDone

000035bc T Java_com_example_SanAngeles_DemoRenderer_nativeInit

000034f4 T Java_com_example_SanAngeles_DemoRenderer_nativeRender

00003584 T Java_com_example_SanAngeles_DemoRenderer_nativeResize

000056bc T _Unwind_Backtrace

000048b8 T _Unwind_Complete

000048bc T _Unwind_DeleteException

00005698 T _Unwind_ForcedUnwind

000048b0 T _Unwind_GetCFA

00005740 T _Unwind_GetDataRelBase

00005778 T _Unwind_GetLanguageSpecificData

00005794 T _Unwind_GetRegionStart

00005738 T _Unwind_GetTextRelBase

0000562c T _Unwind_RaiseException

复制代码

这样局部符号都没有了,只有jni入口函数被导出。这样提高了jni动态库的安全性,同时.so文件的大小也小了不少。

关于elf文件的更多资料,可以参考

这篇文章

。如果要了解gcc和strip更多的选项,请移步

gcc

binutils

的官方文档。

android 动态库符号表,Android NDK隐藏jni动态库的内部符号表相关推荐

  1. Android App 瘦身总结 第二章 jni动态库及cpu兼容

    目录 一.利弊分析,按需引用 二.平台兼容 三.动态加载 四.总结 在前一章主要分析了图片资源部分的优化(Android App 瘦身总结 第一章 图片资源的优化处理_There is a Bug!! ...

  2. 【Android NDK 开发】Visual Studio 2019 使用 CMake 开发 JNI 动态库 ( 动态库编译配置 | JNI 头文件导入 | JNI 方法命名规范 )

    文章目录 I . JNI 与 NDK 区别 II . Visual Studio 编译动态库 III. 配置 导入 jni.h 头文件 IV . IntelliJ IDEA Community Edi ...

  3. android ndk 动态库_百度经验,android ndk 动态库

    android ndk开发经常遇到了动态库的问题,本文主要介绍: ① 动态链接库的生成: ② 在Java和C混合编程的情况下如何调用第三方动态链接库: ③ 通过jar包的方式间接调用第三方动态链接库: ...

  4. android编译boost,使用android ndk编译boost动态库

    由于以往我写过不少使用boost库开发的项目,而最近准备移植一些代码到android上(上层界面以及jni层我不管,也没研究过,现在只完成代码的移植编译,具体如何调用,由其它人负责),所以先要解决的就 ...

  5. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 测试 lib7zr.so 动态库调用 )

    文章目录 一.拷贝 p7zip 源码中的头文件到 Android Studio 项目中 二.完整代码示例 1.Java 层代码 2.JNI 层代码 3.日志头文件 4.执行结果 四.参考资料 前置博客 ...

  6. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库头文件到 Android 工程中 | 配置 CMakeLists.txt 构建脚本 )

    文章目录 一.拷贝 p7zip 源码中的头文件到 Android Studio 项目中 二.配置 CMakeLists.txt 构建脚本 1.导入动态库 2.导入头文件 三.完整 CMakeLists ...

  7. 【Android NDK 开发】NDK 交叉编译 ( NDK 函数库目录 | Linux 交叉编译环境搭建 | 指定头文件目录 | 指定函数库目录 | 编译 Android 命令行可执行文件 )

    文章目录 I . NDK platforms 目录下的 函数库 II . Ubuntu 配置 NDK 交叉编译环境 III . 同时指定编译的头文件和库文件 IV . 指定编译的头文件 V . 指定编 ...

  8. android jxl.jar 使用,使用jxl.jar在Android中操作Excel表格——重中之重——对隐藏表的处理...

    曾简单了解过C#,将Excel(数据库表)表中的数据导入到C#中,使用C#制作的图形化界面进行对Excel表中数据进行操作. 今天想试试,在Android中导入Excel表格进行操作.在网上查阅资料, ...

  9. 实现Android APK加固:代码加密隐藏、资源加密隐藏、so库加密隐藏。兼容unity引擎。附加固工具链接。

    1.为什么做加固 因为不想辛辛苦苦做的东西,被别人拿去改成各种版,半路摘我的桃子. 所以需要将原包的一些核心东西进行加密影藏. 市面上比较好的解决方案就是进行加固,能提升apk安全性. 2.怎么加固 ...

  10. NDK交叉编译及so库导入Android项目

    前言 记录 NDK交叉编译及so库导入Android项目 的简单步骤,以备后续用到时查看. 环境 在Linux和Mac环境下,分别编译输出so库. Red Hat Enterprise Linux 8 ...

最新文章

  1. echarts 坐标自适应_echarts 同一页面,多个图表 页面大小自适应
  2. 作为一名合格的前端开发工程师需要会哪些
  3. ARM下的原子操作实现原理
  4. android studio无线真机调试
  5. Git 的安装与初次使用 —— Git 学习笔记 03
  6. LNMP源码安装脚本
  7. [总结]SqlServer中如何实现自动备份数据!
  8. linux pivot root,[mydocker]---通过例子理解chroot 和 pivot_root
  9. Ubuntu下搭建JavaEE开发环境
  10. opencv 修改 读取路径_opencv中读取图像的绝对路径问题
  11. 【备忘】老男孩IT教育_徐培成_大数据
  12. html 多选框取值,多选框取值
  13. qt设置文本背景透明_QT透明显示文字
  14. 技巧推荐 PDF文件怎么转成word文档
  15. python 跨行字符串_python字符串结束的标志_python-7-字符串的操作_方法_format_列表的操作...
  16. 期货十三篇 第一篇 警示篇
  17. 使用Socket实现账号密码验证
  18. 校招java实习生基础知识面试题
  19. “chmod 777-R 文件名”什么意思?
  20. 独立看门狗和窗口看门狗的区别

热门文章

  1. access汇总_Access数据库使用,你都知道吗?
  2. 关于融资融券和转融通
  3. 股市潜规则 你经历过几个?(转)
  4. android 当电脑屏幕,手机变身为电脑的第二屏幕?让你把手机当成电脑用!
  5. 干了半年的java Web,知道自己特别喜欢游戏开发,那就去干吧
  6. 左手招新,右手裁员,2019开年就业形势扑朔迷离
  7. Network--名词解释
  8. 如何安装 Simscape Multibody Link
  9. 计算机桌面锁屏壁纸怎么换,电脑怎么换锁屏壁纸
  10. ES集群状态检查报错:master_not_discovered_exception 503错误