android的so在proc maps中找不到了

在构建应用的发布版本时,请确保在应用的 build.gradle 文件中将 useLegacyPackaging 设置为 false,以便将未压缩的 .so 文件打包到 APK 中。停用此标志可防止 PackageManager 在安装过程中将 .so 文件从 APK 复制到文件系统,并具有减小应用更新的额外好处。


从 AGP 4.2.0 开始,DSL 选项 useLegacyPackaging 取代了 extractNativeLibs 清单属性。请使用应用的 build.gradle 文件中的 useLegacyPackaging(而非清单文件/manifest中的 extractNativeLibs)来配置原生库压缩行为。


extractNativeLibs属性指示软件包安装程序是否将原生库从 APK 提取到文件系统。如果设置为 “false”,则原生库以未压缩的形式存储在 APK 中。虽然您的 APK 可能较大,但应用加载速度更快,因为库是在应用运行时直接从 APK 加载。

extractNativeLibs 的默认值取决于 minSdkVersion 和您使用的 AGP 版本。在大多数情况下,默认行为很可能符合您的预期,您无需显式设置此属性。


安卓高版本在安装apk时可以不解压lib中的so文件,而将其直接映射到内存中实现加载


建议以未压缩的形式打包原生库,因为这会减小应用安装大小,缩减应用下载大小,并缩短用户的应用加载时间。不过,如果您希望 Android Gradle 插件在构建应用时打包压缩后的原生库,请在应用的 build.gradle 文件中将 useLegacyPackaging 设置为 true:

android {
    packagingOptions {
        jniLibs {
            useLegacyPackaging true
        }
    }
}

在逆向中很常用的一个技巧就是对apk安装后的so文件进行patch然后替换原来的so文件,这样可以绕过签名校验。这种方式的前提是extractNativeLibs必须为true,否则在apk安装目录下并不会找到任何的so文件可以让我们进行patch。

地址                  权限    偏移  dev  inode                          路径
7b7f633000-7b7f635000 r--s 000a5000 fe:06 490828                         /data/app/~~dma2nKNikFTmU3qVUUlOuw==/xxx-t6ddVoyboOdWOHRpLk9xhQ==/base.apk
7b7f635000-7b7f637000 r--s 000b0000 fe:06 490828                         /data/app/~~dma2nKNikFTmU3qVUUlOuw==/xxx-t6ddVoyboOdWOHRpLk9xhQ==/base.apk

其中,地址  表示在 进程的地址空间的 起始地址
    权限, 表示该区段  是否可读,可写, 可执行, 可共享           上面就表示 可读, 可共享
偏移: If the region was mapped from a file (using mmap), this is the offset in the file where the mapping begins. If the memory was not mapped from a file, it's just 0.

设备:  If the region was mapped from a file, this is the major and minor device number (in hex) where the file lives.

inode:  If the region was mapped from a file, this is the file number(文件号)

路径:   If the region was mapped from a file, this is the name of the file. This field is blank for anonymous mapped regions.


在搭载 Android 10(API 级别 29)和更高版本的设备上,您现在可以告知平台直接从应用的 APK 文件运行嵌入式 DEX 代码。如果攻击者曾设法篡改了设备上本地编译的代码,此选项有助于防止这类攻击。

1) 在应用清单文件的 application 元素中将 android::useEmbeddedDex 属性设置为 true。
2) 在模块级 build.gradle.kts 文件(如果您使用的是 Groovy,则为 build.gradle 文件)中将 useLegacyPackaging 设置为 false


New approach introduced by Google in Marshmallow (Android 6) is enabled by setting extractNativeLibs to “false”. It expects the libraries stored uncompressed in the APK (STORE method) and zipaligned. There’s no need to extract them during installation. On app startup, the libraries can be loaded (memmapped) directly from the APK.

Android 6.0之后,就可以, app在启动时,直接从apk载入 lib, (mem mapped)


从Android 6.0 & AGP 3.6.0开始,系统支持直接加载apk中未压缩的so,也就是说在App安装时,系统不再将apk中的so解压,而在加载so时,直接从apk中加载。

findLibrary最终的实现是在DexPathList.findLibrary中,此时libraryName为”mytest”,经过System.mapLibraryName转换后,得到fileName为”libmytest.so”

加载so是先查找App路径下,然后再查找系统路径。通过前缀,也能发现,支持从zip文件base.apk中直接加载so

base.apk!/lib/arm64-v8a/libmytest.so

NativeLoaderNamespace::Load最终调用android_dlopen_ext加载所需so,采用Flag RTLD_NOW执行立即加载,android_dlopen_ext为Android扩展的dlopen实现,至此可以发现,Android的System.loadLibrary底层调用android_dlopen_ext来加载so,而非OpenJDK采用的dlopen

__loader_android_dlopen_ext

如果是直接从apk中加载so。name将类似于/data/app/~~WdKfQO1G6r3htDT7Rgo1DQ==/com.huchao.mysystemloadlibrary-6wbqoASC9saPFntEre3_MQ==/base.apk!/lib/arm64-v8a/libmytest.so,其路径中包含kZipFileSeparator(!/)将去apk文件中查找,调用open_library_in_zipfile,返回打开的apk文件的fd。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注