/* Chrysalide - Outil d'analyse de fichiers binaires * helper_x86.c - gestion auxiliaire de l'architecture x86 * * Copyright (C) 2014-2017 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "helper_arm.h" #include "elf-int.h" #include "symbols.h" #include "../mangling/demangler.h" /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * relxxx = section .rel.xxx trouvée (zone à traiter). * * dynsym = section .dynsym trouvée (info. dynamiques). * * dynstr = section .dynstr trouvée (chaînes de caractères). * * * * Description : Charge en mémoire la liste des symboles relogés. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr) { bool result; /* Bilan à retourner */ phys_t rel_start; /* Début de la zone à traiter */ phys_t rel_size; /* Taille de cette même zone */ phys_t iter; /* Boucle de parcours */ elf_rel reloc; /* Infos de relocalisation */ off_t index; /* Indice de la portion visée */ elf_sym sym; /* Définition complète */ const char *name; /* Nom du symbole trouvé */ virt_t virt; /* Adresse en mémoire virtuelle*/ virt_t final_virt; /* Adresse virtuelle retenue */ bool status; /* Bilan d'une opération */ vmpa2t addr; /* Localisation d'une routine */ mrange_t range; /* Couverture mémoire associée */ GBinRoutine *routine; /* Nouvelle routine trouvée */ GBinSymbol *symbol; /* Nouveau symbole construit */ result = true; get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL); for (iter = rel_start; iter < (rel_start + rel_size); ) { result = read_elf_relocation(format, &iter, &reloc); if (!result) break; index = ELF_REL_SYM(format, reloc); if (!get_elf_symbol_by_index(format, dynsym, index, &sym)) continue; name = get_elf_symbol_name(format, dynsym, dynstr, index); if (name == NULL) { /* FIXME */ name = "unknown"; } switch (ELF_REL_TYPE(format, reloc)) { case R_ARM_JUMP_SLOT: virt = ELF_SYM(format, sym, st_value); if (virt == 0) continue; final_virt = virt & ~0x1; status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr); if (!status) continue; init_mrange(&range, &addr, 0); routine = try_to_demangle_routine(name); g_binary_routine_set_range(routine, &range); symbol = g_binary_symbol_new(STP_ROUTINE); g_binary_symbol_attach_routine(symbol, routine); /* Comptabilisation pour le désassemblage brut */ g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false); break; default: printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc)); symbol = NULL; break; } if (symbol != NULL) g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); } return result; }