【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 查找 DexFile 对应的C代码 | dalvik_system_DexFile.cpp 分析 )

简介: 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 查找 DexFile 对应的C代码 | dalvik_system_DexFile.cpp 分析 )

文章目录

前言

一、查找 DexFile 对应的 C++ 代码

1、根据 Native 文件命名惯例查找 C++ 代码

2、根据方法名查找

二、dalvik_system_DexFile.cpp 源码分析

前言

上一篇博客 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexFile loadDexFile 函数 | 构造函数 | openDexFile 函数 ) 中 , 介绍了 DexFile 中加载 Dex 文件的流程 , 入口函数是 DexFile 的 loadDexFile 函数 , 然后在该函数中调用了 DexFile 的构造函数 , 之后再构造函数中调用了 openDexFile 函数 , 最终调用了 openDexFileNative 方法 ;


openDexFileNative 方法在 C++ 代码中实现 , 本篇博客介绍该 C++ 实现 ;






一、查找 DexFile 对应的 C++ 代码



1、根据 Native 文件命名惯例查找 C++ 代码


DexFile.java 的路径是


/libcore/dalvik/src/main/java/dalvik/system/DexFile.java



按照 Android 的惯例 , DexFile 对应的 C++ 代码名称一般是将路径中的 “/” 替换成 “_” ;


dalvik/system/DexFile.java 的 Java 代码对应的 C++ 代码一般命名为 dalvik_system_DexFile.cpp , 尝试在 dalvik 模块中搜索该 C++ 代码 ;



dalvik_system_DexFile.cpp 源码路径为 /dalvik/vm/native/dalvik_system_DexFile.cpp



2、根据方法名查找


也可以直接在 http://androidxref.com/4.4.4_r1/ 地址的 Full Search 中 , 搜索 openDexFileNative 方法 , 注意选中 dalvik 模块 ;

image.png







二、dalvik_system_DexFile.cpp 源码分析


在下面的代码中 , 从参数张红获取 dex 文件路径 和 优化 dex 文件路径 ,


// dex 文件路径
    StringObject* sourceNameObj = (StringObject*) args[0];
    // 优化 dex 文件路径 
    StringObject* outputNameObj = (StringObject*) args[1];


判断 dex 文件是否以 " .dex " 结尾 ,


hasDexExtension(sourceName)


如果文件是以 .dex 结尾 , 则进入 dvmRawDexFileOpen 函数执行 ,


dvmRawDexFileOpen(sourceName, outputName, &pRawDexFile, false)



dalvik_system_DexFile.cpp 相关代码示例 :


/*
 * 私有静态int-openDexFileNative(字符串sourceName、字符串outputName、,
 * int标志)引发IOException
 * 
 * 打开一个DEX文件,返回指向内部数据结构的指针。
 * 
 * “sourceName”应该指向“source”jar或DEX文件。
 * 
 * 如果“outputName”为空,则DEX代码将自动查找
 * 缓存目录中的“优化”版本,必要时创建它。
 * 如果它不为NULL,则将使用指定的文件。
 * 
 * TODO:目前,我们很乐意多次打开同一个文件。
 * 为了优化这一点,我们可以在散列中搜索现有条目
 * 表并重新计算它们。需要原子操作或添加“已同步”
 * 指向在此调用的非本机代码。
 * 
 * TODO:应该使用“long”作为指针。
 */
static void Dalvik_dalvik_system_DexFile_openDexFileNative(const u4* args,
    JValue* pResult)
{
  // dex 文件路径
    StringObject* sourceNameObj = (StringObject*) args[0];
    // 优化 dex 文件路径 
    StringObject* outputNameObj = (StringObject*) args[1];
    DexOrJar* pDexOrJar = NULL;
    JarFile* pJarFile;
    RawDexFile* pRawDexFile;
    char* sourceName;
    char* outputName;
    if (sourceNameObj == NULL) {
        dvmThrowNullPointerException("sourceName == null");
        RETURN_VOID();
    }
    sourceName = dvmCreateCstrFromString(sourceNameObj);
    if (outputNameObj != NULL)
        outputName = dvmCreateCstrFromString(outputNameObj);
    else
        outputName = NULL;
    /*
     * 我们必须处理可能有人试图
     * 打开我们的一个引导类DEX文件。依赖项集
     * 将是不同的,因此优化的结果可能是不同的
     * 不同,这意味着我们实际上需要有两个版本的
     * 优化的DEX:只知道引导类的一部分的DEX
     * 这条路,一条知道里面一切的路。后者可能会
     * 基于稍后出现的类优化字段/方法访问
     * 在类路径中。
     * 
     * 我们不能让用户定义的类加载器打开它并开始使用
     * 类,因为代码的优化形式跳过了一些
     * 我们通常使用的方法和场分辨率,以及
     * 我们会有错误的语义。
     * 
     * 我们必须拒绝尝试从启动时手动打开DEX文件
     * 类路径。最简单的方法是通过文件名,这很有效
     * 由于名称的变化(例如“/system/framework//ext.jar”)而无法使用
     * 结果我们命中了不同的dalvik缓存项。也很好
     * 如果调用方指定了自己的输出文件。
     */
    if (dvmClassPathContains(gDvm.bootClassPath, sourceName)) {
        ALOGW("Refusing to reopen boot DEX '%s'", sourceName);
        dvmThrowIOException(
            "Re-opening BOOTCLASSPATH DEX files is not allowed");
        free(sourceName);
        free(outputName);
        RETURN_VOID();
    }
    /*
     * 如果名称以“.DEX”结尾,请尝试直接将其作为DEX打开。
     * 如果失败了(或者一开始就没有尝试过),可以尝试一下
     * 拉链里面有一个“classes.dex”。
     */
    if (hasDexExtension(sourceName)
      // 如果文件是以 .dex 结尾 , 则进入 dvmRawDexFileOpen 函数执行 
            && dvmRawDexFileOpen(sourceName, outputName, &pRawDexFile, false) == 0) {
        ALOGV("Opening DEX file '%s' (DEX)", sourceName);
        pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar));
        pDexOrJar->isDex = true;
        pDexOrJar->pRawDexFile = pRawDexFile;
        pDexOrJar->pDexMemory = NULL;
    } else if (dvmJarFileOpen(sourceName, outputName, &pJarFile, false) == 0) {
        ALOGV("Opening DEX file '%s' (Jar)", sourceName);
        pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar));
        pDexOrJar->isDex = false;
        pDexOrJar->pJarFile = pJarFile;
        pDexOrJar->pDexMemory = NULL;
    } else {
        ALOGV("Unable to open DEX file '%s'", sourceName);
        dvmThrowIOException("unable to open DEX file");
    }
    if (pDexOrJar != NULL) {
        pDexOrJar->fileName = sourceName;
        addToDexFileTable(pDexOrJar);
    } else {
        free(sourceName);
    }
    free(outputName);
    RETURN_PTR(pDexOrJar);
}


源码路径 : /dalvik/vm/native/dalvik_system_DexFile.cpp


目录
相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1665 4
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
安全 Android开发 数据安全/隐私保护
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
1145 21
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
319 8
|
10月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1745 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
10月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1120 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
10月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1200 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
933 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
10月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
439 0
|
11月前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
1378 6

热门文章

最新文章