diff options
Diffstat (limited to 'plugins/fmtp/parser.c')
-rw-r--r-- | plugins/fmtp/parser.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c index b484a0e..8fc693f 100644 --- a/plugins/fmtp/parser.c +++ b/plugins/fmtp/parser.c @@ -33,8 +33,7 @@ /* Effectue l'interprétation d'une définition de champ. */ -static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *); - +static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *, void *); @@ -43,6 +42,7 @@ 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. * +* data = infos complémentaires éventuellement fournies. * * * * Description : Effectue l'interprétation d'une définition de champ. * * * @@ -52,10 +52,11 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t * * * ******************************************************************************/ -static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos) +static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos, void *data) { GBinContent *content; /* Contenu binaire à lire */ SourceEndian endian; /* Boutisme utilisé */ + vmpa2t mod; /* Position modifiable */ bool result; /* Bilan à retourner */ GArchInstruction *instr; /* Instruction décodée */ GImmOperand *imm; /* Opérande à transformer */ @@ -74,9 +75,28 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, content = g_binary_format_get_content(format); endian = g_binary_format_get_endianness(format); - assert(def->repeat > 0); + if (def->get_value != NULL) + { + copy_vmpa(&mod, pos); + + result = def->get_value(def, content, &mod, endian, data); + + if (!result) + goto pfd_exit; + + } + + if (def->is_uleb128) + instr = g_raw_instruction_new_uleb128(content, pos); + + else if (def->is_leb128) + instr = g_raw_instruction_new_sleb128(content, pos); - instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian); + else + { + assert(def->repeat > 0); + instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian); + } result = (instr != NULL); @@ -88,7 +108,9 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, if (def->has_display_rules) { - assert(def->disp_count <= def->repeat); + assert((def->is_uleb128 && def->disp_count == 1) + || (def->is_leb128 && def->disp_count == 1) + || (!def->is_uleb128 && !def->is_leb128 && def->disp_count <= def->repeat)); for (i = 0; i < def->disp_count; i++) { @@ -198,6 +220,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, * count = taille de cette liste. * * format = description de l'exécutable à compléter. * * pos = tête de lecture pour les données. * +* data = infos complémentaires éventuellement fournies. * * * * Description : Lance l'interprétation d'une série de définitions de champs. * * * @@ -207,7 +230,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, * * ******************************************************************************/ -bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos) +bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos, void *data) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours */ @@ -215,7 +238,7 @@ bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat result = true; for (i = 0; i < count && result; i++) - result = parse_field_definition(defs + i, format, pos); + result = parse_field_definition(defs + i, format, pos, data); return result; |