文章目录
一、DexFile 对应的 dalvik_system_DexFile.cc 中的 Native 方法
1、dalvik_system_DexFile.cc 的 DexFile_createCookieWithDirectBuffer 函数
2、dalvik_system_DexFile.cc 的 DexFile_createCookieWithArray 函数
二、dalvik_system_DexFile.cc 的 CreateSingleDexFileCookie 函数
一、DexFile 对应的 dalvik_system_DexFile.cc 中的 Native 方法
在上一篇博客 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | DexFile 构造函数及相关调用函数 | Android 源码中查找 native 函数 ) 中 , 分析了 DexFile 构造函数 , 以及 makeInMemoryDexElements 函数 ; 并查找了 DexFile 中的 native 函数 createCookieWithDirectBuffer 和 createCookieWithArray 函数定义在 /art/runtime/native/dalvik_system_DexFile.cc 中 ;
1、dalvik_system_DexFile.cc 的 DexFile_createCookieWithDirectBuffer 函数
在 DexFile_createCookieWithDirectBuffer 函数中 , 调用的 memcpy 方法中的 dex_mem_map->Begin() 就是 dex 文件的起始地址 , length 是 dex 文件的长度 , 这里可以将内存中的 dex 数据导出 ;
// ★ 此处的 dex_mem_map->Begin() 就是 dex 文件的起始地址 , length 是 dex 文件的长度 memcpy(dex_mem_map->Begin(), base_address, length);
// DexFile 中 createCookieWithDirectBuffer 函数对应的 C++ 函数 static jobject DexFile_createCookieWithDirectBuffer(JNIEnv* env, jclass, jobject buffer, jint start, jint end) { uint8_t* base_address = reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(buffer)); if (base_address == nullptr) { ScopedObjectAccess soa(env); ThrowWrappedIOException("dexFileBuffer not direct"); return 0; } std::unique_ptr<MemMap> dex_mem_map(AllocateDexMemoryMap(env, start, end)); if (dex_mem_map == nullptr) { DCHECK(Thread::Current()->IsExceptionPending()); return 0; } size_t length = static_cast<size_t>(end - start); // ★ 此处的 dex_mem_map->Begin() 就是 dex 文件的起始地址 , length 是 dex 文件的长度 memcpy(dex_mem_map->Begin(), base_address, length); // ★ 核心跳转 return CreateSingleDexFileCookie(env, std::move(dex_mem_map)); }
源码路径 : /art/runtime/native/dalvik_system_DexFile.cc
2、dalvik_system_DexFile.cc 的 DexFile_createCookieWithArray 函数
DexFile_createCookieWithDirectBuffer 和 DexFile_createCookieWithArray 2 22 个 native 方法 , 在最后返回时都调用了 CreateSingleDexFileCookie 方法 ; // DexFile 中 createCookieWithArray 函数对应的 C++ 函数 static jobject DexFile_createCookieWithArray(JNIEnv* env, jclass, jbyteArray buffer, jint start, jint end) { std::unique_ptr<MemMap> dex_mem_map(AllocateDexMemoryMap(env, start, end)); if (dex_mem_map == nullptr) { DCHECK(Thread::Current()->IsExceptionPending()); return 0; } auto destination = reinterpret_cast<jbyte*>(dex_mem_map.get()->Begin()); env->GetByteArrayRegion(buffer, start, end - start, destination); // ★ 核心跳转 return CreateSingleDexFileCookie(env, std::move(dex_mem_map)); }
源码路径 : /art/runtime/native/dalvik_system_DexFile.cc
二、dalvik_system_DexFile.cc 的 CreateSingleDexFileCookie 函数
在该方法中 , 主要创建 dex_file 实例 , 然后将该实例对象返回到 Java 层 ; 传入的参数是 CreateDexFile(env, std::move(data)) , 下面开始分析该函数 ;
dalvik_system_DexFile.cc 的 CreateSingleDexFileCookie 函数源码 :
static jobject CreateSingleDexFileCookie(JNIEnv* env, std::unique_ptr<MemMap> data) { // ★ 创建 dex_file std::unique_ptr<const DexFile> dex_file(CreateDexFile(env, std::move(data))); if (dex_file.get() == nullptr) { DCHECK(env->ExceptionCheck()); return nullptr; } std::vector<std::unique_ptr<const DexFile>> dex_files; dex_files.push_back(std::move(dex_file)); return ConvertDexFilesToJavaArray(env, nullptr, dex_files); }
源码路径 : /art/runtime/native/dalvik_system_DexFile.cc#CreateSingleDexFileCookie