diff options
Diffstat (limited to 'plugins/fmtp')
-rw-r--r-- | plugins/fmtp/Makefile.am | 13 | ||||
-rw-r--r-- | plugins/fmtp/def.h | 149 | ||||
-rw-r--r-- | plugins/fmtp/parser.c | 223 | ||||
-rw-r--r-- | plugins/fmtp/parser.h | 43 |
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 */ |