文章目录

  • 一、ART 虚拟机下 DexClassLoader 类加载器脱壳点总结
    • 1、file_magic.cc#OpenAndReadMagic 函数
    • 2、dex_file.cc#DexFile::OpenCommon
    • 3、dex_file.cc#DexFile::DexFile
  • 总结 ( 兼容 InMemoryDexClassLoader 和 DexClassLoader 两种类加载器的 脱壳点 )

一、ART 虚拟机下 DexClassLoader 类加载器脱壳点总结


从 /art/runtime/dex_file.cc#DexFile::Open 函数开始分析脱壳点位置 ;

其中调用的 /art/runtime/base/file_magic.cc#OpenAndReadMagic 函数 , 可以作为脱壳点 ;

在 /art/runtime/dex_file.cc#OpenFile 函数中 , 调用了 /art/runtime/dex_file.cc#OpenCommon 函数 , 是脱壳点 ;

bool DexFile::Open(const char* filename,const std::string& location,bool verify_checksum,std::string* error_msg,std::vector<std::unique_ptr<const DexFile>>* dex_files) {ScopedTrace trace(std::string("Open dex file ") + std::string(location));DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr";uint32_t magic;// ★ 脱壳点后汉书 File fd = OpenAndReadMagic(filename, &magic, error_msg);if (fd.Fd() == -1) {DCHECK(!error_msg->empty());return false;}if (IsZipMagic(magic)) {return DexFile::OpenZip(fd.Release(), location, verify_checksum, error_msg, dex_files);}if (IsDexMagic(magic)) {// ★ 脱壳点函数std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.Release(),location,/* verify */ true,verify_checksum,error_msg));if (dex_file.get() != nullptr) {dex_files->push_back(std::move(dex_file));return true;} else {return false;}}*error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);return false;
}

1、file_magic.cc#OpenAndReadMagic 函数

file_magic.cc#OpenAndReadMagic 函数是 脱壳点 , 第一个参数 const char* filename 是 Dex 文件的路径 ;

调用该函数的上一个调用位置是 /art/runtime/dex_file.cc#DexFile::Open 函数 ;

file_magic.cc 源码 :

#include "file_magic.h"#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>#include "android-base/stringprintf.h"#include "base/logging.h"
#include "base/unix_file/fd_file.h"
#include "dex_file.h"namespace art {using android::base::StringPrintf;File OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_msg) {CHECK(magic != nullptr);File fd(filename, O_RDONLY, /* check_usage */ false);if (fd.Fd() == -1) {*error_msg = StringPrintf("Unable to open '%s' : %s", filename, strerror(errno));return File();}int n = TEMP_FAILURE_RETRY(read(fd.Fd(), magic, sizeof(*magic)));if (n != sizeof(*magic)) {*error_msg = StringPrintf("Failed to find magic in '%s'", filename);return File();}if (lseek(fd.Fd(), 0, SEEK_SET) != 0) {*error_msg = StringPrintf("Failed to seek to beginning of file '%s' : %s", filename,strerror(errno));return File();}return fd;
}bool IsZipMagic(uint32_t magic) {return (('P' == ((magic >> 0) & 0xff)) &&('K' == ((magic >> 8) & 0xff)));
}bool IsDexMagic(uint32_t magic) {return DexFile::IsMagicValid(reinterpret_cast<const uint8_t*>(&magic));
}}  // namespace art

源码路径 : /art/runtime/base/file_magic.cc#OpenAndReadMagic

2、dex_file.cc#DexFile::OpenCommon

dex_file.cc#DexFile::OpenCommon 函数中 , 可以获取 Dex 文件在内存中的起始地址 ;

注意 : 该脱壳点 与 InMemoryDexClassLoader 类加载器的脱壳点重合 ;

std::unique_ptr<DexFile> DexFile::OpenCommon(const uint8_t* base,size_t size,const std::string& location,uint32_t location_checksum,const OatDexFile* oat_dex_file,bool verify,bool verify_checksum,std::string* error_msg,VerifyResult* verify_result) {if (verify_result != nullptr) {*verify_result = VerifyResult::kVerifyNotAttempted;}std::unique_ptr<DexFile> dex_file(new DexFile(base,size,location,location_checksum,oat_dex_file));if (dex_file == nullptr) {*error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),error_msg->c_str());return nullptr;}if (!dex_file->Init(error_msg)) {dex_file.reset();return nullptr;}if (verify && !DexFileVerifier::Verify(dex_file.get(),dex_file->Begin(),dex_file->Size(),location.c_str(),verify_checksum,error_msg)) {if (verify_result != nullptr) {*verify_result = VerifyResult::kVerifyFailed;}return nullptr;}if (verify_result != nullptr) {*verify_result = VerifyResult::kVerifySucceeded;}return dex_file;
}

源码地址 : /art/runtime/dex_file.cc#OpenCommon

3、dex_file.cc#DexFile::DexFile

在 dex_file.cc#DexFile::DexFile 构造函数中 , 可以获取到 Dex 文件地址 ;

注意 : 该脱壳点 与 InMemoryDexClassLoader 类加载器的脱壳点重合 ;

DexFile::DexFile(const uint8_t* base,size_t size,const std::string& location,uint32_t location_checksum,const OatDexFile* oat_dex_file): begin_(base),size_(size),location_(location),location_checksum_(location_checksum),header_(reinterpret_cast<const Header*>(base)),string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)),type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)),field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)),method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)),proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)),class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)),method_handles_(nullptr),num_method_handles_(0),call_site_ids_(nullptr),num_call_site_ids_(0),oat_dex_file_(oat_dex_file) {CHECK(begin_ != nullptr) << GetLocation();CHECK_GT(size_, 0U) << GetLocation();// Check base (=header) alignment.// Must be 4-byte aligned to avoid undefined behavior when accessing// any of the sections via a pointer.CHECK_ALIGNED(begin_, alignof(Header));InitializeSectionsFromMapList();
}

源码地址 : /art/runtime/dex_file.cc#DexFile


总结 ( 兼容 InMemoryDexClassLoader 和 DexClassLoader 两种类加载器的 脱壳点 )

加固厂商可能使用 InMemoryDexClassLoader 类加载器 , 也可能使用 DexClassLoader 类加载器 , 这里为了保证不管使用什么类加载器 , 都可以进行脱壳 , 选择 222 个类加载器都有的脱壳点 , 可以兼容两种类加载器 ;

【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | ART 虚拟机下 DexClassLoader 类加载器脱壳点总结 )相关推荐

  1. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | InMemoryDexClassLoader 类加载器脱壳点总结 )

    文章目录 一.InMemoryDexClassLoader 类加载器脱壳点总结 1.dalvik_system_DexFile.cc#CreateSingleDexFileCookie 2.dalvi ...

  2. 【Android 插件化】“ 插桩式 “ 插件化框架 ( 类加载器创建 | 资源加载 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  3. 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 类加载器构造函数分析 | DexPathList 引入 )

    文章目录 一.DexClassLoader 类加载器构造函数分析 二.DexPathList 引入 一.DexClassLoader 类加载器构造函数分析 DexClassLoader 是加载 dex ...

  4. 【Android 逆向】加壳的 Android 应用启动流程 | 使用反射替换 LoadedApk 中的类加载器流程

    文章目录 一.加壳的 Android 应用启动流程 二.使用反射替换 LoadedApk 中的类加载器流程 一.加壳的 Android 应用启动流程 加壳的 Android 应用启动流程 : 加壳的 ...

  5. Java虚拟机10:类加载器

    类与类加载器 虚拟机设计团队把类加载阶段张的"通过一个类的全限定名来获取此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这 ...

  6. 深入理解Java虚拟机二(类加载器和类的加载过程)

    类加载器子系统作用 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识. ClassLoader只负责class文件的加载,至于它是否可以运行,则由Ex ...

  7. 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | oat_file_assistant.cc 中涉及的 oat 文件生成流程 )

    文章目录 前言 一.dalvik_system_DexFile.cc#DexFile_openDexFileNative 函数分析 二.oat_file_manager.cc#OpenDexFiles ...

  8. 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )

    文章目录 一.DexClassLoader 源码分析 二.参考 Dalvik 下的 DexClassLoader 类加载流程 一.DexClassLoader 源码分析 ART 虚拟机下的 DexCl ...

  9. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | dex_file.cc 中创建 DexFile 实例对象的相关函数分析 )

    文章目录 前言 一.dalvik_system_DexFile.cc#CreateDexFile 函数分析 二.dex_file.cc#DexFile::Open 函数分析 三.dex_file.cc ...

最新文章

  1. 如何在使用新技术前评估其浏览器兼容性
  2. java treeset 删除_删除Java TreeSet中的最高元素
  3. 关于form标题提交的应用技巧(-)
  4. centos exfat格式U盘不支持问题
  5. MySQL SQL优化
  6. Java 中的四种引用及垃圾回收策略
  7. sql 条件求和_Excel VBA+SQL 多条件求和实例
  8. C4.5决策树生成算法完整版(Python),连续属性的离散化, 缺失样本的添加权重处理, 算法缺陷的修正, 代码等
  9. 【UVa】1600 Patrol Robot(dfs)
  10. 表格行上下移,置顶的js代码
  11. 计算机的发展与组成ppt,第章计算机的发展与组成.ppt
  12. bootstrap php 多行,使用PHP循环将Bootstrap行和正确的列号添加到元素
  13. MySQL5.7 group by新特性报错1055的解决办法
  14. css srcset,研究一下响应式图片加载属性srcset和sizes_html/css_WEB-ITnose
  15. 我的世界Java版最诡异的种子_我的世界:MC出现诡异的种子,地域不停地重复
  16. win7下开启梦幻桌面
  17. Unicode、UTF-8、UTF-16之间的区别
  18. 计算机低配配置单,吃鸡需要什么配置|电脑玩绝地求生最低配置多少
  19. 以 VS Code为例,看大型开源项目是如何应用软件工程的?
  20. 还原王欣:技术宅男的红与黑

热门文章

  1. struts2:struts.xml配置文件详解
  2. 将某个目录上的Excel表,导入到数据库中.sql
  3. 第二次作业 郭昭杰 201731062608
  4. OO第一单元总结博客
  5. 序列化流与反序列化流
  6. 在Python中用Selenium执行JavaScript
  7. 模拟投掷硬币100次
  8. python入门(七)
  9. 2008_10_28_星期二
  10. GARFIELD@05-04-2005