android内存加载dex,安卓8.1版本dex加载流程笔记--第一篇:oatfile,oatdexfile与dexfile...

本帖最后由 L剑仙 于 2020-3-1 18:53 编辑

看雪发一遍了,在52再发一次

e53f6c118a0b6be8d45a5e87391b9f00.gif

菜鸟最近初学脱壳,必须得先搞明白dex的加载流程,才能搞懂哪里到了脱壳的时机。n6装的8.1,最近跟了一遍8.1源码,记录笔记,理解一下类似opencommon的脱壳点

网上的文章大都比较老了,参考这篇6.0的加载https://www.jianshu.com/p/20dcfcf27004

新版本多走了 oat_file_manager.cc ,oat_file_assistant.cc这2个重要的类,

而没有去走linker,需要重新跟一次,在调试一遍才能搞明白整个流程。java层肯定走classloader,最终调用了dalvik_system_DexFile.cc的opeDexFileNative,进入so层,从这里开始分析

先放个简要流程,源码分别在dalvik_system_DexFile.cc ,oat_file_manager.cc ,oat_file_assistant.cc,oat_file.cc,dex_file.cc里,大致就是先得到Oat,通过Oat得到 OatDexFile,在通过 OatDexFile得到 DexFile

[C++] 纯文本查看 复制代码opeDexFileNative dalvik_system_DexFile.cc

{

OpenDexFilesFromOat oat_file_manager.cc

{

GetBestOatFile oat_file_assistant.cc

{

OatFile::Open oat_file.cc

}

LoadDexFiles oat_file_assistant.cc

{

GetOatDexFile(得到上面open的OatFile的OatDexFile)oat_file.cc

OpenDexFile oat_file.cc

{

DexFile::Open dex_file.cc

}

}

}

}

下面开始一步一步分析

1.首先是dalvik_system_DexFile.cc的opeDexFileNative

关键是这一句

dex_files = runtime->GetOatFileManager().OpenDexFilesFromOat(sourceName.c_str(),class_loader,dex_elements,/*out*/ &oat_file,/*out*/ &error_msgs);

与之前如6.0不同,OpenDexFilesFromOat这个函数放在了oat_file_manager.cc而不是class_linker.cc

[C++] 纯文本查看 复制代码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(); //获得linker

std::vector<:unique_ptr dexfile>> dex_files;

std::vector<:string> error_msgs;

const OatFile* oat_file = nullptr;

dex_files = runtime->GetOatFileManager().OpenDexFilesFromOat(sourceName.c_str(),

class_loader,

dex_elements,

/*out*/ &oat_file,

/*out*/ &error_msgs);//这句调用OpenDexFilesFromOat获得dex_files

if (!dex_files.empty()) {

jlongArray array = ConvertDexFilesToJavaArray(env, oat_file, dex_files);//这句把DexFiles转化为JavaArray,方便java层使用

if (array == nullptr) {

ScopedObjectAccess soa(env);

for (auto& dex_file : dex_files) {

if (linker->IsDexFileRegistered(soa.Self(), *dex_file)) { //这里linker只用来判断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;

}

}

2.进入oat_file_manager.cc的 OpenDexFilesFromOat

2.1,先通过:std::unique_ptr oat_file(oat_file_assistant.GetBestOatFile().release())这句获得了oat_file,

2.2然后通过:dex_files = oat_file_assistant.LoadDexFiles(*source_oat_file, dex_location)这里通过加载source_oat_file获得dex_files2.3如果上面2.1与2.2不成立:DexFile::Open(dex_location, dex_location, kVerifyChecksum, /*out*/ &error_msg, &dex_files)) //如果LoadDexFiles上面没有获得dex_files,直接DexFile::Open打开加载原始的dexfile

[C++] 纯文本查看 复制代码std::vector<:unique_ptr dexfile>> OatFileManager::OpenDexFilesFromOat(

const char* dex_location,

jobject class_loader,

jobjectArray dex_elements,

const OatFile** out_oat_file,

std::vector<:string>* error_msgs) {

ScopedTrace trace(__FUNCTION__);

CHECK(dex_location != nullptr);

CHECK(error_msgs != nullptr);

// Verify we aren't holding the mutator lock, which could starve GC if we

// have to generate or relocate an oat file.

Thread* const self = Thread::Current();

Locks::mutator_lock_->AssertNotHeld(self);

Runtime* const runtime = Runtime::Current();

OatFileAssistant oat_file_assistant(dex_location,

kRuntimeISA,

!runtime->IsAotCompiler());

// Lock the target oat location to avoid races generating and loading the

// oat file.

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) << "OatFileAssistant::Lock: " << error_msg;

}

const OatFile* source_oat_file = nullptr;

if (!oat_file_assistant.IsUpToDate()) {

// Update the oat file on disk if we can, based on the --compiler-filter

// option derived from the current runtime options.

// This may fail, but that's okay. Best effort is all that matters here.

switch (oat_file_assistant.MakeUpToDate(/*profile_changed*/false, /*out*/ &error_m

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值