Android NDK隐藏jni动态库的内部符号表

今天来介绍Android下面NDK编译so时,怎样实现符号隐藏,gcc默认的情况下是将所有符号都导出的,为了安全启见可以将符号隐藏,可以给破解带来很大的麻烦,另外还可以有效减小so文件的大小,还有一个好处是可以加快程序的运行速度。写过win32程序的朋友对dll导出函数名都很熟悉,大家都可以通过.def文件或者 __declspec(dllexport)来指定导出的函数名。在android下,可执行文件或者动态链接库用的是elf格式,和win32的pe格式有所不同。

隐藏符号基本有几种方式:一种是在函数定义时添加visibility属性(__attribute__((visibility("hidden");一种是在Android.mk中添加-fvisibility=hidden编译选项;另外一种是添加--version-script选项,并编译version script脚本。
先来介绍前两种方法,最后修改以后编译用readelf查看就可以发现符号表里已经没有你定义的函数。
当编译动态链接库时,缺省的编译选项下默认所有的符号表都会导出。以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_
0000577c T _Unwind_Backtrace
00004978 T _Unwind_Complete
0000497c T _Unwind_DeleteException
00005758 T _Unwind_ForcedUnwind
00004970 T _Unwind_GetCFA
00005800 T _Unwind_GetDataRelBase
00005808 t _Unwind_GetGR
0000482c t _Unwind_GetGR
00005838 T _Unwind_GetLanguageSpecificData
00005854 T _Unwind_GetRegionStart
000057f8 T _Unwind_GetTextRelBase
000056ec T _Unwind_RaiseException
00005710 T _Unwind_Resume
00005734 T _Unwind_Resume_or_Rethrow
000048a0 t _Unwind_SetGR
000047e0 T _Unwind_VRS_Get
0000528c T _Unwind_VRS_Pop
00004854 T _Unwind_VRS_Set
000047cc t _Unwind_decode_target2
0000577c T ___Unwind_Backtrace
00005758 T ___Unwind_ForcedUnwind
000056ec T ___Unwind_RaiseException
00005710 T ___Unwind_Resume
00005734 T ___Unwind_Resume_or_Rethrow
00003874 T __adddf3
0000413c T __addsf3
000046f8 T __aeabi_cfcmpeq
000046f8 T __aeabi_cfcmple
000046e8 T __aeabi_cfrcmple
00004090 T __aeabi_d2f
00003874 T __aeabi_dadd
00003e8c T __aeabi_ddiv
00003c20 T __aeabi_dmul
00003868 T __aeabi_drsub
00003870 T __aeabi_dsub
00003b6c T __aeabi_f2d
00004770 T __aeabi_f2iz
0000413c T __aeabi_fadd
0000470c T __aeabi_fcmpeq
00004748 T __aeabi_fcmpge
0000475c T __aeabi_fcmpgt
00004734 T __aeabi_fcmple
00004720 T __aeabi_fcmplt
00004518 T __aeabi_fdiv
00004380 T __aeabi_fmul
00004130 T __aeabi_frsub
00004138 T __aeabi_fsub
00003b44 T __aeabi_i2d
000042d4 T __aeabi_i2f
00003770 T __aeabi_idiv
00003864 T __aeabi_idiv0
0000384c T __aeabi_idivmod
00003bc0 T __aeabi_l2d
00004304 T __aeabi_l2f
00003864 T __aeabi_ldiv0
00003b20 T __aeabi_ui2d
000042cc T __aeabi_ui2f
000036ac T __aeabi_uidiv
00003758 T __aeabi_uidivmod
00003bac T __aeabi_ul2d
000042f4 T __aeabi_ul2f
00004d5c T __aeabi_unwind_cpp_pr0
00004d54 W __aeabi_unwind_cpp_pr1
00004d4c W __aeabi_unwind_cpp_pr2
        U __android_log_print 
000076d4 A __bss_end__
00007658 A __bss_start
00007658 A __bss_start__
00004688 T __cmpsf2
        w __cxa_begin_cleanup 
        w __cxa_call_unexpected 
        w __cxa_type_match 
000074b8 D __data_start
00003864 T __div0
00003e8c T __divdf3
00004518 T __divsf3
00003770 T __divsi3
000076d4 A __end__
00004688 T __eqsf2
00006334 A __exidx_end
000061a4 A __exidx_start
00003b6c T __extendsfdf2
00004770 T __fixsfsi
00003bc0 T __floatdidf
00004304 T __floatdisf
00003b44 T __floatsidf
000042d4 T __floatsisf
00003bac T __floatundidf
000042f4 T __floatundisf
00003b20 T __floatunsidf
000042cc T __floatunsisf
00004678 T __gesf2
00004f04 T __gnu_Unwind_Backtrace
        w __gnu_Unwind_Find_exidx 
000050e8 T __gnu_Unwind_ForcedUnwind
0000515c T __gnu_Unwind_RaiseException
0000560c T __gnu_Unwind_Restore_VFP
0000561c T __gnu_Unwind_Restore_VFP_D
0000562c T __gnu_Unwind_Restore_VFP_D_16_to_31
000056c4 T __gnu_Unwind_Restore_WMMXC
0000563c T __gnu_Unwind_Restore_WMMXD
00005220 T __gnu_Unwind_Resume
00005200 T __gnu_Unwind_Resume_or_Rethrow
00005614 T __gnu_Unwind_Save_VFP
00005624 T __gnu_Unwind_Save_VFP_D
00005634 T __gnu_Unwind_Save_VFP_D_16_to_31
000056d8 T __gnu_Unwind_Save_WMMXC
00005680 T __gnu_Unwind_Save_WMMXD
00005864 T __gnu_unwind_execute
00005be0 T __gnu_unwind_frame
0000499c t __gnu_unwind_pr_common
00004678 T __gtsf2
00004680 T __lesf2
00004680 T __ltsf2
00003c20 T __muldf3
00004380 T __mulsf3
00004688 T __nesf2
000055f8 T __restore_core_regs
00003870 T __subdf3
00004138 T __subsf3
00004090 T __truncdfsf2
000036ac T __udivsi3
000076d4 A _bss_end__
00007658 A _edata
000076d4 A _end
00003590 t _getTime
00080000 N _stack
        U abort 
000020c8 T appDeinit
00002238 T appInit
00002ee0 T appRender
        U cos 
00001ec8 t drawGLObject
00001f18 t drawModels
        U free 
000020a8 t freeGLObject
00007654 D gAppAlive
00004d64 t get_eit_entry
        U gettimeofday 
        U glBlendFunc 
        U glClear 
        U glClearColorx 
        U glColor4x 
        U glColorPointer 
        U glDisable 
        U glDisableClientState 
        U glDrawArrays 
        U glEnable 
        U glEnableClientState 
        U glFrustumx 
        U glLightxv 
        U glLoadIdentity 
        U glMaterialx 
        U glMaterialxv 
        U glMatrixMode 
        U glMultMatrixx 
        U glNormalPointer 
        U glPopMatrix 
        U glPushMatrix 
        U glRotatex 
        U glScalex 
        U glShadeModel 
        U glTranslatex 
        U glVertexPointer 
        U glViewport 
00001e1c T importGLDeinit
00001e18 T importGLInit
000075ec d light0Diffuse.3407
000075dc d light0Position.3406
0000760c d light1Diffuse.3409
000075fc d light1Position.3408
0000762c d light2Diffuse.3411
0000761c d light2Position.3410
        U malloc 
0000763c d materialSpecular.3412
        U memcpy 
000020f4 t newGLObject
000057a0 t next_unwind_byte
        U pow 
0000610c r quadVertices.3337
000055f8 T restore_core_regs
00004e98 t restore_non_core_regs
000074bc d sCamTracks
000076bc b sCurrentCamTrack
000076c0 b sCurrentCamTrackStartTick
000076c4 b sDemoStopped
000076b4 b sGroundPlane
000074b8 d sNextCamTrackStartTick
00007658 b sRandomSeed
000076b8 b sStartTick
0000765c b sSuperShapeObjects
00005c20 r sSuperShapeParams
000076b0 b sTick
000076c8 b sTimeOffset
000076d0 b sTimeOffsetInit
000076cc b sTimeStopped
00007650 d sWindowHeight
0000764c d sWindowWidth
000048e4 t search_EIT_table
000048cc t selfrel_offset31
        U sin 
        U sqrt 
00002164 t ssFunc
00001e20 t superShapeMap
00005830 t unwind_UCB_from_context
00005104 t unwind_phase2
00004fcc t unwind_phase2_forced

这里可以看到几乎所有的函数名全局变量名都会被导出。其中有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
000045fc t _Unwind_GetGR
000055d8 t _Unwind_GetGR
00005608 T _Unwind_GetLanguageSpecificData
00005624 T _Unwind_GetRegionStart
000055c8 T _Unwind_GetTextRelBase
000054bc T _Unwind_RaiseException
000054e0 T _Unwind_Resume
00005504 T _Unwind_Resume_or_Rethrow
00004670 t _Unwind_SetGR
000045b0 T _Unwind_VRS_Get
0000505c T _Unwind_VRS_Pop
00004624 T _Unwind_VRS_Set
0000459c t _Unwind_decode_target2
0000554c T ___Unwind_Backtrace
00005528 T ___Unwind_ForcedUnwind
000054bc T ___Unwind_RaiseException
000054e0 T ___Unwind_Resume
00005504 T ___Unwind_Resume_or_Rethrow
00003644 T __adddf3
00003f0c T __addsf3
000044c8 T __aeabi_cfcmpeq
000044c8 T __aeabi_cfcmple
000044b8 T __aeabi_cfrcmple
00003e60 T __aeabi_d2f
00003644 T __aeabi_dadd
00003c5c T __aeabi_ddiv
000039f0 T __aeabi_dmul
00003638 T __aeabi_drsub
00003640 T __aeabi_dsub
0000393c T __aeabi_f2d
00004540 T __aeabi_f2iz
00003f0c T __aeabi_fadd
000044dc T __aeabi_fcmpeq
00004518 T __aeabi_fcmpge
0000452c T __aeabi_fcmpgt
00004504 T __aeabi_fcmple
000044f0 T __aeabi_fcmplt
000042e8 T __aeabi_fdiv
00004150 T __aeabi_fmul
00003f00 T __aeabi_frsub
00003f08 T __aeabi_fsub
00003914 T __aeabi_i2d
000040a4 T __aeabi_i2f
00003540 T __aeabi_idiv
00003634 T __aeabi_idiv0
0000361c T __aeabi_idivmod
00003990 T __aeabi_l2d
000040d4 T __aeabi_l2f
00003634 T __aeabi_ldiv0
000038f0 T __aeabi_ui2d
0000409c T __aeabi_ui2f
0000347c T __aeabi_uidiv
00003528 T __aeabi_uidivmod
0000397c T __aeabi_ul2d
000040c4 T __aeabi_ul2f
00004b2c T __aeabi_unwind_cpp_pr0
00004b24 W __aeabi_unwind_cpp_pr1
00004b1c W __aeabi_unwind_cpp_pr2
        U __android_log_print 
000074a4 A __bss_end__
00007428 A __bss_start
00007428 A __bss_start__
00004458 T __cmpsf2
        w __cxa_begin_cleanup 
        w __cxa_call_unexpected 
        w __cxa_type_match 
00007288 D __data_start
00003634 T __div0
00003c5c T __divdf3
000042e8 T __divsf3
00003540 T __divsi3
000074a4 A __end__
00004458 T __eqsf2
00006104 A __exidx_end
00005f74 A __exidx_start
0000393c T __extendsfdf2
00004540 T __fixsfsi
00003990 T __floatdidf
000040d4 T __floatdisf
00003914 T __floatsidf
000040a4 T __floatsisf
0000397c T __floatundidf
000040c4 T __floatundisf
000038f0 T __floatunsidf
0000409c T __floatunsisf
00004448 T __gesf2
00004cd4 T __gnu_Unwind_Backtrace
        w __gnu_Unwind_Find_exidx 
00004eb8 T __gnu_Unwind_ForcedUnwind
00004f2c T __gnu_Unwind_RaiseException
000053dc T __gnu_Unwind_Restore_VFP
000053ec T __gnu_Unwind_Restore_VFP_D
000053fc T __gnu_Unwind_Restore_VFP_D_16_to_31
00005494 T __gnu_Unwind_Restore_WMMXC
0000540c T __gnu_Unwind_Restore_WMMXD
00004ff0 T __gnu_Unwind_Resume
00004fd0 T __gnu_Unwind_Resume_or_Rethrow
000053e4 T __gnu_Unwind_Save_VFP
000053f4 T __gnu_Unwind_Save_VFP_D
00005404 T __gnu_Unwind_Save_VFP_D_16_to_31
000054a8 T __gnu_Unwind_Save_WMMXC
00005450 T __gnu_Unwind_Save_WMMXD
00005634 T __gnu_unwind_execute
000059b0 T __gnu_unwind_frame
0000476c t __gnu_unwind_pr_common
00004448 T __gtsf2
00004450 T __lesf2
00004450 T __ltsf2
000039f0 T __muldf3
00004150 T __mulsf3
00004458 T __nesf2
000053c8 T __restore_core_regs
00003640 T __subdf3
00003f08 T __subsf3
00003e60 T __truncdfsf2
0000347c T __udivsi3
000074a4 A _bss_end__
00007428 A _edata
000074a4 A _end
00003360 t _getTime
00080000 N _stack
        U abort 
00001e98 t appDeinit
00002008 t appInit
00002cb0 t appRender
        U cos 
00001c98 t drawGLObject
00001ce8 t drawModels
        U free 
00001e78 t freeGLObject
00007424 d gAppAlive
00004b34 t get_eit_entry
        U gettimeofday 
        U glBlendFunc 
        U glClear 
        U glClearColorx 
        U glColor4x 
        U glColorPointer 
        U glDisable 
        U glDisableClientState 
        U glDrawArrays 
        U glEnable 
        U glEnableClientState 
        U glFrustumx 
        U glLightxv 
        U glLoadIdentity 
        U glMaterialx 
        U glMaterialxv 
        U glMatrixMode 
        U glMultMatrixx 
        U glNormalPointer 
        U glPopMatrix 
        U glPushMatrix 
        U glRotatex 
        U glScalex 
        U glShadeModel 
        U glTranslatex 
        U glVertexPointer 
        U glViewport 
00001bec t importGLDeinit
00001be8 t importGLInit
000073bc d light0Diffuse.3407
000073ac d light0Position.3406
000073dc d light1Diffuse.3409
000073cc d light1Position.3408
000073fc d light2Diffuse.3411
000073ec d light2Position.3410
        U malloc 
0000740c d materialSpecular.3412
        U memcpy 
00001ec4 t newGLObject
00005570 t next_unwind_byte
        U pow 
00005edc r quadVertices.3337
000053c8 T restore_core_regs
00004c68 t restore_non_core_regs
0000728c d sCamTracks
0000748c b sCurrentCamTrack
00007490 b sCurrentCamTrackStartTick
00007494 b sDemoStopped
00007484 b sGroundPlane
00007288 d sNextCamTrackStartTick
00007428 b sRandomSeed
00007488 b sStartTick
0000742c b sSuperShapeObjects
000059f0 r sSuperShapeParams
00007480 b sTick
00007498 b sTimeOffset
000074a0 b sTimeOffsetInit
0000749c b sTimeStopped
00007420 d sWindowHeight
0000741c d sWindowWidth
000046b4 t search_EIT_table
0000469c t selfrel_offset31
        U sin 
        U sqrt 
00001f34 t ssFunc
00001bf0 t superShapeMap
00005600 t unwind_UCB_from_context
00004ed4 t unwind_phase2
00004d9c t unwind_phase2_forced

这里可以看到所有源代码里出现的函数名和全局变量名(符号名)都变成了'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
00005650 T _Unwind_Resume
00005674 T _Unwind_Resume_or_Rethrow
00004720 T _Unwind_VRS_Get
000051cc T _Unwind_VRS_Pop
00004794 T _Unwind_VRS_Set
000056bc T ___Unwind_Backtrace
00005698 T ___Unwind_ForcedUnwind
0000562c T ___Unwind_RaiseException
00005650 T ___Unwind_Resume
00005674 T ___Unwind_Resume_or_Rethrow
000037b4 T __adddf3
0000407c T __addsf3
00004638 T __aeabi_cfcmpeq
00004638 T __aeabi_cfcmple
00004628 T __aeabi_cfrcmple
00003fd0 T __aeabi_d2f
000037b4 T __aeabi_dadd
00003dcc T __aeabi_ddiv
00003b60 T __aeabi_dmul
000037a8 T __aeabi_drsub
000037b0 T __aeabi_dsub
00003aac T __aeabi_f2d
000046b0 T __aeabi_f2iz
0000407c T __aeabi_fadd
0000464c T __aeabi_fcmpeq
00004688 T __aeabi_fcmpge
0000469c T __aeabi_fcmpgt
00004674 T __aeabi_fcmple
00004660 T __aeabi_fcmplt
00004458 T __aeabi_fdiv
000042c0 T __aeabi_fmul
00004070 T __aeabi_frsub
00004078 T __aeabi_fsub
00003a84 T __aeabi_i2d
00004214 T __aeabi_i2f
000036b0 T __aeabi_idiv
000037a4 T __aeabi_idiv0
0000378c T __aeabi_idivmod
00003b00 T __aeabi_l2d
00004244 T __aeabi_l2f
000037a4 T __aeabi_ldiv0
00003a60 T __aeabi_ui2d
0000420c T __aeabi_ui2f
000035ec T __aeabi_uidiv
00003698 T __aeabi_uidivmod
00003aec T __aeabi_ul2d
00004234 T __aeabi_ul2f
00004c9c T __aeabi_unwind_cpp_pr0
00004c94 W __aeabi_unwind_cpp_pr1
00004c8c W __aeabi_unwind_cpp_pr2
        U __android_log_print 
00007614 A __bss_end__
00007598 A __bss_start
00007598 A __bss_start__
000045c8 T __cmpsf2
        w __cxa_begin_cleanup 
        w __cxa_call_unexpected 
        w __cxa_type_match 
000073f8 D __data_start
000037a4 T __div0
00003dcc T __divdf3
00004458 T __divsf3
000036b0 T __divsi3
00007614 A __end__
000045c8 T __eqsf2
00006274 A __exidx_end
000060e4 A __exidx_start
00003aac T __extendsfdf2
000046b0 T __fixsfsi
00003b00 T __floatdidf
00004244 T __floatdisf
00003a84 T __floatsidf
00004214 T __floatsisf
00003aec T __floatundidf
00004234 T __floatundisf
00003a60 T __floatunsidf
0000420c T __floatunsisf
000045b8 T __gesf2
00004e44 T __gnu_Unwind_Backtrace
        w __gnu_Unwind_Find_exidx 
00005028 T __gnu_Unwind_ForcedUnwind
0000509c T __gnu_Unwind_RaiseException
0000554c T __gnu_Unwind_Restore_VFP
0000555c T __gnu_Unwind_Restore_VFP_D
0000556c T __gnu_Unwind_Restore_VFP_D_16_to_31
00005604 T __gnu_Unwind_Restore_WMMXC
0000557c T __gnu_Unwind_Restore_WMMXD
00005160 T __gnu_Unwind_Resume
00005140 T __gnu_Unwind_Resume_or_Rethrow
00005554 T __gnu_Unwind_Save_VFP
00005564 T __gnu_Unwind_Save_VFP_D
00005574 T __gnu_Unwind_Save_VFP_D_16_to_31
00005618 T __gnu_Unwind_Save_WMMXC
000055c0 T __gnu_Unwind_Save_WMMXD
000057a4 T __gnu_unwind_execute
00005b20 T __gnu_unwind_frame
000045b8 T __gtsf2
000045c0 T __lesf2
000045c0 T __ltsf2
00003b60 T __muldf3
000042c0 T __mulsf3
000045c8 T __nesf2
00005538 T __restore_core_regs
000037b0 T __subdf3
00004078 T __subsf3
00003fd0 T __truncdfsf2
000035ec T __udivsi3
00007614 A _bss_end__
00007598 A _edata
00007614 A _end
00080000 N _stack
        U abort 
        U cos 
        U free 
        U gettimeofday 
        U glBlendFunc 
        U glClear 
        U glClearColorx 
        U glColor4x 
        U glColorPointer 
        U glDisable 
        U glDisableClientState 
        U glDrawArrays 
        U glEnable 
        U glEnableClientState 
        U glFrustumx 
        U glLightxv 
        U glLoadIdentity 
        U glMaterialx 
        U glMaterialxv 
        U glMatrixMode 
        U glMultMatrixx 
        U glNormalPointer 
        U glPopMatrix 
        U glPushMatrix 
        U glRotatex 
        U glScalex 
        U glShadeModel 
        U glTranslatex 
        U glVertexPointer 
        U glViewport 
        U malloc 
        U memcpy 
        U pow 
00005538 T restore_core_regs
        U sin 
        U sqrt

这样局部符号都没有了,只有jni入口函数被导出。这样提高了jni动态库的安全性,同时.so文件的大小也小了不少。
最后,再简单介绍一下第三种方法: 添加--version-script选项
version script是用户编写的可以直接被编译到ld链接脚本中的脚本文件,就是链接器在链接的时候会把你编写的version script脚本加入到链接脚本中,链接器就会执行version script中的命令,来实现一些功能。

链接器最主要的功能就是实现符号到地址的链接,在这个过程中链接器会定义一个树状结构,其中每个节点(version node)根据version script中定义的符号的名字和相互依赖来组成,version script可以指定某个符号被绑定到某个节点(version node)上,这样的话就可以把一些符号设定为local区域,那么这些符号就可以对so外部隐藏。

version script的格式如下:

  1. VER1 {  
  2.      global:  
  3.          foo1;  
  4.      local:  
  5.          old*;   
  6.          original*;   
  7.          new*;   
  8. };  
其中VER1是脚本中类似函数的东西,也可以叫做标签,可以定义多个标签类似VER2、VER3等等,编译后的so中它们用来区分不同的符号,即把某些符号绑定到这个标签上。

global定义的是对外可见的符号。

local是仅对内可见的符号。

*和?是通配符分别表示匹配多个和一个字符。

参考链接:

1. 关于elf文件的更多资料,可以参考 这篇文章
2.如果要了解gcc和strip更多的选项,请移步gccbinutils的官方文档。
3.http://man7.org/conf/lca2006/shared_libraries/slide18c.html
4.http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_25.html
5.http://www.gnu.org/software/gnulib/manual/html_node/LD-Version-Scripts.html

猜你喜欢

转载自blog.csdn.net/u010144805/article/details/80811214