在理解android的类加载后,我们可以愉快对apk来脱壳了。脱壳重要的是断点:

  断点:在哪个位置脱壳,这里着重指的是在哪个方法

  先介绍断点,我们只要知道加壳是用哪个方法来加载dex的,hook这个方法就可以追踪到dex了。这个方法就是我们要的断点!

  dvmDexFileOpenPartial:——int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)

    apk为dex文件,android在执行前会先将dex转化为odex文件,由函数dvmContinueOptimization(/dalvik/vm/analysis/DexPrepare.cpp)执行。在dvmContinueOptimization中先调用mmap(这也是一个断点)将原Dex文件整体映射到内存;然后调用dvmDexFileOpenPartial去尝试生成DexFile(既然会生成DexFile,当然会调用dexFileParse函数)。以上步骤在dex转odex时才会执行,若加固的apk本来就是odex,则此断点失效。

  dexFileParse:——DexFile* dexFileParse(const u1* data, size_t length, int flags)

    odex会生成dex的内存描述DexFile(dalvik浅析三:类加载),此函数的前2个参数与dvmDexFileOpenPartial相同(自行查看源码)。没什么好说的了,记住在生成DexFile时调用。看雪上已经将提取dex代码集成到libdvm中了:【原创】让开下,让我脱下壳

  上面提及的是在dex加载过程(优化,解析)中,我们可以下断的函数(当然其他还有很多,不一一举例)。但这个有缺点是需要动态调试时才能dump出dex,这需要我们过加固apk的反调试,有点繁琐。新方法是修改libdvm代码去自动脱壳,参考上面看雪中的做法,下面还会详细解析。以下是dump dex的ida script command:

static main(void)
{
auto fp, begin, end, dexbyte;
fp = fopen("C:\\dump.dex", "wb");
begin = r0;
end = r0 + r1;
for ( dexbyte = begin; dexbyte < end; dexbyte ++ )
fputc(Byte(dexbyte), fp);
}

  下面来看看dex运行过程中可以下断点函数(native):——/dalvik/vm/native/dalvik_system_DexFile.cpp基于源码4.4

const DalvikNativeMethod dvm_dalvik_system_DexFile[] = {
520 { "openDexFileNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
521 Dalvik_dalvik_system_DexFile_openDexFileNative },
522 { "openDexFile", "([B)I",
523 Dalvik_dalvik_system_DexFile_openDexFile_bytearray },
524 { "closeDexFile", "(I)V",
525 Dalvik_dalvik_system_DexFile_closeDexFile },
526 { "defineClassNative", "(Ljava/lang/String;Ljava/lang/ClassLoader;I)Ljava/lang/Class;",
527 Dalvik_dalvik_system_DexFile_defineClassNative },
528 { "getClassNameList", "(I)[Ljava/lang/String;",
529 Dalvik_dalvik_system_DexFile_getClassNameList },
530 { "isDexOptNeeded", "(Ljava/lang/String;)Z",
531 Dalvik_dalvik_system_DexFile_isDexOptNeeded },
532 { NULL, NULL, NULL },
533};

  上面的几个函数在加载dex或运行dex会执行,Dalvik_dalvik_system_DexFile_openDexFile_bytearray对于加壳的来说很熟悉吧(看我加壳中提到的文章)。这几个函数已经不能像先前一样直接到dex的addr和len来dump了。但你可以从中得到DexFile,然后在组合出dex文件。在这里你需要了解以下结构体:

  DexFile、DvmDex、DexOrJar;

/*
521 * The set of DEX files loaded by custom class loaders.
522 */
523 HashTable* userDexFiles;      //dvmHashTableRemove(gDvm.userDexFiles, hash, pDexOrJar)

  知道userDexFiles的作用,它管理着用户加载的DexFile。

  ok,有了上面的知识我们可以写代码来脱壳,你可以用xposed来函数,也可以修改源码直接dump。

  

  修改源码脱壳:

  用上面看雪上的代码来解释,它修改了dexFileParse源码,在其中直接添加脱壳代码(具体的脱壳代码执行请看源码)。代码写好了,如何编译呢(编译libdvm.so: makefile,mm)。当然事情到这里还没有结束,若修改了内存的dex结构体,那我们dump出来东西也无法执行。这时候需要我先进行修复,看参考资料3、4。dannerWorking这方面还没去研究待续。

参考资料:

  1 安卓动态调试七种武器之孔雀翎 – Ida Pro

  2 【原创】让开下,让我脱下壳

   3  从Android运行时出发,打造我们的脱壳神器

4  Android应用程序通用自动脱壳方法研究

      

apk 脱壳的更多相关文章

  1. DexHunter在ART虚拟机模式下的脱壳原理分析

    本文博客地址: http://blog.csdn.net/qq1084283172/article/details/78494620 DexHunter脱壳工具在Dalvik虚拟机模式下的脱壳原理分析 ...

  2. Dalvik模式下基于Android运行时类加载的函数dexFindClass脱壳

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78003184 前段时间在看雪论坛发现了<发现一个安卓万能脱壳方法>这篇 ...

  3. Android crash特殊位置定位

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 通常情况下,在我们开发的过程中遇到的crash,可以到logcat中找原因:如果做定制App,对方用 ...

  4. Java中的Html解析:使用jsoup

    包:jsoup-1.10.2.jar import java.io.File; import java.io.IOException; import org.jsoup.Jsoup; import o ...

  5. Android 开发日常积累

    Android 集合 Android 开源项目分类汇总 扔物线的 HenCoder 高级 Android 教程 hencoder HenCoder:给高级 Android 工程师的进阶手册 Andro ...

  6. 掘金 Android 文章精选合集

    掘金 Android 文章精选合集 掘金官方 关注 2017.07.10 16:42* 字数 175276 阅读 50053评论 13喜欢 669 用两张图告诉你,为什么你的 App 会卡顿? - A ...

  7. Android中实现Activity的启动拦截之----实现360卫士的安装应用界面

    第一.摘要 今天不是周末,但是我已经放假了,所以就开始我们的技术探索之旅,今天我们来讲一下Android中最期待的技术,就是拦截Activity的启动,其实我在去年的时候,就像实现这个技术了,但是因为 ...

  8. APK加固之静态脱壳机编写入门

    目录: 0x00APK加固简介与静态脱壳机的编写思路 1.大家都知道Android中的程序反编译比较简单,辛苦开发出一个APK轻易被人反编译了,所以现在就有很多APK加固的第三方平台,比如爱加密和梆梆 ...

  9. 【逆向&渗透实战】Dump内存中的Dex_我是如何脱壳某公司加固过的Apk并利用其API渗透对方数据库

    /作者:Kali_MG1937 QQ:3496925334 CNBLOG博客号:ALDYS4/ 某天午睡,朦朦胧胧梦到给学校提供建站模板的公司有个注射点 梦醒后,我凭借着零散的记忆日进了对面的数据库, ...

随机推荐

  1. Chome 88如何正确隐藏 webdriver?

    从 Chrome 88开始,它的 V8 引擎升级了,一些接口发生了改变. 使用 Selenium 调用 Chrome 的时候,只需要增加一个配置参数: chrome_options.add_argum ...

  2. C#连接Excel读取与写入数据库SQL ( 上 )

    第一次写C#与sql的东西,主要任务是从Excel读取数据,再存到SQL server中. 先上读取Excel文件的code如下. public bool GetFiles(string equipN ...

  3. Django 页面缓存的cache_key是如何生成的

    页面缓存 e.g. @cache_page(time_out, key_prefix=key_prefix) def my_view(): ... 默认情况下,将使用配置中的default cache ...

  4. [ONTAK2010] Peaks 加强版

    [ONTAK2010] Peaks 加强版 题目大意:原题变为强制在线查询 Solution 读入山高,排序后依然建立树链,初始化并查集,初始化重构树新节点标号为\(n+1\) 读入边,按照边权从小到 ...

  5. Mybatis最权威的知识点

    1.什么是Mybatis? (1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动.创建连接.创建statement ...

  6. RichText实现动态输入关键字高亮颜色显示

    int a = 0; string[] kc = new string[40] { "private","protected","public&quo ...

  7. P1618 三连击(升级版)(JAVA语言)

    题目描述 将1,2,-,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出"No!!!". //感谢黄小U饮品 ...

  8. Git本地仓库基本操作-1

    code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...

  9. OpenCV 之 图象几何变换

    二维平面中,图像的几何变换有等距.相似.仿射.投影等,如下所示: 1  图象几何变换 1.1  等距变换 等距变换 (Isometric Transformation),是一种二维的刚体变换,可理解为 ...

  10. 以Aliyun体验机为例,从零搭建LNMPR环境(上)

    使用云服务器搭建 Web 运行环境,尤其是搭建常见的 LNMPR(Linux+Nginx+MySQL+PHP+Redis) 环境,对于开发人员是必备的职场基本技能之一.在这里,借着搭建我的" ...