AOSP+Fart脱壳相关
前置条件
- 首先修改AOSP相关源码,去AOSP系统特征,去fart特征
一、User版(抽取型示例)
- 安装App,并赋予存储权限
- 指定需要进行抽取脱壳的包名
echo com.youxiang.soyoungapp > /data/local/tmp/xxx.txt
- 创建exclude_class.txt和exclude_method.txt
touch /data/local/tmp/exclude_class.txt touch /data/local/tmp/exclude_method.txt
对于某些app会故意定义一些方法,让你执行时闪退,所以需要根据日志信息,将闪退时的类或者方法名记录下来,不去执行
- 将最后一个类加入exclude_class.txt 或 最后一个方法加入exclude_method.txt【二选一即可】
- 最后一个类
echo com.google.android.gms.internal.ads.zzcaw > /data/local/tmp/exclude_class.txt
- 最后一个方法(这个示例中是构造方法)
echo "com.google.android.gms.internal.ads.zzcaw(int,android.os.Bundle,com.google.android.gms.internal.ads.zzbdk,com.google.android.gms.internal.ads.zzbdp,java.lang.String,android.content.pm.ApplicationInfo,android.content.pm.PackageInfo,java.lang.String,java.lang.String,java.lang.String,com.google.android.gms.internal.ads.zzcgy,android.os.Bundle,int,java.util.List,android.os.Bundle,boolean,int,int,float,java.lang.String,long,java.lang.String,java.util.List,java.lang.String,com.google.android.gms.internal.ads.zzblw,java.util.List,long,java.lang.String,float,boolean,int,int,boolean,java.lang.String,java.lang.String,boolean,int,android.os.Bundle,java.lang.String,com.google.android.gms.internal.ads.zzbhk,boolean,android.os.Bundle,java.lang.String,java.lang.String,java.lang.String,boolean,java.util.List,java.lang.String,java.util.List,int,boolean,boolean,boolean,java.util.ArrayList,java.lang.String,com.google.android.gms.internal.ads.zzbry,java.lang.String,android.os.Bundle)" > exclude_method.txt
推荐:在winows下直接写入文件中,然后adb push到手机
- 最后一个类
- 将最后一个类加入exclude_class.txt 或 最后一个方法加入exclude_method.txt【二选一即可】
- 查看日志信息
adb logcat -s ActivityThread
- 启动app
- 查看脱壳内容
- 存放目录比如:/sdcard/xxx/包名
- 抽取型后缀名:xxx.dex
- 整体型后缀名:xxxExecute.dex
- 抽取型后缀名:xxx.dex
- 存放目录比如:/sdcard/xxx/包名
- 动态加载dex处理
- 如果导出的dex不全,可以考虑是否存在动态加载dex问题
- 解决方案
- 基于Frida的Hook脚本去获取到相应的自定义ClassLoader
Java.perform(function () { // 大多数会继承于DexClassLoader,也有的会继承于BaseDexClassLoader或者PathClassLoader【DexClassLoader继承于BaseDexClassLoader】 var dexclassLoader = Java.use("dalvik.system.DexClassLoader"); // var baseDexclassLoader = Java.use("dalvik.system.BaseDexClassLoader"); dexclassLoader.$init.implementation = function (dexPath, optimizedDirectory, librarySearchPath, parent) { this.$init(dexPath, optimizedDirectory, librarySearchPath, parent); console.log('DexClassLoader构造方法执行。。。') console.log("dexpath =>",dexPath) console.log(JSON.stringify(this)); // console.log(this.getParent()); //主动执行 android.app.ActivityThread.fartwithClassloader var ActivityThread = Java.use("android.app.ActivityThread"); ActivityThread.doLuffywithClassloader(this); }; }); //frida -U -f com.nb.loaderdemo2 -l 14-fart_加载自定义ClassLoader.js
- 基于Frida的Hook脚本去获取到相应的自定义ClassLoader
- dex修复
- 对于某些壳,dumpArtMethod的上半部分已经能对dex进行整体dump,但是对于部分抽取壳,dex即使被dump下来,函数体还是以nop填充,即空函数体,FART还把函数的CodeItem给dump下来是让用户手动来修复这些dump下来的空函数。
- 工具github地址:https://github.com/dqzg12300/dexfixer
- 使用:
java -jar dexfixer.jar dexpath binpath outpath
- 示例
java -jar dexfixer.jar 7693460_dexfile.dex 7693460_ins_5125.bin demo.dex
demo.dex即修复后的dex文件
- 使用:
二、userdebug版本
-
adbd不降权、ptrace、以及其它
asop/build/core/main.mk aosp/system/core/adb/daemon/set_verity_enable_state_service.cpp
main.mk中需要强制ro.debuggable=0
当ro.debuggable=0时,会影响adb disable-verity的执行会受影响,因此需要注释掉/* if(!_android_log_is_debuggable){...return;} */
- 删除文件:/system/xbin/su
- 对于系统文件操作,需要利用挂载
- 解决方案
- 设置/system可写
- 删除/system/xbin/su
- 设置/system可读
- 具体指令
>>>adb disable-verity >>>adb reboot 重启使上述命令生效 当mount命令提示'system' not in /proc/mounts时需要执行上述两行命令 >>>adb shell >>>mount -o rw,remount /system >>>rm /system/xbin/su >>>mount -o ro,remount /system
-
- 集成证书
- 导出charles证书,比如证书名charles-ssl-proxying-certificate.pem
- 处理证书
openssl x509 -subject_hash_old -in charles-ssl-proxying-certificate.pem
得到字符串,比如29348ce7
- 修改证书名
- 将【charles-ssl-proxying-certificate.pem】修改为【29348ce7.0】
- 注意修改后的证书名和上述得到的字符串有关
- 植入手机
- 将证书文件放入目录【/system/etc/security/cacerts/】
- 参照上述挂载命令,在将/system挂载的情况下,执行
>>>adb push 29348ce7.0 /data/local/tmp/29348ce7.0 >>>mv /data/local/tmp/df697b32.0 /system/etc/security/cacerts/ >>>mount -o ro,remount /system
三、AOSP系统无法上网问题解决
- 可以先插上手机卡,用流量去运行测试,如果仍无法上网,则执行下面的操作
- AOSP系统特征被检测所导致的情况
-
1、修改buildinfo.sh【位于 aosp/build/tools/buildinfo.sh】
#!/bin/bash echo "# begin build properties" echo "# autogenerated by buildinfo.sh" # echo "ro.build.id=$BUILD_ID" echo "ro.build.id=QD1A.190821.011" # echo "ro.build.display.id=$BUILD_DISPLAY_ID" echo "ro.build.display.id=QD1A.190821.011" # echo "ro.build.version.incremental=$BUILD_NUMBER" echo "ro.build.version.incremental=5849216" echo "ro.build.version.sdk=$PLATFORM_SDK_VERSION" echo "ro.build.version.preview_sdk=$PLATFORM_PREVIEW_SDK_VERSION" echo "ro.build.version.preview_sdk_fingerprint=$PLATFORM_PREVIEW_SDK_FINGERPRINT" echo "ro.build.version.codename=$PLATFORM_VERSION_CODENAME" echo "ro.build.version.all_codenames=$PLATFORM_VERSION_ALL_CODENAMES" echo "ro.build.version.release=$PLATFORM_VERSION" echo "ro.build.version.security_patch=$PLATFORM_SECURITY_PATCH" echo "ro.build.version.base_os=$PLATFORM_BASE_OS" echo "ro.build.version.min_supported_target_sdk=$PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION" echo "ro.build.date=`$DATE`" echo "ro.build.date.utc=`$DATE +%s`" # echo "ro.build.type=$TARGET_BUILD_TYPE" echo "ro.build.type=user" # echo "ro.build.user=$BUILD_USERNAME" echo "ro.build.user=android-build" # echo "ro.build.host=$BUILD_HOSTNAME" echo "ro.build.host=abfarm857" # echo "ro.build.tags=$BUILD_VERSION_TAGS" echo "ro.build.tags=release-keys" # echo "ro.build.flavor=$TARGET_BUILD_FLAVOR" echo "ro.build.flavor=coral-user" if [ -n "$BOARD_BUILD_SYSTEM_ROOT_IMAGE" ] ; then echo "ro.build.system_root_image=$BOARD_BUILD_SYSTEM_ROOT_IMAGE" fi if [ -n "$AB_OTA_UPDATER" ] ; then echo "ro.build.ab_update=$AB_OTA_UPDATER" fi # These values are deprecated, use "ro.product.cpu.abilist" # instead (see below). echo "# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete," echo "# use ro.product.cpu.abilist instead." echo "ro.product.cpu.abi=$TARGET_CPU_ABI" if [ -n "$TARGET_CPU_ABI2" ] ; then echo "ro.product.cpu.abi2=$TARGET_CPU_ABI2" fi echo "ro.product.cpu.abilist=$TARGET_CPU_ABI_LIST" echo "ro.product.cpu.abilist32=$TARGET_CPU_ABI_LIST_32_BIT" echo "ro.product.cpu.abilist64=$TARGET_CPU_ABI_LIST_64_BIT" if [ -n "$PRODUCT_DEFAULT_LOCALE" ] ; then echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE" fi echo "ro.wifi.channels=$PRODUCT_DEFAULT_WIFI_CHANNELS" echo "# ro.build.product is obsolete; use ro.product.device" echo "ro.build.product=$TARGET_DEVICE" echo "# Do not try to parse description or thumbprint" # echo "ro.build.description=$PRIVATE_BUILD_DESC" echo "ro.build.description=coral-user 10 QD1A.190821.011 5849216 release-keys" if [ -n "$BUILD_THUMBPRINT" ] ; then echo "ro.build.thumbprint=$BUILD_THUMBPRINT" fi echo "# end build properties"
-
2、修改buildinfo_common.sh【位于aosp/build/tools/buildinfo_common.sh】
#!/bin/bash partition="$1" if [ "$#" -ne 1 ]; then echo "Usage: $0 <partition>" 1>&2 exit 1 fi echo "# begin common build properties" echo "# autogenerated by $0" echo "ro.${partition}.build.date=`$DATE`" echo "ro.${partition}.build.date.utc=`$DATE +%s`" # echo "ro.${partition}.build.fingerprint=$BUILD_FINGERPRINT" echo "ro.system.build.fingerprint=google/coral/coral:10/QD1A.190821.011/5849216:user/release-keys" # echo "ro.${partition}.build.id=$BUILD_ID" echo "ro.${partition}.build.id=QD1A.190821.011" # echo "ro.${partition}.build.tags=$BUILD_VERSION_TAGS" echo "ro.system.build.tags=release-keys" # echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE" echo "ro.${partition}.build.type=user" # echo "ro.${partition}.build.version.incremental=$BUILD_NUMBER" echo "ro.${partition}.build.version.incremental=5849216" echo "ro.${partition}.build.version.release=$PLATFORM_VERSION" echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION" # echo "ro.product.${partition}.brand=$PRODUCT_BRAND" echo "ro.product.${partition}.brand=google" # echo "ro.product.${partition}.device=$PRODUCT_DEVICE" echo "ro.product.${partition}.device=generic" # echo "ro.product.${partition}.manufacturer=$PRODUCT_MANUFACTURER" echo "ro.product.${partition}.manufacturer=Google" # echo "ro.product.${partition}.model=$PRODUCT_MODEL" echo "ro.product.${partition}.model=Pixel 4" # echo "ro.product.${partition}.name=$PRODUCT_NAME" echo "ro.product.${partition}.name=Pixel 4" echo "# end common build properties"
上述以pixel 4手机为例
-
四、编译、刷系统
- 编译
>>>cd ~/bin/aosp
>>>source build/envsetup.sh >>>make clobber # 重新编译生效(仅在切换编译版本时需要) >>>lunch >>>选择序号 >>>make -j4 【数字越大,占内存越大,编译越快】 - 刷系统
sudo adb devices sudo adb reboot bootloader source ~/bin/aosp/build/envsetup.sh sudo ANDROID_PRODUCT_OUT=~/bin/aosp/out/target/product/flame fastboot flashall -w
五、刷机包使用
- 1、刷机
adb reboot bootloader ./flash-all.bat
- 2、关闭verity
>>>adb disable-verity >>>adb reboot
- 3、删除su
>>>adb shell >>>mount -o rw,remount /system >>>rm /system/xbin/su >>>mount -o ro,remount /system
- 4、集成证书
>>>adb push 29348ce7.0 /data/local/tmp/29348ce7.0 >>>adb shell >>>mount -o rw,remount /system >>>mv /data/local/tmp/29348ce7.0 /system/etc/security/cacerts/ >>>mount -o ro,remount /system
- 5、脱壳
- 1、安装APP & 赋予手机存储权限 - 2、写入包名 echo com.xxx.xxx > /data/local/tmp/luffy.txt - 3、查看日志 & 运行APP adb logcat -s ActivityThread - 看到 -> 包名 /data/local/tmp/luffy.txt -> 等待60s -> ... - 4、如果闪退 将类名或函数名(包含构造函数)写入以下对应文件 - /data/local/tmp/exclude_class.txt - /data/local/tmp/exclude_method.txt - 5、查看脱壳内容 /sdcard/luffy/包名 - xxxExecute.dex 整体脱壳 - xxx.dex 抽取脱壳 - 6、服务端证书校验相关 - 每次使用前,建议先删除证书相关文件 adb shell cd /sdcard/Download rm -rf luffy* - 证书相关文件 - /sdcard/Download/luffy_cert_时间戳