【问题标题】:Unsatisfied linker error when linking with openssl libraries built for Android与为 Android 构建的 openssl 库链接时出现不满意的链接器错误
【发布时间】:2017-09-27 14:49:01
【问题描述】:

将 openssl 库 (ssl/crypto) 与我的 Android 本机代码链接时出现以下错误。我使用 openssl v1.0.2l 代码并使用 android-sdk/ndk-bundle 目录下的 ndk-build 构建它。

错误信息

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pkg-name.client, PID: 26925
java.lang.UnsatisfiedLinkError: **dlopen failed: cannot locate symbol "i2d_DHxparams"** referenced by "/data/app/com.pkg-name.client-1/lib/arm/libnative-lib.so"...

我的 android-config.make 文件有以下内容:

#
# These flags represent the build-time configuration of openssl for android
#
# They were pruned from the "Makefile" generated by running ./Configure from import_openssl.sh
#

# From CLFAG=   
LOCAL_CFLAGS += -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -O3 -fomit-frame-pointer -Wall #-DTERMIO

# From DEPFLAG=
LOCAL_CFLAGS += -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_SCTP \
                -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_CAST -DOPENSSL_NO_CMS -DOPENSSL_NO_GMP -DOPENSSL_NO_IDEA -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_SHA0 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED -DOPENSSL_NO_STORE -DOPENSSL_NO_WHIRLPOOL

#Copied by seaching for the OPENSSL_NO_
#LOCAL_CFLAGS += -DOPENSSL_NO_DEPRECATED

# Extra
LOCAL_CFLAGS += -DOPENSSL_NO_HW -DOPENSSL_NO_ENGINE -DZLIB

# Debug
# LOCAL_CFLAGS += -DCIPHER_DEBUG

如果我需要启用任何标志,请告诉我。 我尝试了适用于 Android 的预构建 openssl 库并遇到了类似问题。

【问题讨论】:

    标签: ssl android-ndk openssl


    【解决方案1】:
    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.pkg-name.client, PID: 26925
    java.lang.UnsatisfiedLinkError: **dlopen failed: cannot locate symbol "i2d_DHxparams"**
    referenced by "/data/app/com.pkg-name.client-1/lib/arm/libnative-lib.so"...
    

    i2d_DHxparams 是 OpenSSL 1.1.0 中的宏,而不是 1.0.2:

    $ cd openssl
    $ grep -IR i2d_DHxparams
    crypto.map:        i2d_DHxparams;
    util/libcrypto.num:i2d_DHxparams                           2206 1_1_0   EXIST::FUNCTION:DH
    doc/man3/d2i_X509.pod:i2d_DHxparams,
    include/openssl/dh.h:# define i2d_DHxparams_fp(fp,x) \
    include/openssl/dh.h:    ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x))
    include/openssl/dh.h:# define i2d_DHxparams_bio(bp,x) \
    include/openssl/dh.h:    ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x)
    include/openssl/dh.h:int i2d_DHxparams(const DH *a, unsigned char **pp);
    crypto/dh/dh_ameth.c:        return i2d_DHxparams(a, pp);
    crypto/dh/dh_asn1.c:int i2d_DHxparams(const DH *dh, unsigned char **pp)
    apps/dhparam.c:                i = i2d_DHxparams_bio(out, dh);
    

    听起来您可能使用了错误的标头或库。也许您在路径上有 1.1.0 标头,并且它们在 Android 标头之前被拾取。


    编辑:看起来这个符号也出现在 OpenSSL 1.0.2 中:

    $ git checkout OpenSSL_1_0_2-stable
    $ grep -IR i2d_DHxparams
    crypto.map:        i2d_DHxparams;
    util/libeay.num:i2d_DHxparams                           4683    EXIST::FUNCTION:DH
    crypto/dh/dh.h:# define i2d_DHxparams_fp(fp,x) \
    crypto/dh/dh.h:    ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x))
    crypto/dh/dh.h:# define i2d_DHxparams_bio(bp,x) \
    crypto/dh/dh.h:    ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x)
    crypto/dh/dh.h:int i2d_DHxparams(const DH *a, unsigned char **pp);
    crypto/dh/dh_ameth.c:        return i2d_DHxparams(a, pp);
    crypto/dh/dh_asn1.c:int i2d_DHxparams(const DH *dh, unsigned char **pp)
    apps/dhparam.c:                i = i2d_DHxparams_bio(out, dh);
    

    但它似乎不存在于 1.0.1 中:

    $ grep -IR i2d_DHxparams
    crypto.map:        i2d_DHxparams;
    

    【讨论】:

    • @user3391612 - 我检查了 1.0.2 分支,以及那里的符号。我不知道该怎么做。找到 OpenSSL 的 libcrypto.so 并在其上运行 strings 以转储 OpenSSL 版本。即strings libcrypto.so | egrep -i 'OpenSSL|version'。听起来标题和库确实不匹配。让我们联系一下 OpenSSL 开发人员之一的 Matt Caswell。
    • 我在我的代码中使用了 openssl v1.0.2l 标头。 opensslv.h 定义了以下宏。 #define OPENSSL_VERSION_NUMBER 0x100020cfL 我在另一个设备上遇到了另一个链接器问题。 09-28 13:23:52.905 29981-29981/com.pkg-name.client E/art: dlopen("/data/app/com.pkg-name.client/lib/arm/libnative-lib.so", RTLD_LAZY) 失败:dlopen 失败:找不到“libnative-lib.so”引用的符号“EC_curve_nist2nid”...
    • 我在 libcryto.a 上运行 strings 命令,发现版本为“OpenSSL 1.0.2l 2017 年 5 月 25 日的一部分”
    • 回答 ping 但不确定我是否可以为上述讨论添加很多内容。该符号肯定存在于 1.0.2 中 - 但我不熟悉在 Android 上构建,所以我无法提出问题所在。
    • @MattCaswell - 你知道谷歌是否对他们的端口做了什么特别的事情吗?也许将一些#defines 转换为弱符号?
    猜你喜欢
    • 2011-12-29
    • 2016-04-26
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多