文章目录
前言
- 前言
- 一、dalvik_system_DexFile.cc#DexFile_openDexFileNative 函数分析
- 二、oat_file_manager.cc#OpenDexFilesFromOat 函数分析
- 三、oat_file_assistant.cc#MakeUpToDate 函数分析
- 四、oat_file_assistant.cc#GenerateOatFileNoChecks 函数分析
- 五、oat_file_assistant.cc#Dex2Oat 函数分析
在上一篇博客 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 ) 中 , 分析了 ART 虚拟机下 DexClassLoader 类加载器加载 dex 文件的 Java 层流程 , 与 Dalvik 虚拟机下基本一致 , 从 native 层开始不一致 , 本篇博客开始分析 native 层的类加载流程 ;
一、dalvik_system_DexFile.cc#DexFile_openDexFileNative 函数分析在下面的 DexFile_openDexFileNative 方法中 ,
jstring javaSourceName 参数是要加载的 dex 文件路径 ,
下面调用的 OpenDexFilesFromOat 函数 , 是生成 oat 文件的关键流程入口 ;
dex_files = runtime->GetOatFileManager().OpenDexFilesFromOat(sourceName.c_str(),
class_loader,
dex_elements,
/*out*/ &oat_file,
/*out*/ &error_msgs);
dalvik_system_DexFile.cc#DexFile_openDexFileNative 源码 :
// TODO(calin): clean up the unused parameters (here and in libcore).
static jobject DexFile_openDexFileNative(JNIEnv* env,
jclass,
jstring javaSourceName,
jstring javaOutputName ATTRIBUTE_UNUSED,
jint flags ATTRIBUTE_UNUSED,
jobject class_loader,
jobjectArray dex_elements) {
ScopedUtfChars sourceName(env, javaSourceName);
if (sourceName.c_str() == nullptr) {
return 0;
}
Runtime* const runtime = Runtime::Current();
ClassLinker* linker = runtime->GetClassLinker();
std::vector dex_files;
std::vector error_msgs;
// OAT 文件
const OatFile* oat_file = nullptr;
// ★ 核心跳转
dex_files = runtime->GetOatFileManager().OpenDexFilesFromOat(sourceName.c_str(),
class_loader,
dex_elements,
/*out*/ &oat_file,
/*out*/ &error_msgs);
if (!dex_files.empty()) {
jlongArray array = ConvertDexFilesToJavaArray(env, oat_file, dex_files);
if (array == nullptr) {
ScopedObjectAccess soa(env);
for (auto& dex_file : dex_files) {
if (linker->IsDexFileRegistered(soa.Self(), *dex_file)) {
dex_file.release();
}
}
}
return array;
} else {
ScopedObjectAccess soa(env);
CHECK(!error_msgs.empty());
// The most important message is at the end. So set up nesting by going forward, which will
// wrap the existing exception as a cause for the following one.
auto it = error_msgs.begin();
auto itEnd = error_msgs.end();
for ( ; it != itEnd; ++it) {
ThrowWrappedIOException("%s", it->c_str());
}
return nullptr;
}
}
源码路径 : /art/runtime/native/dalvik_system_DexFile.cc#DexFile_openDexFileNative
二、oat_file_manager.cc#OpenDexFilesFromOat 函数分析先声明 oat 文件对象 ,
// 声明 OatFile 对象
const OatFile* source_oat_file = nullptr;
然后判断是否有生成 oat 文件 , 如果是第一次调用 , 肯定没有生成 oat 文件 ,
!oat_file_assistant.IsUpToDate()
如果没有生成 oat 文件 , 则执行
oat_file_assistant.MakeUpToDate(/*profile_changed*/false, /*out*/ &error_msg)
方法 , 开始生成 oat 文件 ;
oat_file_manager.cc#OpenDexFilesFromOat 函数源码 :
std::vector OatFileManager::OpenDexFilesFromOat(
const char* dex_location,
jobject class_loader,
jobjectArray dex_elements,
const OatFile** out_oat_file,
std::vector* error_msgs) {
ScopedTrace trace(__FUNCTION__);
CHECK(dex_location != nullptr);
CHECK(error_msgs != nullptr);
// 验证我们没有持有mutator锁,如果我们必须生成或重新定位oat文件,这可能会导致GC饥饿。
Thread* const self = Thread::Current();
Locks::mutator_lock_->AssertNotHeld(self);
Runtime* const runtime = Runtime::Current();
OatFileAssistant oat_file_assistant(dex_location,
kRuntimeISA,
!runtime->IsAotCompiler());
// 锁定目标oat位置以避免生成和加载oat文件。
std::string error_msg;
if (!oat_file_assistant.Lock(/*out*/&error_msg)) {
// Don't worry too much if this fails. If it does fail, it's unlikely we
// can generate an oat file anyway.
VLOG(class_linker)
关注
打赏
热门博文
- 【Android Gradle 插件】Gradle 自定义 Plugin 插件 ③ ( 自定义插件作用 | Android Gradle 插件的扩展 | 自定义 Extension 扩展 )
- 【Android Gradle 插件】Gradle 构建生命周期 ③ ( BuildListener 构建监听器 | TaskExecutionGraphListener 任务执行图监听器 )
- 【Android Gradle 插件】Gradle 构建生命周期 ② ( Gradle 类的添加构建生命周期监听器函数 | Gradle#addListener 函数 )
- 【Android Gradle 插件】Gradle 构建生命周期 ① ( 分析构建脚本 | 执行初始化配置 | 执行 Gradle 任务 | Project#beforeEvaluate 函数 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑨ ( 控制 Gradle 执行任务顺序 | Task#finalizedBy 函数 | 控制 Gradle 执行任务顺序示例分析 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑧ ( 控制 Gradle 执行任务顺序 | Task#shouldRunAfter 函数 | 三个函数使用场景对比 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑦ ( 控制 Gradle 执行任务顺序 | Task#dependsOn 函数 | Task#mustRunAfter 函数 )
- 【数学分析】集合 ① ( 集合概念 | 集合表示 | 常用的数集合 | 集合的表示 )
- 【数学分析】学科简介 ( 初等数学缺陷 | 微分与积分 | 学习数学分析的目的 | 数学分析与高等数学对比 )
- 【Android Gradle 插件】自定义 Gradle 任务 ③ ( Gradle 自定义任务创建方法 Project#task 函数 | Task#doFirst 函数用法 )