diff options
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | src/binary.c | 99 | ||||
-rw-r--r-- | src/format/elf/e_elf.c | 128 | ||||
-rw-r--r-- | src/format/elf/e_elf.h | 5 | ||||
-rw-r--r-- | src/format/elf/elf-int.h | 23 | ||||
-rw-r--r-- | src/format/elf/section.c | 3 | ||||
-rw-r--r-- | src/format/exe_format-int.h | 23 | ||||
-rw-r--r-- | src/format/exe_format.c | 136 | ||||
-rw-r--r-- | src/format/exe_format.h | 25 |
10 files changed, 425 insertions, 41 deletions
@@ -1,3 +1,25 @@ +2008-10-12 Cyrille Bagard <nocbos@gmail.com> + + * src/binary.c: + Use the new functions to analyze code. + + * src/format/elf/e_elf.c: + * src/format/elf/e_elf.h: + Provide default code parts to analyze. + + * src/format/elf/elf-int.h: + Try to support both 32 and 64 bits architectures. + + * src/format/elf/section.c: + Fix a bug if no section name is found. + + * src/format/exe_format.c: + * src/format/exe_format.h: + Add functions to handle given parts of binary code. + + * src/format/exe_format-int.h: + Provide default code parts to analyze. + 2008-10-05 Cyrille Bagard <nocbos@gmail.com> * src/binary.c: diff --git a/Makefile.am b/Makefile.am index 02f2409..2773ce2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ EXTRA_DIST = config.rpath config.rpath ChangeLog -SUBDIRS = po src +SUBDIRS = src ACLOCAL_AMFLAGS = -I m4 diff --git a/src/binary.c b/src/binary.c index 8de0bdb..f9cc906 100644 --- a/src/binary.c +++ b/src/binary.c @@ -351,6 +351,10 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel) asm_processor *proc; asm_instr *instr; + bin_part **parts; + size_t parts_count; + + char **comments; uint64_t *offsets; size_t comments_count; @@ -373,6 +377,8 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel) size_t i; + size_t k; + proc = create_x86_processor(); pos = 0; @@ -388,11 +394,11 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel) if (bin_data == NULL) return; + format = load_elf(bin_data, length); dformat = load_dwarf(bin_data, length, format); - //comments_count = get_dwarf_comments(dformat, &comments, &offsets); comments = NULL; @@ -411,60 +417,83 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel) - find_exe_section(format, ".text", &pos, &len, &base); + parts = get_elf_default_code_parts(format, &parts_count); - /*find_line_info(bin_data, &len);*/ - - /* - printf("Exiting...\n"); - exit(0); - */ - - offset = base; - - for (i = 0; i < comments_count; i++) - if (comments_list[i]->offset >= base) break; + list = NULL; + list_len = 0; gtk_snippet_set_format(snippet, format); gtk_snippet_set_processor(snippet, proc); - gtk_snippet_add_line(snippet, create_code_line_info(offset, NULL, "Simple HelloWorld !")); + for (i = 0; i < parts_count; i++) + { + get_bin_part_values(parts[i], &pos, &len, &base); - start = pos; - pos = 0; + /*find_line_info(bin_data, &len);*/ - list = NULL; - list_len = 0; + /* + printf("Exiting...\n"); + exit(0); + */ - while (pos < len) - { - offset = base + pos; + offset = base; - /* Si on a un commentaire pour cette ligne... */ - if (i < comments_count && comments_list[i]->offset == offset) - { - list = (code_line_info **)realloc(list, ++list_len * sizeof(code_line_info *)); - list[list_len - 1] = comments_list[i++]; - } + for (k = 0; k < comments_count; k++) + if (comments_list[k]->offset >= base) break; - instr = decode_instruction(proc, &bin_data[start], &pos, len, offset); - item = create_code_line_info(offset, instr, NULL); + item = create_code_line_info(offset, NULL, "Simple HelloWorld !"); list = (code_line_info **)realloc(list, ++list_len * sizeof(code_line_info *)); list[list_len - 1] = item; - //gtk_snippet_add_line(snippet, offset, instr, NULL); + start = pos; + pos = 0; + + while (pos < len) + { + offset = base + pos; + + /* Si on a un commentaire pour cette ligne... */ + if (k < comments_count && comments_list[k]->offset == offset) + { + list = (code_line_info **)realloc(list, ++list_len * sizeof(code_line_info *)); + list[list_len - 1] = comments_list[k++]; + } + + + instr = decode_instruction(proc, &bin_data[start], &pos, len, offset); + + + item = create_code_line_info(offset, instr, NULL); + + list = (code_line_info **)realloc(list, ++list_len * sizeof(code_line_info *)); + list[list_len - 1] = item; + + //gtk_snippet_add_line(snippet, offset, instr, NULL); + + + } + + + /**** + ret = munmap(bin_data, length); + ****/ + + /* + gtk_snippet_build_content(snippet); + */ + } for (i = 0; i < list_len; i++) @@ -473,16 +502,6 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel) /* TODO: free() */ } - - /**** - ret = munmap(bin_data, length); - ****/ - - /* - gtk_snippet_build_content(snippet); - */ - - handle_new_exe_on_symbols_panel(panel, format); } diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c index f716846..3aa9394 100644 --- a/src/format/elf/e_elf.c +++ b/src/format/elf/e_elf.c @@ -35,6 +35,10 @@ + + + + /****************************************************************************** * * * Paramètres : content = contenu binaire à parcourir. * @@ -53,17 +57,39 @@ elf_format *load_elf(const uint8_t *content, off_t length) elf_format *result; /* Structure à retourner */ bool test; /* Bilan d'une initialisation */ + + Elf32_Half i; + Elf32_Phdr phdr; + + size_t count; + + result = (elf_format *)calloc(1, sizeof(elf_format)); EXE_FORMAT(result)->content = content; EXE_FORMAT(result)->length = length; + EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_elf_default_code_parts; EXE_FORMAT(result)->find_section = (find_section_fc)find_elf_section; EXE_FORMAT(result)->get_symbols = (get_symbols_fc)get_elf_symbols; EXE_FORMAT(result)->resolve_symbol = (resolve_symbol_fc)resolve_elf_symbol; memcpy(&result->header, content, sizeof(Elf32_Ehdr)); + result->is_32b = true; + + + for (i = 0; i < result->header.e_phnum; i++) + { + + memcpy(&phdr, &content[result->header.e_phoff + i * result->header.e_phentsize], result->header.e_phentsize); + + + printf(" seg [0x%08x] :: %d -> %d\n", phdr.p_type, phdr.p_offset, phdr.p_filesz); + + + } + test = read_elf_section_names(result); @@ -74,6 +100,108 @@ elf_format *load_elf(const uint8_t *content, off_t length) printf("ok ? %d\n", test); + + return result; + +} + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = quantité de zones listées. [OUT] * +* * +* Description : Fournit les références aux zones de code à analyser. * +* * +* Retour : Zones de code à analyser. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bin_part **get_elf_default_code_parts(const elf_format *format, size_t *count) +{ + bin_part **result; /* Tableau à retourner */ + bin_part *part; /* Partie à intégrer à la liste*/ + off_t offset; /* Position physique */ + off_t size; /* Taille de la partie */ + uint64_t voffset; /* Adresse virtuelle éventuelle*/ + int i; /* Boucle de parcours */ + Elf_Shdr shdr; /* En-tête de programme ELF */ + + result = NULL; + *count = 0; + + if (format->sec_size > 0) + { + if (find_elf_section(format, ".init", &offset, &size, &voffset)) + { + part = create_bin_part(); + + set_bin_part_name(part, ".init"); + set_bin_part_values(part, offset, size, voffset); + + result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); + result[*count - 1] = part; + + } + + if (find_elf_section(format, ".text", &offset, &size, &voffset)) + { + part = create_bin_part(); + + set_bin_part_name(part, ".text"); + set_bin_part_values(part, offset, size, voffset); + + result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); + result[*count - 1] = part; + + } + + if (find_elf_section(format, ".fini", &offset, &size, &voffset)) + { + part = create_bin_part(); + + set_bin_part_name(part, ".fini"); + set_bin_part_values(part, offset, size, voffset); + + result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); + result[*count - 1] = part; + + } + + } + + /* Si aucune section n'a été trouvée... */ + + if (*count == 0) + for (i = 0; i < format->header.e_shnum; i++) + { + offset = format->header.e_shoff + format->header.e_shentsize * i; + if ((offset + format->header.e_shentsize) >= EXE_FORMAT(format)->length) break; + + memcpy(&shdr, &EXE_FORMAT(format)->content[offset], format->header.e_shentsize); + + if (ELF_SHDR(format, shdr, sh_flags) & SHF_EXECINSTR) + { + part = create_bin_part(); + + /* TODO : nom */ + + set_bin_part_values(part, ELF_SHDR(format, shdr, sh_offset), + ELF_SHDR(format, shdr, sh_size), + ELF_SHDR(format, shdr, sh_addr)); + + result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); + result[*count - 1] = part; + + } + + } + return result; } diff --git a/src/format/elf/e_elf.h b/src/format/elf/e_elf.h index e101fc6..b11fb24 100644 --- a/src/format/elf/e_elf.h +++ b/src/format/elf/e_elf.h @@ -42,6 +42,11 @@ typedef struct _elf_format elf_format; /* Prend en charge un nouvel ELF. */ elf_format *load_elf(const uint8_t *, off_t); + + +/* Fournit les références aux zones de code à analyser. */ +bin_part **get_elf_default_code_parts(const elf_format *, size_t *); + /* Récupère tous les symboles présents dans le contenu binaire. */ size_t get_elf_symbols(const elf_format *, char ***, SymbolType **, uint64_t **); diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h index 2ec33c3..f366c71 100644 --- a/src/format/elf/elf-int.h +++ b/src/format/elf/elf-int.h @@ -50,6 +50,7 @@ struct _elf_format exe_format dummy; /* A laisser en premier */ Elf32_Ehdr header; /* En-tête du format */ + bool is_32b; /* Format du binaire */ char *sec_names; /* Noms des sections */ size_t sec_size; /* Taille de ces définitions */ @@ -61,6 +62,28 @@ struct _elf_format +/* En-tête de section ELF */ +typedef union _Elf_Shdr +{ + Elf32_Shdr section32; /* Version 32 bits */ + Elf64_Shdr section64; /* Version 64 bits */ + +} Elf_Shdr; + +#define ELF_SHDR(fmt, sec, fld) (fmt->is_32b ? sec.section32.fld : sec.section64.fld) + + +/* En-tête de programme ELF */ +typedef union _Elf_Phdr +{ + Elf32_Phdr header32; /* Version 32 bits */ + Elf64_Phdr header64; /* Version 64 bits */ + +} Elf_Phdr; + +#define ELF_PHDR(fmt, hdr, fld) (fmt->is_32b ? hdr.header32.fld : hdr.header64.fld) + + #endif /* _FORMAT_ELF_ELF_INT_H */ diff --git a/src/format/elf/section.c b/src/format/elf/section.c index a055f47..f16e002 100644 --- a/src/format/elf/section.c +++ b/src/format/elf/section.c @@ -130,6 +130,9 @@ bool find_elf_section(const elf_format *format, const char *target, off_t *offse Elf32_Half i; Elf32_Shdr data; + /* Si on perd notre temps... */ + if (format->sec_size == 0) return false; + result = false; for (i = 0; i < format->header.e_shnum; i++) diff --git a/src/format/exe_format-int.h b/src/format/exe_format-int.h index d1f9381..4dcf1c4 100644 --- a/src/format/exe_format-int.h +++ b/src/format/exe_format-int.h @@ -29,6 +29,28 @@ +/* ------------------------ MANIPULATION DES PARTIES DE CODE ------------------------ */ + + +/* Description d'une partie binaire */ +struct _bin_part +{ + char *name; /* Désignation humaine */ + + off_t offset; /* Position physique */ + off_t size; /* Taille de la partie */ + uint64_t voffset; /* Adresse virtuelle éventuelle*/ + +}; + + + + + + +/* Fournit les références aux zones de code à analyser. */ +typedef bin_part ** (* get_def_parts_fc) (const exe_format *, size_t *); + /* Recherche une section donnée au sein de binaire. */ typedef bool (* find_section_fc) (const exe_format *, const char *, off_t *, off_t *, uint64_t *); @@ -46,6 +68,7 @@ struct _exe_format const uint8_t *content; /* Contenu binaire à étudier */ off_t length; /* Taille de ce contenu */ + get_def_parts_fc get_def_parts; /* Liste des parties de code */ find_section_fc find_section; /* Recherche d'une section */ get_symbols_fc get_symbols; /* Liste des symboles présents */ resolve_symbol_fc resolve_symbol; /* Recherche de symboles */ diff --git a/src/format/exe_format.c b/src/format/exe_format.c index 1481d22..bc6cfff 100644 --- a/src/format/exe_format.c +++ b/src/format/exe_format.c @@ -24,10 +24,146 @@ #include "exe_format.h" +#include <malloc.h> +#include <string.h> + + #include "exe_format-int.h" +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION DES PARTIES DE CODE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une description de partie de code vierge. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bin_part *create_bin_part(void) +{ + bin_part *result; /* Structure à renvoyer */ + + result = (bin_part *)calloc(1, sizeof(bin_part)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : part = description de partie à mettre à jour. * +* name = nom à donner à la partie. * +* * +* Description : Attribue une description humaine à une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_bin_part_name(bin_part *part, const char *name) +{ + if (part->name != NULL) free(part->name); + + part->name = strdup(name); + +} + + +/****************************************************************************** +* * +* Paramètres : part = description de partie à mettre à jour. * +* offset = position de la section à conserver. * +* size = taille de la section à conserver. * +* voffset = adresse virtuelle de la section à conserver. * +* * +* Description : Définit les valeurs utiles d'une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_bin_part_values(bin_part *part, off_t offset, off_t size, uint64_t voffset) +{ + part->offset = offset; + part->size = size; + part->voffset = voffset; + +} + + +/****************************************************************************** +* * +* Paramètres : part = description de partie à mettre à jour. * +* offset = position de la section à donner. [OUT] * +* size = taille de la section à donner. [OUT] * +* voffset = adresse virtuelle de la section à donner. [OUT] * +* * +* Description : Fournit les valeurs utiles d'une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void get_bin_part_values(const bin_part *part, off_t *offset, off_t *size, uint64_t *voffset) +{ + *offset = part->offset; + *size = part->size; + *voffset = part->voffset; + +} + + +/****************************************************************************** +* * +* Paramètres : part = description de partie à effacer. * +* * +* Description : Supprime de la mémoire une description de partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_bin_part(bin_part *part) +{ + if (part->name != NULL) free(part->name); + + free(part); + +} + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION DES PARTIES DE CODE */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** diff --git a/src/format/exe_format.h b/src/format/exe_format.h index f859e13..24ebbcc 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -31,6 +31,31 @@ +/* ------------------------ MANIPULATION DES PARTIES DE CODE ------------------------ */ + + +/* Description d'une partie binaire */ +typedef struct _bin_part bin_part; + + +/* Crée une description de partie de code vierge. */ +bin_part *create_bin_part(void); + +/* Attribue une description humaine à une partie de code. */ +void set_bin_part_name(bin_part *, const char *); + +/* Définit les valeurs utiles d'une partie de code. */ +void set_bin_part_values(bin_part *, off_t, off_t, uint64_t); + +/* Fournit les valeurs utiles d'une partie de code. */ +void get_bin_part_values(const bin_part *, off_t *, off_t *, uint64_t *); + +/* Supprime de la mémoire une description de partie de code. */ +void delete_bin_part(bin_part *); + + + + /* Support générique d'un format d'exécutable */ typedef struct _exe_format exe_format; |