Android伪加密与解决思路
2023-09-15 18:19:10
Android APK文件本质上是一种zip格式的文件,如果您想进行修改,首先得解压它。但是您会发现,Android 11源码中的zip解压库有一些特殊的地方。
我们以Zygote进程为例,在Zygote进程启动后,Android会使用zip library解压apk文件,并将classes.dex文件通过dex2oat工具转换成oat文件,然后通过dlopen和dlsym加载oat文件中的so和函数。
我们如果想修改apk中的so,那么我们就得在Android解压apk之前将其从apk文件中提取出来。在Android 11源码中,提取apk中so的函数是ExtractNativeLibs。
但是Android并没有提供直接调用ExtractNativeLibs函数的接口,这就给修改apk中的so造成了很大的困难。那我们该怎么办呢?
经过分析,我们发现我们可以通过调用ZygoteInit类的startSystemServer方法来间接调用ExtractNativeLibs函数。startSystemServer方法会在Zygote进程启动后被调用,它会调用Zygote类中的nativeForkSystemServer方法,而nativeForkSystemServer方法最终会调用nativeZygoteStartSystemServer方法,而nativeZygoteStartSystemServer方法中会调用ExtractNativeLibs函数。
因此,我们可以通过继承ZygoteInit类,重写startSystemServer方法,在startSystemServer方法中调用ExtractNativeLibs函数,这样就可以提取出apk中的so文件了。
现在我们已经成功地提取出了apk中的so文件,接下来我们就可以对其进行修改了。修改so文件后,我们需要将其重新打包成apk文件。
在Android 11源码中,打包apk文件的函数是make_zip_archive,我们可以通过调用这个函数将修改后的so文件重新打包成apk文件。
result = make_zip_archive(from, dest, compression_level, comment, offset,
block_size, page_alignment, recompress_level,
is_strict, bytes_per_crc, crc32_table,
extra_compression_methods, crypt_method, clevel,
read_buffer_size, self_test, verbosity, symlinks,
deterministic, android_level);
其中,from是输入文件路径,dest是输出文件路径,compression_level是压缩级别,comment是注释,offset是偏移量,block_size是块大小,page_alignment是页面对齐,recompress_level是重新压缩级别,is_strict是严格模式,bytes_per_crc是每个crc的字节数,crc32_table是crc32表,extra_compression_methods是额外的压缩方法,crypt_method是加密方法,clevel是加密级别,read_buffer_size是读取缓冲区大小,self_test是自测,verbosity是详细程度,symlinks是符号链接,deterministic是确定性,android_level是android级别。
我们只需要将修改后的so文件作为输入文件,将apk文件作为输出文件,然后调用make_zip_archive函数即可将修改后的so文件重新打包成apk文件。
这样我们就成功地修改了apk中的so文件。
需要注意的是,修改apk中的so文件可能会导致apk文件无法正常运行,因此在修改apk中的so文件之前,请务必备份好原始的apk文件。