android oat如何提取dex文件字节码,8.1版本dex加载流程笔记--第三篇: OatFile::Open流程与OatDexFile的获得...

[C++] 纯文本查看 复制代码bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) {

if (!GetOatHeader().IsValid()) {

std::string cause = GetOatHeader().GetValidationErrorMessage();

*error_msg = StringPrintf("Invalid oat header for '%s': %s",

GetLocation().c_str(),

cause.c_str());

return false;

}

PointerSize pointer_size = GetInstructionSetPointerSize(GetOatHeader().GetInstructionSet());

size_t key_value_store_size =

(Size() >= sizeof(OatHeader)) ? GetOatHeader().GetKeyValueStoreSize() : 0u;

if (Size() < sizeof(OatHeader) + key_value_store_size) {

*error_msg = StringPrintf("In oat file '%s' found truncated OatHeader, "

"size = %zu < %zu + %zu",

GetLocation().c_str(),

Size(),

sizeof(OatHeader),

key_value_store_size);

return false;

}

size_t oat_dex_files_offset = GetOatHeader().GetOatDexFilesOffset();

if (oat_dex_files_offset < GetOatHeader().GetHeaderSize() || oat_dex_files_offset > Size()) {

*error_msg = StringPrintf("In oat file '%s' found invalid oat dex files offset: "

"%zu is not in [%zu, %zu]",

GetLocation().c_str(),

oat_dex_files_offset,

GetOatHeader().GetHeaderSize(),

Size());

return false;

}

const uint8_t* oat = Begin() + oat_dex_files_offset; // Jump to the OatDexFile records.//oat指针跳到OatDexFile去

DCHECK_GE(static_cast(pointer_size), alignof(GcRoot<:object>));

if (!IsAligned(bss_begin_) ||

!IsAlignedParam(bss_methods_, static_cast(pointer_size)) ||

!IsAlignedParam(bss_roots_, static_cast(pointer_size)) ||

!IsAligned)>(bss_end_)) {

*error_msg = StringPrintf("In oat file '%s' found unaligned bss symbol(s): "

"begin = %p, methods_ = %p, roots = %p, end = %p",

GetLocation().c_str(),

bss_begin_,

bss_methods_,

bss_roots_,

bss_end_);

return false;

}

if ((bss_methods_ != nullptr && (bss_methods_ < bss_begin_ || bss_methods_ > bss_end_)) ||

(bss_roots_ != nullptr && (bss_roots_ < bss_begin_ || bss_roots_ > bss_end_)) ||

(bss_methods_ != nullptr && bss_roots_ != nullptr && bss_methods_ > bss_roots_)) {

*error_msg = StringPrintf("In oat file '%s' found bss symbol(s) outside .bss or unordered: "

"begin = %p, methods_ = %p, roots = %p, end = %p",

GetLocation().c_str(),

bss_begin_,

bss_methods_,

bss_roots_,

bss_end_);

return false;

}

uint8_t* after_arrays = (bss_methods_ != nullptr) ? bss_methods_ : bss_roots_; // May be null.

uint8_t* dex_cache_arrays = (bss_begin_ == after_arrays) ? nullptr : bss_begin_;

uint8_t* dex_cache_arrays_end =

(bss_begin_ == after_arrays) ? nullptr : (after_arrays != nullptr) ? after_arrays : bss_end_;

DCHECK_EQ(dex_cache_arrays != nullptr, dex_cache_arrays_end != nullptr);

uint32_t dex_file_count = GetOatHeader().GetDexFileCount();//获得dex_file_count

oat_dex_files_storage_.reserve(dex_file_count);

for (size_t i = 0; i < dex_file_count; i++) {

uint32_t dex_file_location_size;

if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_location_size))) //循环通过ReadOatDexFileData函数读取dex_file_location_size并调整oat指针

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu truncated after dex file "

"location size",

GetLocation().c_str(),

i);

return false;

}

if (UNLIKELY(dex_file_location_size == 0U)) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu with empty location name",

GetLocation().c_str(),

i);

return false;

}

if (UNLIKELY(static_cast(End() - oat) < dex_file_location_size)) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu with truncated dex file "

"location",

GetLocation().c_str(),

i);

return false;

}

const char* dex_file_location_data = reinterpret_cast(oat);

oat += dex_file_location_size;

std::string dex_file_location = ResolveRelativeEncodedDexLocation(

abs_dex_location,

std::string(dex_file_location_data, dex_file_location_size));

uint32_t dex_file_checksum;

if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_checksum))) {//通过ReadOatDexFileData函数读取dex_file_checksum并调整oat指针

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated after "

"dex file checksum",

GetLocation().c_str(),

i,

dex_file_location.c_str());

return false;

}

uint32_t dex_file_offset;

if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_offset))) {//通过ReadOatDexFileData函数读取dex_file_offset并调整oat指针

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated "

"after dex file offsets",

GetLocation().c_str(),

i,

dex_file_location.c_str());

return false;

}

if (UNLIKELY(dex_file_offset == 0U)) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with zero dex "

"file offset",

GetLocation().c_str(),

i,

dex_file_location.c_str());

return false;

}

if (UNLIKELY(dex_file_offset > DexSize())) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "

"offset %u > %zu",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

dex_file_offset,

DexSize());

return false;

}

if (UNLIKELY(DexSize() - dex_file_offset < sizeof(DexFile::Header))) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "

"offset %u of %zu but the size of dex file header is %zu",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

dex_file_offset,

DexSize(),

sizeof(DexFile::Header));

return false;

}

const uint8_t* dex_file_pointer = DexBegin() + dex_file_offset;

if (UNLIKELY(!DexFile::IsMagicValid(dex_file_pointer))) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with invalid "

"dex file magic '%s'",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

dex_file_pointer);

return false;

}

if (UNLIKELY(!DexFile::IsVersionValid(dex_file_pointer))) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with invalid "

"dex file version '%s'",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

dex_file_pointer);

return false;

}

const DexFile::Header* header = reinterpret_cast(dex_file_pointer);

if (DexSize() - dex_file_offset < header->file_size_) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "

"offset %u and size %u truncated at %zu",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

dex_file_offset,

header->file_size_,

DexSize());

return false;

}

uint32_t class_offsets_offset;

if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &class_offsets_offset))) {//通过ReadOatDexFileData函数读取class_offsets_offset并调整oat指针

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated "

"after class offsets offset",

GetLocation().c_str(),

i,

dex_file_location.c_str());

return false;

}

if (UNLIKELY(class_offsets_offset > Size()) ||

UNLIKELY((Size() - class_offsets_offset) / sizeof(uint32_t) < header->class_defs_size_)) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with truncated "

"class offsets, offset %u of %zu, class defs %u",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

class_offsets_offset,

Size(),

header->class_defs_size_);

return false;

}

if (UNLIKELY(!IsAligned(class_offsets_offset))) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with unaligned "

"class offsets, offset %u",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

class_offsets_offset);

return false;

}

const uint32_t* class_offsets_pointer =

reinterpret_cast(Begin() + class_offsets_offset);

uint32_t lookup_table_offset;

if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &lookup_table_offset))) {//通过ReadOatDexFileData函数读取lookup_table_offset并调整oat指针,lookup_table用于加速类的查找

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' truncated "

"after lookup table offset",

GetLocation().c_str(),

i,

dex_file_location.c_str());

return false;

}

const uint8_t* lookup_table_data = lookup_table_offset != 0u

? Begin() + lookup_table_offset

: nullptr;

if (lookup_table_offset != 0u &&

(UNLIKELY(lookup_table_offset > Size()) ||

UNLIKELY(Size() - lookup_table_offset <

TypeLookupTable::RawDataLength(header->class_defs_size_)))) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with truncated "

"type lookup table, offset %u of %zu, class defs %u",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

lookup_table_offset,

Size(),

header->class_defs_size_);

return false;

}

uint32_t dex_layout_sections_offset;

if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_layout_sections_offset))) {//通过ReadOatDexFileData函数读取dex_layout_sections_offset并调整oat指针

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' truncated "

"after dex layout sections offset",

GetLocation().c_str(),

i,

dex_file_location.c_str());

return false;

}

const DexLayoutSections* const dex_layout_sections = dex_layout_sections_offset != 0

? reinterpret_cast(Begin() + dex_layout_sections_offset)

: nullptr;

uint32_t method_bss_mapping_offset;

if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &method_bss_mapping_offset))) {//通过ReadOatDexFileData函数读取method_bss_mapping_offset并调整oat指针

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' truncated "

"after method bss mapping offset",

GetLocation().c_str(),

i,

dex_file_location.c_str());

return false;

}

const bool readable_method_bss_mapping_size =

method_bss_mapping_offset != 0u &&

method_bss_mapping_offset <= Size() &&

IsAligned(method_bss_mapping_offset) &&

Size() - method_bss_mapping_offset >= MethodBssMapping::ComputeSize(0);

const MethodBssMapping* method_bss_mapping = readable_method_bss_mapping_size

? reinterpret_cast(Begin() + method_bss_mapping_offset)

: nullptr;

if (method_bss_mapping_offset != 0u &&

(UNLIKELY(method_bss_mapping == nullptr) ||

UNLIKELY(method_bss_mapping->size() == 0u) ||

UNLIKELY(Size() - method_bss_mapping_offset <

MethodBssMapping::ComputeSize(method_bss_mapping->size())))) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with unaligned or "

" truncated method bss mapping, offset %u of %zu, length %zu",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

method_bss_mapping_offset,

Size(),

method_bss_mapping != nullptr ? method_bss_mapping->size() : 0u);

return false;

}

if (kIsDebugBuild && method_bss_mapping != nullptr) {

const MethodBssMappingEntry* prev_entry = nullptr;

for (const MethodBssMappingEntry& entry : *method_bss_mapping) {

CHECK_ALIGNED_PARAM(entry.bss_offset, static_cast(pointer_size));

CHECK_LT(entry.bss_offset, BssSize());

CHECK_LE(POPCOUNT(entry.index_mask) * static_cast(pointer_size), entry.bss_offset);

size_t index_mask_span = (entry.index_mask != 0u) ? 16u - CTZ(entry.index_mask) : 0u;

CHECK_LE(index_mask_span, entry.method_index);

if (prev_entry != nullptr) {

CHECK_LT(prev_entry->method_index, entry.method_index - index_mask_span);

}

prev_entry = &entry;

}

CHECK_LT(prev_entry->method_index,

reinterpret_cast(dex_file_pointer)->method_ids_size_);

}

uint8_t* current_dex_cache_arrays = nullptr;

if (dex_cache_arrays != nullptr) {

// All DexCache types except for CallSite have their instance counts in the

// DexFile header. For CallSites, we need to read the info from the MapList.

//对于CallSites,必须从MapList中读取,他不存储在header中

const DexFile::MapItem* call_sites_item = nullptr;

if (!FindDexFileMapItem(DexBegin(), //通过FindDexFileMapItem读取call_sites_item并解析

DexEnd(),

DexFile::MapItemType::kDexTypeCallSiteIdItem,

&call_sites_item)) {

*error_msg = StringPrintf("In oat file '%s' could not read data from truncated DexFile map",

GetLocation().c_str());

return false;

}

size_t num_call_sites = call_sites_item == nullptr ? 0 : call_sites_item->size_;

DexCacheArraysLayout layout(pointer_size, *header, num_call_sites);

if (layout.Size() != 0u) {

if (static_cast(dex_cache_arrays_end - dex_cache_arrays) < layout.Size()) {

*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with "

"truncated dex cache arrays, %zu < %zu.",

GetLocation().c_str(),

i,

dex_file_location.c_str(),

static_cast(dex_cache_arrays_end - dex_cache_arrays),

layout.Size());

return false;

}

current_dex_cache_arrays = dex_cache_arrays;

dex_cache_arrays += layout.Size();

}

}

std::string canonical_location = DexFile::GetDexCanonicalLocation(dex_file_location.c_str());

// Create the OatDexFile and add it to the owning container.

OatDexFile* oat_dex_file = new OatDexFile(this, //根据上面ReadOatDexFileData和FindDexFileMapItem获得的信息构建oat_dex_file

dex_file_location,

canonical_location,

dex_file_checksum,

dex_file_pointer,

lookup_table_data,

method_bss_mapping,

class_offsets_pointer,

current_dex_cache_arrays,

dex_layout_sections);

oat_dex_files_storage_.push_back(oat_dex_file);

// Add the location and canonical location (if different) to the oat_dex_files_ table.

StringPiece key(oat_dex_file->GetDexFileLocation());

oat_dex_files_.Put(key, oat_dex_file);

if (canonical_location != dex_file_location) {

StringPiece canonical_key(oat_dex_file->GetCanonicalDexFileLocation());

oat_dex_files_.Put(canonical_key, oat_dex_file);

}

}

if (dex_cache_arrays != dex_cache_arrays_end) {

// We expect the bss section to be either empty (dex_cache_arrays and bss_end_

// both null) or contain just the dex cache arrays and optionally some GC roots.

*error_msg = StringPrintf("In oat file '%s' found unexpected bss size bigger by %zu bytes.",

GetLocation().c_str(),

static_cast(bss_end_ - dex_cache_arrays));

return false;

}

return true;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值