Чтобы перехватить функцию libc приложения Android (то есть app_process32
), я сначала читаю все адресное пространство, сохраненное в /proc/self/maps
, и для каждого загруженного ELF я перезаписываю соответствующую запись о перемещении.
Чтение строки /proc/self/maps
:
Elf32_Addr start, end;
sscanf(line, "%8x-%8x", &start, &end);
Затем я проверяю, эльф ли это, проверяя магию. Если это ELF, я читаю его сегмент PT_DYNAMIC и просматриваю его записи:
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) start;
Elf32_Phdr *phdr = (Elf32_Phdr *) ((unsigned char *) ehdr + ehdr->e_phoff);
Elf32_Half phnum = ehdr->e_phnum;
Elf32_Addr dynamic = 0;
for (; phnum > 0; --phnum, ++phdr) {
if (phdr->p_type == PT_DYNAMIC) {
dynamic = start + phdr->p_vaddr;
break;
}
}
И вот как я перебираю динамические записи:
Elf32_Dyn *dyn;
for (dyn = (Elf32_Dyn *) dynamic; dyn->d_tag; dyn++) {
Elf32_Addr addr = dyn->d_un.d_ptr;
Elf32_Sword val = dyn->d_un.d_val;
switch (dyn->d_tag) {
// rest of the code.
}
}
Для некоторых общих объектов это нормально, однако для некоторых я получаю SIGSEGV при проверке условия цикла for dyn->d_tag
. Почему PT_DYNAMIC указывает на место, которое я не могу прочитать? Также я заметил, что dynamic
обычно > end
, это нормально?
Я использую устройство под управлением 32-разрядной версии Android 6.0.