从 android 本机库中获取原始 dex 文件

Get original dex file from android native library

我想实施安全检查 - 应用程序(或 dex 文件)的签名验证,以验证未修改的应用程序是否使用我使用 NDK 构建的共享本机库 (*.so)。我想直接在 C++ 中执行所有签名检查,而不需要 Java。目前我发现可以在这里访问 apk 文件:/data/app/--1/base.apk。从 apk 文件中,我想即使不提取也有可能获取原始 dex 文件的内容,因为 apk 文件是对齐的。

  1. 有谁知道如何在不从 apk 中提取的情况下读取 dex 文件?

我说原始 dex 文件是因为如果我理解正确(如果我错了请纠正我)安装 apk 时 dex 文件会转换为 ELF 共享对象 - 特定于设备体系结构的二进制可执行文件。这就是为什么我无法 /proc/self/maps 中列出的 *.dex 文件的 check/verify 签名的原因(例如:/data/dalvik-cache/x86/data@app@com.asdf.pkg@base.apk @classes.dex) 因为在编译时不可能知道签名,因为 dex 文件会被更改。

我知道检查原始 dex 文件的方法不是很安全,因为我认为它可以通过替换优化的 dex 文件轻松地在 root 设备上绕过 - 只需 运行 dex2oat 自定义 dex 文件并将其放在(/data/dalvik-cache/...).

  1. 是否有任何其他更好的方法来使用普通 C++ 检查应用程序是否来自本机库? (不通过 JNI 调用 Java)
  1. 有谁知道如何在不从 apk 中提取的情况下读取 dex 文件?

暂时想不出办法

  1. 是否有任何其他更好的方法来使用纯 C++ 检查应用程序是否来自本机库? (不通过 JNI 调用 Java)

我能想到几个(他们都疯了):

  1. 对 APK 进行哈希处理并与外部网络服务器上的哈希值进行比较。不能对散列进行硬编码,因为这样做会更改散列。这应该是最简单的。对于奖励积分,将其保存在本地,这样以后运行就不需要网络连接了。
  2. 在您的应用中嵌入 jarsigner。将它放在您的资产文件夹中,并使用 exec 或任何 C++ 使用的方式从本机调用它。 Hosting an executable within Android application says that it's possible to do. Oracle documentation of jarsigner 表示自签名的 jars 为发布者输出 UNKNOWN。不太可能有人会将该应用程序上传到 Google Play,但理论上他们可以使用真实证书对其进行签名,因此不确定这是否真的安全。再一次,您应该能够检查它是否已使用您的证书签名。

对于像我这样使用基于 Intel 设备的傻瓜来说可能会失败。

  1. 火与硫磺。用 zlib and check certificate with OpenSSL 解压。在尝试这个之前我会认真考虑转行,但是,我不喜欢 C/C++。