diff options
Diffstat (limited to 'src/format/elf/symbol.c')
-rw-r--r-- | src/format/elf/symbol.c | 112 |
1 files changed, 82 insertions, 30 deletions
diff --git a/src/format/elf/symbol.c b/src/format/elf/symbol.c index 8fa5690..4b7740d 100644 --- a/src/format/elf/symbol.c +++ b/src/format/elf/symbol.c @@ -84,74 +84,105 @@ bool load_elf_symbol_table_64(elf_format *, const off_t *, const off_t *, const bool load_elf_symbols(elf_format *format) { bool result; /* Bilan à retourner */ - - + Elf_Shdr *sections; /* Groupe de sections trouvées */ + size_t count; /* Quantité de données */ + size_t i; /* Boucle de parcours */ + Elf_Shdr section; /* Section trouvée ou non */ off_t sym_start; /* Début de section */ off_t sym_size; /* Taille de section */ off_t str_start; /* Début de section */ off_t str_size; /* Taille de section */ - - - off_t plt_start; /* Début de section */ - off_t plt_size; /* Taille de section */ + off_t rel_start; /* Début de section */ + off_t rel_size; /* Taille de section */ off_t dyn_start; /* Début de section */ off_t dyn_size; /* Taille de section */ asm_instr **instructions; /* Instructions décodées */ - size_t count; /* Quantité d'instructions */ - result = find_elf_section(format, ".symtab", &sym_start, &sym_size, NULL); + result = true; - result &= find_elf_section(format, ".strtab", &str_start, &str_size, NULL); + /* Table des symboles */ - if (result) + find_elf_section_by_type(format, SHT_SYMTAB, §ions, &count); + + for (i = 0; i < count; i++) { + /* Section ".symtab" */ + get_elf_section_content(format, §ions[i], &sym_start, &sym_size, NULL); + /* Section ".strtab" */ - result = load_elf_symbol_table_32(format, &sym_start, &sym_size, &str_start, &str_size); + result &= find_elf_section_by_index(format, ELF_SHDR(format, §ions[i], sh_link), §ion); + get_elf_section_content(format, §ion, &str_start, &str_size, NULL); + if (result) + { - } + result = load_elf_symbol_table_32(format, &sym_start, &sym_size, &str_start, &str_size); + } + } - result = find_elf_section(format, ".rel.plt", &plt_start, &plt_size, NULL); + /* Relocalisations dynamiques */ - result &= find_elf_section(format, ".dynsym", &dyn_start, &dyn_size, NULL); + find_elf_section_by_type(format, SHT_REL, §ions, &count); - result &= find_elf_section(format, ".dynstr", &str_start, &str_size, NULL); + for (i = 0; i < count; i++) + { + /* Section ".rel.xxx" */ + get_elf_section_content(format, §ions[i], &rel_start, &rel_size, NULL); + /* Section ".dynsym" */ - if (result) - { + result &= find_elf_section_by_index(format, ELF_SHDR(format, §ions[i], sh_link), §ion); + + get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); + /* Section ".dynstr" */ + result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - result = load_elf_relocation_table(format, &plt_start, &plt_size, &dyn_start, &dyn_size, &str_start, &str_size); + get_elf_section_content(format, §ion, &str_start, &str_size, NULL); + /* Récupération (première partie) */ if (result) { - instructions = decode_elf_relocations(format, &count); - translate_elf_relocations(format, instructions, count); + result = load_elf_relocation_table(format, &rel_start, &rel_size, &dyn_start, &dyn_size, &str_start, &str_size); - /* TODO : free instructions */ + } + } + + free(sections); + + /* Récupération (seconde partie) */ + + if (result) + { + instructions = decode_elf_relocations(format, &count); + + translate_elf_relocations(format, instructions, count); + + /* TODO : free instructions */ } + + return result; } @@ -446,6 +477,9 @@ asm_instr **decode_elf_relocations(elf_format *format, size_t *count) off_t rel_start; /* Début de section */ off_t rel_size; /* Taille de section */ uint64_t rel_vaddress; /* Adresse virtuelle associée */ + Elf_Shdr *sections; /* Groupe de sections trouvées */ + size_t sec_count; /* Quantité de données */ + size_t i; /* Boucle de parcours */ off_t pos; /* Tête de lecture */ uint64_t offset; /* Adresse virtuelle courante */ asm_instr *instr; /* Instruction décodée */ @@ -456,17 +490,35 @@ asm_instr **decode_elf_relocations(elf_format *format, size_t *count) result = NULL; *count = 0; - if (find_elf_section(format, ".plt", &rel_start, &rel_size, &rel_vaddress)) - for (pos = 0; pos < rel_size; ) - { - offset = rel_vaddress + pos; + if (!find_elf_section_content_by_name(format, ".plt", &rel_start, &rel_size, &rel_vaddress)) + { + printf("No .plt section found ! Trying to guess it...\n"); - instr = decode_instruction(proc, &EXE_FORMAT(format)->content[rel_start], &pos, rel_size, offset); + find_elf_section_by_type(format, SHT_PROGBITS, §ions, &sec_count); - result = (asm_instr **)realloc(result, ++(*count) * sizeof(asm_instr *)); - result[*count - 1] = instr; + for (i = 0; i < sec_count; i++) + if (ELF_SHDR(format, §ions[i], sh_entsize) > 0) + { + get_elf_section_content(format, §ions[i], &rel_start, &rel_size, &rel_vaddress); + break; + } - } + free(sections); + + if (i == sec_count) return NULL; + + } + + for (pos = 0; pos < rel_size; ) + { + offset = rel_vaddress + pos; + + instr = decode_instruction(proc, &EXE_FORMAT(format)->content[rel_start], &pos, rel_size, offset); + + result = (asm_instr **)realloc(result, ++(*count) * sizeof(asm_instr *)); + result[*count - 1] = instr; + + } return result; @@ -497,7 +549,7 @@ void translate_elf_relocations(elf_format *format, asm_instr **instructions, siz for (i = 0; (i + 2) < count; ) { - if (instructions[i]->type == AIT_JUMP + if ((instructions[i]->type == AIT_JUMP || instructions[i]->type == AIT_CALL) && instructions[i + 1]->type == AIT_PUSH && instructions[i + 2]->type == AIT_JUMP) { |