diff options
Diffstat (limited to 'src/format/elf')
-rw-r--r-- | src/format/elf/dynamic.c | 4 | ||||
-rw-r--r-- | src/format/elf/elf-int.c | 239 | ||||
-rw-r--r-- | src/format/elf/elf-int.h | 10 | ||||
-rw-r--r-- | src/format/elf/helper_arm.c | 439 | ||||
-rw-r--r-- | src/format/elf/helper_x86.c | 25 | ||||
-rw-r--r-- | src/format/elf/section.c | 31 | ||||
-rw-r--r-- | src/format/elf/section.h | 6 | ||||
-rw-r--r-- | src/format/elf/strings.c | 26 | ||||
-rw-r--r-- | src/format/elf/symbols.c | 81 |
9 files changed, 223 insertions, 638 deletions
diff --git a/src/format/elf/dynamic.c b/src/format/elf/dynamic.c index e1f50b0..f3367f7 100644 --- a/src/format/elf/dynamic.c +++ b/src/format/elf/dynamic.c @@ -87,7 +87,7 @@ bool find_elf_dynamic_item_from_pheader(const GElfFormat *format, const elf_phdr bool result; /* Bilan à retourner */ off_t max; /* Nombre d'entités présentes */ off_t i; /* Boucle de parcours */ - off_t pos; /* Position de lecture */ + phys_t pos; /* Position de lecture */ result = false; @@ -97,7 +97,7 @@ bool find_elf_dynamic_item_from_pheader(const GElfFormat *format, const elf_phdr { pos = ELF_PHDR(format, *dynamic, p_offset) + i * ELF_SIZEOF_DYN(format); - if (!read_elf_dynamic_entry(format, &pos, item)) + if (!read_elf_dynamic_entry(format, pos, item)) break; result = (ELF_DYN(format, *item, d_tag) == type); diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c index 7ca958b..3e70932 100644 --- a/src/format/elf/elf-int.c +++ b/src/format/elf/elf-int.c @@ -46,22 +46,14 @@ bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, SourceEndian *endian) { bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ - off_t pos; /* Position de lecture */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; - result = (length >= EI_NIDENT); + init_vmpa(&pos, 0, VMPA_NO_VIRTUAL); - pos = 0; - - if (result) - { - memcpy(header->hdr32.e_ident, content, EI_NIDENT); - pos += EI_NIDENT; - } + result = g_binary_content_get_raw(content, &pos, EI_NIDENT, (bin_t *)header->hdr32.e_ident); /* Détermination de l'espace d'adressage */ if (result) @@ -95,35 +87,35 @@ bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, Sourc if (*is_32b) { - result &= read_u16(&header->hdr32.e_type, content, &pos, length, *endian); - result &= read_u16(&header->hdr32.e_machine, content, &pos, length, *endian); - result &= read_u32(&header->hdr32.e_version, content, &pos, length, *endian); - result &= read_u32(&header->hdr32.e_entry, content, &pos, length, *endian); - result &= read_u32(&header->hdr32.e_phoff, content, &pos, length, *endian); - result &= read_u32(&header->hdr32.e_shoff, content, &pos, length, *endian); - result &= read_u32(&header->hdr32.e_flags, content, &pos, length, *endian); - result &= read_u16(&header->hdr32.e_ehsize, content, &pos, length, *endian); - result &= read_u16(&header->hdr32.e_phentsize, content, &pos, length, *endian); - result &= read_u16(&header->hdr32.e_phnum, content, &pos, length, *endian); - result &= read_u16(&header->hdr32.e_shentsize, content, &pos, length, *endian); - result &= read_u16(&header->hdr32.e_shnum, content, &pos, length, *endian); - result &= read_u16(&header->hdr32.e_shstrndx, content, &pos, length, *endian); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_type); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_machine); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_version); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_entry); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_phoff); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_shoff); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_flags); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_ehsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_phentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_phnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shstrndx); } else { - result &= read_u16(&header->hdr64.e_type, content, &pos, length, *endian); - result &= read_u16(&header->hdr64.e_machine, content, &pos, length, *endian); - result &= read_u32(&header->hdr64.e_version, content, &pos, length, *endian); - result &= read_u64(&header->hdr64.e_entry, content, &pos, length, *endian); - result &= read_u64(&header->hdr64.e_phoff, content, &pos, length, *endian); - result &= read_u64(&header->hdr64.e_shoff, content, &pos, length, *endian); - result &= read_u32(&header->hdr64.e_flags, content, &pos, length, *endian); - result &= read_u16(&header->hdr64.e_ehsize, content, &pos, length, *endian); - result &= read_u16(&header->hdr64.e_phentsize, content, &pos, length, *endian); - result &= read_u16(&header->hdr64.e_phnum, content, &pos, length, *endian); - result &= read_u16(&header->hdr64.e_shentsize, content, &pos, length, *endian); - result &= read_u16(&header->hdr64.e_shnum, content, &pos, length, *endian); - result &= read_u16(&header->hdr64.e_shstrndx, content, &pos, length, *endian); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_type); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_machine); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr64.e_version); + result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_entry); + result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_phoff); + result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_shoff); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr64.e_flags); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_ehsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_phentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_phnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shstrndx); } return result; @@ -134,7 +126,7 @@ bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, Sourc /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * -* pos = position de début de lecture. [OUT] * +* phys = position de début de lecture. * * header = structure lue à retourner. [OUT] * * * * Description : Procède à la lecture d'une en-tête de programme ELF. * @@ -145,36 +137,37 @@ bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, Sourc * * ******************************************************************************/ -bool read_elf_program_header(const GElfFormat *format, off_t pos, elf_phdr *header) +bool read_elf_program_header(const GElfFormat *format, phys_t phys, elf_phdr *header) { bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; + + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); if (format->is_32b) { - result = read_u32(&header->phdr32.p_type, content, &pos, length, format->endian); - result &= read_u32(&header->phdr32.p_offset, content, &pos, length, format->endian); - result &= read_u32(&header->phdr32.p_vaddr, content, &pos, length, format->endian); - result &= read_u32(&header->phdr32.p_paddr, content, &pos, length, format->endian); - result &= read_u32(&header->phdr32.p_filesz, content, &pos, length, format->endian); - result &= read_u32(&header->phdr32.p_memsz, content, &pos, length, format->endian); - result &= read_u32(&header->phdr32.p_flags, content, &pos, length, format->endian); - result &= read_u32(&header->phdr32.p_align, content, &pos, length, format->endian); + result = g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_type); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_offset); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_vaddr); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_paddr); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_filesz); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_memsz); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_flags); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_align); } else { - result = read_u32(&header->phdr64.p_type, content, &pos, length, format->endian); - result &= read_u32(&header->phdr64.p_flags, content, &pos, length, format->endian); - result &= read_u64(&header->phdr64.p_offset, content, &pos, length, format->endian); - result &= read_u64(&header->phdr64.p_vaddr, content, &pos, length, format->endian); - result &= read_u64(&header->phdr64.p_paddr, content, &pos, length, format->endian); - result &= read_u64(&header->phdr64.p_filesz, content, &pos, length, format->endian); - result &= read_u64(&header->phdr64.p_memsz, content, &pos, length, format->endian); - result &= read_u64(&header->phdr64.p_align, content, &pos, length, format->endian); + result = g_binary_content_read_u32(content, &pos, format->endian, &header->phdr64.p_type); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr64.p_flags); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_offset); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_vaddr); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_paddr); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_filesz); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_memsz); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_align); } return result; @@ -185,7 +178,7 @@ bool read_elf_program_header(const GElfFormat *format, off_t pos, elf_phdr *head /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * -* pos = position de la tête de lecture. * +* phys = position de début de lecture. * * section = section lue. [OUT] * * * * Description : Procède à la lecture d'une en-tête de section ELF. * @@ -196,49 +189,50 @@ bool read_elf_program_header(const GElfFormat *format, off_t pos, elf_phdr *head * * ******************************************************************************/ -bool read_elf_section_header(const GElfFormat *format, off_t pos, elf_shdr *section) +bool read_elf_section_header(const GElfFormat *format, phys_t phys, elf_shdr *section) { bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ elf32_shdr *shdr32; /* Version 32 bits */ elf64_shdr *shdr64; /* Version 32 bits */ result = true; content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; + + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); if (format->is_32b) { shdr32 = §ion->shdr32; - result = read_u32(&shdr32->sh_name, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_type, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_flags, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_addr, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_offset, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_size, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_link, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_info, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_addralign, content, &pos, length, format->endian); - result &= read_u32(&shdr32->sh_entsize, content, &pos, length, format->endian); + result = g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_name); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_type); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_flags); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_addr); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_offset); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_size); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_link); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_info); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_addralign); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_entsize); } else { shdr64 = §ion->shdr64; - result = read_u32(&shdr64->sh_name, content, &pos, length, format->endian); - result &= read_u32(&shdr64->sh_type, content, &pos, length, format->endian); - result &= read_u64(&shdr64->sh_flags, content, &pos, length, format->endian); - result &= read_u64(&shdr64->sh_addr, content, &pos, length, format->endian); - result &= read_u64(&shdr64->sh_offset, content, &pos, length, format->endian); - result &= read_u64(&shdr64->sh_size, content, &pos, length, format->endian); - result &= read_u32(&shdr64->sh_link, content, &pos, length, format->endian); - result &= read_u32(&shdr64->sh_info, content, &pos, length, format->endian); - result &= read_u64(&shdr64->sh_addralign, content, &pos, length, format->endian); - result &= read_u64(&shdr64->sh_entsize, content, &pos, length, format->endian); + result = g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_name); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_type); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_flags); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_addr); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_offset); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_size); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_link); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_info); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_addralign); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_entsize); } @@ -250,7 +244,7 @@ bool read_elf_section_header(const GElfFormat *format, off_t pos, elf_shdr *sect /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * -* pos = position de début de lecture. [OUT] * +* phys = position de début de lecture. * * dyn = structure lue à retourner. [OUT] * * * * Description : Procède à la lecture d'une entrée de type 'DYNAMIC' ELF. * @@ -261,24 +255,25 @@ bool read_elf_section_header(const GElfFormat *format, off_t pos, elf_shdr *sect * * ******************************************************************************/ -bool read_elf_dynamic_entry(const GElfFormat *format, off_t *pos, elf_dyn *dyn) +bool read_elf_dynamic_entry(const GElfFormat *format, phys_t phys, elf_dyn *dyn) { bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; + + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); if (format->is_32b) { - result = read_s32(&dyn->dyn32.d_tag, content, pos, length, format->endian); - result &= read_u32(&dyn->dyn32.d_un.d_val, content, pos, length, format->endian); + result = g_binary_content_read_s32(content, &pos, format->endian, &dyn->dyn32.d_tag); + result &= g_binary_content_read_u32(content, &pos, format->endian, &dyn->dyn32.d_un.d_val); } else { - result = read_s64(&dyn->dyn64.d_tag, content, pos, length, format->endian); - result &= read_u64(&dyn->dyn64.d_un.d_val, content, pos, length, format->endian); + result = g_binary_content_read_s64(content, &pos, format->endian, &dyn->dyn64.d_tag); + result &= g_binary_content_read_u64(content, &pos, format->endian, &dyn->dyn64.d_un.d_val); } return result; @@ -300,34 +295,38 @@ bool read_elf_dynamic_entry(const GElfFormat *format, off_t *pos, elf_dyn *dyn) * * ******************************************************************************/ -bool read_elf_symbol(const GElfFormat *format, off_t *pos, elf_sym *sym) +bool read_elf_symbol(const GElfFormat *format, phys_t *phys, elf_sym *sym) { bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; + + init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); if (format->is_32b) { - result = read_u32(&sym->sym32.st_name, content, pos, length, format->endian); - result &= read_u32(&sym->sym32.st_value, content, pos, length, format->endian); - result &= read_u32(&sym->sym32.st_size, content, pos, length, format->endian); - result &= read_u8(&sym->sym32.st_info, content, pos, length, format->endian); - result &= read_u8(&sym->sym32.st_other, content, pos, length, format->endian); - result &= read_u16(&sym->sym32.st_shndx, content, pos, length, format->endian); + result = g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_name); + result &= g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_value); + result &= g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_size); + result &= g_binary_content_read_u8(content, &pos, &sym->sym32.st_info); + result &= g_binary_content_read_u8(content, &pos, &sym->sym32.st_other); + result &= g_binary_content_read_u16(content, &pos, format->endian, &sym->sym32.st_shndx); } else { - result = read_u32(&sym->sym64.st_name, content, pos, length, format->endian); - result &= read_u8(&sym->sym64.st_info, content, pos, length, format->endian); - result &= read_u8(&sym->sym64.st_other, content, pos, length, format->endian); - result &= read_u16(&sym->sym64.st_shndx, content, pos, length, format->endian); - result &= read_u64(&sym->sym64.st_value, content, pos, length, format->endian); - result &= read_u64(&sym->sym64.st_size, content, pos, length, format->endian); + result = g_binary_content_read_u32(content, &pos, format->endian, &sym->sym64.st_name); + result &= g_binary_content_read_u8(content, &pos, &sym->sym64.st_info); + result &= g_binary_content_read_u8(content, &pos, &sym->sym64.st_other); + result &= g_binary_content_read_u16(content, &pos, format->endian, &sym->sym64.st_shndx); + result &= g_binary_content_read_u64(content, &pos, format->endian, &sym->sym64.st_value); + result &= g_binary_content_read_u64(content, &pos, format->endian, &sym->sym64.st_size); } + if (result) + *phys = get_phy_addr(&pos); + return result; } @@ -336,7 +335,7 @@ bool read_elf_symbol(const GElfFormat *format, off_t *pos, elf_sym *sym) /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * -* pos = position de début de lecture. [OUT] * +* phys = position de début de lecture. [OUT] * * reloc = structure lue à retourner. [OUT] * * * * Description : Procède à la lecture d'une relocalisation ELF. * @@ -347,26 +346,30 @@ bool read_elf_symbol(const GElfFormat *format, off_t *pos, elf_sym *sym) * * ******************************************************************************/ -bool read_elf_relocation(const GElfFormat *format, off_t *pos, elf_rel *reloc) +bool read_elf_relocation(const GElfFormat *format, phys_t *phys, elf_rel *reloc) { bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; + + init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); if (format->is_32b) { - result = read_u32(&reloc->rel32.r_offset, content, pos, length, format->endian); - result &= read_u32(&reloc->rel32.r_info, content, pos, length, format->endian); + result = g_binary_content_read_u32(content, &pos, format->endian, &reloc->rel32.r_offset); + result &= g_binary_content_read_u32(content, &pos, format->endian, &reloc->rel32.r_info); } else { - result = read_u64(&reloc->rel64.r_offset, content, pos, length, format->endian); - result &= read_u64(&reloc->rel64.r_info, content, pos, length, format->endian); + result = g_binary_content_read_u64(content, &pos, format->endian, &reloc->rel64.r_offset); + result &= g_binary_content_read_u64(content, &pos, format->endian, &reloc->rel64.r_info); } + if (result) + *phys = get_phy_addr(&pos); + return result; } diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h index fd0b74d..e0ae03b 100644 --- a/src/format/elf/elf-int.h +++ b/src/format/elf/elf-int.h @@ -56,19 +56,19 @@ struct _GElfFormatClass bool read_elf_header(GElfFormat *, elf_header *, bool *, SourceEndian *); /* Procède à la lecture d'une en-tête de programme ELF. */ -bool read_elf_program_header(const GElfFormat *, off_t, elf_phdr *); +bool read_elf_program_header(const GElfFormat *, phys_t, elf_phdr *); /* Procède à la lecture d'une en-tête de section ELF. */ -bool read_elf_section_header(const GElfFormat *, off_t, elf_shdr *); +bool read_elf_section_header(const GElfFormat *, phys_t, elf_shdr *); /* Procède à la lecture d'une entrée de type 'DYNAMIC' ELF. */ -bool read_elf_dynamic_entry(const GElfFormat *, off_t *, elf_dyn *); +bool read_elf_dynamic_entry(const GElfFormat *, phys_t, elf_dyn *); /* Procède à la lecture d'un symbole ELF. */ -bool read_elf_symbol(const GElfFormat *, off_t *, elf_sym *); +bool read_elf_symbol(const GElfFormat *, phys_t *, elf_sym *); /* Procède à la lecture d'une relocalisation ELF. */ -bool read_elf_relocation(const GElfFormat *, off_t *, elf_rel *); +bool read_elf_relocation(const GElfFormat *, phys_t *, elf_rel *); diff --git a/src/format/elf/helper_arm.c b/src/format/elf/helper_arm.c index c77df55..cd2d922 100644 --- a/src/format/elf/helper_arm.c +++ b/src/format/elf/helper_arm.c @@ -53,9 +53,9 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr) { bool result; /* Bilan à retourner */ - off_t rel_start; /* Début de la zone à traiter */ - off_t rel_size; /* Taille de cette même zone */ - off_t iter; /* Boucle de parcours */ + 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 */ @@ -79,10 +79,6 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL); - printf("rel :: %d -> %d\n", rel_start, rel_start + rel_size); - - - for (iter = rel_start; iter < (rel_start + rel_size); ) { result = read_elf_relocation(format, &iter, &reloc); @@ -147,432 +143,3 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, return result; } - - - - - - - - - - - - - - - - - - - - - - - -#if 0 - -#include <malloc.h> -#include <stdio.h> -#include <string.h> - - -#include "elf-int.h" -#include "../symbol.h" -#include "../mangling/demangler.h" -#include "../../arch/immediate.h" -#include "../../arch/processor.h" -#include "../../arch/x86/instruction.h" - - -// Désactivation -#define g_x86_instruction_get_opcode(i) 0 - - -/* symbols.c : Récupère la désignation d'un symbole donné. */ -extern const char *get_elf_symbol_name(GElfFormat *, const elf_shdr *, const elf_shdr *, off_t); - - -/* Décode les instructions liées à la relocalisation. */ -GArchInstruction **decode_elf_relocations(GElfFormat *, const elf_shdr *, size_t *); - -/* Déduit les adresses effectives des relocalisations. */ -void translate_exe_elf_relocations(GElfFormat *, GArchInstruction **, size_t); - -/* Déduit les adresses effectives des relocalisations. */ -void translate_dyn_elf_relocations(GElfFormat *, GArchInstruction **, size_t, const elf_shdr *, const elf_shdr *, const elf_shdr *); - - - -/****************************************************************************** -* * -* 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 dynamiques. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_elf_x86_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr) -{ - bool result; /* Bilan à retourner */ - off_t rel_start; /* Début de la zone à traiter */ - off_t rel_size; /* Taille de cette même zone */ - off_t iter; /* Boucle de parcours */ - elf_rel reloc; /* Infos de relocalisation */ - off_t index; /* Indice de la portion visée */ - const char *name; /* Nom du symbole trouvé */ - GBinSymbol *symbol; /* Nouveau symbole construit */ - - - - - result = true; - - - - get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL); - - - printf("rel :: %d -> %d\n", rel_start, rel_start + rel_size); - - - - for (iter = rel_start; iter < (rel_start + rel_size); ) - { - result = read_elf_relocation(format, &iter, &reloc); - if (!result) break; - - switch (ELF_REL_TYPE(format, reloc)) - { - case R_386_NONE: - break; - - case R_386_JMP_SLOT: - - index = ELF_REL_SYM(format, reloc); - name = get_elf_symbol_name(format, dynsym, dynstr, index); - - - //printf("got a jump ! >> %d - %s\n", index, name); - - - if (name == NULL) - { - /* FIXME */ - name = "unknown"; - } - - symbol = g_binary_symbol_new(STP_FUNCTION); - g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); - - break; - - default: - printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc)); - break; - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* plt = section .plt trouvée (points d'entrées dynamiques). * -* rel = section .rel.plt présentant la table des symboles. * -* dynsym = section listant tous les symboles. * -* dynstr = section contenant le nom de ces symboles. * -* * -* Description : Déduit les adresses effectives des appels externes. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_x86_dynamic_symbols(GElfFormat *format, const elf_shdr *plt, const elf_shdr *rel, const elf_shdr *dynsym, const elf_shdr *dynstr) -{ - GArchInstruction **instructions; /* Instructions décodées */ - size_t count; /* Quantité d'instructions */ - size_t i; /* Boucle de parcours */ - - instructions = decode_elf_relocations(format, plt, &count); - - switch (ELF_HDR(format, format->header, e_type)) - { - case ET_EXEC: - translate_exe_elf_relocations(format, instructions, count); - break; - - case ET_DYN: - translate_dyn_elf_relocations(format, instructions, count, rel, dynsym, dynstr); - break; - - } - - for (i = 0; i < count; i++) - /* TODO : free instructions[i] */; - - if (instructions != NULL) - free(instructions); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* plt = section .plt trouvée (points d'entrées dynamiques). * -* count = nombre d'instructions lues. [OUT] * -* * -* Description : Décode les instructions liées à la relocalisation. * -* * -* Retour : Liste des instructions décodées ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction **decode_elf_relocations(GElfFormat *format, const elf_shdr *plt, size_t *count) -{ - GArchInstruction **result; /* Liste à renvoyer */ - off_t plt_start; /* Début de section */ - off_t plt_size; /* Taille de section */ - vmpa_t plt_address; /* Adresse virtuelle associée */ - GArchProcessor *proc; /* Processeur pour le décodage */ - off_t pos; /* Tête de lecture */ - vmpa_t address; /* Adresse virtuelle courante */ - GArchInstruction *instr; /* Instruction décodée */ - - result = NULL; - *count = 0; - - get_elf_section_content(format, plt, &plt_start, &plt_size, &plt_address); - - proc = NULL;//get_arch_processor_for_type(APT_386); - - for (pos = 0; pos < plt_size; ) - { - address = plt_address + pos; - - instr = g_arch_processor_decode_instruction(proc, NULL /*FIXME*/, &G_BIN_FORMAT(format)->content[plt_start], - &pos, plt_size, address, NULL /*FIXME*/); - - result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *)); - result[*count - 1] = instr; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* instructions = listes des instructions à interpréter. * -* count = nombre d'instructions lues. * -* * -* Description : Déduit les adresses effectives des relocalisations. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void translate_exe_elf_relocations(GElfFormat *format, GArchInstruction **instructions, size_t count) -{ - size_t i; /* Boucle de parcours #1 */ - X86Opcodes opcode_n0; /* Opcode de l'instruction n */ - X86Opcodes opcode_n1; /* Opcode de l'instruction n+1 */ - X86Opcodes opcode_n2; /* Opcode de l'instruction n+2 */ - const GArchOperand *operand; /* Valeur du saut */ - vmpa_t address; /* Adresse virtuelle finale */ - GBinSymbol **symbols; /* Liste des symboles existants*/ - size_t symbols_count; /* Taille de cette liste */ - size_t j; /* Boucle de parcours #2 */ - size_t new_len; /* Taille du nouveau nom */ - char *new_name; /* Nom avec suffixe @plt */ - GBinRoutine *routine; /* Nouvelle routine déduite */ - GBinSymbol *symbol; /* Nouveau symbole construit */ - - for (i = 0; (i + 2) < count; ) - { - opcode_n0 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i])); - opcode_n1 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 1])); - opcode_n2 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 2])); - - if (opcode_n0 == XOP_JMP_RM1632 - && opcode_n1 == XOP_PUSH_IMM1632 - && opcode_n2 == XOP_JMP_REL1632) - { - operand = g_arch_instruction_get_operand(instructions[i], 0); - - if (g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address)) - { - symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &symbols_count); - - for (j = 0; j < symbols_count; j++) - if (0 /* FIXME g_binary_symbol_get_address(symbols[j]) == address*/) - { - /* Nom final */ - - new_len = strlen(g_binary_symbol_get_label(symbols[j])) + 4 + 1; - new_name = calloc(new_len, sizeof(char)); - snprintf(new_name, new_len, "%s@plt", g_binary_symbol_get_label(symbols[j])); - - g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); - - /* Routine */ - - routine = try_to_demangle_routine(g_binary_symbol_get_label(symbols[j])); - - ///g_binary_routine_set_address(routine, address); - - ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); - - /* Symbole uniquement */ - - symbol = g_binary_symbol_new(STP_FUNCTION); - - g_binary_symbol_attach_routine(symbol, routine); - - g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); - - break; - - } - - } - - i += 3; - - } - else i++; - - } - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* instructions = listes des instructions à interpréter. * -* count = nombre d'instructions lues. * -* * -* Description : Déduit les adresses effectives des relocalisations. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instructions, size_t count, const elf_shdr *rel, const elf_shdr *dynsym, const elf_shdr *dynstr) -{ - off_t rel_start; /* Début de la zone à traiter */ - off_t rel_size; /* Taille de cette même zone */ - size_t i; /* Boucle de parcours #1 */ - X86Opcodes opcode_n0; /* Opcode de l'instruction n */ - X86Opcodes opcode_n1; /* Opcode de l'instruction n+1 */ - X86Opcodes opcode_n2; /* Opcode de l'instruction n+2 */ - const GArchOperand *operand; /* Valeur du saut */ - off_t pos; /* Tête de lecture */ - bool negative; /* Tête de lecture invalide ? */ - elf_rel reloc; /* Infos de relocalisation */ - off_t index; /* Indice de la portion visée */ - const char *name; /* Nom du symbole trouvé */ - size_t new_len; /* Taille du nouveau nom */ - char *new_name; /* Nom avec suffixe @plt */ - vmpa_t address; /* Adresse virtuelle finale */ - GBinRoutine *routine; /* Nouvelle routine déduite */ - GBinSymbol *symbol; /* Nouveau symbole construit */ - - get_elf_section_content(format, rel, &rel_start, &rel_size, NULL); - - for (i = 0; (i + 2) < count; ) - { - opcode_n0 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i])); - opcode_n1 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 1])); - opcode_n2 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 2])); - - if (opcode_n0 == XOP_JMP_RM1632 - && opcode_n1 == XOP_PUSH_IMM1632 - && opcode_n2 == XOP_JMP_REL1632) - { - operand = g_arch_instruction_get_operand(instructions[i + 1], 0); - - if (!g_imm_operand_to_off_t(G_IMM_OPERAND(operand), &pos, &negative)) - goto next_op; - - if ((pos + ELF_SIZEOF_REL(format)) > rel_size) - goto next_op; - - pos += rel_start; - - if (!read_elf_relocation(format, &pos, &reloc)) - goto next_op; - - index = ELF_REL_SYM(format, reloc); - name = get_elf_symbol_name(format, dynsym, dynstr, index); - - if (name == NULL) - { - /* FIXME */ - name = "unknown"; - } - - /* Nom final */ - - new_len = strlen(name) + 4 + 1; - new_name = calloc(new_len, sizeof(char)); - snprintf(new_name, new_len, "%s@plt", name); - - g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); - - /* Routine */ - - routine = try_to_demangle_routine(name); - - ////g_binary_routine_set_address(routine, address); - - ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); - - /* Symbole uniquement */ - - symbol = g_binary_symbol_new(STP_FUNCTION); - - g_binary_symbol_attach_routine(symbol, routine); - - g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); - - next_op: - - i += 3; - - } - else i++; - - } - -} - -#endif diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c index deb1ead..da71214 100644 --- a/src/format/elf/helper_x86.c +++ b/src/format/elf/helper_x86.c @@ -24,6 +24,25 @@ #include "helper_x86.h" + +bool load_elf_x86_relocated_symbols(GElfFormat *a, const elf_shdr *b, const elf_shdr *c, const elf_shdr *d) +{ + return false; +} + +/* Déduit les adresses effectives des appels externes. */ +bool find_elf_x86_dynamic_symbols(GElfFormat *a, const elf_shdr *b, const elf_shdr *c, const elf_shdr *d, const elf_shdr *e) +{ + return false; +} + + + + + + +#if 0 + #include <malloc.h> #include <stdio.h> #include <string.h> @@ -98,7 +117,7 @@ bool load_elf_x86_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, for (iter = rel_start; iter < (rel_start + rel_size); ) { - result = read_elf_relocation(format, &iter, &reloc); + result = false;//read_elf_relocation(format, &iter, &reloc); if (!result) break; switch (ELF_REL_TYPE(format, reloc)) @@ -380,7 +399,7 @@ void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instru pos += rel_start; - if (!read_elf_relocation(format, &pos, &reloc)) + if (!false/*read_elf_relocation(format, &pos, &reloc)*/) goto next_op; index = ELF_REL_SYM(format, reloc); @@ -426,3 +445,5 @@ void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instru } } + +#endif diff --git a/src/format/elf/section.c b/src/format/elf/section.c index 3feb869..2b46d9e 100644 --- a/src/format/elf/section.c +++ b/src/format/elf/section.c @@ -48,7 +48,7 @@ bool find_elf_section_by_index(const GElfFormat *format, uint16_t index, elf_shdr *section) { - off_t offset; /* Emplacement à venir lire */ + phys_t offset; /* Emplacement à venir lire */ if (index >= ELF_HDR(format, format->header, e_shnum)) return false; @@ -118,7 +118,7 @@ bool find_elf_section_by_name(const GElfFormat *format, const char *name, elf_sh * * ******************************************************************************/ -bool find_elf_section_by_virtual_address(const GElfFormat *format, uint32_t addr, elf_shdr *section) +bool find_elf_section_by_virtual_address(const GElfFormat *format, virt_t addr, elf_shdr *section) { bool result; /* Bilan à faire remonter */ uint16_t i; /* Boucle de parcours */ @@ -194,7 +194,7 @@ bool find_elf_sections_by_type(const GElfFormat *format, uint32_t type, elf_shdr * * ******************************************************************************/ -void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, off_t *offset, off_t *size, vmpa_t *addr) +void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, phys_t *offset, phys_t *size, virt_t *addr) { *offset = ELF_SHDR(format, *section, sh_offset); *size = ELF_SHDR(format, *section, sh_size); @@ -221,7 +221,7 @@ void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, * * ******************************************************************************/ -bool find_elf_section_content_by_name(const GElfFormat *format, const char *name, off_t *offset, off_t *size, vmpa_t *address) +bool find_elf_section_content_by_name(const GElfFormat *format, const char *name, phys_t *offset, phys_t *size, virt_t *address) { bool result; /* Bilan à retourner */ elf_shdr section; /* Section trouvée ou non */ @@ -253,24 +253,25 @@ bool find_elf_section_content_by_name(const GElfFormat *format, const char *name const char *extract_name_from_elf_string_section(const GElfFormat *format, const elf_shdr *section, off_t index) { const char *result; /* Nom trouvé à renvoyer */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ - off_t last; /* Dernier '\0' possible */ - off_t pos; /* Point de lecture */ - - content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; + phys_t last; /* Dernier '\0' possible */ + phys_t phys; /* Point de lecture physique */ + vmpa2t pos; /* Position de lecture */ + const GBinContent *content; /* Contenu binaire à lire */ last = ELF_SHDR(format, *section, sh_offset) + ELF_SHDR(format, *section, sh_size); - pos = ELF_SHDR(format, *section, sh_offset) + index; + phys = ELF_SHDR(format, *section, sh_offset) + index; - if ((pos + 1) >= MIN(length, last)) + if ((phys + 1) >= last) return NULL; - result = (const char *)&content[pos]; + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); + + content = G_BIN_FORMAT(format)->content; + + result = (const char *)g_binary_content_get_raw_access(content, &pos, 1); - if ((pos + strlen(result)) > last) + if ((phys + strlen(result)) > last) return NULL; return result; diff --git a/src/format/elf/section.h b/src/format/elf/section.h index e300ee3..4da3df9 100644 --- a/src/format/elf/section.h +++ b/src/format/elf/section.h @@ -37,16 +37,16 @@ bool find_elf_section_by_index(const GElfFormat *, uint16_t, elf_shdr *); bool find_elf_section_by_name(const GElfFormat *, const char *, elf_shdr *); /* Recherche une section donnée au sein de binaire par type. */ -bool find_elf_section_by_virtual_address(const GElfFormat *, uint32_t, elf_shdr *); +bool find_elf_section_by_virtual_address(const GElfFormat *, virt_t, elf_shdr *); /* Recherche une section donnée au sein de binaire par type. */ bool find_elf_sections_by_type(const GElfFormat *, uint32_t, elf_shdr **, size_t *); /* Fournit les adresses et taille contenues dans une section. */ -void get_elf_section_content(const GElfFormat *, const elf_shdr *, off_t *, off_t *, vmpa_t *); +void get_elf_section_content(const GElfFormat *, const elf_shdr *, phys_t *, phys_t *, virt_t *); /* Recherche une zone donnée au sein de binaire par nom. */ -bool find_elf_section_content_by_name(const GElfFormat *, const char *, off_t *, off_t *, vmpa_t *); +bool find_elf_section_content_by_name(const GElfFormat *, const char *, phys_t *, phys_t *, virt_t *); /* Identifie une chaîne de caractères dans une section adéquate. */ const char *extract_name_from_elf_string_section(const GElfFormat *, const elf_shdr *, off_t); diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c index 6832f5b..4d8a32e 100644 --- a/src/format/elf/strings.c +++ b/src/format/elf/strings.c @@ -37,7 +37,7 @@ /* Enregistre toutes les chaînes de caractères trouvées. */ -bool parse_elf_string_data(GElfFormat *, off_t, off_t, vmpa_t); +bool parse_elf_string_data(GElfFormat *, phys_t, phys_t, virt_t); @@ -56,14 +56,14 @@ bool parse_elf_string_data(GElfFormat *, off_t, off_t, vmpa_t); bool find_all_elf_strings(GElfFormat *format) { bool got_string; /* Indique un remplissage */ - off_t str_start; /* Début de section */ - off_t str_size; /* Taille de section */ - vmpa_t str_addr; /* Adresse virtuelle associée */ + phys_t str_start; /* Début de section */ + phys_t str_size; /* Taille de section */ + virt_t str_addr; /* Adresse virtuelle associée */ elf_shdr *sections; /* Groupe de sections trouvées */ size_t count; /* Quantité de données */ size_t i; /* Boucle de parcours #1 */ - off_t length; /* Taille totale du contenu */ - off_t iter; /* Boucle de parcours #2 */ + phys_t max; /* Borne à ne pas dépasser */ + phys_t iter; /* Boucle de parcours #2 */ elf_phdr phdr; /* En-tête de programme ELF */ got_string = false; @@ -109,10 +109,10 @@ bool find_all_elf_strings(GElfFormat *format) if (!got_string) { - length = G_BIN_FORMAT(format)->length; - length = MIN(length, ELF_HDR(format, format->header, e_phnum) * ELF_SIZEOF_PHDR(format)); + max = ELF_HDR(format, format->header, e_phoff) + + ELF_HDR(format, format->header, e_phnum) * ELF_SIZEOF_PHDR(format); - for (iter = ELF_HDR(format, format->header, e_phoff); iter < length; iter += ELF_SIZEOF_PHDR(format)) + for (iter = ELF_HDR(format, format->header, e_phoff); iter < max; iter += ELF_SIZEOF_PHDR(format)) { if (!read_elf_program_header(format, iter, &phdr)) continue; @@ -148,7 +148,7 @@ bool find_all_elf_strings(GElfFormat *format) * * ******************************************************************************/ -bool parse_elf_string_data(GElfFormat *format, off_t start, off_t size, vmpa_t address) +bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t address) { bool result; /* Bilan à faire remonter */ GBinContent *content; /* Contenu binaire à lire */ @@ -167,7 +167,7 @@ bool parse_elf_string_data(GElfFormat *format, off_t start, off_t size, vmpa_t a /* Préparation des accès */ - content = g_binary_format_get_conten_(G_BIN_FORMAT(format)); + content = g_binary_format_get_content(G_BIN_FORMAT(format)); data = (char *)malloc(size * sizeof(char)); @@ -194,7 +194,7 @@ bool parse_elf_string_data(GElfFormat *format, off_t start, off_t size, vmpa_t a init_vmpa(&pos, start + i, address + i); - instr = g_raw_instruction_new_array(G_BIN_FORMAT(format)->conten_, MDS_8_BITS, + instr = g_raw_instruction_new_array(G_BIN_FORMAT(format)->content, MDS_8_BITS, end - i, &pos, format->endian); g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); @@ -227,6 +227,8 @@ bool parse_elf_string_data(GElfFormat *format, off_t start, off_t size, vmpa_t a pesd_error: + g_object_unref(G_OBJECT(content)); + free(data); return result; diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index 1fa3d0e..04c584d 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -188,15 +188,11 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le routine = g_binary_symbol_get_routine(symbol); g_object_ref(G_OBJECT(routine)); - printf(" -- SYM CHANGE @ 0x%08x\n", vaddr); - _g_binary_symbol_attach_routine(symbol, routine, STP_ENTRY_POINT); } else { - printf(" -- SYM ENTRY @ 0x%08x\n", vaddr); - init_mrange(&range, &addr, len); g_binary_routine_set_range(routine, &range); @@ -229,10 +225,10 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format) elf_phdr dynamic; /* En-tête de programme DYNAMIC*/ elf_dyn item_a; /* Premier élément DYNAMIC */ elf_dyn item_b; /* Second élément DYNAMIC */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ + const GBinContent *content; /* Contenu binaire à lire */ + phys_t length; /* Taille totale du contenu */ bool status; /* Bilan d'une opération */ - off_t pos; /* Tête de lecture courante */ + vmpa2t pos; /* Tête de lecture courante */ uint32_t virt_32; /* Adresse virtuelle sur 32b */ uint64_t virt_64; /* Adresse virtuelle sur 64b */ @@ -285,26 +281,24 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format) assert(sizeof(fullname) >= (strlen(prefix) + sizeof(XSTR(UINT64_MAX) + 1))); content = G_BIN_FORMAT(fmt)->content; - length = G_BIN_FORMAT(fmt)->length; - status = g_exe_format_translate_address_into_offset(G_EXE_FORMAT(format), - ELF_DYN(fmt, *ar, d_un.d_val), - &pos); + status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), + ELF_DYN(fmt, *ar, d_un.d_val), + &pos); if (!status) return; - if ((pos + ELF_DYN(fmt, *sz, d_un.d_val)) < length) - length = pos + ELF_DYN(fmt, *sz, d_un.d_val); + length = get_phy_addr(&pos) + ELF_DYN(fmt, *sz, d_un.d_val); - for (i = 0; pos < length; i++) + for (i = 0; get_phy_addr(&pos) < length; i++) { if (fmt->is_32b) { - status = read_u32(&virt_32, content, &pos, length, fmt->endian); + status = g_binary_content_read_u32(content, &pos, fmt->endian, &virt_32); ep = virt_32; } else { - status = read_u64(&virt_64, content, &pos, length, fmt->endian); + status = g_binary_content_read_u64(content, &pos, fmt->endian, &virt_64); ep = virt_64; } @@ -354,31 +348,30 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format) if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_PLTGOT, &item_a)) { - status = g_exe_format_translate_address_into_offset(G_EXE_FORMAT(format), - ELF_DYN(format, item_a, d_un.d_val), - &pos); + status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), + ELF_DYN(format, item_a, d_un.d_val), + &pos); if (status) { content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; /* On saute le premier élément... */ if (format->is_32b) - status = read_u32(&virt_32, content, &pos, length, format->endian); + status = g_binary_content_read_u32(content, &pos, format->endian, &virt_32); else - status = read_u64(&virt_64, content, &pos, length, format->endian); + status = g_binary_content_read_u64(content, &pos, format->endian, &virt_64); while (1) { if (format->is_32b) { - status = read_u32(&virt_32, content, &pos, length, format->endian); + status = g_binary_content_read_u32(content, &pos, format->endian, &virt_32); ep = virt_32; } else { - status = read_u64(&virt_64, content, &pos, length, format->endian); + status = g_binary_content_read_u64(content, &pos, format->endian, &virt_64); ep = virt_64; } @@ -428,9 +421,9 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format) bool get_elf_symbol_by_index(GElfFormat *format, const elf_shdr *sym, off_t index, elf_sym *symbol) { - off_t sym_start; /* Début de section */ - off_t sym_size; /* Taille de section */ - off_t offset; /* Emplacement à venir lire */ + phys_t sym_start; /* Début de section */ + phys_t sym_size; /* Taille de section */ + phys_t offset; /* Emplacement à venir lire */ get_elf_section_content(format, sym, &sym_start, &sym_size, NULL); @@ -505,9 +498,9 @@ static bool load_elf_internal_symbols(GElfFormat *format) { elf_shdr strtab; /* Section .strtab trouvée */ bool has_strtab; /* Présence de cette section */ - off_t start; /* Début de la zone à traiter */ - off_t size; /* Taille de cette même zone */ - off_t iter; /* Boucle de parcours */ + phys_t start; /* Début de la zone à traiter */ + phys_t size; /* Taille de cette même zone */ + phys_t iter; /* Boucle de parcours */ elf_sym sym; /* Symbole aux infos visées */ virt_t virt; /* Adresse virtuelle */ vmpa2t addr; /* Localisation d'une routine */ @@ -682,50 +675,48 @@ static bool load_elf_internal_symbols(GElfFormat *format) static bool find_elf_dynamic_item(const GElfFormat *format, const elf_shdr *section, int32_t type, elf_dyn *item) { bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ - off_t pos; /* Position de lecture */ - off_t tmp; /* Position écrasable */ + const GBinContent *content; /* Contenu binaire à lire */ + phys_t pos; /* Position de lecture */ + vmpa2t tmp; /* Position écrasable */ int32_t tag32; /* Type de l'entrée (32 bits) */ int64_t tag64; /* Type de l'entrée (64 bits) */ result = true; content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; for (pos = ELF_SHDR(format, *section, sh_offset); - pos < length/* FIXME !! + xploit */ && result; + result; pos += ELF_SIZEOF_DYN(format)) { - tmp = pos; + init_vmpa(&tmp, pos, VMPA_NO_VIRTUAL); if (format->is_32b) { - result = read_s32(&tag32, content, &tmp, length, format->endian); + result = g_binary_content_read_s32(content, &tmp, format->endian, &tag32); if (tag32 == type) break; } else { - result = read_s64(&tag64, content, &tmp, length, format->endian); + result = g_binary_content_read_s64(content, &tmp, format->endian, &tag64); if (tag64 == type) break; } } - result &= (pos < length); - if (result) { + init_vmpa(&tmp, pos, VMPA_NO_VIRTUAL); + if (format->is_32b) { - result = read_s32(&item->dyn32.d_tag, content, &pos, length, format->endian); - result &= read_s32(&item->dyn32.d_un.d_val, content, &pos, length, format->endian); + result = g_binary_content_read_s32(content, &tmp, format->endian, &item->dyn32.d_tag); + result &= g_binary_content_read_s32(content, &tmp, format->endian, &item->dyn32.d_un.d_val); } else { - result = read_s64(&item->dyn64.d_tag, content, &pos, length, format->endian); - result &= read_s64(&item->dyn64.d_un.d_val, content, &pos, length, format->endian); + result = g_binary_content_read_s64(content, &tmp, format->endian, &item->dyn64.d_tag); + result &= g_binary_content_read_s64(content, &tmp, format->endian, &item->dyn64.d_un.d_val); } } |