static void getSegmentInfo(ElfInfo &info, const Elf32_Word type, Elf32_Phdr **pPhdr, Elf32_Word *pSize,
T *data) {
Elf32_Phdr *_phdr = findSegmentByType(info, type);
if (_phdr) {
if (info.handle->fromfile) {
SAFE_SET_VALUE(data, reinterpret_cast<T>(info.elf_base + _phdr->p_offset));
SAFE_SET_VALUE(pSize, _phdr->p_filesz);
} else {
SAFE_SET_VALUE(data, reinterpret_cast<T>(info.elf_base + _phdr->p_vaddr));
SAFE_SET_VALUE(pSize, _phdr->p_memsz);
}
} else {
LOGI("find segment fail!");
exit(-1);
}
SAFE_SET_VALUE(pPhdr, _phdr);
}
void getElfInfoBySegmentView(ElfInfo &info, const ElfHandle *handle) {
info.handle = handle;
info.elf_base = (uint8_t *) handle->base;
info.ehdr = reinterpret_cast<Elf32_Ehdr *>(info.elf_base);
info.shdr = reinterpret_cast<Elf32_Shdr *>(info.elf_base + info.ehdr->e_shoff);
info.phdr = reinterpret_cast<Elf32_Phdr *>(info.elf_base + info.ehdr->e_phoff);
info.shstr = NULL;
Elf32_Phdr *dynamic = NULL;
Elf32_Word size = 0;
getSegmentInfo(info, PT_DYNAMIC, &dynamic, &size, &info.dyn);
if (!dynamic) {
LOGI("Error );
exit(-1);
}
info.dynsz = size / sizeof(Elf32_Dyn);
Elf32_Dyn *dyn = info.dyn;
}
我通过上面的代码读取/system/lib/libart.so,然后解析,我在0104中查看结构dynamic_link_table地址是否正确,在Android4.4 DVM中,Elf32_Dyn * dyn = info.dyn;运行的结果是正确的,但在Android7.0中,运行到Elf32_Dyn * dyn = info.dyn; dyn是错误的结果
答案 0 :(得分:1)
在Android6.0偏移之后,需要添加[程序头表(R__)可加载段p_vaddr]值
所以,效果很好!