【Android 逆向】Dalvik 函数抽取加壳 ④ ( 类加载流程分析 | native 函数查询 | dalvik_system_DexFile.cpp#defineClassNative函数)

本文主要是介绍【Android 逆向】Dalvik 函数抽取加壳 ④ ( 类加载流程分析 | native 函数查询 | dalvik_system_DexFile.cpp#defineClassNative函数),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、查询 defineClassNative 函数
  • 二、dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数分析

前言


上一篇博客 【Android 逆向】Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 ) 中 , 分析到了调用到 DexFile#loadClassBinaryName 函数 , 该函数是 native 函数 ;





一、查询 defineClassNative 函数



在 Android 源码页面 http://androidxref.com/4.4.4_r1 , 选中 dalvik 工程 , 然后在 " Full Search " 中搜索 defineClassNative 函数 ;

查询出的对应的 native 函数是 /dalvik/vm/native/dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative ,

在这里插入图片描述





二、dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数分析



在 /dalvik/vm/native/dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数中 , 如果加载的是 dex 文件 , 则调用 dvmGetRawDexFileDex 函数 ;

    	// 如果加载的是 dex 文件 , 走这个分支 pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile);

dvmGetRawDexFileDex 函数定义在 /dalvik/vm/RawDexFile.h#dvmGetRawDexFileDex 中 , 该函数实现很简单 :

/** 从 RawDexFile 中撬出 DexFile。*/
INLINE DvmDex* dvmGetRawDexFileDex(RawDexFile* pRawDexFile) {return pRawDexFile->pDvmDex;
}

在之后 , 调用了 Class.cpp#dvmDefineClass 函数 ;


dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数源码 :

/** 私有静态类defineClassNative(字符串名称、类加载器、,* int cookie)* * 从DEX文件加载类。这大致相当于defineClass()* 在常规VM中——类装入器调用它以导致* 创建特定类。不同之处在于,搜索和* 字节的读取是在VM中完成的。* * 类名是一个“二进制名称”,例如“java.lang.String”。* * 如果找不到类,则返回空指针,无异常。* 在其他失败时引发异常。*/
static void Dalvik_dalvik_system_DexFile_defineClassNative(const u4* args,JValue* pResult)
{StringObject* nameObj = (StringObject*) args[0];Object* loader = (Object*) args[1];int cookie = args[2];ClassObject* clazz = NULL;// 获取 cookie DexOrJar* pDexOrJar = (DexOrJar*) cookie;DvmDex* pDvmDex;char* name;char* descriptor;name = dvmCreateCstrFromString(nameObj);descriptor = dvmDotToDescriptor(name);ALOGV("--- Explicit class load '%s' l=%p c=0x%08x",descriptor, loader, cookie);free(name);if (!validateCookie(cookie))RETURN_VOID();if (pDexOrJar->isDex)// 如果加载的是 dex 文件 , 走这个分支 pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile);elsepDvmDex = dvmGetJarFileDex(pDexOrJar->pJarFile);/* 一旦加载了某些内容,就无法取消映射存储 */pDexOrJar->okayToFree = false;// 此处加载类 clazz = dvmDefineClass(pDvmDex, descriptor, loader);Thread* self = dvmThreadSelf();if (dvmCheckException(self)) {/** 如果我们抛出了一个“未找到类”异常,请扼杀它,因为* 较高方法中的contract表示,如果* 找不到该类。*/Object* excep = dvmGetException(self);if (strcmp(excep->clazz->descriptor,"Ljava/lang/ClassNotFoundException;") == 0 ||strcmp(excep->clazz->descriptor,"Ljava/lang/NoClassDefFoundError;") == 0){dvmClearException(self);}clazz = NULL;}free(descriptor);RETURN_PTR(clazz);
}

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

这篇关于【Android 逆向】Dalvik 函数抽取加壳 ④ ( 类加载流程分析 | native 函数查询 | dalvik_system_DexFile.cpp#defineClassNative函数)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/266545

相关文章

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十