summaryrefslogtreecommitdiff
path: root/src/format/elf/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/elf/symbol.c')
-rw-r--r--src/format/elf/symbol.c112
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, &sections, &count);
+
+ for (i = 0; i < count; i++)
{
+ /* Section ".symtab" */
+ get_elf_section_content(format, &sections[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, &sections[i], sh_link), &section);
+ get_elf_section_content(format, &section, &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, &sections, &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, &sections[i], &rel_start, &rel_size, NULL);
+ /* Section ".dynsym" */
- if (result)
- {
+ result &= find_elf_section_by_index(format, ELF_SHDR(format, &sections[i], sh_link), &section);
+
+ get_elf_section_content(format, &section, &dyn_start, &dyn_size, NULL);
+ /* Section ".dynstr" */
+ result &= find_elf_section_by_index(format, ELF_SHDR(format, &section, sh_link), &section);
- result = load_elf_relocation_table(format, &plt_start, &plt_size, &dyn_start, &dyn_size, &str_start, &str_size);
+ get_elf_section_content(format, &section, &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, &sections, &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, &sections[i], sh_entsize) > 0)
+ {
+ get_elf_section_content(format, &sections[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)
{