diff options
72 files changed, 3835 insertions, 1650 deletions
| @@ -1,3 +1,138 @@ +09-08-09  Cyrille Bagard <nocbos@gmail.com> + +	* plugins/stackvars/operand.c: +	* plugins/stackvars/stackvars.c: +	* src/analysis/binary.c: +	* src/analysis/binary.h: +	* src/analysis/delayed.c: +	* src/analysis/delayed.h: +	* src/analysis/line_code.c: +	* src/analysis/roptions.c: +	* src/analysis/roptions.h: +	* src/arch/artificial.c: +	* src/arch/immediate.c: +	* src/arch/instruction.c: +	* src/arch/instruction.h: +	* src/arch/instruction-int.h: +	* src/arch/jvm/instruction.c: +	* src/arch/jvm/operand.c: +	* src/arch/mips/instruction.c: +	* src/arch/mips/operand.c: +	* src/arch/operand.c: +	* src/arch/operand.h: +	* src/arch/operand-int.h: +	* src/arch/processor.c: +	* src/arch/processor.h: +	* src/arch/x86/instruction.c: +	* src/arch/x86/operand.c: +	Update the code (mainly exe_format -> GExeFormat). + +	* src/common/endianness.c: +	* src/common/endianness.h: +	Read uint16_t in little endian, uint64_t and signed values. + +	* src/editor.c: +	Update the code loading the strings panel. + +	* src/format/dwarf/dwarf.c: +	* src/format/dwarf/dwarf.h: +	New entries: create a new interface for the Dwarf debug format. + +	* src/format/dwarf/Makefile.am: +	Only keep dwarf.[ch] in libformatdwarf_la_SOURCES. + +	* src/format/elf/e_elf.c: +	* src/format/elf/e_elf.h: +	Deleted entries: see elf.[ch] instead. + +	* src/format/elf/elf.c: +	* src/format/elf/elf_def.h: +	* src/format/elf/elf.h: +	New entries: define a new interface for the ELF format and do not rely +	on /usr/include/elf.h anymore. + +	* src/format/elf/elf-int.c: +	New entry: provide functions to read ELF items (32bits or 64bits). + +	* src/format/elf/elf-int.h: +	* src/format/elf/helper_x86.c: +	* src/format/elf/helper_x86.h: +	Update the code handling the ELF format. + +	* src/format/elf/Makefile.am: +	Add the elf-int.c, elf.[ch], elf_def.h and symbols.[ch] files to libformatelf_la_SOURCES, +	remove symbol.[ch] and disable helper_mips.[ch]. + +	* src/format/elf/section.c: +	* src/format/elf/section.h: +	* src/format/elf/strings.c: +	* src/format/elf/strings.h: +	Update the code handling the ELF format. + +	* src/format/elf/symbol.c: +	* src/format/elf/symbol.h: +	Renamed entries: see symbols.[ch]. + +	* src/format/elf/symbols.c: +	* src/format/elf/symbols.h: +	Update the code handling the ELF format. + +	* src/format/executable.c: +	* src/format/executable.h: +	* src/format/executable-int.h: +	New entries: define the common properties for all executable formats. + +	* src/format/exe_format.h: +	Disable the content of this file before removal. + +	* src/format/format.c: +	* src/format/format.h: +	* src/format/format-int.h: +	New entries: define the common properties for all formats. + +	* src/format/Makefile.am: +	Disable Java and PE building. Define the new libformat_la_SOURCES with executable-int.h, +	executable.[ch], format-int.h, format.[ch], part.[ch] and symbol.[ch]. + +	* src/format/part.c: +	* src/format/part.h: +	New entries: manage binary parts. + +	* src/format/symbol.c: +	* src/format/symbol.h: +	New entries: manage binary symbols (objects, functions and strings). + +	* src/gtkext/gtkgraphview.c: +	Update the code and remove some GCC warnings. + +	* src/main.c: +	Init all formats. + +	* src/Makefile.am: +	Remove the pan_strings.[ch] from openida_SOURCES. + +	* src/panel/Makefile.am: +	Add the strings.[ch] files to libpanel_a_SOURCES. + +	* src/panel/panels.c: +	* src/panel/panels.h: +	Load the strings panel. + +	* src/panel/strings.c: +	* src/panel/strings.h: +	New entries: display all found strings. + +	* src/panel/symbols.c: +	* src/panel/symbols.h: +	Update the code using the new symbols. + +	* src/pan_strings.c: +	* src/pan_strings.h: +	Renamed entries: see panel/strings.[ch]. + +	* src/project.c: +	Display found strings again. +  09-08-01  Cyrille Bagard <nocbos@gmail.com>  	* configure.ac: diff --git a/plugins/stackvars/operand.c b/plugins/stackvars/operand.c index 321312a..6eff546 100644 --- a/plugins/stackvars/operand.c +++ b/plugins/stackvars/operand.c @@ -57,7 +57,7 @@ static void g_stack_var_operand_class_init(GStackVarOperandClass *);  static void g_stack_var_operand_init(GStackVarOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_stack_var_operand_get_text(const GStackVarOperand *, const exe_format *, AsmSyntax); +static char *g_stack_var_operand_get_text(const GStackVarOperand *, const GExeFormat *, AsmSyntax);  /* Indique le type défini pour un opérande de substitution pour variable de pile. */ @@ -145,7 +145,7 @@ GArchOperand *g_stack_var_operand_new(const GArchOperand *child)  *                                                                             *  ******************************************************************************/ -static char *g_stack_var_operand_get_text(const GStackVarOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_stack_var_operand_get_text(const GStackVarOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */ diff --git a/plugins/stackvars/stackvars.c b/plugins/stackvars/stackvars.c index 9a7b965..5d0da59 100644 --- a/plugins/stackvars/stackvars.c +++ b/plugins/stackvars/stackvars.c @@ -27,7 +27,8 @@  #include <analysis/line_code.h>  #include <analysis/prototype.h>  #include <arch/x86/operand.h> -#include <format/exe_format.h> +#include <format/executable.h> +#include <format/format.h>  #include "operand.h" @@ -100,7 +101,7 @@ G_MODULE_EXPORT bool execute_action_on_binary(GOpenidaBinary *binary, PluginActi  {      bool result;                            /* Bilan à retourner           */      GRenderingLine *lines;                  /* Lignes de rendu             */ -    exe_format *format;                     /* Format du binaire fourni    */ +    GExeFormat *format;                     /* Format du binaire fourni    */      GBinRoutine **routines;                 /* Liste des routines trouvées */      size_t routines_count;                  /* Nombre de ces routines      */      size_t i;                               /* Boucle de parcours          */ @@ -112,7 +113,7 @@ G_MODULE_EXPORT bool execute_action_on_binary(GOpenidaBinary *binary, PluginActi      lines = g_openida_binary_get_lines(binary);      format = g_openida_binary_get_format(binary); -    routines = get_all_exe_routines(format, &routines_count); +    routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);      for (i = 0; i < routines_count; i++)          result |= replace_stack_vars_in_routine(routines[i], lines); diff --git a/src/Makefile.am b/src/Makefile.am index fd11575..3685409 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,7 +66,6 @@ openida_SOURCES = 						\  	dlg_sections.h dlg_sections.c		\  	editor.h editor.c					\  	main.c								\ -	pan_strings.h pan_strings.c			\  	params.h params.c					\  	project.h project.c					\  	shell.h shell.c						\ diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 9351c48..38d3d19 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -41,6 +41,7 @@  #include "line_prologue.h"  #include "prototype.h"  #include "../common/extstr.h" +#include "../format/format.h"  #include "../panel/log.h"  #include "../plugins/pglist.h" @@ -67,7 +68,7 @@ struct _GOpenidaBinary      off_t bin_length;                       /* Taille des données brutes   */      bin_t *bin_data;                        /* Données binaires brutes     */ -    exe_format *format;                     /* Format du binaire           */ +    GExeFormat *format;                     /* Format du binaire           */      GArchProcessor *proc;                   /* Architecture du binaire     */      GRenderingLine *lines;                  /* Lignes de rendu en place    */ @@ -174,10 +175,10 @@ GOpenidaBinary *g_openida_binary_new_from_file(const char *filename)      result->bin_data = map_binary_file(filename, &result->bin_length);      if (result->bin_data == NULL) goto lbf_error; -    result->format = load_new_exe_format(result->bin_data, result->bin_length); +    result->format = G_EXE_FORMAT(load_new_format(FMT_EXEC, result->bin_data, result->bin_length));      if (result->format == NULL) goto lbf_error; -    switch (get_exe_target_machine(result->format)) +    switch (g_exe_format_get_target_machine(result->format))      {          case FTM_JVM:              log_simple_message(LMT_INFO, _("Detected architecture: Java Virtual Machine")); @@ -312,14 +313,13 @@ bool g_openida_binary_save(const GOpenidaBinary *binary, xmlDocPtr xdoc, xmlXPat  void g_openida_binary_analyse(GOpenidaBinary *binary)  {      GDelayedManager *manager;               /* Gestionnaire de différés    */ -    bin_part **parts;                       /* Parties d'élément binaire   */ +    GBinPart **parts;                       /* Parties d'élément binaire   */      size_t parts_count;                     /* Nombre de ces parties       */      manager = get_delayed_manager(); -    parts = /* !!! */get_elf_default_code_parts(binary->format, &parts_count); -    qsort(parts, parts_count, sizeof(bin_part *), compare_bin_parts); - +    parts = g_exe_format_get_parts(binary->format, &parts_count); +    qsort(parts, parts_count, sizeof(GBinPart *), g_binary_part_compare);      g_signal_connect(manager, "disassembly-completed", @@ -407,7 +407,7 @@ bin_t *g_openida_binary_get_data(const GOpenidaBinary *binary, off_t *length)  *                                                                             *  ******************************************************************************/ -exe_format *g_openida_binary_get_format(const GOpenidaBinary *binary) +GExeFormat *g_openida_binary_get_format(const GOpenidaBinary *binary)  {      return binary->format; @@ -623,7 +623,8 @@ void ack_completed_disassembly(GDelayedManager *manager, GOpenidaBinary *binary, -    line = g_rendering_line_find_by_address(lines, NULL, get_exe_entry_point(binary->format)); +    line = g_rendering_line_find_by_address(lines, NULL, +                                            g_exe_format_get_entry_point(binary->format));      if (line != NULL) g_rendering_line_add_flag(line, RLF_ENTRY_POINT);      /* Action post-désassemblage */ diff --git a/src/analysis/binary.h b/src/analysis/binary.h index e6fc698..0a8d0e9 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -31,7 +31,7 @@  #include "line.h"  #include "../arch/processor.h" -#include "../format/exe_format.h" +#include "../format/executable.h"  #include "../xml.h" @@ -75,7 +75,7 @@ const char *g_openida_binary_get_filename(const GOpenidaBinary *);  bin_t *g_openida_binary_get_data(const GOpenidaBinary *, off_t *);  /* Fournit le format de fichier reconnu dans le contenu binaire. */ -exe_format *g_openida_binary_get_format(const GOpenidaBinary *); +GExeFormat *g_openida_binary_get_format(const GOpenidaBinary *);  /* Fournit les options d'affichage définies pour le binaire. */  GRenderingOptions *g_openida_binary_get_options(const GOpenidaBinary *); diff --git a/src/analysis/delayed.c b/src/analysis/delayed.c index 1906713..6ec03e8 100644 --- a/src/analysis/delayed.c +++ b/src/analysis/delayed.c @@ -30,6 +30,7 @@  #include "line_code.h"  #include "line_comment.h"  #include "../common/dllist.h" +#include "../format/format.h"  #include "../gtkext/gtkextstatusbar.h"  #include "../gtkext/iodamarshal.h" @@ -49,7 +50,7 @@ typedef struct _disassembly_task      DL_LIST_ITEM(link);                     /* Lien vers les maillons      */ -    bin_part **parts;                       /* Parties binaires à traiter  */ +    GBinPart **parts;                       /* Parties binaires à traiter  */      size_t count;                           /* Nombre de ces parties       */  } disassembly_task; @@ -60,7 +61,7 @@ typedef struct _disassembly_task  /* Crée un tâche de désassemblage différé. */ -static disassembly_task *create_disassembly_task(GOpenidaBinary *, bin_part **, size_t); +static disassembly_task *create_disassembly_task(GOpenidaBinary *, GBinPart **, size_t);  /* Efface une tâche de désassemblage de la mémoire. */  static void delete_disassembly_task(disassembly_task *); @@ -142,7 +143,7 @@ static vmpa_t find_best_ending_address_for_routine(GRenderingLine *, size_t, con  *                                                                             *  ******************************************************************************/ -static disassembly_task *create_disassembly_task(GOpenidaBinary *owner, bin_part **parts, size_t count) +static disassembly_task *create_disassembly_task(GOpenidaBinary *owner, GBinPart **parts, size_t count)  {      disassembly_task *result;               /* Tâche à retourner           */ @@ -321,7 +322,7 @@ static void *process_disassemblies(GDelayedManager *manager)          g_mutex_unlock(manager->disass_mutex); -        routines = get_all_exe_routines(g_openida_binary_get_format(task->owner), &routines_count); +        routines = g_binary_format_get_routines(G_BIN_FORMAT(g_openida_binary_get_format(task->owner)), &routines_count);          qsort(routines, routines_count, sizeof(GBinRoutine *), g_binary_routine_rcompare);          /* Première étape */ @@ -412,7 +413,7 @@ static GRenderingLine *disassemble_binary_parts(disassembly_task *task, GBinRout      for (i = 0; i < task->count; i++)      { -        get_bin_part_values(task->parts[i], NULL, &len, NULL); +        g_binary_part_get_values(task->parts[i], NULL, &len, NULL);          sum += len;      } @@ -420,7 +421,7 @@ static GRenderingLine *disassemble_binary_parts(disassembly_task *task, GBinRout      for (i = 0; i < task->count; i++)      { -        get_bin_part_values(task->parts[i], &pos, &len, &base); +        g_binary_part_get_values(task->parts[i], &pos, &len, &base);          /* Décodage des instructions */ @@ -715,7 +716,7 @@ static vmpa_t find_best_ending_address_for_routine(GRenderingLine *line, size_t  *                                                                             *  ******************************************************************************/ -void g_delayed_manager_schedule_disassembly(GDelayedManager *manager, GOpenidaBinary *binary, bin_part **parts, size_t count) +void g_delayed_manager_schedule_disassembly(GDelayedManager *manager, GOpenidaBinary *binary, GBinPart **parts, size_t count)  {      disassembly_task *task;                 /* Nouveau désassemblage       */ diff --git a/src/analysis/delayed.h b/src/analysis/delayed.h index 5548531..437f968 100644 --- a/src/analysis/delayed.h +++ b/src/analysis/delayed.h @@ -54,7 +54,7 @@ typedef struct _GDelayedManagerClass GDelayedManagerClass;  GType g_delayed_manager_get_type(void);  /* Place un nouveau désassemblage en attente. */ -void g_delayed_manager_schedule_disassembly(GDelayedManager *, GOpenidaBinary *, bin_part **, size_t); +void g_delayed_manager_schedule_disassembly(GDelayedManager *, GOpenidaBinary *, GBinPart **, size_t); diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c index c44899e..697dd7d 100644 --- a/src/analysis/line_code.c +++ b/src/analysis/line_code.c @@ -29,6 +29,7 @@  #include "line-int.h" +#include "../format/format.h" @@ -220,7 +221,7 @@ void g_code_line_refresh_markup(GCodeLine *line, MainRendering rendering)      if (show_code)      { -        exe_content = get_exe_content(g_rendering_options_get_format(line->options), NULL); +        exe_content = g_binary_format_get_content(G_BIN_FORMAT(g_rendering_options_get_format(line->options)), NULL);          max_bin_len = &G_RENDERING_LINE(line)->max_bin_len[rendering];          bin_code = (char *)calloc(*max_bin_len + 1, sizeof(char)); diff --git a/src/analysis/roptions.c b/src/analysis/roptions.c index aab8ef7..4c49a15 100644 --- a/src/analysis/roptions.c +++ b/src/analysis/roptions.c @@ -28,7 +28,7 @@  /* Options de représentation (instance) */  struct _GRenderingOptions  { -    exe_format *format;                     /* Format du contenu bianire   */ +    GExeFormat *format;                     /* Format du contenu bianire   */      GArchProcessor *proc;                   /* Architecture utilisée       */      bool show_address[MRD_COUNT];           /* Affichage de l'adresse ?    */ @@ -105,7 +105,7 @@ static void g_rendering_options_init(GRenderingOptions *options)  *                                                                             *  ******************************************************************************/ -GRenderingOptions *g_rendering_options_new(exe_format *format, GArchProcessor *proc) +GRenderingOptions *g_rendering_options_new(GExeFormat *format, GArchProcessor *proc)  {      GRenderingOptions *result;              /* Structure à retourner       */ @@ -131,7 +131,7 @@ GRenderingOptions *g_rendering_options_new(exe_format *format, GArchProcessor *p  *                                                                             *  ******************************************************************************/ -exe_format *g_rendering_options_get_format(const GRenderingOptions *options) +GExeFormat *g_rendering_options_get_format(const GRenderingOptions *options)  {      return options->format; diff --git a/src/analysis/roptions.h b/src/analysis/roptions.h index 184f59a..85dc5fb 100644 --- a/src/analysis/roptions.h +++ b/src/analysis/roptions.h @@ -30,7 +30,7 @@  #include "../arch/processor.h" -#include "../format/exe_format.h" +#include "../format/executable.h" @@ -63,10 +63,10 @@ typedef struct _GRenderingOptionsClass GRenderingOptionsClass;  GType g_rendering_options_get_type(void);  /* Crée un un groupe d'options pour le rendu des lignes. */ -GRenderingOptions *g_rendering_options_new(exe_format *, GArchProcessor *); +GRenderingOptions *g_rendering_options_new(GExeFormat *, GArchProcessor *);  /* Fournit le format du contenu binaire représenté. */ -exe_format *g_rendering_options_get_format(const GRenderingOptions *); +GExeFormat *g_rendering_options_get_format(const GRenderingOptions *);  /* Fournit l'architecture du contenu binaire représenté. */  GArchProcessor *g_rendering_options_get_processor(const GRenderingOptions *); diff --git a/src/arch/artificial.c b/src/arch/artificial.c index 6783579..a1fa56e 100644 --- a/src/arch/artificial.c +++ b/src/arch/artificial.c @@ -54,7 +54,7 @@ static void g_db_instruction_class_init(GDbInstructionClass *);  static void g_db_instruction_init(GDbInstruction *);  /* Traduit une instruction en version humainement lisible. */ -static const char *g_db_instruction_get_text(const GDbInstruction *, const exe_format *, AsmSyntax); +static const char *g_db_instruction_get_text(const GDbInstruction *, const GExeFormat *, AsmSyntax);  /* Informe sur une éventuelle référence à une autre instruction. */  static InstructionLinkType g_db_instruction_get_link(const GDbInstruction *, vmpa_t *); @@ -166,7 +166,7 @@ GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, off_t *pos,  *                                                                             *  ******************************************************************************/ -static const char *g_db_instruction_get_text(const GDbInstruction *instr, const exe_format *format, AsmSyntax syntax) +static const char *g_db_instruction_get_text(const GDbInstruction *instr, const GExeFormat *format, AsmSyntax syntax)  {      return "db"; diff --git a/src/arch/immediate.c b/src/arch/immediate.c index c57919f..f8bba35 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -31,6 +31,7 @@  #include "operand-int.h"  #include "../common/extstr.h" +#include "../format/format.h" @@ -83,7 +84,7 @@ static void g_imm_operand_class_init(GImmOperandClass *);  static void g_imm_operand_init(GImmOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_imm_operand_get_text(const GImmOperand *, const exe_format *, AsmSyntax); +static char *g_imm_operand_get_text(const GImmOperand *, const GExeFormat *, AsmSyntax);  /* Indique le type défini pour un opérande de valeur numérique. */ @@ -337,12 +338,13 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -static char *g_imm_operand_get_text(const GImmOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_imm_operand_get_text(const GImmOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */ -    char *label;                            /* Etiquette de symbole        */ -    SymbolType symtype;                     /* Type de symbole             */      vmpa_t address;                         /* Décallage final constaté    */ +    const char *label;                      /* Etiquette de symbole        */ +    SymbolType symtype;                     /* Type de symbole             */ +    char *printable;                        /* Version texte présentable   */      char buffer[256];                       /* Complément d'information    */      /* Valeur brute */ @@ -437,28 +439,29 @@ static char *g_imm_operand_get_text(const GImmOperand *operand, const exe_format      {          address = operand->unsigned_imm.val32; /* FIXME !!! */ -        if (resolve_exe_symbol(format, &label, &symtype, &address)) +        if (g_binary_format_resolve_symbol(G_BIN_FORMAT(format), &label, &symtype, &address))          {              switch (symtype)              { -                case STP_SECTION: +                case STP_OBJECT: +                case STP_FUNCTION:                      if (address == 0) snprintf(buffer, 256, " <%s>", label);                      else snprintf(buffer, 256, " <%s+0x%llx>", label, address);                      result = stradd(result, buffer);                      break;                  case STP_STRING: -                    label = escape_crlf(label); -                    label = strrpl(label, "<", "<"); -                    label = strrpl(label, ">", ">"); -                    snprintf(buffer, 256, " \"%s\"", label); +                    printable = strdup(label); +                    printable = escape_crlf(printable); +                    printable = strrpl(printable, "<", "<"); +                    printable = strrpl(printable, ">", ">"); +                    snprintf(buffer, 256, " \"%s\"", printable);                      result = stradd(result, buffer); +                    free(printable);                      break;              } -            free(label); -          }      } diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index db6a3bf..ab37d62 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -31,7 +31,7 @@  /* Traduit une instruction en version humainement lisible. */ -typedef const char * (* get_instruction_text_fc) (const GArchInstruction *, const exe_format *, AsmSyntax); +typedef const char * (* get_instruction_text_fc) (const GArchInstruction *, const GExeFormat *, AsmSyntax);  /* Informe sur une éventuelle référence à une autre instruction. */  typedef InstructionLinkType (* get_instruction_link_fc) (const GArchInstruction *, vmpa_t *); diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 37b2147..338f496 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -317,7 +317,7 @@ void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *op  *                                                                             *  ******************************************************************************/ -char *g_arch_instruction_get_text(const GArchInstruction *instr, const exe_format *format, AsmSyntax syntax) +char *g_arch_instruction_get_text(const GArchInstruction *instr, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */      size_t i;                               /* Boucle de parcours          */ diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 0e6444b..accaed6 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -32,7 +32,7 @@  #include "archbase.h"  #include "operand.h" -#include "../format/exe_format.h" +#include "../format/executable.h" @@ -92,7 +92,7 @@ void g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, cons  void g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);  /* Traduit une instruction en version humainement lisible. */ -char *g_arch_instruction_get_text(const GArchInstruction *, const exe_format *, AsmSyntax); +char *g_arch_instruction_get_text(const GArchInstruction *, const GExeFormat *, AsmSyntax);  /* Informe sur une éventuelle référence à une autre instruction. */  InstructionLinkType g_arch_instruction_get_link(const GArchInstruction *, vmpa_t *); diff --git a/src/arch/jvm/instruction.c b/src/arch/jvm/instruction.c index 9ada8f0..1b927e5 100644 --- a/src/arch/jvm/instruction.c +++ b/src/arch/jvm/instruction.c @@ -151,7 +151,7 @@ static jvm_instruction _instructions[JOP_COUNT] = {  /* Traduit une instruction en version humainement lisible. */ -static const char *jvm_get_instruction_text(const GJvmInstruction *, const exe_format *, AsmSyntax); +static const char *jvm_get_instruction_text(const GJvmInstruction *, const GExeFormat *, AsmSyntax); @@ -293,7 +293,7 @@ JvmOpcodes jvm_guess_next_instruction(const bin_t *data, off_t pos, off_t len, b  *                                                                             *  ******************************************************************************/ -static const char *jvm_get_instruction_text(const GJvmInstruction *instr, const exe_format *format, AsmSyntax syntax) +static const char *jvm_get_instruction_text(const GJvmInstruction *instr, const GExeFormat *format, AsmSyntax syntax)  {      return _instructions[instr->type].keyword; diff --git a/src/arch/jvm/operand.c b/src/arch/jvm/operand.c index da95101..429516a 100644 --- a/src/arch/jvm/operand.c +++ b/src/arch/jvm/operand.c @@ -255,10 +255,10 @@ static char *g_jvm_ref_operand_get_text(const GJvmRefOperand *operand, const exe      switch (operand->type)      {          case JOT_FIELD_REF: -            result = build_reference_from_java_pool((const java_format *)format, operand->index, JRT_FIELD); +            result = NULL;//build_reference_from_java_pool((const java_format *)format, operand->index, JRT_FIELD);              break;          case JOT_METHOD_REF: -            result = build_reference_from_java_pool((const java_format *)format, operand->index, JRT_METHOD); +            result = NULL;//build_reference_from_java_pool((const java_format *)format, operand->index, JRT_METHOD);              break;          default:              result = NULL; diff --git a/src/arch/mips/instruction.c b/src/arch/mips/instruction.c index 54999a1..fd39d5c 100644 --- a/src/arch/mips/instruction.c +++ b/src/arch/mips/instruction.c @@ -126,7 +126,7 @@ static mips_instruction _instructions[MOP_COUNT] = {  /* Traduit une instruction en version humainement lisible. */ -static const char *mips_get_instruction_text(const GMipsInstruction *, const exe_format *, AsmSyntax); +static const char *mips_get_instruction_text(const GMipsInstruction *, const GExeFormat *, AsmSyntax); @@ -274,7 +274,7 @@ MipsOpcodes mips_guess_next_instruction(const bin_t *data, off_t pos, off_t len)  *                                                                             *  ******************************************************************************/ -static const char *mips_get_instruction_text(const GMipsInstruction *instr, const exe_format *format, AsmSyntax syntax) +static const char *mips_get_instruction_text(const GMipsInstruction *instr, const GExeFormat *format, AsmSyntax syntax)  {      const char *result;                     /* Chaîne à retourner          */ diff --git a/src/arch/mips/operand.c b/src/arch/mips/operand.c index 68599a4..4021cf6 100644 --- a/src/arch/mips/operand.c +++ b/src/arch/mips/operand.c @@ -89,7 +89,7 @@ static void g_mips_register_operand_class_init(GMipsRegisterOperandClass *);  static void g_mips_register_operand_init(GMipsRegisterOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_mips_register_operand_get_text(const GMipsRegisterOperand *, const exe_format *, AsmSyntax); +static char *g_mips_register_operand_get_text(const GMipsRegisterOperand *, const GExeFormat *, AsmSyntax); @@ -122,7 +122,7 @@ static void g_mips_mem_content_operand_class_init(GMipsMemContentOperandClass *)  static void g_mips_mem_content_operand_init(GMipsMemContentOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_mips_mem_content_operand_get_text(const GMipsMemContentOperand *, const exe_format *, AsmSyntax); +static char *g_mips_mem_content_operand_get_text(const GMipsMemContentOperand *, const GExeFormat *, AsmSyntax); @@ -154,7 +154,7 @@ static void g_mips_offset_operand_class_init(GMipsOffsetOperandClass *);  static void g_mips_offset_operand_init(GMipsOffsetOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_mips_offset_operand_get_text(const GMipsOffsetOperand *, const exe_format *, AsmSyntax); +static char *g_mips_offset_operand_get_text(const GMipsOffsetOperand *, const GExeFormat *, AsmSyntax); @@ -301,7 +301,7 @@ GArchOperand *g_mips_register_operand_new(bin_t index)  *                                                                             *  ******************************************************************************/ -static char *g_mips_register_operand_get_text(const GMipsRegisterOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_mips_register_operand_get_text(const GMipsRegisterOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */ @@ -431,7 +431,7 @@ GArchOperand *g_mips_mem_content_operand_new(bin_t index, int16_t offset)  *                                                                             *  ******************************************************************************/ -static char *g_mips_mem_content_operand_get_text(const GMipsMemContentOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_mips_mem_content_operand_get_text(const GMipsMemContentOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */      char *tmp;                              /* Déplacement                 */ @@ -544,7 +544,7 @@ GArchOperand *g_mips_offset_operand_new(int16_t offset)  *                                                                             *  ******************************************************************************/ -static char *g_mips_offset_operand_get_text(const GMipsOffsetOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_mips_offset_operand_get_text(const GMipsOffsetOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      return g_arch_operand_get_text(G_ARCH_OPERAND(operand->offset), format, syntax); diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h index 8048548..90e3e06 100644 --- a/src/arch/operand-int.h +++ b/src/arch/operand-int.h @@ -30,7 +30,7 @@  /* Traduit un opérande en version humainement lisible. */ -typedef char * (* get_operand_text_fc) (const GArchOperand *, const exe_format *, AsmSyntax); +typedef char * (* get_operand_text_fc) (const GArchOperand *, const GExeFormat *, AsmSyntax);  /* Définition générique d'un opérande d'architecture (instance) */ diff --git a/src/arch/operand.c b/src/arch/operand.c index 0f488b3..724f3c0 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -91,7 +91,7 @@ static void g_arch_operand_init(GArchOperand *operand)  *                                                                             *  ******************************************************************************/ -char *g_arch_operand_get_text(const GArchOperand *operand, const exe_format *format, AsmSyntax syntax) +char *g_arch_operand_get_text(const GArchOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      return operand->get_text(operand, format, syntax); diff --git a/src/arch/operand.h b/src/arch/operand.h index cd7b213..c84c7fb 100644 --- a/src/arch/operand.h +++ b/src/arch/operand.h @@ -62,7 +62,7 @@ typedef enum _AsmOperandSize  #include <glib-object.h> -#include "../format/exe_format.h" +#include "../format/executable.h" @@ -83,7 +83,7 @@ typedef struct _GArchOperandClass GArchOperandClass;  GType g_arch_operand_get_type(void);  /* Traduit un opérande en version humainement lisible. */ -char *g_arch_operand_get_text(const GArchOperand *, const exe_format *, AsmSyntax); +char *g_arch_operand_get_text(const GArchOperand *, const GExeFormat *, AsmSyntax); diff --git a/src/arch/processor.c b/src/arch/processor.c index c8630d7..103296a 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -249,11 +249,11 @@ GArchProcessor *get_arch_processor_for_type(ArchProcessorType type)  *                                                                             *  ******************************************************************************/ -GArchProcessor *get_arch_processor_from_format(const exe_format *format) +GArchProcessor *get_arch_processor_from_format(const GExeFormat *format)  {      GArchProcessor *result;                 /* Conversion à retourner      */ -    switch (get_exe_target_machine(format)) +    switch (g_exe_format_get_target_machine(format))      {          case FTM_JVM:              result = get_arch_processor_for_type(APT_JVM); diff --git a/src/arch/processor.h b/src/arch/processor.h index 8529d50..ea954cc 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -82,7 +82,7 @@ bool init_all_processors(void);  GArchProcessor *get_arch_processor_for_type(ArchProcessorType);  /* Fournit le processeur d'architecture lié à un format. */ -GArchProcessor *get_arch_processor_from_format(const exe_format *); +GArchProcessor *get_arch_processor_from_format(const GExeFormat *); diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c index 0af29c1..65be263 100644 --- a/src/arch/x86/instruction.c +++ b/src/arch/x86/instruction.c @@ -321,7 +321,7 @@ static x86_instruction _instructions[XOP_COUNT] = {  /* Traduit une instruction en version humainement lisible. */ -static const char *x86_get_instruction_text(const GX86Instruction *, const exe_format *, AsmSyntax); +static const char *x86_get_instruction_text(const GX86Instruction *, const GExeFormat *, AsmSyntax);  /* Informe sur une éventuelle référence à une autre instruction. */  static InstructionLinkType x86_get_instruction_link(const GX86Instruction *, vmpa_t *); @@ -537,7 +537,7 @@ X86Opcodes x86_guess_next_instruction(const bin_t *data, off_t pos, off_t len, X  *                                                                             *  ******************************************************************************/ -static const char *x86_get_instruction_text(const GX86Instruction *instr, const exe_format *format, AsmSyntax syntax) +static const char *x86_get_instruction_text(const GX86Instruction *instr, const GExeFormat *format, AsmSyntax syntax)  {      const char *result;                     /* Chaîne à retourner          */ diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index 24613cf..69c08dc 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -90,7 +90,7 @@ static void g_x86_register_operand_class_init(GX86RegisterOperandClass *);  static void g_x86_register_operand_init(GX86RegisterOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_x86_register_operand_get_text(const GX86RegisterOperand *, const exe_format *, AsmSyntax); +static char *g_x86_register_operand_get_text(const GX86RegisterOperand *, const GExeFormat *, AsmSyntax); @@ -125,7 +125,7 @@ static void g_x86_mod_rm_operand_class_init(GX86ModRMOperandClass *);  static void g_x86_mod_rm_operand_init(GX86ModRMOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_x86_mod_rm_operand_get_text(const GX86ModRMOperand *, const exe_format *, AsmSyntax); +static char *g_x86_mod_rm_operand_get_text(const GX86ModRMOperand *, const GExeFormat *, AsmSyntax); @@ -156,7 +156,7 @@ static void g_x86_relative_operand_class_init(GX86RelativeOperandClass *);  static void g_x86_relative_operand_init(GX86RelativeOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_x86_relative_operand_get_text(const GX86RelativeOperand *, const exe_format *, AsmSyntax); +static char *g_x86_relative_operand_get_text(const GX86RelativeOperand *, const GExeFormat *, AsmSyntax); @@ -187,7 +187,7 @@ static void g_x86_moffs_operand_class_init(GX86MOffsOperandClass *);  static void g_x86_moffs_operand_init(GX86MOffsOperand *);  /* Traduit un opérande en version humainement lisible. */ -static char *g_x86_moffs_operand_get_text(const GX86MOffsOperand *, const exe_format *, AsmSyntax); +static char *g_x86_moffs_operand_get_text(const GX86MOffsOperand *, const GExeFormat *, AsmSyntax); @@ -417,7 +417,7 @@ GArchOperand *g_x86_register_operand_new_from_index(bin_t index, AsmOperandSize  *                                                                             *  ******************************************************************************/ -static char *g_x86_register_operand_get_text(const GX86RegisterOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_x86_register_operand_get_text(const GX86RegisterOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */ @@ -596,7 +596,7 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,  *                                                                             *  ******************************************************************************/ -static char *g_x86_mod_rm_operand_get_text(const GX86ModRMOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_x86_mod_rm_operand_get_text(const GX86ModRMOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */      char *tmp;                              /* Chaîne de registre          */ @@ -834,7 +834,7 @@ GArchOperand *g_x86_relative_operand_new(const bin_t *data, off_t *pos, off_t le  *                                                                             *  ******************************************************************************/ -static char *g_x86_relative_operand_get_text(const GX86RelativeOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_x86_relative_operand_get_text(const GX86RelativeOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */ @@ -964,7 +964,7 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,  *                                                                             *  ******************************************************************************/ -static char *g_x86_moffs_operand_get_text(const GX86MOffsOperand *operand, const exe_format *format, AsmSyntax syntax) +static char *g_x86_moffs_operand_get_text(const GX86MOffsOperand *operand, const GExeFormat *format, AsmSyntax syntax)  {      char *result;                           /* Chaîne à retourner          */ diff --git a/src/common/endianness.c b/src/common/endianness.c index 059295d..32bb65a 100755 --- a/src/common/endianness.c +++ b/src/common/endianness.c @@ -80,6 +80,24 @@ bool read_u16(uint16_t *target, const bin_t *data, off_t *pos, off_t len, Source      switch (endian)      { +        case SRE_LITTLE: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            *target = data[*pos] | (uint16_t)data[*pos + 1] << 8; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            *target = data[*pos + 1] | (uint16_t)data[*pos] << 8; + +#else + +#   error "TODO : PDP !" + +#endif + +            break; + @@ -181,3 +199,27 @@ bool read_u32(uint32_t *target, const bin_t *data, off_t *pos, off_t len, Source      return true;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          * +*                data   = flux de données à analyser.                         * +*                pos    = position courante dans ce flux. [OUT]               * +*                len    = taille totale des données à analyser.               * +*                endian = ordre des bits dans la source.                      * +*                                                                             * +*  Description : Lit un nombre non signé sur huit octets.                     * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool read_u64(uint64_t *target, const bin_t *data, off_t *pos, off_t len, SourceEndian endian) +{ + +    return false; + +} diff --git a/src/common/endianness.h b/src/common/endianness.h index b4c3975..f9d421e 100755 --- a/src/common/endianness.h +++ b/src/common/endianness.h @@ -52,6 +52,15 @@ bool read_u16(uint16_t *, const bin_t *, off_t *, off_t, SourceEndian);  /* Lit un nombre non signé sur quatre octets. */  bool read_u32(uint32_t *, const bin_t *, off_t *, off_t, SourceEndian); +/* Lit un nombre non signé sur huit octets. */ +bool read_u64(uint64_t *, const bin_t *, off_t *, off_t, SourceEndian); + + +#define read_s8(target, data, pos, len, endian) read_u8((uint8_t *)target, data, pos, len, endian) +#define read_s16(target, data, pos, len, endian) read_u16((uint16_t *)target, data, pos, len, endian) +#define read_s32(target, data, pos, len, endian) read_u32((uint32_t *)target, data, pos, len, endian) +#define read_s64(target, data, pos, len, endian) read_u64((uint64_t *)target, data, pos, len, endian) +  #endif  /* _COMMON_ENDIANNESS_H */ diff --git a/src/editor.c b/src/editor.c index 6b088c5..3830e4c 100644 --- a/src/editor.c +++ b/src/editor.c @@ -41,7 +41,6 @@  #include "dlg_sections.h" -#include "pan_strings.h"  #include "analysis/binary.h"  #include "gtkext/easygtk.h"  #include "gtkext/gtkextstatusbar.h" @@ -469,9 +468,7 @@ GtkWidget *create_editor(void)      ditem = gtk_dock_item_new(_("Messages"), get_panel(PNT_LOG));      gtk_dock_panel_add_item(dpanel, ditem); -    panel = build_strings_panel(G_OBJECT(result)); - -    ditem = gtk_dock_item_new(_("Strings"), panel); +    ditem = gtk_dock_item_new(_("Strings"), get_panel(PNT_STRINGS));      gtk_dock_panel_add_item(dpanel, ditem); diff --git a/src/format/Makefile.am b/src/format/Makefile.am index 92a774b..9bfdd92 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -2,17 +2,35 @@  noinst_LTLIBRARIES = libformat.la  libformat_la_SOURCES =					\ -	exe_format.h exe_format.c			\ -	exe_format-int.h					\ -	dbg_format.h dbg_format.c			\ -	dbg_format-int.h +	executable-int.h					\ +	executable.h executable.c			\ +	format-int.h						\ +	format.h format.c					\ +	part.h part.c						\ +	symbol.h symbol.c + +# libformat_la_SOURCES =					\ +# 	exe_format.h exe_format.c			\ +# 	exe_format-int.h					\ +# 	executable-int.h					\ +# 	executable.h executable.c			\ +# 	format-int.h						\ +# 	format.h format.c					\ +# 	dbg_format.h dbg_format.c			\ +# 	dbg_format-int.h					\ +# 	part.h part.c  libformat_la_LIBADD =					\  	dwarf/libformatdwarf.la				\  	elf/libformatelf.la					\ -	java/libformatjava.la				\ -	mangling/libformatmangling.la		\ -	pe/libformatpe.la +	mangling/libformatmangling.la + +# libformat_la_LIBADD =					\ +# 	dwarf/libformatdwarf.la				\ +# 	elf/libformatelf.la					\ +# 	java/libformatjava.la				\ +# 	mangling/libformatmangling.la		\ +# 	pe/libformatpe.la  libformat_la_LDFLAGS =  @@ -23,4 +41,5 @@ AM_CPPFLAGS =  AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = dwarf elf java mangling pe +SUBDIRS = dwarf elf mangling +#SUBDIRS = dwarf elf java mangling pe diff --git a/src/format/dwarf/Makefile.am b/src/format/dwarf/Makefile.am index de1d228..6c6491a 100644 --- a/src/format/dwarf/Makefile.am +++ b/src/format/dwarf/Makefile.am @@ -2,11 +2,15 @@  noinst_LTLIBRARIES = libformatdwarf.la  libformatdwarf_la_SOURCES =				\ -	abbrev.h abbrev.c					\ -	d_dwarf.h d_dwarf.c					\ -	dwarf_def.h							\ -	info.h info.c						\ -	utils.h utils.c +	dwarf.h dwarf.c + +# libformatdwarf_la_SOURCES =				\ +# 	abbrev.h abbrev.c					\ +# 	dwarf.h dwarf.c						\ +# 	d_dwarf.h d_dwarf.c					\ +# 	dwarf_def.h							\ +# 	info.h info.c						\ +# 	utils.h utils.c  libformatdwarf_la_LDFLAGS = $(LIBGTK_LIBS) diff --git a/src/format/dwarf/dwarf.c b/src/format/dwarf/dwarf.c new file mode 100644 index 0000000..dc47ed2 --- /dev/null +++ b/src/format/dwarf/dwarf.c @@ -0,0 +1,86 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dwarf.c - support du format Dwarf + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "dwarf.h" + + + + + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type    = type de format recherché.                          * +*                content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                                                                             * +*  Description : Indique si le format peut être pris en charge ici.           * +*                                                                             * +*  Retour      : true si la réponse est positive, false sinon.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool dwarf_is_matching(FormatType type, const uint8_t *content, off_t length) +{ +    bool result;                            /* Bilan à faire connaître     */ + +    result = false; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                                                                             * +*  Description : Prend en charge un nouveau format Dwarf.                     * +*                                                                             * +*  Retour      : Adresse de la structure mise en place ou NULL en cas d'échec.* +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinFormat *g_dwarf_format_new(const bin_t *content, off_t length) +{ + + + +    return NULL; + + + +} diff --git a/src/format/dwarf/dwarf.h b/src/format/dwarf/dwarf.h new file mode 100644 index 0000000..35ab3ec --- /dev/null +++ b/src/format/dwarf/dwarf.h @@ -0,0 +1,40 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dwarf.h - prototypes pour le support du format Dwarf + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_DWARF_DWARF_H +#define _FORMAT_DWARF_DWARF_H + + +#include "../format.h" + + + +/* Indique si le format peut être pris en charge ici. */ +bool dwarf_is_matching(FormatType, const uint8_t *, off_t); + +/* Prend en charge un nouveau format Dwarf. */ +GBinFormat *g_dwarf_format_new(const bin_t *, off_t); + + + +#endif  /* _FORMAT_DWARF_DWARF_H */ diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am index 822ea44..1e18356 100644 --- a/src/format/elf/Makefile.am +++ b/src/format/elf/Makefile.am @@ -2,13 +2,15 @@  noinst_LTLIBRARIES = libformatelf.la  libformatelf_la_SOURCES =				\ -	e_elf.h e_elf.c						\ -	elf-int.h							\ -	helper_mips.h helper_mips.c			\ +	elf-int.h elf-int.c					\ +	elf.h elf.c							\ +	elf_def.h							\  	helper_x86.h helper_x86.c			\  	section.h section.c					\  	strings.h strings.c					\ -	symbol.h symbol.c +	symbols.h symbols.c + +# 	helper_mips.h helper_mips.c  libformatelf_la_LDFLAGS =  diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c deleted file mode 100644 index a91e279..0000000 --- a/src/format/elf/e_elf.c +++ /dev/null @@ -1,604 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * e_elf.c - support du format ELF - * - * Copyright (C) 2008 Cyrille Bagard - * - *  This file is part of OpenIDA. - * - *  OpenIDA 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. - * - *  OpenIDA 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 <http://www.gnu.org/licenses/>. - */ - - -#include "e_elf.h" - - -#include <malloc.h> -#include <string.h> - - -#include "elf-int.h" -#include "section.h" -#include "strings.h" -#include "symbol.h" -#include "../../panel/log.h" -#include "../../common/extstr.h" - - - - -#define _(str) str - - - - -/* Indique le type d'architecture visée par le format. */ -FormatTargetMachine get_elf_target_machine(const elf_format *); - - - -/* Fournit l'adresse mémoire du point d'entrée du programme. */ -uint64_t get_elf_entry_point(const elf_format *); - - - - - -/* Récupère tous les éléments identifiées dans le binaire. */ -size_t get_elf_resolved_items(const elf_format *, char ***, ResolvedType **, uint64_t **); - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : content = contenu binaire à parcourir.                       * -*                length  = taille du contenu en question.                     * -*                                                                             * -*  Description : Indique si le format peut être pris en charge ici.           * -*                                                                             * -*  Retour      : true si la réponse est positive, false sinon.                * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool elf_is_matching(const uint8_t *content, off_t length) -{ -    bool result;                            /* Bilan à faire connaître     */ - -    result = false; - -    if (length >= 4) -        result = (strncmp((const char *)content, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : content = contenu binaire à parcourir.                       * -*                length  = taille du contenu en question.                     * -*                                                                             * -*  Description : Prend en charge un nouvel ELF.                               * -*                                                                             * -*  Retour      : Adresse de la structure mise en place ou NULL en cas d'échec.* -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -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_target_machine = (get_target_machine_fc)get_elf_target_machine; -    EXE_FORMAT(result)->get_entry_point = (get_entry_point_fc)get_elf_entry_point; -    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_content_by_name; -    EXE_FORMAT(result)->get_symbols = (get_symbols_fc)get_elf_symbols; -    EXE_FORMAT(result)->get_resolved = (get_resolved_fc)get_elf_resolved_items; -    EXE_FORMAT(result)->resolve_symbol = (resolve_symbol_fc)resolve_elf_symbol; -    EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_elf_routines; - -    memcpy(&result->header, content, sizeof(Elf32_Ehdr)); - - -    /* TODO : endian */ - - -    /* Vérification des tailles d'entrée de table */ -    switch (result->header.e_ident[EI_CLASS]) -    { -        case ELFCLASS32: - -            if (result->header.e_phentsize != sizeof(Elf32_Phdr)) -            { -                log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), -                                     result->header.e_phentsize); -                result->header.e_phentsize = sizeof(Elf32_Phdr); -            } - -            if (result->header.e_shentsize != sizeof(Elf32_Shdr)) -            { -                log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), -                                     result->header.e_shentsize); -                result->header.e_shentsize = sizeof(Elf32_Shdr); -            } - -            break; - -        case ELFCLASS64: - -            if (result->header.e_phentsize != sizeof(Elf64_Phdr)) -            { -                log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), -                                     result->header.e_phentsize); -                result->header.e_phentsize = sizeof(Elf64_Phdr); -            } - -            if (result->header.e_shentsize != sizeof(Elf64_Shdr)) -            { -                log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), -                                     result->header.e_shentsize); -                result->header.e_shentsize = sizeof(Elf64_Shdr); -            } - -            break; - -        default: -            log_variadic_message(LMT_BAD_BINARY, ("Invalid ELF class '%hhu'"), -                                 result->header.e_ident[EI_CLASS]); -            break; - -    } - - -    /* FIXME : à améliorer */ -    if ((result->header.e_shnum * result->header.e_shentsize) >= length) -    { -        log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !")); -        result->header.e_shnum = 0; -    } - - -    result->is_32b = (result->header.e_ident[EI_CLASS] == ELFCLASS32); - - -    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); - -    printf("section names ok ? %d\n", test); - -    test = find_all_elf_strings(result); - -    printf("strings ok ? %d\n", test); - -    test = load_elf_symbols(result); - -    printf("symbols ok ? %d\n", test); - - - -    return result; - - lelf: - -    /* TODO */ - -    return NULL; - -} - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = informations chargées à consulter.                  * -*                                                                             * -*  Description : Indique le type d'architecture visée par le format.          * -*                                                                             * -*  Retour      : Identifiant de l'architecture ciblée par le format.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -FormatTargetMachine get_elf_target_machine(const elf_format *format) -{ -    FormatTargetMachine result;             /* Identifiant à retourner     */ - -    switch (format->header.e_machine) -    { -        case EM_MIPS: -            result = FTM_MIPS; -            break; - -        case EM_386: -            result = FTM_386; -            break; - -        default: -            /* FIXME */ -            break; - -    } - -    return result; - -} - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = informations chargées à consulter.                  * -*                                                                             * -*  Description : Fournit l'adresse mémoire du point d'entrée du programme.    * -*                                                                             * -*  Retour      : Adresse de mémoire.                                          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -uint64_t get_elf_entry_point(const elf_format *format) -{ -    return format->header.e_entry; - -} - - -/****************************************************************************** -*                                                                             * -*  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 section ELF      */ -    Elf_Phdr phdr;                          /* En-tête de programme ELF    */ - -    result = NULL; -    *count = 0; - -    if (format->sec_size > 0) -    { -        if (find_elf_section_content_by_name(format, ".plt", &offset, &size, &voffset)) -        { -            part = create_bin_part(); - -            set_bin_part_name(part, ".plt"); -            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_content_by_name(format, ".MIPS.stubs", &offset, &size, &voffset)) -        { -            part = create_bin_part(); - -            set_bin_part_name(part, ".MIPS.stubs"); -            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_content_by_name(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_content_by_name(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_content_by_name(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) continue; - -            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; - -            } - -        } - -    /* En désespoir de cause, on se rabbat sur les parties de programme directement */ - -    if (*count == 0) -        for (i = 0; i < format->header.e_phnum; i++) -        { -            offset = format->header.e_phoff + format->header.e_phentsize * i; -            if ((offset + format->header.e_phentsize) >= EXE_FORMAT(format)->length) continue; - -            memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize); - -            if (ELF_PHDR(format, &phdr, p_flags) & PF_X) -            { -                part = create_bin_part(); - -                /* TODO : nom */ - -                set_bin_part_values(part, ELF_PHDR(format, &phdr, p_offset), -                                    ELF_PHDR(format, &phdr, p_filesz), -                                    ELF_PHDR(format, &phdr, p_vaddr)); - -                result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); -                result[*count - 1] = part; - -            } - -        } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format  = informations chargées à consulter.                 * -*                labels  = liste des commentaires à insérer. [OUT]            * -*                types   = type des symboles listés. [OUT]                    * -*                offsets = liste des indices des commentaires. [OUT]          * -*                                                                             * -*  Description : Récupère tous les symboles présents dans le contenu binaire. * -*                                                                             * -*  Retour      : Nombre d'éléments mis en place.                              * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -size_t get_elf_symbols(const elf_format *format, char ***labels, SymbolType **types, uint64_t **offsets) -{ -    size_t result;                          /* Quantité à retourner        */ -    size_t i;                               /* Boucle de parcours          */ - -    result = format->sym_count; - -    *labels = (char **)calloc(result, sizeof(char *)); -    *types = (SymbolType *)calloc(result, sizeof(SymbolType)); -    *offsets = (uint64_t *)calloc(result, sizeof(uint64_t)); - -    for (i = 0; i < format->sym_count; i++) -    { -        (*labels)[i] = strdup(format->symbols[i].name); -        (*types)[i] = STP_SECTION; -        (*offsets)[i] = format->symbols[i].address; -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format  = informations chargées à consulter.                 * -*                labels  = liste des commentaires à insérer. [OUT]            * -*                types   = type des symboles listés. [OUT]                    * -*                offsets = liste des indices des commentaires. [OUT]          * -*                                                                             * -*  Description : Récupère tous les éléments identifiées dans le binaire.      * -*                                                                             * -*  Retour      : Nombre d'éléments mis en place.                              * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -size_t get_elf_resolved_items(const elf_format *format, char ***labels, ResolvedType **types, uint64_t **offsets) -{ -    size_t result;                          /* Quantité à retourner        */ -    size_t i;                               /* Boucle de parcours          */ -    size_t start;                           /* Point de départ du tour     */ - -    result = format->sym_count + format->str_count; - -    *labels = (char **)calloc(result, sizeof(char *)); -    *types = (SymbolType *)calloc(result, sizeof(SymbolType)); -    *offsets = (uint64_t *)calloc(result, sizeof(uint64_t)); - -    for (i = 0; i < format->sym_count; i++) -    { -        (*labels)[i] = strdup(format->symbols[i].name); -        (*types)[i] = RTP_SECTION; -        (*offsets)[i] = format->symbols[i].address; -    } - -    start = format->sym_count; - -    for (i = 0; i < format->str_count; i++) -    { -        (*labels)[start + i] = strndup(format->strings[i].value, format->strings[i].len); -        (*types)[start + i] = RTP_STRING; -        (*offsets)[start + i] = format->strings[i].address; - -        (*labels)[start + i] = escape_crlf((*labels)[start + i]); - -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format  = informations chargées à consulter.                 * -*                label   = étiquette du symbole si trouvé. [OUT]              * -*                type    = type du symbole trouvé. [OUT]                      * -*                address = adresse à cibler, puis décallage final. [OUT]      * -*                                                                             * -*  Description : Recherche le symbole correspondant à une adresse.            * -*                                                                             * -*  Retour      : true si l'opération a été un succès, false sinon.            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool resolve_elf_symbol(const elf_format *format, char **label, SymbolType *type, vmpa_t *address) -{ -    bool result;                            /* Bilan à retourner           */ -    size_t best_index;                      /* Meilleur symbole trouvé     */ -    vmpa_t best_addr;                       /* Meilleure adresse trouvée   */ -    vmpa_t addr;                            /* Adresse de routine          */ -    size_t i;                               /* Boucle de parcours          */ - -    if (resolve_elf_strings(format, label, address)) -    { -        *type = STP_STRING; -        return true; -    } - -    best_index = format->routines_count;    /* Pour GCC */ -    best_addr = UINT64_MAX; /* FIXME */ - -    for (i = 0; i < format->routines_count; i++) -    { -        addr = g_binary_routine_get_address(format->routines[i]); - -        if (addr <= *address && (*address - addr) < best_addr) -        { -            best_index = i; -            best_addr = *address - addr; -        } - -    } - -    result = (best_addr != UINT64_MAX); - -    if (result) -    { -        *label = strdup(g_binary_routine_get_name(format->routines[best_index])); -        *type = STP_SECTION; -        *address -= g_binary_routine_get_address(format->routines[best_index]); -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = informations chargées à consulter.                  * -*                count  = taille du tableau créé. [OUT]                       * -*                                                                             * -*  Description : Fournit le prototype de toutes les routines détectées.       * -*                                                                             * -*  Retour      : Tableau créé ou NULL si aucun symbole de routine trouvé.     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GBinRoutine **get_all_elf_routines(const elf_format *format, size_t *count) -{ -    *count = format->routines_count; - -    return format->routines; - -} diff --git a/src/format/elf/e_elf.h b/src/format/elf/e_elf.h deleted file mode 100644 index b8abe05..0000000 --- a/src/format/elf/e_elf.h +++ /dev/null @@ -1,63 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * e_elf.h - prototypes pour le support du format ELF - * - * Copyright (C) 2008 Cyrille Bagard - * - *  This file is part of OpenIDA. - * - *  OpenIDA 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. - * - *  OpenIDA 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 <http://www.gnu.org/licenses/>. - */ - - -#ifndef _FORMAT_ELF_ELF_H -#define _FORMAT_ELF_ELF_H - - -#include <stdbool.h> -#include <stdint.h> -#include <sys/types.h> - - -#include "../exe_format.h" - - - -/* Description du format ELF */ -typedef struct _elf_format elf_format; - - -/* Indique si le format peut être pris en charge ici. */ -bool elf_is_matching(const uint8_t *, off_t); - -/* 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 **); - -/* Recherche le symbole correspondant à une adresse. */ -bool resolve_elf_symbol(const elf_format *, char **, SymbolType *, vmpa_t *); - -/* Fournit le prototype de toutes les routines détectées. */ -GBinRoutine **get_all_elf_routines(const elf_format *, size_t *); - - - -#endif  /* _FORMAT_ELF_ELF_H */ diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c new file mode 100644 index 0000000..69363d2 --- /dev/null +++ b/src/format/elf/elf-int.c @@ -0,0 +1,227 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * elf-int.c - structures internes du format ELF + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "elf-int.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                pos    = position de début de lecture. [OUT]                 * +*                header = structure lue à retourner. [OUT]                    * +*                                                                             * +*  Description : Procède à la lecture d'une en-tête de programme ELF.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool read_elf_program_header(const GElfFormat *format, off_t *pos, elf_phdr *header) +{ +    bool result;                            /* Bilan à retourner           */ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */ + +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; + +    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); +    } +    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); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = informations chargées à consulter.                 * +*                pos     = position de la tête de lecture.                    * +*                section = section lue. [OUT]                                 * +*                                                                             * +*  Description : Procède à la lecture d'une en-tête de section ELF.           * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool read_elf_section_header(const GElfFormat *format, off_t pos, elf_shdr *section) +{ +    bool result;                            /* Bilan à retourner           */ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */ +    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; + +    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); + +    } +    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); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                pos    = position de début de lecture. [OUT]                 * +*                sym    = structure lue à retourner. [OUT]                    * +*                                                                             * +*  Description : Procède à la lecture d'un symbole ELF.                       * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool read_elf_symbol(const GElfFormat *format, off_t *pos, elf_sym *sym) +{ +    bool result;                            /* Bilan à retourner           */ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */ + +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; + +    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); +    } +    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); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                pos    = position de début de lecture. [OUT]                 * +*                reloc  = structure lue à retourner. [OUT]                    * +*                                                                             * +*  Description : Procède à la lecture d'une relocalisation ELF.               * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool read_elf_relocation(const GElfFormat *format, off_t *pos, elf_rel *reloc) +{ +    bool result;                            /* Bilan à retourner           */ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */ + +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; + +    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); +    } +    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); +    } + +    return result; + +} diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h index 4339475..f7fd804 100644 --- a/src/format/elf/elf-int.h +++ b/src/format/elf/elf-int.h @@ -25,115 +25,44 @@  #define _FORMAT_ELF_ELF_INT_H +#include "elf.h" +#include "elf_def.h" +#include "../executable-int.h" +#include "../../common/endianness.h" -#include <elf.h> -#include <sys/types.h> -#include "../exe_format-int.h" - - - -/* Chaîne de caractères présente */ -typedef struct _elf_string -{ -    const char *value;                      /* Valeur humainement lisible  */ -    size_t len;                             /* Longueur de la chaîne       */ -    vmpa_t address;                         /* Adresse de localisation     */ - -} elf_string; - -/* Symbole trouvé */ -typedef struct _elf_symbol -{ -    const char *name;                       /* Désignation du symbole      */ -    uint64_t address;                       /* Adresse du symbole          */ -    off_t size;                             /* Taille du code associé      */ - -} elf_symbol; - -/* Relocalisation trouvée */ -typedef struct _elf_relocation +/* Format d'exécutable générique (instance) */ +struct _GElfFormat  { -    const char *name;                       /* Désignation du symbole      */ -    vmpa_t address;                         /* Adresse du symbole          */ +    GExeFormat parent;                      /* A laisser en premier        */ -} elf_relocation; - - - -/* Description du format ELF */ -struct _elf_format -{ -    exe_format dummy;                       /* A laisser en premier        */ - -    Elf32_Ehdr header;                      /* En-tête du format           */ +    elf_header 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   */ - -    elf_relocation *relocations;            /* Liste des relocalisations   */ -    size_t rel_count;                       /* Taille de cette liste       */ - -    GBinRoutine **routines;                 /* Liste des routines trouvées */ -    size_t routines_count;                  /* Nombre de ces routines      */ - -    elf_symbol *symbols;                    /* Liste des symboles          */ -    size_t sym_count;                       /* Taille de cette liste       */ - -    elf_string *strings;                    /* Liste des chaînes           */ -    size_t str_count;                       /* Taille de cette liste       */ +    SourceEndian endian;                    /* Boutisme du format          */  }; - - - -/* 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) - - -/* Entrée de la table de relocalisation */ - -typedef union _Elf_Rel +/* Format d'exécutable générique (classe) */ +struct _GElfFormatClass  { -    Elf32_Rel rel32;                        /* Version 32 bits             */ -    Elf64_Rel rel64;                        /* Version 64 bits             */ - -} Elf_Rel; - -#define ELF_SIZEOF_REL(fmt) (fmt->is_32b ? sizeof(Elf32_Rel) : sizeof(Elf64_Rel)) - -#define ELF_REL(fmt, rl, fld) (fmt->is_32b ? rl.rel32.fld : rl.rel64.fld) - -#define ELF_REL_SYM(fmt, rl) (fmt->is_32b ? ELF32_R_SYM(rl.rel32.r_info) : ELF64_R_SYM(rl.rel64.r_info)) -#define ELF_REL_TYPE(fmt, rl) (fmt->is_32b ? ELF32_R_TYPE(rl.rel32.r_info) : ELF64_R_TYPE(rl.rel64.r_info)) +    GExeFormatClass parent;                 /* A laisser en premier        */ +}; -/* Information sur un symbole */ - -typedef union _Elf_Sym -{ -    Elf32_Sym sym32;                        /* Version 32 bits             */ -    Elf64_Sym sym64;                        /* Version 64 bits             */ - -} Elf_Sym; -#define ELF_SIZEOF_SYM(fmt) (fmt->is_32b ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym)) -#define ELF_SYM(fmt, sb, fld) (fmt->is_32b ? sb.sym32.fld : sb.sym64.fld) +/* Procède à la lecture d'une en-tête de programme ELF. */ +bool read_elf_program_header(const GElfFormat *, off_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 *); -#define ELF_ST_TYPE ELF32_ST_TYPE +/* Procède à la lecture d'un symbole ELF. */ +bool read_elf_symbol(const GElfFormat *, off_t *, elf_sym *); +/* Procède à la lecture d'une relocalisation ELF. */ +bool read_elf_relocation(const GElfFormat *, off_t *, elf_rel *); diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c new file mode 100644 index 0000000..d24a89e --- /dev/null +++ b/src/format/elf/elf.c @@ -0,0 +1,444 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * elf.c - support du format ELF + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "elf.h" + + +#include <malloc.h> +#include <string.h> + + +#include "elf-int.h" +#include "section.h" +#include "strings.h" +#include "symbols.h" +#include "../../panel/log.h" + + + + +#ifndef _ +#   define _(str) (str) +#endif + + + + +/* Initialise la classe des formats d'exécutables ELF. */ +static void g_elf_format_class_init(GElfFormatClass *); + +/* Initialise une instance de format d'exécutable ELF. */ +static void g_elf_format_init(GElfFormat *); + +/* Procède à la lecture de l'en-tête d'un contenu binaire. */ +static bool read_elf_header(const bin_t *, off_t, elf_header *, bool *, SourceEndian *); + +/* Indique le type d'architecture visée par le format. */ +static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *); + +/* Fournit l'adresse mémoire du point d'entrée du programme. */ +static vmpa_t g_elf_format_get_entry_point(const GElfFormat *); + +/* Fournit les références aux zones binaires à analyser. */ +static GBinPart **g_elf_format_get_parts(const GElfFormat *, size_t *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type    = type de format recherché.                          * +*                content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                                                                             * +*  Description : Indique si le format peut être pris en charge ici.           * +*                                                                             * +*  Retour      : true si la réponse est positive, false sinon.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool elf_is_matching(FormatType type, const bin_t *content, off_t length) +{ +    bool result;                            /* Bilan à faire connaître     */ + +    result = false; + +    if (length >= 4) +        result = (memcmp(content, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); + +    return result; + +} + + +/* Indique le type défini pour un format d'exécutable ELF. */ +G_DEFINE_TYPE(GElfFormat, g_elf_format, G_TYPE_EXE_FORMAT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des formats d'exécutables ELF.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_elf_format_class_init(GElfFormatClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de format d'exécutable ELF.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_elf_format_init(GElfFormat *format) +{ +    GExeFormat *exe_format; + +    exe_format = G_EXE_FORMAT(format); + +    exe_format->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine; +    exe_format->get_entry_point = (get_entry_point_fc)g_elf_format_get_entry_point; +    exe_format->get_parts = (get_parts_fc)g_elf_format_get_parts; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                header  = en-tête à déterminer. [OUT]                        * +*                is_32b  = indique si le format est en 32 ou 64 bits. [OUT]   * +*                endian  = boutisme reconnu dans le format. [OUT]             * +*                                                                             * +*  Description : Procède à la lecture de l'en-tête d'un contenu binaire.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool read_elf_header(const bin_t *content, off_t length, elf_header *header, bool *is_32b, SourceEndian *endian) +{ +    bool result;                            /* Bilan à retourner           */ +    off_t pos;                              /* Position de lecture         */ + +    result = (length >= EI_NIDENT); + +    pos = 0; + +    if (result) +    { +        memcpy(header->e_ident, content, EI_NIDENT); +        pos += EI_NIDENT; +    } + +    /* Détermination de l'espace d'adressage */ +    if (result) +        switch (header->e_ident[EI_CLASS]) +        { +            case ELFCLASS32: +                *is_32b = true; +                break; +            case ELFDATA2MSB: +                *is_32b = false; +                break; +            default: +                result = false; +                break; +        } + +    /* Détermination du boutisme */ +    if (result) +        switch (header->e_ident[EI_DATA]) +        { +            case ELFDATA2LSB: +                *endian = SRE_LITTLE; +                break; +            case ELFDATA2MSB: +                *endian = SRE_BIG; +                break; +            default: +                result = false; +                break; +        } + +    if (result) +        result = read_u16(&header->e_type, content, &pos, length, *endian); + +    if (result) +        result = read_u16(&header->e_machine, content, &pos, length, *endian); + +    if (result) +        result = read_u32(&header->e_version, content, &pos, length, *endian); + +    if (result) +    { +        if (*is_32b) +            result = read_u32(&header->e_entry.addr32, content, &pos, length, *endian); +        else +            result = read_u64(&header->e_entry.addr64, content, &pos, length, *endian); +    } + +    if (result) +    { +        if (*is_32b) +            result = read_u32(&header->e_phoff.off32, content, &pos, length, *endian); +        else +            result = read_u64(&header->e_phoff.off64, content, &pos, length, *endian); +    } + +    if (result) +    { +        if (*is_32b) +            result = read_u32(&header->e_shoff.off32, content, &pos, length, *endian); +        else +            result = read_u64(&header->e_shoff.off64, content, &pos, length, *endian); +    } + +    if (result) +        result = read_u32(&header->e_flags, content, &pos, length, *endian); + +    if (result) +        result = read_u16(&header->e_ehsize, content, &pos, length, *endian); + +    if (result) +        result = read_u16(&header->e_phentsize, content, &pos, length, *endian); + +    if (result) +        result = read_u16(&header->e_phnum, content, &pos, length, *endian); + +    if (result) +        result = read_u16(&header->e_shentsize, content, &pos, length, *endian); + +    if (result) +        result = read_u16(&header->e_shnum, content, &pos, length, *endian); + +    if (result) +        result = read_u16(&header->e_shstrndx, content, &pos, length, *endian); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                                                                             * +*  Description : Prend en charge un nouveau format ELF.                       * +*                                                                             * +*  Retour      : Adresse de la structure mise en place ou NULL en cas d'échec.* +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinFormat *g_elf_format_new(const bin_t *content, off_t length) +{ +    GElfFormat *result;                     /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_ELF_FORMAT, NULL); + +    g_binary_format_set_content(G_BIN_FORMAT(result), content, length); + +    if (!read_elf_header(content, length, &result->header, &result->is_32b, &result->endian)) +    { +        /* TODO */ +        return NULL; +    } + + +    /* Vérification des tailles d'entrée de table */ + +    if (result->header.e_phentsize != ELF_SIZEOF_PHDR(result)) +    { +        log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), +                             result->header.e_phentsize); +        result->header.e_phentsize = ELF_SIZEOF_PHDR(result); +    } + +    if (result->header.e_shentsize != ELF_SIZEOF_SHDR(result)) +    { +        log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), +                             result->header.e_shentsize); +        result->header.e_shentsize = ELF_SIZEOF_SHDR(result); +    } + +    /* FIXME : à améliorer */ +    if ((result->header.e_shnum * result->header.e_shentsize) >= length) +    { +        log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !")); +        result->header.e_shnum = 0; +    } + + + + +    if (!load_elf_symbols(result)) +    { +        /* TODO */ +        return NULL; +    } + + +    if (!find_all_elf_strings(result)) +    { +        /* TODO */ +        return NULL; +    } + + + +    return G_BIN_FORMAT(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                                                                             * +*  Description : Indique le type d'architecture visée par le format.          * +*                                                                             * +*  Retour      : Identifiant de l'architecture ciblée par le format.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *format) +{ +    FormatTargetMachine result;             /* Identifiant à retourner     */ + +    switch (format->header.e_machine) +    { +        case EM_MIPS: +            result = FTM_MIPS; +            break; + +        case EM_386: +            result = FTM_386; +            break; + +        case EM_NONE: +        default: +            result = FTM_NONE; +            break; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                                                                             * +*  Description : Fournit l'adresse mémoire du point d'entrée du programme.    * +*                                                                             * +*  Retour      : Adresse de mémoire.                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static vmpa_t g_elf_format_get_entry_point(const GElfFormat *format) +{ +    return (format->is_32b ? format->header.e_entry.addr32 : format->header.e_entry.addr64); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                count  = quantité de zones listées. [OUT]                    * +*                                                                             * +*  Description : Fournit les références aux zones binaires à analyser.        * +*                                                                             * +*  Retour      : Zones binaires à analyser.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count) +{ +    GBinPart **result;                      /* Tableau à retourner         */ +    uint16_t i;                             /* Boucle de parcours          */ +    elf_shdr section;                       /* En-tête de section ELF      */ +    GBinPart *part;                         /* Partie à intégrer à la liste*/ + +    result = NULL; +    *count = 0; + +    /* Première tentative : les sections */ + +    for (i = 0; i < format->header.e_shnum; i++) +    { +        if (!find_elf_section_by_index(format, i, §ion)) +            continue; + + +            if (ELF_SHDR(format, section, sh_flags) & SHF_EXECINSTR) +            { +                part = g_binary_part_new(); + +                /* TODO : nom, droits/type */ + +                g_binary_part_set_values(part, +                                         ELF_SHDR(format, section, sh_offset), +                                         ELF_SHDR(format, section, sh_size), +                                         ELF_SHDR(format, section, sh_addr)); + +                result = (GBinPart **)realloc(result, ++(*count) * sizeof(GBinPart *)); +                result[*count - 1] = part; + +            } + +        } + +    return result; + +} diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h new file mode 100644 index 0000000..e8ad70b --- /dev/null +++ b/src/format/elf/elf.h @@ -0,0 +1,62 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * elf.h - prototypes pour le support du format ELF + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_ELF_ELF_H +#define _FORMAT_ELF_ELF_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <sys/types.h> + + +#include "../format.h" + + + +#define G_TYPE_ELF_FORMAT               g_elf_format_get_type() +#define G_ELF_FORMAT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_elf_format_get_type(), GElfFormat)) +#define G_IS_ELF_FORMAT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_elf_format_get_type())) +#define G_ELF_FORMAT_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_elf_format_get_type(), GElfFormatIface)) +#define G_ELF_FORMAT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ELF_FORMAT, GElfFormatClass)) + + +/* Format d'exécutable ELF (instance) */ +typedef struct _GElfFormat GElfFormat; + +/* Format d'exécutable ELF (classe) */ +typedef struct _GElfFormatClass GElfFormatClass; + + +/* Indique si le format peut être pris en charge ici. */ +bool elf_is_matching(FormatType, const bin_t *, off_t); + +/* Indique le type défini pour un format d'exécutable ELF. */ +GType g_elf_format_get_type(void); + +/* Prend en charge un nouveau format ELF. */ +GBinFormat *g_elf_format_new(const bin_t *, off_t); + + + +#endif  /* _FORMAT_ELF_ELF_H */ diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h new file mode 100644 index 0000000..bbd6117 --- /dev/null +++ b/src/format/elf/elf_def.h @@ -0,0 +1,388 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * elf_def.h - liste des structures et constantes utilisées par le format ELF + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_ELF_ELF_DEF_H +#define _FORMAT_ELF_ELF_DEF_H + + +#include <stdint.h> + + + +/* Adresses virtuelles */ +typedef union _elf_addr +{ +    uint32_t addr32;                        /* Elf 32 bits                 */ +    uint64_t addr64;                        /* Elf 64 bits                 */ + +} elf_addr; + +/* Positions dans le fichier */ +typedef union _elf_off +{ +    uint32_t off32;                         /* Elf 32 bits                 */ +    uint64_t off64;                         /* Elf 64 bits                 */ + +} elf_off; + + +#define ELF_OFF(fmt, off) (fmt->is_32b ? (off).off32 : (off).off64) + + + +/* ---------------------------- EN-TETE DES FICHIERS ELF ---------------------------- */ + + +#define EI_NIDENT   16 + + +/* En-tête de fichier ELF */ +typedef struct _elf_header +{ +    uint8_t e_ident[EI_NIDENT];             /* Magic number + informations */ +    uint16_t e_type;                        /* Type de fichier             */ +    uint16_t e_machine;                     /* Architecture                */ +    uint32_t e_version;                     /* Version du type de fichier  */ +    elf_addr e_entry;                       /* Point d'entrée du programme */ +    elf_off e_phoff;                        /* Début de la table 'Program' */ +    elf_off e_shoff;                        /* Début de la table 'Section' */ +    uint32_t e_flags;                       /* Prop. spécifiques au proc.  */ +    uint16_t e_ehsize;                      /* Taille de l'en-tête en oct. */ +    uint16_t e_phentsize;                   /* Taille d'une entrée Program */ +    uint16_t e_phnum;                       /* Nombre d'éléments 'Program' */ +    uint16_t e_shentsize;                   /* Taille d'une entrée Section */ +    uint16_t e_shnum;                       /* Nombre d'éléments 'Section' */ +    uint16_t e_shstrndx;                    /* Indice de la section chaînes*/ + +} elf_header; + + +/* Composition du champ e_ident */ + + +#define EI_CLASS        4                   /* Indice de classe du fichier */ +#define EI_DATA         5                   /* Indice de l'encodage        */ + + +/* ... EI_CLASS */ + +#define ELFCLASSNONE    0                   /* Objet invalide              */ +#define ELFCLASS32      1                   /* Objet 32 bits               */ +#define ELFCLASS64      2                   /* Objet 64 bits               */ + +/* ... EI_DATA */ + +#define ELFDATANONE     0                   /* Encodage invalide           */ +#define ELFDATA2LSB     1                   /* Complément à 2, petit bout. */ +#define ELFDATA2MSB     2                   /* Complément à 2, grand bout. */ + + +/* Valeurs possibles pour e_machine */ + +#define EM_NONE         0                   /* Aucune machine              */ +#define EM_386          3                   /* Intel 80386                 */ +#define EM_MIPS         8                   /* MIPS R3000 big-endian       */ +#define EM_MIPS_RS3_LE  10                  /* MIPS R3000 little-endian    */ + + + +/* --------------------------- EN-TETE DES PROGRAMMES ELF --------------------------- */ + + +/* Version 32 et 64 bits */ + + +typedef struct _elf32_phdr +{ +    uint32_t p_type;                        /* Type de segment             */ +    uint32_t p_offset;                      /* Position dans le fichier    */ +    uint32_t p_vaddr;                       /* Adresse virtuelle du segment*/ +    uint32_t p_paddr;                       /* Adresse physique du segment */ +    uint32_t p_filesz;                      /* Taille dans le fichier      */ +    uint32_t p_memsz;                       /* Taille en mémoire           */ +    uint32_t p_flags;                       /* Drapeaux pour le segment    */ +    uint32_t p_align;                       /* Alignement du segment       */ + +} elf32_phdr; + +typedef struct _elf64_phdr +{ +    uint32_t p_type;                        /* Type de segment             */ +    uint32_t p_flags;                       /* Drapeaux pour le segment    */ +    uint64_t p_offset;                      /* Position dans le fichier    */ +    uint64_t p_vaddr;                       /* Adresse virtuelle du segment*/ +    uint64_t p_paddr;                       /* Adresse physique du segment */ +    uint64_t p_filesz;                      /* Taille dans le fichier      */ +    uint64_t p_memsz;                       /* Taille en mémoire           */ +    uint64_t p_align;                       /* Alignement du segment       */ + +} elf64_phdr; + +typedef union _elf_phdr +{ +    elf32_phdr phdr32;                      /* Version 32 bits             */ +    elf64_phdr phdr64;                      /* Version 32 bits             */ + +} elf_phdr; + + +#define ELF_PHDR(fmt, hdr, fld) (fmt->is_32b ? hdr.phdr32.fld : hdr.phdr64.fld) + +#define ELF_SIZEOF_PHDR(fmt) (fmt->is_32b ? sizeof(elf32_phdr) : sizeof(elf64_phdr)) + + +/* Valeurs possibles pour p_flags */ + +#define PF_X    (1 << 0)                    /* Le segment est exécutable   */ +#define PF_W    (1 << 1)                    /* Le segment est écrasable    */ +#define PF_R    (1 << 2)                    /* Le segment est lisible      */ + + + +/* ---------------------------- EN-TETE DES SECTIONS ELF ---------------------------- */ + + +/* Version 32 et 64 bits */ + +typedef struct _elf32_shdr +{ +    uint32_t sh_name;                       /* Indice du nom de la section */ +    uint32_t sh_type;                       /* Type de section             */ +    uint32_t sh_flags;                      /* Drapeaux pour la section    */ +    uint32_t sh_addr;                       /* Adresse virtuelle à l'exec. */ +    uint32_t sh_offset;                     /* Position dans le fichier    */ +    uint32_t sh_size;                       /* Taille en octets            */ +    uint32_t sh_link;                       /* Lien vers une autre section */ +    uint32_t sh_info;                       /* Infos. complémentaires      */ +    uint32_t sh_addralign;                  /* Alignement de la section    */ +    uint32_t sh_entsize;                    /* Eventuelle taille d'élément */ + +} elf32_shdr; + +typedef struct _elf64_shdr +{ +    uint32_t sh_name;                       /* Indice du nom de la section */ +    uint32_t sh_type;                       /* Type de section             */ +    uint64_t sh_flags;                      /* Drapeaux pour la section    */ +    uint64_t sh_addr;                       /* Adresse virtuelle à l'exec. */ +    uint64_t sh_offset;                     /* Position dans le fichier    */ +    uint64_t sh_size;                       /* Taille en octets            */ +    uint32_t sh_link;                       /* Lien vers une autre section */ +    uint32_t sh_info;                       /* Infos. complémentaires      */ +    uint64_t sh_addralign;                  /* Alignement de la section    */ +    uint64_t sh_entsize;                    /* Eventuelle taille d'élément */ + +} elf64_shdr; + +typedef union _elf_shdr +{ +    elf32_shdr shdr32;                      /* Version 32 bits             */ +    elf64_shdr shdr64;                      /* Version 32 bits             */ + +} elf_shdr; + + +#define ELF_SHDR(fmt, shdr, fld) (fmt->is_32b ? (shdr).shdr32.fld : (shdr).shdr64.fld) + +#define ELF_SIZEOF_SHDR(fmt) (fmt->is_32b ? sizeof(elf32_shdr) : sizeof(elf64_shdr)) + + +/* Valeurs possibles pour sh_type */ + +#define SHT_NULL        0                   /* Entrée non utilisée         */ +#define SHT_PROGBITS    1                   /* Données de programme        */ +#define SHT_SYMTAB      2                   /* Table des symboles          */ +#define SHT_STRTAB      3                   /* Table de chaînes de carac.  */ +#define SHT_DYNAMIC     6                   /* Info. de liaison dynamique  */ + + +/* Valeurs possibles pour sh_flags */ + +#define SHF_ALLOC       (1 << 1)            /* Copie en mémoire pdt l'exec.*/ +#define SHF_EXECINSTR   (1 << 2)            /* Section exécutable          */ +#define SHF_STRINGS     (1 << 5)            /* Contient des chaînes ('\0') */ + + + +/* ----------------------------- DONNEES POUR LE LINKER ----------------------------- */ + + +/* Entrées de la section dynamique (version 32 et 64 bits) */ + +typedef struct _elf32_dyn +{ +    int32_t d_tag;                          /* Type de l'entrée            */ + +    union +    { +        uint32_t d_val;                     /* Valeur entière              */ +        uint32_t d_ptr;                     /* Valeur d'adresse            */ + +    } d_un; + +} elf32_dyn; + +typedef struct _elf64_dyn +{ +    int64_t d_tag;                          /* Type de l'entrée            */ + +    union +    { +        uint64_t d_val;                     /* Valeur entière              */ +        uint64_t d_ptr;                     /* Valeur d'adresse            */ + +    } d_un; + +} elf64_dyn; + +typedef union _elf_dyn +{ +    elf32_dyn dyn32;                        /* Version 32 bits             */ +    elf64_dyn dyn64;                        /* Version 32 bits             */ + +} elf_dyn; + + +#define ELF_DYN(fmt, dyn, fld) (fmt->is_32b ? (dyn).dyn32.fld : (dyn).dyn64.fld) + +#define ELF_SIZEOF_DYN(fmt) (fmt->is_32b ? sizeof(elf32_dyn) : sizeof(elf64_dyn)) + + + +/* Valeurs possibles pour d_tag */ + +#define DT_SYMTAB       6                   /* Table des symboles          */ +#define DT_JMPREL       23                  /* Relocalisations PLT         */ + + + +/* ---------------------------- SYMBOLES DE BINAIRES ELF ---------------------------- */ + + +/* Elément de la table des symboles */ + +typedef struct _elf32_sym +{ +    uint32_t st_name;                       /* Indice pour le nom          */ +    uint32_t st_value;                      /* Valeur du symbole           */ +    uint32_t st_size;                       /* Taille du symbole           */ +    unsigned char st_info;                  /* Type et infos. du symbole   */ +    unsigned char st_other;                 /* Visibilité du symbole       */ +    uint16_t st_shndx;                      /* Indice de la section        */ + +} elf32_sym; + +typedef struct _elf64_sym +{ +    uint32_t st_name;                       /* Indice pour le nom          */ +    unsigned char st_info;                  /* Type et infos. du symbole   */ +    unsigned char st_other;                 /* Visibilité du symbole       */ +    uint16_t st_shndx;                      /* Indice de la section        */ +    uint64_t st_value;                      /* Valeur du symbole           */ +    uint64_t st_size;                       /* Taille du symbole           */ + +} elf64_sym; + +typedef union _elf_sym +{ +    elf32_sym sym32;                        /* Version 32 bits             */ +    elf64_sym sym64;                        /* Version 64 bits             */ + +} elf_sym; + + +#define ELF_SYM(fmt, sb, fld) (fmt->is_32b ? sb.sym32.fld : sb.sym64.fld) + +#define ELF_ST_BIND(fmt, sym) (fmt->is_32b ? ELF32_ST_BIND(sym.sym32.st_info) : ELF64_ST_BIND(sym.sym64.st_info)) +#define ELF_ST_TYPE(fmt, sym) (fmt->is_32b ? ELF32_ST_TYPE(sym.sym32.st_info) : ELF64_ST_TYPE(sym.sym64.st_info)) + +#define ELF_SIZEOF_SYM(fmt) (fmt->is_32b ? sizeof(elf32_sym) : sizeof(elf64_sym)) + + +/* Extraction des informations de st_info */ + +#define ELF32_ST_BIND(val)      (((unsigned char)(val)) >> 4) +#define ELF32_ST_TYPE(val)      ((val) & 0xf) + +#define ELF64_ST_BIND(val)      ELF32_ST_BIND(val) +#define ELF64_ST_TYPE(val)      ELF32_ST_TYPE(val) + +/* Valeurs pour le sous-champ ST_TYPE de st_info  */ + +#define STT_NOTYPE  0                       /* Type de symbole non spécifié*/ +#define STT_OBJECT  1                       /* Symbole, objet de données   */ +#define STT_FUNC    2                       /* Symbole, objet de code      */ + + + +/* ------------------------- INFORMATIONS DE RELOCALISATION ------------------------- */ + + +/* Entrée de la table de relocalisation */ + +typedef struct _elf32_rel +{ +    uint32_t r_offset;                      /* Adresse                     */ +    uint32_t r_info;			            /* Indice de type et symbole   */ + +} elf32_rel; + +typedef struct _elf64_rel +{ +    uint64_t r_offset;                      /* Adresse                     */ +    uint64_t r_info;			            /* Indice de type et symbole   */ + +} elf64_rel; + +typedef union _elf_rel +{ +    elf32_rel rel32;                        /* Version 32 bits             */ +    elf64_rel rel64;                        /* Version 64 bits             */ + +} elf_rel; + + +#define ELF_REL(fmt, rl, fld) (fmt->is_32b ? rl.rel32.fld : rl.rel64.fld) + +#define ELF_REL_SYM(fmt, rl) (fmt->is_32b ? ELF32_R_SYM(rl.rel32.r_info) : ELF64_R_SYM(rl.rel64.r_info)) +#define ELF_REL_TYPE(fmt, rl) (fmt->is_32b ? ELF32_R_TYPE(rl.rel32.r_info) : ELF64_R_TYPE(rl.rel64.r_info)) + +#define ELF_SIZEOF_REL(fmt) (fmt->is_32b ? sizeof(elf32_rel) : sizeof(elf64_rel)) + + +/* Extraction des informations de r_info */ + +#define ELF32_R_SYM(val)        ((val) >> 8) +#define ELF32_R_TYPE(val)       ((val) & 0xff) + +#define ELF64_R_SYM(val)        ((val) >> 32) +#define ELF64_R_TYPE(val)       ((val) & 0xffffffff) + +/* Type de relocalisation (x86) */ + +#define R_386_NONE          0               /* Pas de relocalisation       */ +#define R_386_JMP_SLOT      7               /* Entrée PLT                  */ + + + +#endif  /* _FORMAT_ELF_ELF_DEF_H */ diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c index 1975709..82be74c 100644 --- a/src/format/elf/helper_x86.c +++ b/src/format/elf/helper_x86.c @@ -25,37 +25,117 @@  #include <malloc.h> +#include <stdio.h>  #include <string.h>  #include "elf-int.h" -#include "section.h" +#include "../symbol.h"  #include "../../arch/immediate.h"  #include "../../arch/processor.h"  #include "../../arch/x86/instruction.h" -#include "../../panel/log.h" -#define _(str)  (str) - +/* 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(elf_format *, size_t *); +GArchInstruction **decode_elf_relocations(GElfFormat *, const elf_shdr *, size_t *);  /* Déduit les adresses effectives des relocalisations. */ -void translate_elf_relocations(elf_format *, GArchInstruction **, size_t); +void translate_elf_relocations(GElfFormat *, GArchInstruction **, size_t);  /******************************************************************************  *                                                                             * -*  Paramètres  : format    = description de l'exécutable à compléter.         * -*                dyn_start = début des informations dynamiques associées.     * -*                dyn_size  = taille de la zone associée.                      * -*                str_start = début de la zone de chaîne de caractères.        * -*                str_size  = taille de la zone de chaînes de caractères.      * +*  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, name, ELF_REL(format, reloc, r_offset)); +                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). *  *                                                                             *  *  Description : Déduit les adresses effectives des appels externes.          *  *                                                                             * @@ -65,13 +145,13 @@ void translate_elf_relocations(elf_format *, GArchInstruction **, size_t);  *                                                                             *  ******************************************************************************/ -bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start, off_t dyn_size, off_t str_start, off_t str_size) +bool find_elf_x86_dynamic_symbols(GElfFormat *format, const elf_shdr *plt)  {      GArchInstruction **instructions;        /* Instructions décodées       */      size_t count;                           /* Quantité d'instructions     */      size_t i;                               /* Boucle de parcours          */ -    instructions = decode_elf_relocations(format, &count); +    instructions = decode_elf_relocations(format, plt, &count);      translate_elf_relocations(format, instructions, count); @@ -89,6 +169,7 @@ bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start,  /******************************************************************************  *                                                                             *  *  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.           * @@ -99,15 +180,12 @@ bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start,  *                                                                             *  ******************************************************************************/ -GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count) +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  */ -    Elf_Shdr *sections;                     /* Groupe de sections trouvées */ -    size_t sec_count;                       /* Quantité de données         */ -    size_t i;                               /* Boucle de parcours          */      GArchProcessor *proc;                   /* Processeur pour le décodage */      off_t pos;                              /* Tête de lecture             */      vmpa_t address;                         /* Adresse virtuelle courante  */ @@ -116,26 +194,7 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count)      result = NULL;      *count = 0; -    if (!find_elf_section_content_by_name(format, ".plt", &plt_start, &plt_size, &plt_address)) -    { -        log_simple_message(LMT_BAD_BINARY, _("No .plt section found ! Trying to guess it...")); - -        /* FIXME : 64 bits ! */ - -        find_elf_section_by_type(format, SHT_PROGBITS, §ions, &sec_count); - -        for (i = 0; i < sec_count; i++) -            if (ELF_SHDR(format, §ions[i], sh_entsize) > 0) -            { -                get_elf_section_content(format, §ions[i], &plt_start, &plt_size, &plt_address); -                break; -            } - -        free(sections); - -        if (i == sec_count) return NULL; - -    } +    get_elf_section_content(format, plt, &plt_start, &plt_size, &plt_address);      proc = get_arch_processor_for_type(APT_386); @@ -143,7 +202,7 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count)      {          address = plt_address + pos; -        instr = g_arch_processor_decode_instruction(proc, &EXE_FORMAT(format)->content[plt_start], +        instr = g_arch_processor_decode_instruction(proc, &G_BIN_FORMAT(format)->content[plt_start],                                                      &pos, plt_size, 0/* FIXME*/, address);          result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *)); @@ -170,18 +229,21 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count)  *                                                                             *  ******************************************************************************/ -void translate_elf_relocations(elf_format *format, GArchInstruction **instructions, size_t count) +void translate_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 */ -    GArchOperand *operand;                  /* Valeur du saut              */ +    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; )      { @@ -195,31 +257,39 @@ void translate_elf_relocations(elf_format *format, GArchInstruction **instructio          {              operand = g_arch_instruction_get_operand(instructions[i], 0); -              g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address);              if (g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address)) -                for (j = 0; j < format->rel_count; j++) -                    if (format->relocations[j].address == address) +            { +                symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &symbols_count); + +                for (j = 0; j < symbols_count; j++) +                    if (g_binary_symbol_get_address(symbols[j]) == address)                      { -                        new_len = strlen(format->relocations[j].name) + 4 + 1; +                        new_len = strlen(g_binary_symbol_to_string(symbols[j])) + 4 + 1;                          new_name = calloc(new_len, sizeof(char)); -                        snprintf(new_name, new_len, "%s@plt", format->relocations[j].name); +                        snprintf(new_name, new_len, "%s@plt", g_binary_symbol_to_string(symbols[j]));                          g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); +                        /* Routine */ +                          routine = g_binary_routine_new();                          g_binary_routine_set_name(routine, new_name);                          g_binary_routine_set_address(routine, address); -                        format->routines = (GBinRoutine **)realloc(format->routines, -                                                       ++format->routines_count * sizeof(GBinRoutine *)); +                        g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + +                        /* Symbole uniquement */ -                        format->routines[format->routines_count - 1] = routine; +                        symbol = g_binary_symbol_new(STP_FUNCTION, new_name, address); +                        g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);                      } +            } +              i += 3;          } diff --git a/src/format/elf/helper_x86.h b/src/format/elf/helper_x86.h index 957c8c3..eae7c8b 100644 --- a/src/format/elf/helper_x86.h +++ b/src/format/elf/helper_x86.h @@ -25,16 +25,15 @@  #define _FORMAT_ELF_HELPER_X86_H -#include <stdbool.h> -#include <sys/types.h> +#include "section.h" -#include "e_elf.h" - +/* Charge en mémoire la liste des symboles dynamiques. */ +bool load_elf_x86_relocated_symbols(GElfFormat *, const elf_shdr *, const elf_shdr *, const elf_shdr *);  /* Déduit les adresses effectives des appels externes. */ -bool g_elf_format_find_x86_dynamic_symbols(elf_format *, off_t, off_t, off_t, off_t); +bool find_elf_x86_dynamic_symbols(GElfFormat *, const elf_shdr *); diff --git a/src/format/elf/section.c b/src/format/elf/section.c index c619293..940acdf 100644 --- a/src/format/elf/section.c +++ b/src/format/elf/section.c @@ -34,9 +34,11 @@  /******************************************************************************  *                                                                             * -*  Paramètres  : format = description de l'exécutable à compléter.            * +*  Paramètres  : format  = description de l'exécutable à consulter.           * +*                index   = indice de la section recherchée.                   * +*                section = ensemble d'informations à faire remonter. [OUT]    *  *                                                                             * -*  Description : Charge en mémoire la liste humaine des sections.             * +*  Description : Recherche une section donnée au sein de binaire par indice.  *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -44,25 +46,15 @@  *                                                                             *  ******************************************************************************/ -bool read_elf_section_names(elf_format *format) +bool find_elf_section_by_index(const GElfFormat *format, uint16_t index, elf_shdr *section)  { -    off_t offset;                           /* Position des données        */ -    Elf32_Shdr section;                     /* Section visée               */ - -    offset = format->header.e_shoff + format->header.e_shentsize * format->header.e_shstrndx; - -    if ((offset + sizeof(Elf32_Shdr)) > EXE_FORMAT(format)->length) return false; - -    memcpy(§ion, &EXE_FORMAT(format)->content[offset], sizeof(Elf32_Shdr)); - -    if ((section.sh_offset + section.sh_size) > EXE_FORMAT(format)->length) return false; +    off_t offset;                           /* Emplacement à venir lire    */ -    format->sec_names = (char *)calloc(section.sh_size + 1, sizeof(char)); -    format->sec_size = section.sh_size; +    if (index >= format->header.e_shnum) return false; -    memcpy(format->sec_names, &EXE_FORMAT(format)->content[section.sh_offset], section.sh_size); +    offset = ELF_OFF(format, format->header.e_shoff) + format->header.e_shentsize * index; -    return true; +    return read_elf_section_header(format, offset, section);  } @@ -81,13 +73,15 @@ bool read_elf_section_names(elf_format *format)  *                                                                             *  ******************************************************************************/ -bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Shdr *section) +bool find_elf_section_by_name(const GElfFormat *format, const char *name, elf_shdr *section)  { -    bool result;                            /* Bilan à retourner           */ +    bool result;                            /* Bilan à faire remonter      */ +    elf_shdr strings;                       /* Section des descriptions    */      uint16_t i;                             /* Boucle de parcours          */ +    const char *secname;                    /* Nom d'une section analysée  */ -    /* Si on perd notre temps... */ -    if (format->sec_size == 0) return false; +    if (!find_elf_section_by_index(format, format->header.e_shstrndx, &strings)) +        return false;      result = false; @@ -95,7 +89,10 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh      {          find_elf_section_by_index(format, i, section); -        result = (strcmp(name, &format->sec_names[ELF_SHDR(format, section, sh_name)]) == 0); +        secname = extract_name_from_elf_string_section(format, &strings, +                                                       ELF_SHDR(format, *section, sh_name)); + +        result = (strcmp(name, secname) == 0);      } @@ -106,10 +103,9 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh  /******************************************************************************  *                                                                             * -*  Paramètres  : format   = description de l'exécutable à consulter.          * -*                type     = type de la section recherchée.                    * -*                sections = tableau d'informations à faire remonter. [OUT]    * -*                count    = nombre d'éléments présents dans le tableau. [OUT] * +*  Paramètres  : format  = description de l'exécutable à consulter.           * +*                addr    = adresse de la section recherchée. (32 bits)        * +*                section = ensemble d'informations à faire remonter. [OUT]    *  *                                                                             *  *  Description : Recherche une section donnée au sein de binaire par type.    *  *                                                                             * @@ -119,38 +115,34 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh  *                                                                             *  ******************************************************************************/ -bool find_elf_section_by_type(const elf_format *format, uint16_t type, Elf_Shdr **sections, size_t *count) +bool find_elf_section_by_virtual_address(const GElfFormat *format, uint32_t addr, elf_shdr *section)  { +    bool result;                            /* Bilan à faire remonter      */      uint16_t i;                             /* Boucle de parcours          */ -    Elf_Shdr section;                       /* Section à analyser          */ -    *sections = NULL; -    *count = 0; +    result = false; -    for (i = 0; i < format->header.e_shnum; i++) +    for (i = 0; i < format->header.e_shnum && !result; i++)      { -        find_elf_section_by_index(format, i, §ion); +        find_elf_section_by_index(format, i, section); -        if (type == ELF_SHDR(format, §ion, sh_type)) -        { -            *sections = (Elf_Shdr *)realloc(*sections, ++(*count) * sizeof(Elf_Shdr)); -            (*sections)[*count - 1] = section; -        } +        result = (addr == ELF_SHDR(format, *section, sh_addr));      } -    return (*count > 0); +    return result;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : format  = description de l'exécutable à consulter.           * -*                index   = indice de la section recherchée.                   * -*                section = ensemble d'informations à faire remonter. [OUT]    * +*  Paramètres  : format   = description de l'exécutable à consulter.          * +*                type     = type de la section recherchée.                    * +*                sections = tableau d'informations à faire remonter. [OUT]    * +*                count    = nombre d'éléments présents dans le tableau. [OUT] *  *                                                                             * -*  Description : Recherche une section donnée au sein de binaire par indice.  * +*  Description : Recherche une section donnée au sein de binaire par type.    *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -158,17 +150,27 @@ bool find_elf_section_by_type(const elf_format *format, uint16_t type, Elf_Shdr  *                                                                             *  ******************************************************************************/ -bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shdr *section) +bool find_elf_sections_by_type(const GElfFormat *format, uint32_t type, elf_shdr **sections, size_t *count)  { -    off_t offset;                           /* Emplacement à venir lire    */ +    uint16_t i;                             /* Boucle de parcours          */ +    elf_shdr section;                       /* Section à analyser          */ -    if (index >= format->header.e_shnum) return false; +    *sections = NULL; +    *count = 0; -    offset = format->header.e_shoff + format->header.e_shentsize * index; +    for (i = 0; i < format->header.e_shnum; i++) +    { +        find_elf_section_by_index(format, i, §ion); -    memcpy(section, &EXE_FORMAT(format)->content[offset], ELF_SIZEOF_SHDR(format)); +        if (type == ELF_SHDR(format, section, sh_type)) +        { +            *sections = (elf_shdr *)realloc(*sections, ++(*count) * sizeof(elf_shdr)); +            (*sections)[*count - 1] = section; +        } + +    } -    return true; +    return (*count > 0);  } @@ -179,7 +181,7 @@ bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shd  *                section = section à consulter.                               *  *                offset  = position de la section trouvée. [OUT]              *  *                size    = taille de la section trouvée. [OUT]                * -*                voffset = adresse virtuelle de la section trouvée. [OUT]     * +*                addr    = adresse virtuelle de la section trouvée. [OUT]     *  *                                                                             *  *  Description : Fournit les adresses et taille contenues dans une section.   *  *                                                                             * @@ -189,13 +191,13 @@ bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shd  *                                                                             *  ******************************************************************************/ -void get_elf_section_content(const elf_format *format, const Elf_Shdr *section, off_t *offset, off_t *size, uint64_t *voffset) +void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, off_t *offset, off_t *size, vmpa_t *addr)  { -    *offset = ELF_SHDR(format, section, sh_offset); -    *size = ELF_SHDR(format, section, sh_size); +    *offset = ELF_SHDR(format, *section, sh_offset); +    *size = ELF_SHDR(format, *section, sh_size); -    if (voffset != NULL) -        *voffset = ELF_SHDR(format, section, sh_addr); +    if (addr != NULL) +        *addr = ELF_SHDR(format, *section, sh_addr);  } @@ -206,7 +208,7 @@ void get_elf_section_content(const elf_format *format, const Elf_Shdr *section,  *                name    = nom de la section recherchée.                      *  *                offset  = position de la section trouvée. [OUT]              *  *                size    = taille de la section trouvée. [OUT]                * -*                voffset = adresse virtuelle de la section trouvée. [OUT]     * +*                address = adresse virtuelle de la section trouvée. [OUT]     *  *                                                                             *  *  Description : Recherche une zone donnée au sein de binaire par nom.        *  *                                                                             * @@ -216,15 +218,15 @@ void get_elf_section_content(const elf_format *format, const Elf_Shdr *section,  *                                                                             *  ******************************************************************************/ -bool find_elf_section_content_by_name(const elf_format *format, const char *name, off_t *offset, off_t *size, uint64_t *voffset) +bool find_elf_section_content_by_name(const GElfFormat *format, const char *name, off_t *offset, off_t *size, vmpa_t *address)  {      bool result;                            /* Bilan à retourner           */ -    Elf_Shdr section;                       /* Section trouvée ou non      */ +    elf_shdr section;                       /* Section trouvée ou non      */      result = find_elf_section_by_name(format, name, §ion);      if (result) -        get_elf_section_content(format, §ion, offset, size, voffset); +        get_elf_section_content(format, §ion, offset, size, address);      return result; @@ -234,28 +236,39 @@ bool find_elf_section_content_by_name(const elf_format *format, const char *name  /******************************************************************************  *                                                                             *  *  Paramètres  : format  = description de l'exécutable à consulter.           * -*                index   = indice de la section recherchée.                   * -*                offset  = position de la section trouvée. [OUT]              * -*                size    = taille de la section trouvée. [OUT]                * -*                voffset = adresse virtuelle de la section trouvée. [OUT]     * +*                section = section contenant des chaînes terminées par '\0'.  * +*                index   = indice du premier caractères à cerner.             *  *                                                                             * -*  Description : Recherche une zone donnée au sein de binaire par indice.     * +*  Description : Identifie une chaîne de caractères dans une section adéquate.*  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : Pointeur vers la chaîne recherchée ou NULL en cas d'échec.   *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool find_elf_section_content_by_index(const elf_format *format, uint16_t index, off_t *offset, off_t *size, uint64_t *voffset) +const char *extract_name_from_elf_string_section(const GElfFormat *format, const elf_shdr *section, uint16_t index)  { -    bool result;                            /* Bilan à retourner           */ -    Elf_Shdr section;                       /* Section trouvée ou non      */ +    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            */ -    result = find_elf_section_by_index(format, index, §ion); +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; -    if (result) -        get_elf_section_content(format, §ion, offset, size, voffset); +    last = ELF_SHDR(format, *section, sh_offset) + ELF_SHDR(format, *section, sh_size); + +    pos = ELF_SHDR(format, *section, sh_offset) + index; + +    if ((pos + 1) >= MIN(length, last)) +        return NULL; + +    result = (const char *)&content[pos]; + +    if ((pos + strlen(result)) > last) +        return NULL;      return result; diff --git a/src/format/elf/section.h b/src/format/elf/section.h index 6bc3a75..944fd7c 100644 --- a/src/format/elf/section.h +++ b/src/format/elf/section.h @@ -25,47 +25,31 @@  #define _FORMAT_ELF_SECTION_H -#include <elf.h> +#include "elf.h" +#include "elf_def.h" -#include "e_elf.h" - -/* 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_SIZEOF_SHDR(fmt) (fmt->is_32b ? sizeof(Elf32_Shdr) : sizeof(Elf64_Shdr)) - -#define ELF_SHDR(fmt, shdr, fld) (fmt->is_32b ? (shdr)->section32.fld : (shdr)->section64.fld) - - - -/* Charge en mémoire la liste humaine des sections. */ -bool read_elf_section_names(elf_format *); +/* Recherche une section donnée au sein de binaire par indice. */ +bool find_elf_section_by_index(const GElfFormat *, uint16_t, elf_shdr *);  /* Recherche une section donnée au sein de binaire par nom. */ -bool find_elf_section_by_name(const elf_format *, const char *, 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_type(const elf_format *, uint16_t, Elf_Shdr **, size_t *); +bool find_elf_section_by_virtual_address(const GElfFormat *, uint32_t, elf_shdr *); -/* Recherche une section donnée au sein de binaire par indice. */ -bool find_elf_section_by_index(const elf_format *, uint16_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 elf_format *, const Elf_Shdr *, off_t *, off_t *, uint64_t *); +void get_elf_section_content(const GElfFormat *, const elf_shdr *, off_t *, off_t *, vmpa_t *);  /* Recherche une zone donnée au sein de binaire par nom. */ -bool find_elf_section_content_by_name(const elf_format *, const char *, off_t *, off_t *, uint64_t *); +bool find_elf_section_content_by_name(const GElfFormat *, const char *, off_t *, off_t *, vmpa_t *); -/* Recherche une zone donnée au sein de binaire par indice. */ -bool find_elf_section_content_by_index(const elf_format *, uint16_t, off_t *, off_t *, uint64_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 *, uint16_t); diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c index 2bcd911..157d3b5 100644 --- a/src/format/elf/strings.c +++ b/src/format/elf/strings.c @@ -27,6 +27,7 @@  #include <ctype.h>  #include <malloc.h>  #include <string.h> +#include <sys/param.h>  #include "elf-int.h" @@ -35,7 +36,7 @@  /* Enregistre toutes les chaînes de caractères trouvées. */ -bool parse_elf_string_data(elf_format *, const off_t, const off_t, uint64_t); +bool parse_elf_string_data(GElfFormat *, off_t, off_t, vmpa_t); @@ -51,63 +52,81 @@ bool parse_elf_string_data(elf_format *, const off_t, const off_t, uint64_t);  *                                                                             *  ******************************************************************************/ -bool find_all_elf_strings(elf_format *format) +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           */ -    uint64_t str_vaddr;                     /* Adresse virtuelle associée  */ -    Elf_Shdr *sections;                     /* Groupe de sections trouvées */ +    vmpa_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          */ -    off_t offset;                           /* Position physique           */ -    Elf_Phdr phdr;                          /* En-tête de programme ELF    */ +    size_t i;                               /* Boucle de parcours #1       */ +    off_t length;                           /* Taille totale du contenu    */ +    off_t iter;                             /* Boucle de parcours #2       */ +    elf_phdr phdr;                          /* En-tête de programme ELF    */ + +    got_string = false;      /* Données en lecture seule */ -    if (find_elf_section_content_by_name(format, ".rodata", &str_start, &str_size, &str_vaddr)) -        parse_elf_string_data(format, str_start, str_size, str_vaddr); +    if (find_elf_section_content_by_name(format, ".rodata", &str_start, &str_size, &str_addr)) +        got_string |= parse_elf_string_data(format, str_start, str_size, str_addr);      else      { -        find_elf_section_by_type(format, SHT_PROGBITS, §ions, &count); +        if (find_elf_sections_by_type(format, SHT_PROGBITS, §ions, &count)) +        { +            for (i = 0; i < count; i++) +                if (ELF_SHDR(format, sections[i], sh_flags) == SHF_ALLOC +                    || (ELF_SHDR(format, sections[i], sh_flags) & SHF_STRINGS)) +                { +                    get_elf_section_content(format, §ions[i], &str_start, &str_size, &str_addr); +                    got_string |= parse_elf_string_data(format, str_start, str_size, str_addr); +                } -        for (i = 0; i < count; i++) -            if (ELF_SHDR(format, §ions[i], sh_flags) == SHF_ALLOC -                || (ELF_SHDR(format, §ions[i], sh_flags) & SHF_STRINGS)) -            { -                get_elf_section_content(format, §ions[i], &str_start, &str_size, &str_vaddr); -                parse_elf_string_data(format, str_start, str_size, str_vaddr); -            } +            free(sections); + +        }      }      /* Chaîne de caractères déclarées */ -    find_elf_section_by_type(format, SHT_STRTAB, §ions, &count); - -    for (i = 0; i < count; i++) +    if (find_elf_sections_by_type(format, SHT_STRTAB, §ions, &count))      { -        get_elf_section_content(format, §ions[i], &str_start, &str_size, &str_vaddr); -        parse_elf_string_data(format, str_start, str_size, str_vaddr); +        for (i = 0; i < count; i++) +        { +            get_elf_section_content(format, §ions[i], &str_start, &str_size, &str_addr); +            got_string |= parse_elf_string_data(format, str_start, str_size, str_addr); +        } + +        free(sections); +      }      /* En désespoir de cause, on se rabbat sur les parties de programme directement */ -    if (format->str_count == 0 && format->header.e_shnum == 0 /* FIXME : cond. à garder ? */) -        for (i = 0; i < format->header.e_phnum; i++) -        { -            offset = format->header.e_phoff + format->header.e_phentsize * i; -            if ((offset + format->header.e_phentsize) >= EXE_FORMAT(format)->length) continue; +    if (!got_string) +    { +        length = G_BIN_FORMAT(format)->length; +        length = MIN(length, format->header.e_phnum * ELF_SIZEOF_PHDR(format)); -            memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize); +        for (iter = ELF_OFF(format, format->header.e_phoff); iter < length; ) +        { +            if (!read_elf_program_header(format, &iter, &phdr)) +                continue; -            if (ELF_PHDR(format, &phdr, p_flags) & PF_R && !(ELF_PHDR(format, &phdr, p_flags) & PF_X)) -                parse_elf_string_data(format, ELF_PHDR(format, &phdr, p_offset), -                                      ELF_PHDR(format, &phdr, p_filesz), -                                      ELF_PHDR(format, &phdr, p_vaddr)); +            if (ELF_PHDR(format, phdr, p_flags) & PF_R +                && !(ELF_PHDR(format, phdr, p_flags) & PF_X)) +                parse_elf_string_data(format, +                                      ELF_PHDR(format, phdr, p_offset), +                                      ELF_PHDR(format, phdr, p_filesz), +                                      ELF_PHDR(format, phdr, p_vaddr));          } +    } +      return true;  } @@ -115,77 +134,49 @@ bool find_all_elf_strings(elf_format *format)  /******************************************************************************  *                                                                             * -*  Paramètres  : format   = description de l'exécutable à compléter.          * -*                start    = début de la zone à parcourir.                     * -*                size     = taille de l'espace à parcourir.                   * -*                vaddress = adresse virtuelle du début de la section.         * +*  Paramètres  : format  = description de l'exécutable à compléter.           * +*                start   = début de la zone à parcourir.                      * +*                size    = taille de l'espace à parcourir.                    * +*                address = adresse virtuelle du début de la section.          *  *                                                                             *  *  Description : Enregistre toutes les chaînes de caractères trouvées.        *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : true si des chaînes ont été ajoutées, false sinon.           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool parse_elf_string_data(elf_format *format, const off_t start, const off_t size, uint64_t vaddress) +bool parse_elf_string_data(GElfFormat *format, off_t start, off_t size, vmpa_t address)  { +    bool result;                            /* Bilan à faire remonter      */ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */      off_t i;                                /* Boucle de parcours          */      off_t end;                              /* Position de fin de chaîne   */ +    GBinSymbol *symbol;                     /* Nouveau symbole construit   */ -    if (vaddress == 0) return false; - -    for (i = start; i < (start + size); i++) -        if (isprint(EXE_FORMAT(format)->content[i])) -        { -            for (end = i + 1; end < (start + size); end++) -                if (!isprint(EXE_FORMAT(format)->content[end])) break; -  -            format->strings = (elf_string *)realloc(format->strings, ++format->str_count * sizeof(elf_string)); - -            format->strings[format->str_count - 1].value = strndup((const char *)&EXE_FORMAT(format)->content[i], end - i); -            format->strings[format->str_count - 1].len = end - i; -            format->strings[format->str_count - 1].address = vaddress + i - start; - -            i = end; - -        } +    if (address == 0) return false; -    return true; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format  = informations chargées à consulter.                 * -*                label   = étiquette allouée du symbole si trouvé. [OUT]      * -*                vaddres = adresse à cibler, puis décallage final. [OUT]      * -*                                                                             * -*  Description : Recherche une chaîne correspondant à une adresse.            * -*                                                                             * -*  Retour      : true si l'opération a été un succès, false sinon.            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    result = false; -bool resolve_elf_strings(const elf_format *format, char **label, vmpa_t *address) -{ -    bool result;                            /* Bilan de recherche remonté  */ -    size_t real_start;                      /* Début de chaîne effective   */ -    size_t i;                               /* Boucle de parcours          */ +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; -    result = false; +    length = MIN(length, start + size); -    for (i = 0; i < format->str_count && !result; i++) -        if (format->strings[i].address <= *address -            && *address < (format->strings[i].address + format->strings[i].len)) +    for (i = start; i < length; i++) +        if (isprint(content[i]))          { -            real_start = *address - format->strings[i].address; -            *label = strndup(&format->strings[i].value[real_start], -                             format->strings[i].len - real_start); +            for (end = i + 1; end < length; end++) +                if (!isprint(content[end])) break; +  +            symbol = g_binary_symbol_new(STP_STRING, NULL, address + i - start); +            g_binary_symbol_set_alt_name(symbol, strndup((const char *)&content[i], end - i)); +            g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + +            i = end;              result = true;          } diff --git a/src/format/elf/strings.h b/src/format/elf/strings.h index f9b17ac..e52d054 100644 --- a/src/format/elf/strings.h +++ b/src/format/elf/strings.h @@ -25,15 +25,12 @@  #define _FORMAT_ELF_STRINGS_H -#include "e_elf.h" +#include "elf.h"  /*Charge en mémoire toutes les chaînes trouvées. */ -bool find_all_elf_strings(elf_format *); - -/* Recherche une chaîne correspondant à une adresse. */ -bool resolve_elf_strings(const elf_format *, char **, vmpa_t *); +bool find_all_elf_strings(GElfFormat *); diff --git a/src/format/elf/symbol.c b/src/format/elf/symbol.c deleted file mode 100644 index 35943e9..0000000 --- a/src/format/elf/symbol.c +++ /dev/null @@ -1,492 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * symbol.c - gestion des symboles d'un ELF - * - * Copyright (C) 2008 Cyrille Bagard - * - *  This file is part of OpenIDA. - * - *  OpenIDA 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. - * - *  OpenIDA 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 <http://www.gnu.org/licenses/>. - */ - - -#include "symbol.h" - - -#include <malloc.h> -#include <elf.h> -#include <stdio.h> -#include <string.h> - - -#include "elf-int.h" -#include "helper_mips.h" -#include "section.h" - - - - - -/* -------------------------- DETAIL DES SYMBOLES EXTERNES -------------------------- */ - - -/* Charge en mémoire la liste des symboles dynamiques. */ -bool load_elf_relocation_table(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *); - -/* Récupère les informations d'un symbole dynamique donné. */ -char *get_elf_dynamic_symbol_info(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *); - - - - -/* Charge en mémoire la liste humaine des symboles (32 bits). */ -bool load_elf_symbol_table_32(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *); - -/* Charge en mémoire la liste humaine des symboles (64 bits). */ -bool load_elf_symbol_table_64(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *); - - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à compléter.            * -*                                                                             * -*  Description : Charge en mémoire la liste humaine des symboles.             * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -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 rel_start;                        /* Début de section            */ -    off_t rel_size;                         /* Taille de section           */ - - -    bool test;                              /* Bilan d'une recherche       */ - -    off_t dyn_start;                        /* Début de section            */ -    off_t dyn_size;                         /* Taille de section           */ - - - -    result = true; - - -    /* Table des symboles */ - -    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 &= 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); - - - -        } - -    } - -    /* Relocalisations */ - - - -    /* TODO : fixme ! */ - -    find_elf_section_by_type(format, SHT_REL, §ions, &count); - -    for (i = 0; i < count; i++) -    { -        /* Section ".rel.xxx" */ - -        get_elf_section_content(format, §ions[i], &rel_start, &rel_size, NULL); - -        /* Section ".dynsym" */ - -        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); - -        get_elf_section_content(format, §ion, &str_start, &str_size, NULL); - -        /* Récupération (première partie) */ -        if (result) -        { - -            result = load_elf_relocation_table(format, &rel_start, &rel_size, &dyn_start, &dyn_size, &str_start, &str_size); - -   -        } - -    } - -    free(sections); - -    /* TODO : fixme ! */ - - - - - -    /* Liaison dynamique (si elle existe) */ - -    test = find_elf_section_by_name(format, ".dynsym", §ion); - -    if (!test) -    { -        test = find_elf_section_by_type(format, SHT_HASH, §ions, &count); - -        if (test) -            test = find_elf_section_by_index(format, ELF_SHDR(format, §ions[0], sh_link), §ion); - -    } - -    if (test) -    { -        get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); - -        result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - -    } - -    if (result) -    { -        get_elf_section_content(format, §ion, &str_start, &str_size, NULL); - -        switch (get_elf_target_machine(format)) -        { -            case FTM_MIPS: -                result = g_elf_format_find_mips_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); -                break; - -            case FTM_386: -                result = g_elf_format_find_x86_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); -                break; - -            default: -                break; - -        } - -    } - -    return result; - -} - - - - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format    = description de l'exécutable à compléter.         * -*                sym_start = début de la zone à traiter.                      * -*                sym_size  = taille de la zone à traiter.                     * -*                str_start = début de la zone de chaîne de caractères.        * -*                str_size  = taille de la zone de chaînes de caractères.      * -*                                                                             * -*  Description : Charge en mémoire la liste humaine des symboles (32 bits).   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool load_elf_symbol_table_32(elf_format *format, const off_t *sym_start, const off_t *sym_size, const off_t *str_start, const off_t *str_size) -{ -    off_t iter;                             /* Boucle de parcours          */ -    Elf32_Sym symbol;                       /* Symbole ELF lu              */ -    GBinRoutine *routine;                   /* Nouvelle routine trouvée    */ - -    if (*sym_size % sizeof(Elf32_Sym) != 0) return false; - -    for (iter = *sym_start; iter < (*sym_start + *sym_size); iter += sizeof(Elf32_Sym)) -    { -        memcpy(&symbol, &EXE_FORMAT(format)->content[iter], sizeof(Elf32_Sym)); - -        if (!(ELF32_ST_TYPE(symbol.st_info) == STT_FUNC)) continue; - -        if (symbol.st_value == 0) continue; - -        /* Sécurité anti-débordements */ -        if (symbol.st_name >= *str_size) continue; - -        /* Si le symbole possède un nom... */ -        if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0) -        { -            routine = g_binary_routine_new(); - -            g_binary_routine_set_name(routine, strdup(&EXE_FORMAT(format)->content[*str_start + symbol.st_name])); -            g_binary_routine_set_address(routine, symbol.st_value); -            g_binary_routine_set_size(routine, symbol.st_size); - -            format->routines = (GBinRoutine **)realloc(format->routines, -                                                       ++format->routines_count * sizeof(GBinRoutine *)); - -            format->routines[format->routines_count - 1] = routine; - -        } - -    } - -    return true; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format    = description de l'exécutable à compléter.         * -*                sym_start = début de la zone à traiter.                      * -*                sym_size  = taille de la zone à traiter.                     * -*                str_start = début de la zone de chaîne de caractères.        * -*                str_size  = taille de la zone de chaînes de caractères.      * -*                                                                             * -*  Description : Charge en mémoire la liste humaine des symboles (64 bits).   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool load_elf_symbol_table_64(elf_format *format, const off_t *sym_start, const off_t *sym_size, const off_t *str_start, const off_t *str_size) -{ -    off_t iter;                             /* Boucle de parcours          */ -    Elf64_Sym symbol;                       /* Symbole ELF lu              */ - -    if (*sym_size % sizeof(Elf64_Sym) != 0) return false; - -    for (iter = *sym_start; iter < (*sym_start + *sym_size); iter += sizeof(Elf64_Sym)) -    { -        memcpy(&symbol, &EXE_FORMAT(format)->content[iter], sizeof(Elf64_Sym)); - -        if (!(ELF64_ST_TYPE(symbol.st_info) == STT_FUNC -              || (ELF64_ST_TYPE(symbol.st_info) == STT_NOTYPE -                  && ELF64_ST_BIND(symbol.st_info) == STB_GLOBAL))) continue; - -        if (symbol.st_value == 0) continue; - -        /* Sécurité anti-débordements */ -        if (symbol.st_name >= *str_size) continue; - -        /* Si le symbole possède un nom... */ -        if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0) -        { -            format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); - -            format->symbols[format->sym_count - 1].name = &EXE_FORMAT(format)->content[*str_start + symbol.st_name]; -            format->symbols[format->sym_count - 1].address = symbol.st_value; - -        } - -    } - -    return true; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format   = informations chargées à consulter.                * -*                comments = liste des commentaires à insérer. [OUT]           * -*                offsets  = liste des indices des commentaires. [OUT]         * -*                count    = taille des listes construites. [OUT]              * -*                                                                             * -*  Description : Récupère tous les commentaires à insérer dans le code.       * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void get_elf_symbol_comments(const elf_format *format, char ***comments, uint64_t **offsets, size_t *count) -{ -    size_t i;                               /* Boucle de parcours          */ -    size_t len;                             /* Longueur d'une désignation  */ - -    if (format->sym_count > 0) -    { -        *comments = (char **)calloc(*count + format->sym_count, sizeof(char *)); -        *offsets = (uint64_t *)calloc(*count + format->sym_count, sizeof(uint64_t)); - -        for (i = 0; i < format->sym_count; i++) -        { -            len = strlen(format->symbols[i].name); - -            (*comments)[i] = (char *)calloc(len + 9, sizeof(char)); -            snprintf((*comments)[i], len + 9, "<%s>", format->symbols[i].name); - -            (*offsets)[i] = format->symbols[i].address; - -        } - -        *count += format->sym_count; - -    } - -} - - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/*                            DETAIL DES SYMBOLES EXTERNES                            */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format    = description de l'exécutable à compléter.         * -*                plt_start = début de la zone à traiter.                      * -*                plt_size  = taille de la zone à traiter.                     * -*                dyn_start = début des informations dynamiques associées.     * -*                dyn_size  = taille de la zone associée.                      * -*                str_start = début de la zone de chaîne de caractères.        * -*                str_size  = taille de la zone de 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_relocation_table(elf_format *format, const off_t *plt_start, const off_t *plt_size, const off_t *dyn_start, const off_t *dyn_size, const off_t *str_start, const off_t *str_size) -{ -    off_t iter;                             /* Boucle de parcours          */ -    Elf_Rel reloc;                          /* Infos de relocalisation     */ -    off_t index;                            /* Indice de la portion visée  */ -    char *name;                             /* Nom du symbole trouvé       */ - -    for (iter = *plt_start; iter < (*plt_start + *plt_size); iter += ELF_SIZEOF_REL(format)) -    { -        memcpy(&reloc, &EXE_FORMAT(format)->content[iter], ELF_SIZEOF_REL(format)); - -        switch (format->header.e_machine) -        { -            case EM_386: -                switch (ELF32_R_TYPE(ELF_REL_TYPE(format, reloc))) -                { -                    case R_386_JMP_SLOT: - -                        index = ELF_REL_SYM(format, reloc); -                        name = get_elf_dynamic_symbol_info(format, dyn_start, dyn_size, &index, str_start, str_size); - -                        if (name != NULL) -                        { -                            format->relocations = (elf_symbol *)realloc(format->relocations, ++format->rel_count * sizeof(elf_symbol)); - -                            format->relocations[format->rel_count - 1].name = name; -                            format->relocations[format->rel_count - 1].address = ELF_REL(format, reloc, r_offset); - -                        } - -                        break; - -                    default: -                        printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc)); -                        break; - -                } -                break; - -            default: -                printf("Machine not recognized !\n"); -                return false; -                break; - -        } - - -    } - -    return true; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format    = description de l'exécutable à compléter.         * -*                dyn_start = début des informations dynamiques associées.     * -*                dyn_size  = taille de la zone associée.                      * -*                index     = indice de l'entrée à venir lire.                 * -*                str_start = début de la zone de chaîne de caractères.        * -*                str_size  = taille de la zone de chaînes de caractères.      * -*                                                                             * -*  Description : Récupère les informations d'un symbole dynamique donné.      * -*                                                                             * -*  Retour      : Nom du symbole trouvé, ou NULL si erreur ou non adapté.      * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -char *get_elf_dynamic_symbol_info(elf_format *format, const off_t *dyn_start, const off_t *dyn_size, const off_t *index, const off_t *str_start, const off_t *str_size) -{ -    off_t offset;                           /* Emplacement à venir lire    */ -    Elf_Sym symbol;                         /* Symbole aux infos visées    */ - -    offset = *dyn_start + *index * ELF_SIZEOF_SYM(format); -    if ((offset + ELF_SIZEOF_SYM(format)) > (*dyn_start + *dyn_size)) return NULL; - -    memcpy(&symbol, &EXE_FORMAT(format)->content[offset], ELF_SIZEOF_SYM(format)); - -    if (ELF_SYM(format, symbol, st_name) >= *str_size) return NULL; - -    return (char *)&EXE_FORMAT(format)->content[*str_start + ELF_SYM(format, symbol, st_name)]; - -} diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c new file mode 100644 index 0000000..97b6ff2 --- /dev/null +++ b/src/format/elf/symbols.c @@ -0,0 +1,418 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * symbols.c - gestion des symboles d'un ELF + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "symbols.h" + + +#include <malloc.h> +#include <string.h> + + +#include "elf-int.h" +#include "helper_x86.h" +#include "section.h" +#include "../../panel/log.h" + + + + + +#define _(str) str + + + + +/* Récupère la désignation d'un symbole donné. */ +const char *get_elf_symbol_name(GElfFormat *, const elf_shdr *, const elf_shdr *, off_t); + + + +/* -------------------------- DETAIL DES SYMBOLES INTERNES -------------------------- */ + + +/* Charge tous les symboles internes possibles. */ +static bool load_elf_internal_symbols(GElfFormat *); + + + +/* -------------------------- DETAIL DES SYMBOLES EXTERNES -------------------------- */ + + +/* Retrouve un élément donné dans la section dynamique. */ +static bool find_elf_dynamic_item(const GElfFormat *, const elf_shdr *, int32_t, elf_dyn *); + +/* Charge tous les éléments dynamiques externes possibles. */ +static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *); + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Charge en mémoire la liste humaine des symboles.             * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_elf_symbols(GElfFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ +    elf_shdr *sections;                     /* Groupe de sections trouvées */ +    size_t count;                           /* Quantité de données         */ + +    result = true; + +    /* Symboles externes */ + +    if (find_elf_sections_by_type(format, SHT_DYNAMIC, §ions, &count)) +    { +        log_variadic_message(LMT_INFO, _("Binary is dynamically linked")); + +        result &= load_elf_external_symbols(format, §ions[0]); + +        free(sections); + +    } +    else log_variadic_message(LMT_INFO, _("Binary is statically linked")); + +    /* Symboles internes */ +    result &= load_elf_internal_symbols(format); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à consulter.            * +*                sym    = section comprenant les symboles à venir lire.       * +*                str    = section de chaînes de caractères pour les noms.     * +*                index  = indice de l'entrée à venir lire.                    * +*                                                                             * +*  Description : Récupère la désignation d'un symbole donné.                  * +*                                                                             * +*  Retour      : Nom du symbole trouvé, ou NULL si erreur ou non adapté.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *get_elf_symbol_name(GElfFormat *format, const elf_shdr *sym, const elf_shdr *str, off_t index) +{ +    const char *result;                     /* Résultat à retourner        */ +    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 offset;                           /* Emplacement à venir lire    */ +    elf_sym symbol;                         /* Symbole aux infos visées    */ + +    result = NULL; + +    get_elf_section_content(format, sym, &sym_start, &sym_size, NULL); +    get_elf_section_content(format, str, &str_start, &str_size, NULL); + +    offset = sym_start + index * ELF_SIZEOF_SYM(format); +    if ((offset + ELF_SIZEOF_SYM(format)) > (sym_start + sym_size)) return NULL; + +    if (read_elf_symbol(format, &offset, &symbol)) +        result = extract_name_from_elf_string_section(format, str, ELF_SYM(format, symbol, st_name)); + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                            DETAIL DES SYMBOLES INTERNES                            */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Charge tous les symboles internes possibles.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool load_elf_internal_symbols(GElfFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ +    elf_shdr *symtabs;                      /* Groupe de sections trouvées */ +    size_t count;                           /* Quantité de données         */ +    size_t i;                               /* Boucle de parcours          */ +    elf_shdr strtab;                        /* Section .strtab trouvée     */ +    bool has_strtab;                        /* Présence de cette section   */ +    off_t sym_start;                        /* Début de la zone à traiter  */ +    off_t sym_size;                         /* Taille de cette même zone   */ +    off_t iter;                             /* Boucle de parcours          */ +    const char *name;                       /* Nom du symbole trouvé       */ +    elf_sym sym;                            /* Symbole aux infos visées    */ +    GBinRoutine *routine;                   /* Nouvelle routine trouvée    */ +    GBinSymbol *symbol;                     /* Nouveau symbole construit   */ + +    result = true; + +    if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtabs, &count)) +        for (i = 0; i < count && result; i++) +        { +            has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, symtabs[i], sh_link), &strtab); + +            get_elf_section_content(format, &symtabs[i], &sym_start, &sym_size, NULL); + +            for (iter = sym_start; iter < (sym_start + sym_size); ) +            { +                result = read_elf_symbol(format, &iter, &sym); +                if (!result) break; + +                if (ELF_SYM(format, sym, st_value) == 0) continue; + +                if (!(ELF_ST_TYPE(format, sym) == STT_FUNC)) continue; + +                if (!has_strtab) name = NULL; +                else name = get_elf_symbol_name(format, &symtabs[i], &strtab, +                                                ((iter - sym_start) / ELF_SIZEOF_SYM(format)) - 1); + +                if (name == NULL) +                { +                    /* FIXME */ +                    name = "unknown"; +                } + +                /* Routine */ + +                routine = g_binary_routine_new(); + +                g_binary_routine_set_name(routine, strdup(name)); +                g_binary_routine_set_address(routine, ELF_SYM(format, sym, st_value)); +                g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size)); + +                g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + +                /* Symbole uniquement */ + +                symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_SYM(format, sym, st_value)); + +                g_binary_symbol_attach_routine(symbol, routine); + +                g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + +            } + + +        } + +    return true; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                            DETAIL DES SYMBOLES EXTERNES                            */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = informations chargées à consulter.                 * +*                dynamic = section de type SHT_DYNAMIC.                       * +*                type    = sorte d'élément recherché.                         * +*                item    = élément retrouvé dans la section. [OUT]            * +*                                                                             * +*  Description : Retrouve un élément donné dans la section dynamique.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +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          */ +    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; +         pos += ELF_SIZEOF_DYN(format)) +    { +        tmp = pos; + +        if (format->is_32b) +        { +            result = read_s32(&tag32, content, &tmp, length, format->endian); +            if (tag32 == type) break; +        } +        else +        { +            result = read_s64(&tag64, content, &tmp, length, format->endian); +            if (tag64 == type) break; +        } + +    } + +    result &= (pos < length); + +    if (result) +    { +        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); +        } +        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); +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = informations chargées à consulter.                 * +*                dynamic = section de type SHT_DYNAMIC.                       * +*                                                                             * +*  Description : Charge tous les éléments dynamiques externes possibles.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool load_elf_external_symbols(GElfFormat *format, const elf_shdr *section) +{ +    bool result;                            /* Bilan à retourner           */ + +    elf_dyn item;                           /* Elément dynamique           */ +    elf_shdr relxxx;                        /* Section .rel.xxx trouvée    */ +    elf_shdr dynsym;                        /* Section .dynsym trouvée     */ +    elf_shdr dynstr;                        /* Section .dynstr trouvée     */ +    elf_shdr plt;                           /* Section .plt trouvée        */ + +    result = true; + + + + + + +    /* Section .rel.plt */ +    if (find_elf_dynamic_item(format, section, DT_JMPREL, &item)) +    { +        result &= find_elf_section_by_virtual_address(format, ELF_DYN(format, item, d_un.d_ptr), &relxxx); + +        if (result) +            result = find_elf_section_by_index(format, ELF_SHDR(format, relxxx, sh_link), &dynsym); + +        if (result) +            result = find_elf_section_by_index(format, ELF_SHDR(format, dynsym, sh_link), &dynstr); + +        if (result) +            switch (g_exe_format_get_target_machine(G_EXE_FORMAT(format))) +            { +                case FTM_386: +                    result = load_elf_x86_relocated_symbols(format, &relxxx, &dynsym, &dynstr); +                    break; + +                default: +                    break; + +            } + +    } + +    /* Entrées équivalentes dans le binaire */ +    if (find_elf_dynamic_item(format, section, DT_SYMTAB, &item)) +    { +        result &= find_elf_section_by_virtual_address(format, ELF_DYN(format, item, d_un.d_ptr), &dynsym); + +        if (result) +            result = find_elf_section_by_index(format, ELF_SHDR(format, dynsym, sh_link), &dynstr); + +        if (result) +            switch (g_exe_format_get_target_machine(G_EXE_FORMAT(format))) +            { +                case FTM_MIPS: +                    //result = find_elf_mips_dynamic_symbols(format, &dynsym, &dynstr); +                    break; + +                case FTM_386: + +                    if (find_elf_dynamic_item(format, section, DT_JMPREL, &item)) +                    { +                        result &= find_elf_section_by_virtual_address(format, ELF_DYN(format, item, d_un.d_ptr), &relxxx); + +                        if (result) +                            result = find_elf_section_by_index(format, ELF_SHDR(format, relxxx, sh_info), &plt); + +                        if (result) +                            result = find_elf_x86_dynamic_symbols(format, &plt); + +                    } + +                    break; + +                default: +                    break; + +            } + +    } + +    return result; + +} diff --git a/src/format/elf/symbol.h b/src/format/elf/symbols.h index 0a8f203..6644cbf 100644 --- a/src/format/elf/symbol.h +++ b/src/format/elf/symbols.h @@ -1,6 +1,6 @@  /* OpenIDA - Outil d'analyse de fichiers binaires - * symbol.h - prototypes pour la gestion des symboles d'un ELF + * symbols.h - prototypes pour la gestion des symboles d'un ELF   *   * Copyright (C) 2008 Cyrille Bagard   * @@ -21,20 +21,16 @@   */ -#ifndef _FORMAT_ELF_SYMBOL_H -#define _FORMAT_ELF_SYMBOL_H +#ifndef _FORMAT_ELF_SYMBOLS_H +#define _FORMAT_ELF_SYMBOLS_H -#include "e_elf.h" - +#include "elf.h"  /* Charge en mémoire la liste humaine des symboles. */ -bool load_elf_symbols(elf_format *); - -/* Récupère tous les commentaires à insérer dans le code. */ -void get_elf_symbol_comments(const elf_format *, char ***, uint64_t **, size_t *); +bool load_elf_symbols(GElfFormat *); -#endif  /* _FORMAT_ELF_SYMBOL_H */ +#endif  /* _FORMAT_ELF_SYMBOLS_H */ diff --git a/src/format/exe_format.h b/src/format/exe_format.h index 32e35ff..b1cbb17 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -32,6 +32,7 @@  #include "../analysis/prototype.h" +#include "symbol.h"  /* ------------------------ MANIPULATION DES PARTIES DE CODE ------------------------ */ @@ -88,7 +89,7 @@ exe_format *load_new_exe_format(const uint8_t *, off_t); - +#if 0  /* Architectures de destination des formats */  typedef enum _FormatTargetMachine  { @@ -102,7 +103,6 @@ typedef enum _FormatTargetMachine -  /* Types de symbole */  typedef enum _SymbolType  { @@ -110,6 +110,7 @@ typedef enum _SymbolType      STP_STRING                              /* Chaîne de caractères        */  } SymbolType; +#endif  /* Types de symbole */ diff --git a/src/format/executable-int.h b/src/format/executable-int.h new file mode 100644 index 0000000..ca8b7d5 --- /dev/null +++ b/src/format/executable-int.h @@ -0,0 +1,67 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * executable-int.h - prototypes utiles aux formats d'exécutables + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_EXECUTABLE_INT_H +#define _FORMAT_EXECUTABLE_INT_H + + +#include "executable.h" + + +#include "format-int.h" + + + +/* Indique le type d'architecture visée par le format. */ +typedef FormatTargetMachine (* get_target_machine_fc) (const GExeFormat *); + +/* Fournit l'adresse mémoire du point d'entrée du programme. */ +typedef vmpa_t (* get_entry_point_fc) (const GExeFormat *); + +/* Fournit les références aux zones de code à analyser. */ +typedef GBinPart ** (* get_parts_fc) (const GExeFormat *, size_t *); + + + + +/* Format d'exécutable générique (instance) */ +struct _GExeFormat +{ +    GBinFormat parent;                      /* A laisser en premier        */ + +    get_target_machine_fc get_machine;      /* Architecture ciblée         */ +    get_entry_point_fc get_entry_point;     /* Obtention du point d'entrée */ +    get_parts_fc get_parts;                 /* Liste des parties binaires  */ + +}; + +/* Format d'exécutable générique (classe) */ +struct _GExeFormatClass +{ +    GBinFormatClass parent;                 /* A laisser en premier        */ + +}; + + + +#endif  /* _FORMAT_EXECUTABLE_INT_H */ diff --git a/src/format/executable.c b/src/format/executable.c new file mode 100644 index 0000000..4fb6b41 --- /dev/null +++ b/src/format/executable.c @@ -0,0 +1,144 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * executable.c - support des formats d'exécutables + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "executable.h" + + +#include "executable-int.h" +#include "format.h" + + + +/* Initialise la classe des formats d'exécutables génériques. */ +static void g_executable_format_class_init(GExeFormatClass *); + +/* Initialise une instance de format d'exécutable générique. */ +static void g_executable_format_init(GExeFormat *); + + + +/* Indique le type défini pour un format d'exécutable générique. */ +G_DEFINE_TYPE(GExeFormat, g_executable_format, G_TYPE_BIN_FORMAT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des formats d'exécutables génériques.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_executable_format_class_init(GExeFormatClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de format d'exécutable générique.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_executable_format_init(GExeFormat *format) +{ + +} + + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                                                                             * +*  Description : Indique le type d'architecture visée par le format.          * +*                                                                             * +*  Retour      : Identifiant de l'architecture ciblée par le format.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +FormatTargetMachine g_exe_format_get_target_machine(const GExeFormat *format) +{ +    return format->get_machine(format); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                                                                             * +*  Description : Fournit l'adresse mémoire du point d'entrée du programme.    * +*                                                                             * +*  Retour      : Adresse de mémoire.                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +vmpa_t g_exe_format_get_entry_point(const GExeFormat *format) +{ +    return format->get_entry_point(format); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                count  = quantité de zones listées. [OUT]                    * +*                                                                             * +*  Description : Fournit les références aux zones binaires à analyser.        * +*                                                                             * +*  Retour      : Zones binaires à analyser.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinPart **g_exe_format_get_parts(const GExeFormat *format, size_t *count) +{ +    return format->get_parts(format, count); + +} diff --git a/src/format/executable.h b/src/format/executable.h new file mode 100644 index 0000000..bf3269d --- /dev/null +++ b/src/format/executable.h @@ -0,0 +1,80 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * executable.h - prototypes pour le support des formats d'exécutables + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_EXECUTABLE_H +#define _FORMAT_EXECUTABLE_H + + +#include <glib-object.h> + + +#include "part.h" + + + +/* Architectures de destination des formats */ +typedef enum _FormatTargetMachine +{ +    FTM_NONE,                               /* Aucune archi. (reconnue)    */ + +    FTM_JVM,                                /* Java Virtual Machine        */ +    FTM_MIPS,                               /* Mips 32 ou 64 bits          */ +    FTM_386,                                /* Intel 80386                 */ + +    FTM_COUNT + +} FormatTargetMachine; + + +#define G_TYPE_EXE_FORMAT               g_executable_format_get_type() +#define G_EXE_FORMAT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_executable_format_get_type(), GExeFormat)) +#define G_IS_EXE_FORMAT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_executable_format_get_type())) +#define G_EXE_FORMAT_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_executable_format_get_type(), GExeFormatIface)) +#define G_EXE_FORMAT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_EXE_FORMAT, GExeFormatClass)) + + +/* Format d'exécutable générique (instance) */ +typedef struct _GExeFormat GExeFormat; + +/* Format d'exécutable générique (classe) */ +typedef struct _GExeFormatClass GExeFormatClass; + + +/* Indique le type défini pour un format d'exécutable générique. */ +GType g_executable_format_get_type(void); + + + + +/* Indique le type d'architecture visée par le format. */ +FormatTargetMachine g_exe_format_get_target_machine(const GExeFormat *); + +/* Fournit l'adresse mémoire du point d'entrée du programme. */ +vmpa_t g_exe_format_get_entry_point(const GExeFormat *); + +/* Fournit les références aux zones binaires à analyser. */ +GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *); + + + +#endif  /* _FORMAT_EXECUTABLE_H */ diff --git a/src/format/format-int.h b/src/format/format-int.h new file mode 100644 index 0000000..13eb50a --- /dev/null +++ b/src/format/format-int.h @@ -0,0 +1,64 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * format-int.h - prototypes utiles aux formats binaires + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_FORMAT_INT_H +#define _FORMAT_FORMAT_INT_H + + +#include "format.h" + + + +/* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ + + +/* Format binaire générique (instance) */ +struct _GBinFormat +{ +    GObject parent;                         /* A laisser en premier        */ + +    const bin_t *content;                   /* Contenu binaire à étudier   */ +    off_t length;                           /* Taille de ce contenu        */ + +    GBinSymbol **symbols;                   /* Liste des symboles trouvés  */ +    size_t symbols_count;                   /* Quantité de ces symboles    */ + +    GBinRoutine **routines;                 /* Liste des routines trouvées */ +    size_t routines_count;                  /* Nombre de ces routines      */ + +}; + +/* Format binaire générique (classe) */ +struct _GBinFormatClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Définit le contenu binaire à analyser. */ +void g_binary_format_set_content(GBinFormat *, bin_t *, off_t); + + + +#endif  /* _FORMAT_FORMAT_INT_H */ diff --git a/src/format/format.c b/src/format/format.c new file mode 100644 index 0000000..912cdd7 --- /dev/null +++ b/src/format/format.c @@ -0,0 +1,375 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * format.c - support des différents formats binaires + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "format.h" + + +#include <malloc.h> + + +#include "format-int.h" +#include "dwarf/dwarf.h" +#include "elf/elf.h" +#include "../panel/log.h" + + + +#ifndef _ +#   define _(str) str +#endif + + + + +/* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ + + +/* Initialise la classe des formats binaires génériques. */ +static void g_binary_format_class_init(GBinFormatClass *); + +/* Initialise une instance de format binaire générique. */ +static void g_binary_format_init(GBinFormat *); + + + +/* ----------------------- MANIPULATION D'ENSEMBLE DE FORMATS ----------------------- */ + + +/* Format d'exécutables enregistré */ +typedef struct _registered_format +{ +    const char *name;                       /* Désignation du format       */ + +    FormatType type;                        /* Type de format              */ + +    format_match_fc match;                  /* Procédure de reconnaissance */ +    format_load_fc load;                    /* Fonction de chargement      */ + +} registered_format; + + +/* Liste des formats d'exécutables enregistrés */ +static registered_format _formats[FID_COUNT]; + + +#define register_format(id, n, t, m, l)                     \ +    do                                                      \ +    {                                                       \ +        _formats[id].name = n;                              \ +        _formats[id].type = t;                              \ +        _formats[id].match = m;                             \ +        _formats[id].load = l;                              \ +    }                                                       \ +    while (0) + + + +/* ---------------------------------------------------------------------------------- */ +/*                          TRAITEMENT INDIVIDUEL DE FORMATS                          */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un format binaire générique. */ +G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des formats binaires génériques.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_format_class_init(GBinFormatClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de format binaire générique.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_format_init(GBinFormat *format) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = description de l'exécutable à consulter.           * +*                content = contenu binaire à parcourir.                       * +*                length  = taille du contenu fourni.                          * +*                                                                             * +*  Description : Définit le contenu binaire à analyser.                       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_format_set_content(GBinFormat *format, bin_t *content, off_t length) +{ +    format->content = content; +    format->length = length; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à consulter.            * +*                length = taille du contenu à fournir. [OUT]                  * +*                                                                             * +*  Description : Fournit une référence vers le contenu binaire analysé.       * +*                                                                             * +*  Retour      : Adresse du tampon contenant le contenu du binaire.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const bin_t *g_binary_format_get_content(const GBinFormat *format, off_t *length) +{ +    if (length != NULL) *length = format->length; + +    return format->content; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à compléter.                  * +*                symbol = symbole à ajouter à la liste.                       * +*                                                                             * +*  Description : Ajoute un symbole à la collection du format binaire.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol) +{ +    format->symbols = (GBinSymbol **)realloc(format->symbols, +                                             ++format->symbols_count * sizeof(GBinSymbol *)); + +    format->symbols[format->symbols_count - 1] = symbol; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                count  = taille du tableau créé. [OUT]                       * +*                                                                             * +*  Description : Fournit la liste de tous les symboles détectés.              * +*                                                                             * +*  Retour      : Tableau créé ou NULL si aucun symbole trouvé.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count) +{ +    *count = format->symbols_count; + +    return format->symbols; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = informations chargées à compléter.                 * +*                routine = routine à ajouter à la liste.                      * +*                                                                             * +*  Description : Ajoute une routine à la collection du format binaire.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_format_add_routine(GBinFormat *format, GBinRoutine *routine) +{ +    format->routines = (GBinRoutine **)realloc(format->routines, +                                               ++format->routines_count * sizeof(GBinRoutine *)); + +    format->routines[format->routines_count - 1] = routine; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                count  = taille du tableau créé. [OUT]                       * +*                                                                             * +*  Description : Fournit le prototype de toutes les routines détectées.       * +*                                                                             * +*  Retour      : Tableau créé ou NULL si aucun symbole de routine trouvé.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinRoutine **g_binary_format_get_routines(const GBinFormat *format, size_t *count) +{ +    *count = format->routines_count; + +    return format->routines; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = informations chargées à consulter.                 * +*                label   = étiquette du symbole si trouvé. [OUT]              * +*                type    = type du symbole trouvé. [OUT]                      * +*                address = adresse à cibler, puis décallage final. [OUT]      * +*                                                                             * +*  Description : Recherche le symbole correspondant à une adresse.            * +*                                                                             * +*  Retour      : true si l'opération a été un succès, false sinon.            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_binary_format_resolve_symbol(const GBinFormat *format, const char **label, SymbolType *type, vmpa_t *address) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t i;                               /* Boucle de parcours          */ +    vmpa_t addr;                            /* Adresse de symbole          */ +    off_t size;                             /* Taille du symole            */ + +    result = false; + +    for (i = 0; i < format->symbols_count && !result; i++) +    { +        addr = g_binary_symbol_get_address(format->symbols[i]); +        size = g_binary_symbol_get_size(format->symbols[i]); + +        if (addr <= *address && *address < (addr + size)) +        { +            *label = g_binary_symbol_to_string(format->symbols[i]); +            *type = g_binary_symbol_get_target_type(format->symbols[i]); +            *address -= addr; + +            if (*type == STP_STRING) +                *label += *address; + +            result = true; + +        } + +    } + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                         MANIPULATION D'ENSEMBLE DE FORMATS                         */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Procède au chargement des formats binaires reconnus.         * +*                                                                             * +*  Retour      : true pour indiquer un chargement réussi, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool init_all_formats(void) +{ +    register_format(FID_ELF, _("ELF"), FMT_EXEC, elf_is_matching, g_elf_format_new); +    register_format(FID_DWARF, _("Dwarf"), FMT_DEBUG, dwarf_is_matching, g_dwarf_format_new); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type    = type de format recherché.                          * +*                content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                                                                             * +*  Description : Charge si possible un nouveau format binaire.                * +*                                                                             * +*  Retour      : Adresse du nouveau gestionnaire de format ou NULL si erreur. * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinFormat *load_new_format(FormatType type, const uint8_t *content, off_t length) +{ +    GBinFormat *result;                     /* Adresse à retourner         */ +    size_t i;                               /* Boucle de parcours          */ + +    result = NULL; + +    for (i = 0; i < FID_COUNT && result == NULL; i++) +        if (_formats[i].type == type && _formats[i].match(type, content, length)) +        { +            log_variadic_message(LMT_INFO, _("%s is matching..."), _formats[i].name); + +            result = _formats[i].load(content, length); + +        } + +    return result; + +} diff --git a/src/format/format.h b/src/format/format.h new file mode 100644 index 0000000..c485e0b --- /dev/null +++ b/src/format/format.h @@ -0,0 +1,114 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * format.h - prototypes pour le support des différents formats binaires + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_FORMAT_H +#define _FORMAT_FORMAT_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <sys/types.h> + + +#include "symbol.h" + + + +/* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ + + +#define G_TYPE_BIN_FORMAT               g_binary_format_get_type() +#define G_BIN_FORMAT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_format_get_type(), GBinFormat)) +#define G_IS_BIN_FORMAT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_format_get_type())) +#define G_BIN_FORMAT_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_binary_format_get_type(), GBinFormatIface)) +#define G_BIN_FORMAT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_FORMAT, GBinFormatClass)) + + +/* Format binaire générique (instance) */ +typedef struct _GBinFormat GBinFormat; + +/* Format binaire générique (classe) */ +typedef struct _GBinFormatClass GBinFormatClass; + + +/* Indique le type défini pour un format binaire générique. */ +GType g_binary_format_get_type(void); + +/* Fournit une référence vers le contenu binaire analysé. */ +const bin_t *g_binary_format_get_content(const GBinFormat *, off_t *); + +/* Ajoute un symbole à la collection du format binaire. */ +void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *); + +/* Fournit la liste de tous les symboles détectés. */ +GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *); + +/* Ajoute une routine à la collection du format binaire. */ +void g_binary_format_add_routine(GBinFormat *, GBinRoutine *); + +/* Fournit le prototype de toutes les routines détectées. */ +GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *); + +/* Recherche le symbole correspondant à une adresse. */ +bool g_binary_format_resolve_symbol(const GBinFormat *, const char **, SymbolType *, vmpa_t *); + + + +/* ----------------------- MANIPULATION D'ENSEMBLE DE FORMATS ----------------------- */ + + +/* Identifiants pour les différents formats */ +typedef enum _FormatIdentifier +{ +    FID_ELF,                                /* Format ELF                  */ +    FID_DWARF,                              /* Format Dwarf                */ + +    FID_COUNT + +} FormatIdentifier; + +/* Spécialité des formats */ +typedef enum _FormatType +{ +    FMT_EXEC    = (1 << 0),                 /* Format d'exécutable         */ +    FMT_DEBUG   = (1 << 1)                  /* Format de débogage          */ + +} FormatType; + + +/* Indication à propos du support d'un format */ +typedef bool (* format_match_fc) (FormatType, const bin_t *, off_t); + +/* Méthode de chargement d'un format */ +typedef GBinFormat * (* format_load_fc) (const bin_t *, off_t); + + +/* Procède au chargement des formats binaires reconnus. */ +bool init_all_formats(void); + +/* Charge si possible un nouveau format binaire. */ +GBinFormat *load_new_format(FormatType, const uint8_t *, off_t); + + + +#endif  /* _FORMAT_FORMAT_H */ diff --git a/src/format/part.c b/src/format/part.c new file mode 100644 index 0000000..2096c6d --- /dev/null +++ b/src/format/part.c @@ -0,0 +1,217 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * part.h - manipulation des parties de code + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "part.h" + + +#include <malloc.h> +#include <string.h> + + + +/* Bloc de données binaires quelconques (instance) */ +struct _GBinPart +{ +    GObject parent;                         /* A laisser en premier        */ + +    char *name;                             /* Désignation humaine         */ + +    off_t offset;                           /* Position physique           */ +    off_t size;                             /* Taille de la partie         */ +    vmpa_t addr;                            /* Adresse associée            */ + +}; + +/* Bloc de données binaires quelconques (classe) */ +struct _GBinPartClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Initialise la classe des blocs de données binaires. */ +static void g_binary_part_class_init(GBinPartClass *); + +/* Initialise une instance de bloc de données binaires. */ +static void g_binary_part_init(GBinPart *); + + + +/* Indique le type défini par la GLib pour les blocs de doonées. */ +G_DEFINE_TYPE(GBinPart, g_binary_part, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des blocs de données binaires.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_part_class_init(GBinPartClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise une instance de bloc de données binaires.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_part_init(GBinPart *line) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Crée une description de partie de code vierge.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinPart *g_binary_part_new(void) +{ +    GBinPart *result;                   /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_BIN_PART, NULL); + +    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 g_binary_part_set_name(GBinPart *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.                   * +*                addr   = adresse de la section à conserver.                  * +*                                                                             * +*  Description : Définit les valeurs utiles d'une partie de code.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_part_set_values(GBinPart *part, off_t offset, off_t size, vmpa_t addr) +{ +    part->offset = offset; +    part->size = size; +    part->addr = addr; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : part   = description de partie à consulter.                  * +*                offset = position de la section à donner ou NULL. [OUT]      * +*                size   = taille de la section à donner ou NULL. [OUT]        * +*                addr   = adresse de la section à donner ou NULL. [OUT]       * +*                                                                             * +*  Description : Fournit les valeurs utiles d'une partie de code.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_part_get_values(const GBinPart *part, off_t *offset, off_t *size, vmpa_t *addr) +{ +    if (offset != NULL) *offset = part->offset; +    if (size != NULL) *size = part->size; +    if (addr != NULL) *addr = part->addr; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a = premières informations à consulter.                      * +*                b = secondes informations à consulter.                       * +*                                                                             * +*  Description : Etablit la comparaison entre deux blocs binaires.            * +*                                                                             * +*  Retour      : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b).                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int g_binary_part_compare(const GBinPart **a, const GBinPart **b) +{ +    int result;                             /* Bilan à renvoyer            */ + +    if ((*a)->offset < (*b)->offset) result = -1; +    else if((*a)->offset > (*b)->offset) result = 1; +    else result = 0; + +    return result; + +} diff --git a/src/format/part.h b/src/format/part.h new file mode 100644 index 0000000..aec324d --- /dev/null +++ b/src/format/part.h @@ -0,0 +1,71 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * part.h - prototypes pour la manipulation des parties de code + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_PART_H +#define _FORMAT_PART_H + + +#include <glib-object.h> +#include <sys/types.h> + + +#include "../arch/archbase.h" + + + +#define G_TYPE_BIN_PART                (g_binary_part_get_type()) +#define G_BIN_PART(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_PART, GBinPart)) +#define G_IS_BIN_PART(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_PART)) +#define G_BIN_PART_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_PART, GBinPartClass)) +#define G_IS_BIN_PART_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_PART)) +#define G_BIN_PART_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_PART, GBinPartClass)) + + +/* Bloc de données binaires quelconques (instance) */ +typedef struct _GBinPart GBinPart; + +/* Bloc de données binaires quelconques (classe) */ +typedef struct _GBinPartClass GBinPartClass; + + +/* Indique le type défini par la GLib pour les blocs de doonées. */ +GType g_binary_part_get_type(void); + +/* Crée une description de partie de code vierge. */ +GBinPart *g_binary_part_new(void); + +/* Attribue une description humaine à une partie de code. */ +void g_binary_part_set_name(GBinPart *, const char *); + +/* Définit les valeurs utiles d'une partie de code. */ +void g_binary_part_set_values(GBinPart *, off_t, off_t, vmpa_t); + +/* Fournit les valeurs utiles d'une partie de code. */ +void g_binary_part_get_values(const GBinPart *, off_t *, off_t *, vmpa_t *); + +/* Etablit la comparaison entre deux blocs binaires. */ +int g_binary_part_compare(const GBinPart **, const GBinPart **); + + + +#endif  /* _FORMAT_PART_H */ diff --git a/src/format/symbol.c b/src/format/symbol.c new file mode 100644 index 0000000..40efdd2 --- /dev/null +++ b/src/format/symbol.c @@ -0,0 +1,265 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * symbol.c - gestion des symboles dans un binaire + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#include "symbol.h" + + +#include <string.h> + + + +/* Symbole d'exécutable (instance) */ +struct _GBinSymbol +{ +    GObject parent;                         /* A laisser en premier        */ + +    SymbolType type;                        /* Type du symbole             */ + +    const char *name;                       /* Désignation du symbole      */ +    vmpa_t address;                         /* Adresse du symbole          */ + +    char *alt;                              /* Nom alternatif              */ + +    union +    { +        GBinRoutine *routine;               /* Compléments pour fonction   */ + +    } extra; + +}; + +/* Symbole d'exécutable (classe) */ +struct _GBinSymbolClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Initialise la classe des symboles d'exécutables. */ +static void g_binary_symbol_class_init(GBinSymbolClass *); + +/* Initialise une instance de symbole d'exécutable. */ +static void g_binary_symbol_init(GBinSymbol *); + + + +/* Indique le type défini pour un symbole d'exécutable. */ +G_DEFINE_TYPE(GBinSymbol, g_binary_symbol, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des symboles d'exécutables.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_symbol_class_init(GBinSymbolClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de symbole d'exécutable.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_symbol_init(GBinSymbol *symbol) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type    = type de symbole à créer.                           * +*                name    = désignation humaine du symbole.                    * +*                address = adresse associée au symbole.                       * +*                                                                             * +*  Description : Crée un nouveau symbole d'exécutable.                        * +*                                                                             * +*  Retour      : Adresse de l'instance mise en place ou NULL en cas d'échec.  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinSymbol *g_binary_symbol_new(SymbolType type, const char *name, vmpa_t address) +{ +    GBinSymbol *result;                     /* Nouveau symbole à renvoyer  */ + +    result = g_object_new(G_TYPE_BIN_SYMBOL, NULL); + +    result->type = type; +    result->name = name; +    result->address = address; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             * +*  Description : Fournit le type du symbole.                                  * +*                                                                             * +*  Retour      : Type de symbole représenté.                                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +SymbolType g_binary_symbol_get_target_type(const GBinSymbol *symbol) +{ +    return symbol->type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             * +*  Description : Fournit la description humaine du symbole.                   * +*                                                                             * +*  Retour      : Nom du symbole sous forme de chaîne de caractères.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *g_binary_symbol_to_string(const GBinSymbol *symbol) +{ +    return (symbol->alt != NULL ? symbol->alt : symbol->name); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             * +*  Description : Fournit l'adresse associée à un symbole.                     * +*                                                                             * +*  Retour      : Adresse virtuelle ou physique associée.                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol) +{ +    return symbol->address; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             * +*  Description : Fournit la taille officielle d'un symbole.                   * +*                                                                             * +*  Retour      : Taille de symbole.                                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +off_t g_binary_symbol_get_size(const GBinSymbol *symbol) +{ +    off_t result;                           /* Taille à renvoyer           */ + +    switch (symbol->type) +    { +        case STP_OBJECT: +            result = 1; /* FIXME */ +            break; +        case STP_FUNCTION: +            /* FIXME */if (symbol->extra.routine == NULL) result = 1; else +            result = g_binary_routine_get_size(symbol->extra.routine); +            break; +        case STP_STRING: +            result = strlen(g_binary_symbol_to_string(symbol)); +            break; +    } + +    return result;; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                alt    = désignation humaine alternative à favoriser.        * +*                                                                             * +*  Description : Définit un autre nom pour le symbole.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_symbol_set_alt_name(GBinSymbol *symbol, char *alt) +{ +    return symbol->alt = alt; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol  = symbole à venir consulter.                         * +*                routine = prototype de la fonction représentée.              * +*                                                                             * +*  Description : Attache la routine associée au symbole.                      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_symbol_attach_routine(GBinSymbol *symbol, GBinRoutine *routine) +{ +    symbol->extra.routine = routine; + +} diff --git a/src/format/symbol.h b/src/format/symbol.h new file mode 100644 index 0000000..f4fe299 --- /dev/null +++ b/src/format/symbol.h @@ -0,0 +1,83 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * symbol.h - prototypes pour la gestion des symboles dans un binaire + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_SYMBOL_H +#define _FORMAT_SYMBOL_H + + +#include <glib-object.h> + + +#include "../analysis/prototype.h" +#include "../arch/archbase.h" + + + +/* Types de symbole */ +typedef enum _SymbolType +{ +    STP_OBJECT,                             /* Objet quelconque            */ +    STP_FUNCTION,                           /* Simple morceau de code      */ +    STP_STRING                              /* Chaîne de caractères        */ + +} SymbolType; + + +#define G_TYPE_BIN_SYMBOL               g_binary_symbol_get_type() +#define G_BIN_SYMBOL(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_symbol_get_type(), GBinSymbol)) +#define G_IS_BIN_SYMBOL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_symbol_get_type())) +#define G_BIN_SYMBOL_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_binary_symbol_get_type(), GBinSymbolIface)) +#define G_BIN_SYMBOL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_SYMBOL, GBinSymbolClass)) + + +/* Symbole d'exécutable (instance) */ +typedef struct _GBinSymbol GBinSymbol; + +/* Symbole d'exécutable (classe) */ +typedef struct _GBinSymbolClass GBinSymbolClass; + + +/* Indique le type défini pour un symbole d'exécutable. */ +GType g_binary_symbol_get_type(void); + +/* Crée un nouveau symbole d'exécutable. */ +GBinSymbol *g_binary_symbol_new(SymbolType, const char *, vmpa_t); + +/* Fournit le type du symbole. */ +SymbolType g_binary_symbol_get_target_type(const GBinSymbol *); + +/* Fournit la description humaine du symbole. */ +const char *g_binary_symbol_to_string(const GBinSymbol *); + +/* Fournit l'adresse associée à un symbole. */ +vmpa_t g_binary_symbol_get_address(const GBinSymbol *); + +/* Fournit la taille officielle d'un symbole. */ +off_t g_binary_symbol_get_size(const GBinSymbol *); + +/* Définit un autre nom pour le symbole. */ +void g_binary_symbol_set_alt_name(GBinSymbol *, char *); + + + +#endif  /* _FORMAT_SYMBOL_H */ diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index fcf3976..a6d4dd5 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -25,6 +25,8 @@  #include "gtkbinview-int.h" +#include "gtkblockview.h" +#include "../format/format.h"  #include "../graph/layout.h" @@ -305,7 +307,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin  static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr)  { -    exe_format *format;                     /* Type de fichier chargé      */ +    GExeFormat *format;                     /* Type de fichier chargé      */      GBinRoutine **routines;                 /* Liste des routines trouvées */      size_t routines_count;                  /* Nombre de ces routines      */      size_t i;                               /* Boucle de parcours          */ @@ -319,7 +321,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr)          gtk_graph_view_reset(view);          format = g_openida_binary_get_format(GTK_BIN_VIEW(view)->binary); -        routines = get_all_exe_routines(format, &routines_count); +        routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);          for (i = 0; i < routines_count; i++)          { @@ -33,7 +33,7 @@  #include "project.h"  #include "analysis/delayed.h"  #include "arch/processor.h" -#include "format/exe_format.h" +#include "format/format.h"  #include "format/mangling/demangler.h"  #include "gtkext/support.h"  #include "plugins/pglist.h" @@ -90,7 +90,7 @@ int main(int argc, char **argv)      /* Initialisation du programme */      init_all_processors();      init_all_demanglers(); -    init_all_exe_formats(); +    init_all_formats();      /* Création de l'interface */      editor = create_editor(); diff --git a/src/panel/Makefile.am b/src/panel/Makefile.am index 48f0958..20ea22e 100755 --- a/src/panel/Makefile.am +++ b/src/panel/Makefile.am @@ -5,6 +5,7 @@ libpanel_la_SOURCES =					\  	log.h log.c							\  	panels.h panels.c					\  	registers.h registers.c				\ +	strings.h strings.c					\  	symbols.h symbols.c  libpanel_la_LDFLAGS =  diff --git a/src/panel/panels.c b/src/panel/panels.c index 39adc10..9363578 100644 --- a/src/panel/panels.c +++ b/src/panel/panels.c @@ -27,6 +27,7 @@  #include "log.h"  #include "registers.h" +#include "strings.h"  #include "symbols.h" @@ -52,6 +53,7 @@ void init_panels(GObject *ref)      panel_list[PNT_LOG] = build_log_panel();      panel_list[PNT_REGISTERS] = build_registers_panel();      panel_list[PNT_SYMBOLS] = build_symbols_panel(ref); +    panel_list[PNT_STRINGS] = build_strings_panel(ref);  } diff --git a/src/panel/panels.h b/src/panel/panels.h index feaa908..4584bba 100644 --- a/src/panel/panels.h +++ b/src/panel/panels.h @@ -36,6 +36,7 @@ typedef enum _PanelType      PNT_LOG,                                /* Messages système            */      PNT_REGISTERS,                          /* Registres d'architecture    */      PNT_SYMBOLS,                            /* Symboles d'exécutable       */ +    PNT_STRINGS,                            /* Chaînes de carac. trouvées  */      PNT_COUNT diff --git a/src/pan_strings.c b/src/panel/strings.c index 984d0d2..1d09593 100644 --- a/src/pan_strings.c +++ b/src/panel/strings.c @@ -1,6 +1,6 @@  /* OpenIDA - Outil d'analyse de fichiers binaires - * pan_strings.c - panneau d'affichage des chaînes de caractères + * strings.c - panneau d'affichage des chaînes de caractères   *   * Copyright (C) 2006-2007 Cyrille Bagard   * @@ -22,7 +22,11 @@   */ -#include "pan_strings.h" +#include "strings.h" + + +#include "../format/format.h" +  /* Colonnes de la liste des symboles */ @@ -115,40 +119,31 @@ GtkWidget *build_strings_panel(GObject *ref)  *                                                                             *  ******************************************************************************/ -void handle_new_exe_on_strings_panel(GtkWidget *panel, const exe_format *format) +void handle_new_exe_on_strings_panel(GtkWidget *panel, const GExeFormat *format)  {      GtkTreeStore *store;                    /* Modèle de gestion           */ -    GtkTreeIter iter;                       /* Point d'insertion           */ -    char **labels;                          /* Etiquettes humaines         */ -    ResolvedType *types;                    /* Type des symboles listés    */ -    uint64_t *offsets;                      /* Emplacements de mémoire     */ -    size_t count;                           /* Nombre des symboles         */ +    size_t count;                           /* Nombre des chaînes          */ +    GBinSymbol **symbols;                   /* Liste des chaînes trouvées  */      size_t i;                               /* Boucle de parcours          */ -    char address[11]; +    char address[11];                       /* Conversion de l'adresse     */ +    GtkTreeIter iter;                       /* Point d'insertion           */      store = g_object_get_data(G_OBJECT(panel), "store"); -    count = get_exe_resolved_items(format, &labels, &types, &offsets); +    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &count); -    if (count > 0) +    for (i = 0; i < count; i++)      { -        for (i = 0; i < count; i++) -        { -            if (types[i] != RTP_STRING) continue; - -            snprintf(address, 11, "0x%08llx", offsets[i]); - -            gtk_tree_store_append(store, &iter, NULL); -            gtk_tree_store_set(store, &iter, -                               STC_ADDRESS, address, -                               STC_STRING, labels[i], -                               -1); +        if (g_binary_symbol_get_target_type(symbols[i]) != STP_STRING) continue; -        } +        /* FIXME : adresses autres que 32 bits */ +        snprintf(address, 11, "0x%08llx", g_binary_symbol_get_address(symbols[i])); -        free(labels); -        free(types); -        free(offsets); +        gtk_tree_store_append(store, &iter, NULL); +        gtk_tree_store_set(store, &iter, +                           STC_ADDRESS, address, +                           STC_STRING, g_binary_symbol_to_string(symbols[i]), +                           -1);      } diff --git a/src/pan_strings.h b/src/panel/strings.h index 01c2627..8227e89 100644 --- a/src/pan_strings.h +++ b/src/panel/strings.h @@ -1,6 +1,6 @@  /* OpenIDA - Outil d'analyse de fichiers binaires - * pan_strings.h - prototypes pour le panneau d'affichage des chaînes de caractères + * strings.h - prototypes pour le panneau d'affichage des chaînes de caractères   *   * Copyright (C) 2006-2007 Cyrille Bagard   * @@ -22,24 +22,23 @@   */ -#ifndef _PAN_STRINGS_H -#define _PAN_STRINGS_H +#ifndef _PANEL_STRINGS_H +#define _PANEL_STRINGS_H  #include <gtk/gtk.h> -#include "format/exe_format.h" +#include "../format/executable.h"  /* Construit le panneau d'affichage des symboles. */  GtkWidget *build_strings_panel(GObject *); -  /* Affiche la liste des symboles présents dans un exécutable. */ -void handle_new_exe_on_strings_panel(GtkWidget *, const exe_format *); +void handle_new_exe_on_strings_panel(GtkWidget *, const GExeFormat *); -#endif  /* _PAN_STRINGS_H */ +#endif  /* _PANEL_STRINGS_H */ diff --git a/src/panel/symbols.c b/src/panel/symbols.c index a31cc4b..1908ed0 100644 --- a/src/panel/symbols.c +++ b/src/panel/symbols.c @@ -30,6 +30,7 @@  #include "../arch/processor.h" +#include "../format/format.h"  #include "../gtkext/gtkbinview.h" @@ -158,10 +159,10 @@ void change_symbols_selection(GtkTreeSelection *selection, gpointer data)  *                                                                             *  ******************************************************************************/ -void reload_symbols_panel_content(GtkWidget *panel, const exe_format *format) +void reload_symbols_panel_content(GtkWidget *panel, const GExeFormat *format)  { -    GBinRoutine **routines;                 /* Routines trouvées           */ -    size_t count;                           /* Nombre de ces routines      */ +    GBinSymbol **symbols;                   /* Symboles trouvés            */ +    size_t count;                           /* Nombre de ces symboles      */      GtkTreeStore *store;                    /* Modèle de gestion           */      GArchProcessor *proc;                   /* Architecture utilisée       */      size_t i;                               /* Boucle de parcours          */ @@ -169,9 +170,9 @@ void reload_symbols_panel_content(GtkWidget *panel, const exe_format *format)      char tmp[19];                           /* Version humainement lisible */      GtkTreeIter iter;                       /* Point d'insertion           */ -    routines = get_all_exe_routines(format, &count); +    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &count); -    if (routines != NULL) +    if (symbols != NULL)      {          store = g_object_get_data(G_OBJECT(panel), "store"); @@ -179,7 +180,10 @@ void reload_symbols_panel_content(GtkWidget *panel, const exe_format *format)          for (i = 0; i < count; i++)          { -            address = g_binary_routine_get_address(routines[i]); +            if (g_binary_symbol_get_target_type(symbols[i]) == STP_STRING) +                continue; + +            address = g_binary_symbol_get_address(symbols[i]);              switch (g_arch_processor_get_memory_size(proc))              { @@ -205,7 +209,7 @@ void reload_symbols_panel_content(GtkWidget *panel, const exe_format *format)              gtk_tree_store_append(store, &iter, NULL);              gtk_tree_store_set(store, &iter,                                 SBC_ADDRESS, tmp, -                               SBC_NAME, g_binary_routine_get_name(routines[i]), +                               SBC_NAME, g_binary_symbol_to_string(symbols[i]),                                 -1);          } diff --git a/src/panel/symbols.h b/src/panel/symbols.h index 195bcf2..9761fed 100644 --- a/src/panel/symbols.h +++ b/src/panel/symbols.h @@ -29,7 +29,7 @@  #include <gtk/gtk.h> -#include "../format/exe_format.h" +#include "../format/executable.h" @@ -38,7 +38,7 @@ GtkWidget *build_symbols_panel(GObject *);  /* Affiche la liste des symboles présents dans un exécutable. */ -void reload_symbols_panel_content(GtkWidget *, const exe_format *); +void reload_symbols_panel_content(GtkWidget *, const GExeFormat *); diff --git a/src/project.c b/src/project.c index fde1eb2..6824444 100644 --- a/src/project.c +++ b/src/project.c @@ -665,6 +665,7 @@ void display_openida_project(const openida_project *project, GObject *ref)          reload_symbols_panel_content(get_panel(PNT_SYMBOLS), g_openida_binary_get_format(binary)); +        handle_new_exe_on_strings_panel(get_panel(PNT_STRINGS), g_openida_binary_get_format(binary));      } | 
