您当前的位置: 首页 >  ar

韩曙亮

暂无认证

  • 1浏览

    0关注

    1068博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android 逆向】ART 脱壳 ( dex2oat 脱壳 | /art/dex2oat/dex2oat.cc#Dex2oat 函数源码 )

韩曙亮 发布时间:2021-12-16 14:28:00 ,浏览量:1

文章目录
  • 前言
  • 一、/art/dex2oat/dex2oat.cc#Dex2oat 函数源码
  • 二、/art/dex2oat/dex2oat.cc#Setup 函数源码 ( 脱壳点 )

前言

在上一篇博客 【Android 逆向】ART 脱壳 ( dex2oat 脱壳 | aosp 中搜索 dex2oat 源码 | dex2oat.cc#main 主函数源码 ) 中 , 分析到 dex2oat 工具源码中的主函数为 /art/dex2oat/dex2oat.cc#main , 在该函数中调用了 /art/dex2oat/dex2oat.cc#Dex2oat 函数 ;

在将 dex 文件编译为 oat 文件的过程中 , 只要出现了 DexFile 对象 , 就可以将该对象对应的 dex 文件导出 , 即 dex 脱壳 , 该过程的脱壳点很多 ;

脱壳方法参考 【Android 逆向】ART 脱壳 ( 修改 /art/runtime/dex_file.cc#OpenCommon 系统源码进行脱壳 ) 博客 , 在脱壳点添加将内存中的 dex 文件 dump 到本地 SD 卡中的源码 , 然后在编译好的系统中运行要脱壳的应用 , 即可完成脱壳操作 ;

一、/art/dex2oat/dex2oat.cc#Dex2oat 函数源码

在 /art/dex2oat/dex2oat.cc#Dex2oat 函数中 , 调用了 /art/dex2oat/dex2oat.cc#Setup 函数 , 其中就遍历了 DexFile 对象 , 在遍历时可以将内存中的 dex 数据 dump 到 SD 卡中 ;

在调用的 /art/dex2oat/dex2oat.cc#CompileApp 函数中 , 也有脱壳点 ;

/art/dex2oat/dex2oat.cc#Dex2oat 函数源码 :

static dex2oat::ReturnCode Dex2oat(int argc, char** argv) {
  b13564922();

  TimingLogger timings("compiler", false, false);

  // 在堆上而不是堆栈上分配'dex2oat',如Clang
  // 可能产生的堆栈帧对于此函数或
  // 将其内联的函数(如main),这些函数不适合
  // “-Wframe大于”选项的要求。
  std::unique_ptr dex2oat = MakeUnique(&timings);

  // 解析参数。参数错误将导致UsageError中的exit(exit_失败)。
  dex2oat->ParseArgs(argc, argv);

  // 如果需要,处理概要文件信息以进行概要文件引导编译。
  // 此操作涉及I/O。
  if (dex2oat->UseProfile()) {
    if (!dex2oat->LoadProfile()) {
      LOG(ERROR) IsBootImage() || dex2oat->IsHost() || !kIsTargetBuild) {
    LOG(INFO) GetHeap()->GetBootImageSpaces();
      image_file_location_oat_checksum_ = image_spaces[0]->GetImageHeader().GetOatChecksum();
      image_file_location_oat_data_begin_ =
          reinterpret_cast(image_spaces[0]->GetImageHeader().GetOatDataBegin());
      image_patch_delta_ = image_spaces[0]->GetImageHeader().GetPatchDelta();
      // Store the boot image filename(s).
      std::vector image_filenames;
      for (const gc::space::ImageSpace* image_space : image_spaces) {
        image_filenames.push_back(image_space->GetImageFilename());
      }
      std::string image_file_location = android::base::Join(image_filenames, ':');
      if (!image_file_location.empty()) {
        key_value_store_->Put(OatHeader::kImageLocationKey, image_file_location);
      }
    } else {
      image_file_location_oat_checksum_ = 0u;
      image_file_location_oat_data_begin_ = 0u;
      image_patch_delta_ = 0;
    }

    // Open dex files for class path.
    std::vector class_path_locations =
        GetClassPathLocations(runtime_->GetClassPathString());
    OpenClassPathFiles(class_path_locations,
                       &class_path_files_,
                       &opened_oat_files_,
                       runtime_->GetInstructionSet(),
                       classpath_dir_);

    // Store the classpath we have right now.
    std::vector class_path_files = MakeNonOwningPointerVector(class_path_files_);
    std::string encoded_class_path;
    if (class_path_locations.size() == 1 &&
        class_path_locations[0] == OatFile::kSpecialSharedLibrary) {
      // When passing the special shared library as the classpath, it is the only path.
      encoded_class_path = OatFile::kSpecialSharedLibrary;
    } else {
      encoded_class_path = OatFile::EncodeDexFileDependencies(class_path_files, classpath_dir_);
    }
    key_value_store_->Put(OatHeader::kClassPathKey, encoded_class_path);
  }

  // 现在我们已经完成了key\u value\u store\u,开始编写oat文件。
  {
    TimingLogger::ScopedTiming t_dex("Writing and opening dex files", timings_);
    rodata_.reserve(oat_writers_.size());
    for (size_t i = 0, size = oat_writers_.size(); i != size; ++i) {
      rodata_.push_back(elf_writers_[i]->StartRoData());
      // 直接将dex文件解压或复制到oat文件。
      std::unique_ptr opened_dex_files_map;
      std::vector opened_dex_files;
	  // 无需验证以下各项的dex文件:
	  // 1)Dexlayout,因为它进行了验证。也可能无法通过验证,因为
	  // 我们不更新dex校验和。
	  // 2)当我们有一个vdex文件,这意味着它已经被验证。
      const bool verify = !DoDexLayoutOptimizations() && (input_vdex_file_ == nullptr);
      if (!oat_writers_[i]->WriteAndOpenDexFiles(
          kIsVdexEnabled ? vdex_files_[i].get() : oat_files_[i].get(),
          rodata_.back(),
          instruction_set_,
          instruction_set_features_.get(),
          key_value_store_.get(),
          verify,
          update_input_vdex_,
          &opened_dex_files_map,
          &opened_dex_files)) {
        return dex2oat::ReturnCode::kOther;
      }
      dex_files_per_oat_file_.push_back(MakeNonOwningPointerVector(opened_dex_files));
      if (opened_dex_files_map != nullptr) {
        opened_dex_files_maps_.push_back(std::move(opened_dex_files_map));
        for (std::unique_ptr& dex_file : opened_dex_files) {
          dex_file_oat_index_map_.emplace(dex_file.get(), i);
          opened_dex_files_.push_back(std::move(dex_file));
        }
      } else {
        DCHECK(opened_dex_files.empty());
      }
    }
  }

  dex_files_ = MakeNonOwningPointerVector(opened_dex_files_);

  // 我们不得不将互换决定推迟到现在,因为这是我们真正需要的时候
  // 了解我们将要使用的dex文件。

  // 确保我们还没有创建驱动程序。
  CHECK(driver_ == nullptr);
  // 如果我们使用交换文件,请确保我们高于阈值以使其成为必要。
  if (swap_fd_ != -1) {
    if (!UseSwap(IsBootImage(), dex_files_)) {
      close(swap_fd_);
      swap_fd_ = -1;
      VLOG(compiler) Protect(PROT_READ | PROT_WRITE)) {
      PLOG(ERROR) AssertPendingException();
      soa.Self()->ClearException();
      PLOG(ERROR)             
关注
打赏
1663594092
查看更多评论
0.0414s