前言 古早壳,小白学习脱壳入门,仅供技术交流分享,严禁恶意利用
引入 壳的存在有很多种,以下仅供参考
第一代
DEX整体加密(落地加载)
DEX 加密后存于 APK,运行时解密写入磁盘再加载
第二代
DEX内存加载(不落地)
DEX 解密后仅存在于内存,不写磁盘
第三代
方法抽取(Method Extraction)
只保留方法壳,真实指令运行时动态还原
第四代
VMP / Java2C / 自定义虚拟机
将 Java 字节码转为自定义字节码或 C 代码
具体实现方式有如下几种:
1.替换 AndroidManifest.xml 中的 Application 为壳的入口;
2.加密原始 DEX 文件(可能存于 assets、lib 或隐藏在 SO 中);
3.使用自定义 ClassLoader 加载解密后的 DEX;
4.插入反调试、反 Hook、反内存 dump 机制;
这里仅作简单介绍复现脱壳流程,其余细节后续专门做笔记
梆梆加固(BangBao/SecShell ) np dex->com/SecShell/SecShell/H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # static fields .field public static ACFNAME :Ljava /lang/String ; = "###ACFNAME###" .field public static APPNAME :Ljava /lang/String ; = "com.yanben.App" #复制这里的入口 .field public static ISMPAAS :Ljava /lang/String ; = "###MPAAS###" .field public static PKGNAME :Ljava /lang/String ; = "com.yanben" .field public static cl :Ljava /lang/ClassLoader ; public class H { public static String ACFNAME = "###ACFNAME###" ; public static String APPNAME = "com.yanben.App" ; public static String ISMPAAS = "###MPAAS###" ; public static String PKGNAME = "com.yanben" ; public static ClassLoader cl;
到AndroidManifest.xml中替换入口
1 2 3 4 5 6 7 <application android:theme ="@style/AppTheme" android:label ="@string/app_name" android:icon ="@drawable/ic_launcher" android:name ="com.SecShell.SecShell.AW" //此处 android:debuggable ="true" android:resizeableActivity ="true" >
这里即应用程序入口,负责dex解密,跟进去看看,特征很明显,跟之前的H对上了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 static { System.loadLibrary("SecShell" ); H.i(); }try { if (!"" .equals(H.APPNAME)) { f2S5I5LIsIOISII0OlsIIS5OIII = (Application) getClassLoader().loadClass(H.APPNAME).newInstance(); } } catch (Exception unused) { f2S5I5LIsIOISII0OlsIIS5OIII = null ;public void onCreate () { m2S5Ill0sIsILIIlOlISLIIS(); super .onCreate(); Application application = f2S5I5LIsIOISII0OlsIIS5OIII; if (application != null ) { H.attach(application, null ); f2S5I5LIsIOISII0OlsIIS5OIII.onCreate(); } }
样本到此为止,参考链接还有一处特征出现在 AndroidManifest.xml 中
1 2 3 4 5 6 7 8 9 10 <provider android:name ="com.secneo.apkwrapper.CP" <!--CP 代表 ContentProvider-- > android:exported="false" android:authorities="com.yanben.CP" android:initOrder="2147483647" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <manifest ... > <application android:name ="com.SecShell.SecShell.AW" android:label ="@string/app_name" ... > <provider android:name ="com.secneo.apkwrapper.CP" android:exported ="false" android:authorities ="com.yanben.CP" android:initOrder ="2147483647" /> <activity android:name =".ui.activity.MainActivity" ... > ... </activity > </application > </manifest >
接下来小黑盒脱壳,此样本为32位
https://github.com/CodingGay/BlackDex/releases/tag/v3.2
按dex命名规范重命名,按大小排序替换原dex,hook和cookie有些为重复内容选择删除,这里初解包为一个dex用np合并
adb pull /storage/emulated/0/NP/apks/1.apk D:\CTF\ctftimu\apk_demo
效果如下
腾讯御安全(Tencent Yushou/Tencent Protect) dex com/wrapper/proxyapplication/WrapperProxyApplication
1 2 3 4 5 6 7 8 9 .field static baseContext:Landroid/content/Context; = null .field static className:Ljava/lang/String; = ".App" .field static mLoader:Ljava/lang/ClassLoader; = null .field static shellApp:Landroid/app/Application; = null .field static tinkerApp:Ljava/lang/String; = "tinker not support"
androidmanifest.xml
1 2 3 4 5 6 7 <application android:theme ="@style/AppTheme" android:label ="@string/app_name" android:icon ="@drawable/ic_launcher" android:name ="MyWrapperProxyApplication" //此处替换 android:debuggable ="true" android:resizeableActivity ="true" >
blackdex 之后同样套路
百度加固/百度乐固(Baidu Protect) dex->appinfo
蛮犀加固(Manxi Protect) dex->com/mx/dA/dpa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 .method static constructor <clinit > ()V .registers 1 .line 26 const/4 v0, 0x0 sput-object v0, Lcom/mx/dA/dpa;->app:Landroid/app/Application; .line 27 const-string v0, "" sput-object v0, Lcom/mx/dA/dpa;->sCachePath:Ljava/lang/String; .line 28 sput-object v0, Lcom/mx/dA/dpa;->sApkPath:Ljava/lang/String; .line 30 const/4 v0, 0x0 sput-boolean v0, Lcom/mx/dA/dpa;->bAlreadyInit:Z .line 32 const-string v0, "com.yanben.App" //入口 sput-object v0, Lcom/mx/dA/dpa;->sApplicationName:Ljava/lang/String; .line 33 const-string v0, "" sput-object v0, Lcom/mx/dA/dpa;->sAppComFactoryName:Ljava/lang/String; .line 34 const-string v0, "COPYFALSE" sput-object v0, Lcom/mx/dA/dpa;->CopyToLibs:Ljava/lang/String; return-void .end method
xml
1 2 3 4 5 6 7 8 <application android:theme ="@style/AppTheme" android:label ="@string/app_name" android:icon ="@drawable/ic_launcher" android:name ="com.mx.dA.dpa" //此处替换 android:debuggable ="true" android:resizeableActivity ="true" android:appComponentFactory ="com.mx.dAC.dac" > //此行去除
老套路,这里了解后可以直接删除壳特征相关dex,笔者偷懒全部合并
顶象加固(Dingxiang Protect) dex->com/security/shell/AppStub1
1 2 3 4 5 6 7 .class public Lcom/security/shell/AppStub1; .super Landroid/app/Application; .annotation runtime Lcom/security/mobile/annotation/Config; app = "com.one.tinker.MyApplication"#这个就是入口 appFactory = "android.support.v4.app.CoreComponentFactory" versionStr = "dd2d09b486e704b2f124c173fbe65d37" .end annotation
1 2 3 4 5 6 7 android:icon="@7f0d0005" android:name="com.security.shell.AppStub1"#复制的入口替换到这里 android:supportsRtl="true" android:usesCleartextTraffic="true" android:resizeableActivity="false" android:networkSecurityConfig="@7f120007" android:appComponentFactory="com.security.shell.AppComponentFactory0"> <--!此行去除-->
BlackDex原理 本质是早期一二代壳dex解密后动态加载到内存然后被dump下来
首先BlackDex会涉及虚拟化技术启动目标app进程,详细源码可阅览参考链接,这里以图表形式方便理解
BlackDex 整体工作流程图
从 Java 层到 Native 内存地址 ART(Android Runtime)概念介绍:
安卓 5.0 及之后版本默认的应用程序运行引擎,它替代了老旧的 Dalvik 虚拟机。其核心职责是将应用的字节码转换为设备可执行的机器码。通过采用混合编译模式(结合安装不编译、运行时即时编译热点代码、空闲时后台预编译),ART 在保证安装速度和节省存储空间的同时,显著提升了应用的启动与运行效率,并优化了内存回收机制
frida-dexdump 也可以直接pip install frida-dexdump:https://github.com/hluwa/frida-dexdump
查壳工具安利:https://github.com/moyuwa/ApkCheckPack
启动frida-server
frida-dexdump -FU
-U usb -F 前端活动app -f com.app.pkgname
在线脱壳 https://56.al/upload.php
https://www.tosks.top/ (需下载)
https://json2.cc/dev/apk_parser
参考链接 https://www.52pojie.cn/forum.php?mod=viewthread&tid=1453091&extra=page%3D1%26filter%3Dtypeid%26typeid%3D343
https://buaq.net/go-167998.html
https://mezdosec.github.io/post/frida-dexdump-tuo-ke-de-zheng-que-zi-shi/