summaryrefslogtreecommitdiff
path: root/plugins/fmtp
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-04-27 19:55:50 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-04-27 19:55:50 (GMT)
commitac75fdb77854c6f6d2e8db97a474c8bf3af2b0c4 (patch)
tree3a0c320d3ff87006595f52560d0de070ca4ab98e /plugins/fmtp
parent9c1367eb2e75dfac59f33e851dee8d39542072ac (diff)
Parsed ELF format fields using a new generic parser to save memory.
Diffstat (limited to 'plugins/fmtp')
-rw-r--r--plugins/fmtp/Makefile.am13
-rw-r--r--plugins/fmtp/def.h149
-rw-r--r--plugins/fmtp/parser.c223
-rw-r--r--plugins/fmtp/parser.h43
4 files changed, 428 insertions, 0 deletions
diff --git a/plugins/fmtp/Makefile.am b/plugins/fmtp/Makefile.am
new file mode 100644
index 0000000..1c5d0d9
--- /dev/null
+++ b/plugins/fmtp/Makefile.am
@@ -0,0 +1,13 @@
+
+lib_LTLIBRARIES = libfmtp.la
+
+libfmtp_la_SOURCES = \
+ def.h \
+ parser.h parser.c
+
+libfmtp_la_CFLAGS = $(AM_CFLAGS)
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/fmtp/def.h b/plugins/fmtp/def.h
new file mode 100644
index 0000000..d69d20a
--- /dev/null
+++ b/plugins/fmtp/def.h
@@ -0,0 +1,149 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * def.h - prototypes pour la définition des unités de lecture
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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 _PLUGINS_FMTP_DEF_H
+#define _PLUGINS_FMTP_DEF_H
+
+
+#include <stdbool.h>
+
+
+#include <arch/archbase.h>
+#include <common/cpp.h>
+
+
+
+/**
+ * Assurément utile pour les déclarations...
+ */
+
+#define __(s) s
+
+
+/**
+ * Méthodes de définitions des déclarations.
+ */
+
+/* Possibilités pour un champ à commenter */
+typedef struct _field_desc_switch
+{
+ bool is_range; /* Sélection de définition */
+
+ union
+ {
+ uint64_t fixed; /* Valeur fixe */
+
+ struct
+ {
+ uint64_t lower; /* Borne basse */
+ uint64_t upper; /* Borne haute */
+ };
+
+ };
+
+ const char *desc; /* Description associée */
+
+} field_desc_switch;
+
+/* Partie de commentaire */
+typedef struct _comment_part
+{
+ bool is_static; /* Choix du champ textuel */
+ bool avoid_i18n; /* Pas de traduction ! */
+
+ union
+ {
+ const char *static_text; /* Texte alloué statiquement */
+ char *dynamic_text; /* Texte alloué dynamiquement */
+ };
+
+} comment_part;
+
+/* Type de commentaires associés */
+typedef enum _FieldCommentType
+{
+ FCT_PLAIN, /* Brut et statique */
+ FCT_SWITCH, /* Eventail des possibles */
+ FCT_MULTI /* En plusieurs parties */
+
+} FieldCommentType;
+
+/* Définition générale */
+typedef struct _fmt_field_def
+{
+ const char *name; /* Nom du champ */
+
+ MemoryDataSize size; /* Taille d'un élément */
+ size_t repeat; /* Quantité d'éléments présents*/
+
+ bool is_padding; /* Simple bourrage ? */
+
+ bool has_display_rules; /* Validité des champs suivants*/
+ const ImmOperandDisplay *disp_rules; /* Règles d'affichage */
+ size_t disp_count; /* Quantité de ces règles */
+
+ FieldCommentType ctype; /* Type de commentaire */
+ union
+ {
+ const char *plain; /* Commentaire simple */
+
+ struct
+ {
+ const field_desc_switch *choices; /* Choix multiples */
+ size_t ccount; /* Quantité de ces choix */
+ const char *def_choice; /* Commentaire par défaut */
+ };
+
+ struct
+ {
+ comment_part *parts; /* Parties à considérer */
+ size_t pcount; /* Quantité de ces parties */
+ };
+
+ } comment;
+
+} fmt_field_def;
+
+
+/* Règles d'affichage */
+
+#define DISPLAY_RULES(...) \
+ .has_display_rules = true, \
+ .disp_rules = (ImmOperandDisplay []) { __VA_ARGS__ }, \
+ .disp_count = ARRAY_SIZE(((ImmOperandDisplay []) { __VA_ARGS__ }))
+
+/* Rédaction des commentaires */
+
+#define PLAIN_COMMENT(txt) \
+ .ctype = FCT_PLAIN, \
+ .comment.plain = txt
+
+#define SWITCH_COMMENT(array, def) \
+ .ctype = FCT_SWITCH, \
+ .comment.choices = array, \
+ .comment.ccount = ARRAY_SIZE(array), \
+ .comment.def_choice = def
+
+
+
+#endif /* _PLUGINS_FMTP_DEF_H */
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
new file mode 100644
index 0000000..2f469c1
--- /dev/null
+++ b/plugins/fmtp/parser.c
@@ -0,0 +1,223 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * parser.c - interprétation des champs d'un format binaire
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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 "parser.h"
+
+
+#include <assert.h>
+
+
+#include <i18n.h>
+#include <arch/raw.h>
+
+
+
+/* Effectue l'interprétation d'une définition de champ. */
+static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *);
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : def = définition de champ à considérer. *
+* format = description de l'exécutable à compléter. *
+* pos = tête de lecture pour les données. *
+* *
+* Description : Effectue l'interprétation d'une définition de champ. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos)
+{
+ GBinContent *content; /* Contenu binaire à lire */
+ SourceEndian endian; /* Boutisme utilisé */
+ bool result; /* Bilan à retourner */
+ GArchInstruction *instr; /* Instruction décodée */
+ GImmOperand *imm; /* Opérande à transformer */
+ size_t i; /* Boucle de parcours */
+ const vmpa2t *addr; /* Emplacement d'instruction */
+ GDbComment *comment; /* Définition de commentaire */
+ uint64_t raw; /* Valeur brute à étudier */
+ const comment_part *part; /* Accès plus direct */
+
+
+ GBinSymbol *symbol; /* Symbole à intégrer */
+
+
+ /* Lecture */
+
+ content = g_binary_format_get_content(format);
+ endian = g_binary_format_get_endianness(format);
+
+ assert(def->repeat > 0);
+
+ instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian);
+
+ result = (instr != NULL);
+
+ if (!result)
+ goto pfd_exit;
+
+ if (def->is_padding)
+ g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true);
+
+ if (def->has_display_rules)
+ {
+ assert(def->disp_count <= def->repeat);
+
+ for (i = 0; i < def->disp_count; i++)
+ {
+ imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, i));
+
+ g_imm_operand_set_default_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr));
+ g_imm_operand_set_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr));
+
+ // TODO : unref(imm)
+
+ }
+
+ }
+
+ /* Commentaire */
+
+ addr = get_mrange_addr(g_arch_instruction_get_range(instr));
+
+ comment = g_db_comment_new_inlined(addr, BLF_HAS_CODE, false);
+ g_db_item_set_volatile(G_DB_ITEM(comment), true);
+
+ switch (def->ctype)
+ {
+ case FCT_PLAIN:
+ g_db_comment_add_static_text(comment, _(def->comment.plain));
+ break;
+
+ case FCT_SWITCH:
+
+ imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, 0));
+ raw = g_imm_operand_get_raw_value(imm);
+ // TODO : unref(imm)
+
+ for (i = 0; i < def->comment.ccount; i++)
+ {
+ if (def->comment.choices[i].is_range)
+ {
+ if (raw < def->comment.choices[i].lower)
+ continue;
+ if (raw > def->comment.choices[i].upper)
+ continue;
+ }
+
+ else if (raw != def->comment.choices[i].fixed)
+ continue;
+
+ g_db_comment_add_static_text(comment, _(def->comment.choices[i].desc));
+ break;
+
+ }
+
+ if (i == def->comment.ccount)
+ g_db_comment_add_static_text(comment, _(def->comment.def_choice));
+
+ break;
+
+ case FCT_MULTI:
+
+ for (i = 0; i < def->comment.pcount; i++)
+ {
+ part = &def->comment.parts[i];
+
+ if (part->is_static)
+ {
+ if (part->avoid_i18n)
+ g_db_comment_add_static_text(comment, part->static_text);
+ else
+ g_db_comment_add_static_text(comment, _(part->static_text));
+ }
+ else
+ {
+ if (part->avoid_i18n)
+ g_db_comment_add_dynamic_text(comment, part->dynamic_text);
+ else
+ g_db_comment_add_dynamic_text(comment, _(part->dynamic_text));
+ }
+
+ }
+
+ break;
+
+ }
+
+ /* Insertion */
+
+ symbol = g_binary_symbol_new(STP_DATA);
+
+ g_binary_symbol_attach_instruction(symbol, instr);
+ g_binary_symbol_set_comment(symbol, comment);
+
+ result = g_binary_format_add_symbol(format, symbol);
+
+ if (!result)
+ g_object_unref(G_OBJECT(instr));
+
+ pfd_exit:
+
+ g_object_unref(G_OBJECT(content));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : defs = liste de définitions à traiter. *
+* count = taille de cette liste. *
+* format = description de l'exécutable à compléter. *
+* pos = tête de lecture pour les données. *
+* *
+* Description : Lance l'interprétation d'une série de définitions de champs. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ for (i = 0; i < count && result; i++)
+ result = parse_field_definition(defs + i, format, pos);
+
+ return result;
+
+}
diff --git a/plugins/fmtp/parser.h b/plugins/fmtp/parser.h
new file mode 100644
index 0000000..dcd9bf2
--- /dev/null
+++ b/plugins/fmtp/parser.h
@@ -0,0 +1,43 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * parser.h - prototypes pour l'interprétation des champs d'un format binaire
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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 _PLUGINS_FMTP_PARSER_H
+#define _PLUGINS_FMTP_PARSER_H
+
+
+#include <stdbool.h>
+
+
+#include <format/format.h>
+
+
+#include "def.h"
+
+
+
+/* Lance l'interprétation d'une série de définitions de champs. */
+bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *);
+
+
+
+#endif /* _PLUGINS_FMTP_PARSER_H */