热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android二代抽取壳的一些脱壳方法

修改rom通过修改android源码自定义脱壳机,选择合适的时机通过主动调用加载apk中的类,然后再挑选合适的时机对dex文件进行dump。主动调用当一个app启动的时候会调用ha

修改rom

通过修改android源码自定义脱壳机,选择合适的时机通过主动调用加载apk中的类,然后再挑选合适的时机对dex文件进行dump。


主动调用

当一个app启动的时候会调用handleBindApplication函数,此函数会调用Application的attachBaseContext函数和Application的OnCreate函数。可以在handleBindApplication函数调用前或者此函数开头调用函数创建一个线程,因为加壳apk一般会在Application的attachBaseContext函数中通过DexClassLoader和PachClassLoader类自定义classloader并加载原始apk/dex文件,所以线程中可以通过多次反射获取到应用程序默认classloader(mClassloader),需要多次反射的原因是handleBindApplication还没有调用Application的attachBaseContext函数之前的mClassLoader还是壳自身的classloader。

//通过反射获取LoadedApk对象
Class ActivityThreadClass = Class.forName("android.app.ActivityThread");
Method currentActivityThreadMethod = ActivityThreadClass.getDeclaredMethod("currentActivityThread");
Object ActivityThreadObject = currentActivityThreadMethod.invoke(null);
Field mPackagesField = ActivityThreadClass.getDeclaredField("mPackages");
mPackagesField.setAccessible(true);
ArrayMap mPackages = (ArrayMap) mPackagesField.get(ActivityThreadObject);
WeakReference wr = (WeakReference) mPackages.get(this.getPackageName());
//通过反射获取LoadedApk对象的mClassLoader字段
Class LoadedApkClass = Class.forName("android.app.LoadedApk");
Field mClassLoaderField = LoadedApkClass.getDeclaredField("mClassLoader");
mClassLoaderField.setAccessible(true);
ClassLoader mClassLoader = mClassLoaderField.get(wr.get());

这里还有一种特殊情况就是原始apk/dex自己还会自定义classloader并加载其他dex文件,如果这个dex文件也被进行了函数抽取那么也需要获取他的classloader并进行主动调用使函数回填。这里可以通过第三方ART hook框架对DexClassLoader和PachClassLoader类的构造函数进行hook并获取到返回值就是自定义的classloader,然后再进行主动调用使其函数进行自动回填。

主动调用就是通过获取到classloader对应的DexPachList,进一步获取到所有的DexFile对象,通过调用DexFile的entries等方法枚举dex文件中所有的类名称,使用classloader调用loadclass进行主动加载。


dex Dump

通常修改一些native层的函数进行dexdump,只要native函数能够获取到native层DexFile对象就可以对dex文件进行dump。这里使用LoadMethod函数,此函数再dex文件中的函数被加载到虚拟机中时被调用,当然还有其他很多函数都可以。


不修改rom

不修改源码的情况下通常通过frida调试器进行主动调用和dex的dump,缺点是frida很容易被检测到。


主动调用

frida提供了enumerateClassLoaders这个API可以过去到apk中所有的classloader,这样的话就可以通过frida脚本枚举所有classloader,通过得到classloader对应的所有DexFile对象并调用entries枚举dex文件中的所有类名称进行主动加载。

function dealwithClassLoader(classloaderobj) {
if (Java.available) {
Java.perform(function () {
try {
var dexfileclass = Java.use("dalvik.system.DexFile");
var BaseDexClassLoaderclass = Java.use("dalvik.system.BaseDexClassLoader");
var DexPathListclass = Java.use("dalvik.system.DexPathList");
var Elementclass = Java.use("dalvik.system.DexPathList$Element");
var basedexclassloaderobj = Java.cast(classloaderobj, BaseDexClassLoaderclass);
var tmpobj = basedexclassloaderobj.pathList.value;
var pathlistobj = Java.cast(tmpobj, DexPathListclass);
var dexElementsobj = pathlistobj.dexElements.value;
if (dexElementsobj != null) {
for (var i in dexElementsobj) {
var obj = dexElementsobj[i];
var elementobj = Java.cast(obj, Elementclass);
tmpobj = elementobj.dexFile.value;
var dexfileobj = Java.cast(tmpobj, dexfileclass);
const enumeratorClassNames = dexfileobj.entries();
while (enumeratorClassNames.hasMoreElements()) {
var className = enumeratorClassNames.nextElement().toString();
if(-1 != className.indexOf("com.reverccqin")){
console.log("start loadclass->", className);
var loadclass = classloaderobj.loadClass(className);
console.log("after loadclass->", loadclass);
}
}
}
}
} catch (e) {
console.log(e)
}
});
}
}

dex Dump

dex Dump的话就通过frida hook LoadMethod等方法。


关于主动调用脱壳的对抗

检测主动调用的脱壳行为

因为主动调用主要是通过获取到对应的classloader,并调用loadclass将所有的类都主动加载一遍使其自动进行函数的回填。这就可以通过apk中编写一个永远不会使用的类,因为这个类永远都不会使用,所以apk可以通过调用entries枚举classloader中所有的类并判断此类是否被加载,如果被加载说明存在主动调用的脱壳行为,APK直接闪退


绕过检测

可以再进行主动调用的过程中对特定类进行过滤不进行主动加载,也可以通过hook entries欺骗apk的检测代码。



推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
  • struts2重点——ValueStack和OGNL
    一、值栈(ValueStack)1.实现类:OGNLValueStack2.对象栈:CompoundRoot( ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Java集合库的使用方法,包括如何方便地重复使用集合以及下溯造型的应用。通过使用集合库,可以方便地取用各种集合,并将其插入到自己的程序中。为了使集合能够重复使用,Java提供了一种通用类型,即Object类型。通过添加指向集合的对象句柄,可以实现对集合的重复使用。然而,由于集合只能容纳Object类型,当向集合中添加对象句柄时,会丢失其身份或标识信息。为了恢复其本来面貌,可以使用下溯造型。本文还介绍了Java 1.2集合库的特点和优势。 ... [详细]
  • 解决java.lang.IllegalStateException: ApplicationEventMulticaster not initialized错误的方法和原因
    本文介绍了解决java.lang.IllegalStateException: ApplicationEventMulticaster not initialized错误的方法和原因。其中包括修改包名、解决service name重复、处理jar包冲突和添加maven依赖等解决方案。同时推荐了一个人工智能学习网站,该网站内容通俗易懂,风趣幽默,值得一看。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有