GmSSL: java.lang.UnsatisfiedLinkError: dlopen failed: library "libcrypto.so.1.1" not found

将编译完成的GmSSL文件libssl.so,libcrypto.so,libgmssljni.so,添加到src/main/jniLibs目录下,按照对应的指令集存放
例如

jniLibs/armeabi-v7a/libssl.so
jniLibs/armeabi-v7a/libcrypto.so
jniLibs/armeabi-v7a/libgmssljni.so

打包成APK文件,查看so文件是否存在

Java示例代码

static {
	System.loadLibrary("gmssljni"); //运行中,会自动寻找 lib+名字+.so 的文件
}

运行,出现如下错误

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcrypto.so.1.1" not found
        at java.lang.Runtime.loadLibrary(Runtime.java:372)
        at java.lang.System.loadLibrary(System.java:988)
        ......

起初,以为是没有加载crypto库,于修改Java代码

static {
        System.loadLibrary("crypto");
        System.loadLibrary("ssl");
	    System.loadLibrary("gmssljni");
}

运行,依然出行相同错误

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcrypto.so.1.1" not found
        at java.lang.Runtime.loadLibrary(Runtime.java:372)
        at java.lang.System.loadLibrary(System.java:988)
        ......

从APK包中可以确定libcrypto.so都已经打包到APK中了,且也加载成功了,那么为什么运行还会出行错误?

多方检索,从
https://stackoverflow.com/questions/33103867/unsatisfiedlinkerror-libcrypto-so-1-0-0-not-found 找到了答案:

  • Android 应该是厌恶(至少不喜欢)带有版本号的so文件的。我按照 NDK BUILD 指导,编写出来Makefile(Andrid.mk,Application.mk),执行过程中,NDK BUILD最终生成的文件名,全部不带有版本号

  • 通过运行命令readelf -a elf文件查看 libgmssljni.so,部分信息如下

 0x00000001 (NEEDED)                     共享库:[libdl.so]
 0x00000001 (NEEDED)                     共享库:[libcrypto.so.1.1]
 0x00000001 (NEEDED)                     共享库:[libssl.so.1.1]
 0x00000001 (NEEDED)                     共享库:[libc.so]
 0x00000001 (NEEDED)                     共享库:[libm.so]
 0x00000001 (NEEDED)                     共享库:[libstdc++.so]

libgmssljni.so里面设置的依赖库名字为libcrypto.so.1.1

  • 通过运行命令readelf查看 libcrypto.so,部分信息如下
 0x0000000e (SONAME)                     Library soname: [libcrypto.so.1.1]

......
Version definition section '.gnu.version_d' contains 2 entries:
  地址:0x0000000000036424  Offset: 0x036424  Link: 3 (.dynstr)
  000000: Rev: 1  Flags: BASE  Index: 1  Cnt: 1  名称:libcrypto.so.1.1
  • 问题大致清楚了,libgmssljni.so 需要依赖(NEEDED)libcrypto.so.1.1,而我加载的是libcrypto.so

解决办法有两种

  • 1、重新编译libcrypto.solibssl.so,设置合适的编译标志,使其不生成带有版本号的库
  • 2、rpl工具 rpl -R -e 旧字符串 新字符串 elf文件
 rpl -R -e .so.1.1 "1_1_so"  libcrypto.so
 rpl -R -e .so.1.1 "1_1_so"  libssl.so

Java加载代码变为:

static {
        System.loadLibrary("crypto_1_1");
        System.loadLibrary("ssl_1_1");
	    System.loadLibrary("gmssljni");
}

你可能感兴趣的:(调试,Android)