解析android源码中dex文件的几个关键函数

dex简介

dex文件作为android的的首要格式,它是能够直接在Dalvik虚拟机中加载运转的文件。
dex 文件能够分为3个模块,头文件(header)、索引区(xxxx_ids)、数据区(data)。
咱们在进行对android加固和脱壳的时分都需求进行和dex文件格式打交道。
它在体系的定义是定义在/art/runtim虚拟机下载e/dex_file文件索引超出了数组边界什么意思中的。下面对dex文件格式的几个要害函数进行剖析。

CheckMagicAndVersion 函数

//判别dex文件索引超出矩阵维度中魔法值dex后面所跟的版别
bool DexFile::CheckMagicAndVersion(std::string* error_msg) const {
//dex文件魔法值是存在在头文件header中的,悉数通过header就能够获取魔法值
if索引页是哪一页 (!IsMagicValid(header_虚拟机是什么意思->mag索引页是哪一页ic_)) {
std::ostringstream oss;索引贴
oss << "Unrecog索引页是哪一页nized magic numberandroid体系 in "  << GetLocation() << ":"
<< " " << heade虚拟机r_->magic_[0]
<< " " << header_索引失效的几种状况->magic_[1]
<< " " << header_->magic_[2]
<< " " << header_->magic虚拟机型安卓下载_[3];
*error_msg = oss.str();
return false;
}
//判别获取的魔法值是否有用
if (!IsVersionVal索引失效的几种状况id(header_->虚拟机装置教程win10magic_)) {
std::ostringstream oss;
oss << "Unrecognized version number in "  << GetLocation() << ":"
<< " " <&landroid电子市场t; header_->magic_[4]
<<索引贴 " " << header_->magic_[5]
<< "虚拟机的损害 " <&l虚拟机装置教程win10t; header_-&gt索引贴的用法;magic_[6]
<< " " << header_->magic_[7];
*error_msg = oss.str();
return false;
}
retandroid平板电脑价格urn true;
}

DexFile函数

//获取解析dex文件格式
DexFile::DexFile(const byte* baseandroid手机, size_t size,
const std::string& location,
uint32_t location_checksum,
MemMap* mem_map)
: begin_(base),
size_(size),
location_(location),
location_checksum_(location_checksum),
mem_map_(mem_map),
head索引符号eandroid手机r_(reinterpret_cast<const Header*>(base)),
string_ids_(reintandroid下载装置erp索引ret索引贴_cast<const StringId*>(base + header_->string_ids_off_)),
type_ids_(reinterpret_cast<cons索引贴t TypeId*>(b虚拟机怎么运用ase + header_->type_ids_off_)),
field_ids_(reinterpret_cast<const Fie索引是什么意思ldId*>(base + header_-&g索引t;field_ids_off_)),
method_ids_(reinterpret_cast<const MethodId*>(base + header_-&gandroid电子市场t;method_ids_off_)),
proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->prAndroidoto_ids_off_)),
class_defs_(reinterpret_cast&l索引贴t;const ClassDef*>(base + header_->class_defs_off_)),
find_class_def_misses_(0),
class_def_index_(nullptr),
buandroid是什么手机牌子ild_class_def_index_索引贴mutex_("DexFile index creation mutex") {
CHECK(begin_ != NULL) << GetLocation();
CHECK_GT(size_, 0U) &lt索引失效;< GetLocation();
}

Fi索引页是哪一页ndClassDef 函数

/索引贴的用法/查找dex文件中的class_ids数据
const DexFile::ClassDef* DexFile::FindClassDef(uint16_t tandroid电子市场ype_idx) const {
//获取class的数量
size_t num_class_defs = NumClassDefs();
for (size_Androidt i = 0; i < num_class_defs; ++i) {
const ClassDef& class_def = GetClassDef(i)android电子市场;
if (class_def.class_idx_ == type_idx) {
return &class_def;
}
}
return NULL;
}

FindFiandroid下载装置eldId 函数

//查找dex文件中的fileId
const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass,
const DexFile::StringId&虚拟机装置教程 name,
const DexFile:android手机:TypeId& type) const {
// Binary search MethodIds knowing that the索引超出了数组边界什么意思y are sorted by class_idx, name_idx then索引 proto_idx
const uint16_t c索引贴的用法lass_idx = GetIndexForTypeId(declaring_klass);
const uint32_t nam索引超出了数组边界什么意思e_idx = GetIndexForStringId(name);
const uint16_t type_idx = GetIndexForTypeId(type);
iandroid/yunosnt32_t lo = 0;
int32_t hi = Num虚拟机FieldIds() - 1;
while (hi >= lo) {
int32_t mid = (hi + lo) / 2;
//获取FileId数据
const DexFile::FieldId& field = GetFieldId(android手机mid);
if (class_idx > field.class_idx_) {
lo = mid + 1;
} else if (clas虚拟机装置教程win10s_idx < field.class_idx_) {
hi = mid - 1;
} else {
if (name_i虚拟机vmosdx > field.虚拟机装置教程name_idx虚拟机下载_) {
lo = mid + 1;
} else if (name_idx < field.nam虚拟机装置教程e_idx_) {
hi = mid - 1;
} else {
if (type_idx > field.type_idx_) {
lo = mid + 1;
} else if (type_idx < field.type_idx_) {
hi = mid - 1;
} else {
//成功返回获取虚拟机怎么运用到的fileId数据
return索引 &field;
}
}
}
}
return NULL;
}

FindMethodId 函数

该函数多所对应的是dex文件中的Method table数据

//查找dex文件中的FindMethodId数据
const DexFil索引页是哪一页e::MethodId* DexFilAndroide::FindMethodId(const DexFile::TypeId& declaring_klass,
const DexFile::StringId& name,
const DexF虚拟机装置教程win10ile::ProtoId& signature) const {
// Binary search MethodIds knowing that they are sorted by class_idx, name_idx then protandroid手机o_idx
const uint16_t class_idx = GetIndexForType索引失效Id(declaring_klass);
const uint32_t name_idx = GetIndexForStri索引页是哪一页ngId(name);
const uint16_t proto_idx = GetIndexForProtoId(signature);
int32_t lo = 0;
//获取d虚拟机linuxex文件中的悉数android下载装置MethodIds的数量
int32_t hi = Nuandroid/yunosmMethodIds() - 1;
//当数量大于0
while (虚拟机装置教程win10hi >= lo) {
//减半的方法进去一个个获取
int32_t mid = (hi + lo) / 2;
const DexFile::MethodId& method = GetMethodId(mid);
if (class_idx > method.class_idx_) {
lo = mid + 1;
} else if (class_idx < method.class_idx_) {
hi = mid - 1;
} else {
if (name_idx > method.name_idx_) {
lo = mid + 1;
} else if (name_idx < method.name_idx_) {
hi = mid - 1;
} else {
ifandroid是什么手机牌子 (proto_idx > method.pandroid是什么手机牌子roto_idx_) {
lo = mid + 1;
} else if (proto_idx < method.proto_i虚拟机下载dx_) {
hi = mid - 1;
} else {
re虚拟机的损害tur虚拟机对电脑伤害大吗n &method;
}
}
}
}
return NULL;
}

FindStringI索引贴d 函索引贴的用法

该函数对应的是在dex文件中的Str虚拟机装置教程win10ing table上

//查找dex文件中的StringId数据
coandroid电子市场nst DexFile::StringId* DexFile::FindStringId(const char* string) const {
int32_t lo = 0;
//获取dex文件中的悉数StringId是数量
int32_t hi = NumStringIds() - 1;
while (h索引贴的用法i &gt虚拟机vmos;= lo) {
int32_t mid = (hi + lo) / 2;
con虚拟机下载st DexFile::StringId& str_id = Geandroid下载tStringId(mid);
const char* str = GetStringData(str_id);
int compare = CompareModifiedUtf索引是什么意思8ToModifiedUtf8AsUtf16CodePointValues(string, str);
if (compare > 0) {
lo = mid + 1;
} else if (compare < 0) {
hi = mid - 1;
} else {
return &str_id;虚拟机的损害
}
}
return N虚拟机linuxULL;
}

发表评论

提供最优质的资源集合

立即查看 了解详情