From b3471e0c9ce6cc1becc9f56832fb4b93b337cb21 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 2 Mar 2017 15:33:09 +0100 Subject: Filled rendering lines with relative binary contents. --- ChangeLog | 16 ++++++++ src/analysis/disass/area.c | 3 ++ src/arch/instruction-int.h | 1 + src/arch/instruction.c | 26 +++++++++++++ src/arch/instruction.h | 3 ++ src/arch/raw.c | 2 + src/arch/undefined.c | 2 + src/glibext/gbufferline.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++ src/glibext/gbufferline.h | 3 ++ 9 files changed, 152 insertions(+) diff --git a/ChangeLog b/ChangeLog index 09e5a32..e36de8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +17-03-02 Cyrille Bagard + + * src/analysis/disass/area.c: + Set the global content for each collected instruction. + + * src/arch/instruction-int.h: + * src/arch/instruction.c: + * src/arch/instruction.h: + * src/arch/raw.c: + * src/arch/undefined.c: + Remember the global content and print bytes of each instruction. + + * src/glibext/gbufferline.c: + * src/glibext/gbufferline.h: + Fill rendering lines with relative binary contents. + 17-02-28 Cyrille Bagard * src/analysis/binary.c: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 8da8b60..74bdfd3 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -367,6 +367,9 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction area->instructions[offset] = instr; g_atomic_pointer_add(&area->count, 1); + /* Au passage, association du contenu */ + g_arch_instruction_set_global_content(instr, area->content); + } return result; diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index e7d5ba0..89f589a 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -53,6 +53,7 @@ struct _GArchInstruction const instr_hook_fc *hooks; /* Traitements complémentaires */ + const GBinContent *content; /* Contenu binaire global */ mrange_t range; /* Emplacement en mémoire */ GArchOperand **operands; /* Liste des opérandes */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index f539ddb..be049e1 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -190,6 +190,9 @@ static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface) static void g_arch_instruction_dispose(GArchInstruction *instr) { + if (instr->content != NULL) + g_object_unref(G_OBJECT(instr->content)); + G_OBJECT_CLASS(g_arch_instruction_parent_class)->dispose(G_OBJECT(instr)); } @@ -324,6 +327,27 @@ void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type /****************************************************************************** * * * Paramètres : instr = instruction quelconque à modifier. * +* content = contenu binaire global à référencer. * +* * +* Description : Note le contenu du sein duquel l'instruction est issue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_arch_instruction_set_global_content(GArchInstruction *instr, const GBinContent *content) +{ + g_object_ref(G_OBJECT(content)); + instr->content = content; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction quelconque à modifier. * * address = adresse virtuelle et/ou position physique. * * length = taille de l'instruction. * * * @@ -1140,6 +1164,8 @@ static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line g_buffer_line_fill_vmpa(line, get_mrange_addr(&instr->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); + g_buffer_line_fill_content(line, instr->content, &instr->range, VMPA_NO_PHYSICAL); + /* Instruction proprement dite */ key = g_arch_instruction_get_keyword(instr, 0/*, syntax*/); diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 7323a2e..27c28f5 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -107,6 +107,9 @@ void g_arch_instruction_set_hooks(GArchInstruction *, const instr_hook_fc [IPH_C /* Complète un désassemblage accompli pour une instruction. */ void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GExeFormat *); +/* Note le contenu du sein duquel l'instruction est issue. */ +void g_arch_instruction_set_global_content(GArchInstruction *, const GBinContent *); + /* Définit la localisation d'une instruction. */ void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *); diff --git a/src/arch/raw.c b/src/arch/raw.c index 8a44972..9b4a57d 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -479,6 +479,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s { g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); + g_buffer_line_fill_content(line, base->content, &base->range, VMPA_NO_PHYSICAL); + /* Instruction proprement dite */ key = g_arch_instruction_get_keyword(base, 0/*, syntax*/); diff --git a/src/arch/undefined.c b/src/arch/undefined.c index 39b3e8b..8741c43 100644 --- a/src/arch/undefined.c +++ b/src/arch/undefined.c @@ -286,6 +286,8 @@ static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *lin g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); + g_buffer_line_fill_content(line, base->content, &base->range, VMPA_NO_PHYSICAL); + /* Instruction proprement dite */ key = g_arch_instruction_get_keyword(base, 0/*, syntax*/); diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 5a7e53d..d9e974c 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -392,6 +392,102 @@ void g_buffer_line_fill_vmpa(GBufferLine *line, const vmpa2t *addr, MemoryDataSi /****************************************************************************** * * +* Paramètres : line = ligne à venir compléter. * +* content = contenu binaire global à venir lire. * +* range = localisation des données à venir lire et présenter.* +* max = taille maximale de la portion binaire en octets. * +* * +* Description : Construit le tronc commun d'une ligne autour de son contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_line_fill_content(GBufferLine *line, const GBinContent *content, const mrange_t *range, phys_t max) +{ + phys_t length; /* Taille de la couverture */ + bool truncated; /* Indique si le code est coupé*/ + size_t required; /* Taille de traitement requise*/ + char static_buffer[64]; /* Petit tampon local rapide */ + char *bin_code; /* Tampon utilisé pour le code */ + vmpa2t pos; /* Boucle de parcours #1 */ + phys_t i; /* Boucle de parcours #2 */ + char *iter; /* Boucle de parcours #3 */ + int ret; /* Progression dans l'écriture */ + uint8_t byte; /* Octet à représenter */ + + static const char *charset = "0123456789abcdef"; + + /* Détermination du réceptacle */ + + length = get_mrange_length(range); + + truncated = (max != VMPA_NO_PHYSICAL && length > max); + + if (truncated) + { + length = max; + required = length * 3 + 4 /* "..." */ + 1; + } + else + required = length * 3 + 1; + + if (required <= sizeof(static_buffer)) + bin_code = static_buffer; + else + bin_code = (char *)calloc(required, sizeof(char)); + + /* Code brut */ + + copy_vmpa(&pos, get_mrange_addr(range)); + + for (i = 0, iter = bin_code; i < length; i++, iter += ret) + { + if (i == 0) + ret = 0; + else + { + iter[0] = ' '; + ret = 1; + } + + if (!g_binary_content_read_u8(content, &pos, &byte)) + { + iter[ret + 0] = '?'; + iter[ret + 1] = '?'; + } + else + { + iter[ret + 0] = charset[byte >> 4]; + iter[ret + 1] = charset[byte & 0x0f]; + } + + ret += 2; + + } + + if (truncated) + { + strcpy(iter, "..."); + iter += 3; + } + else + *iter = '\0'; + + /* Conclusion */ + + g_buffer_line_append_text(line, BLC_BINARY, bin_code, iter - bin_code, RTT_RAW_CODE, NULL); + + if (bin_code != static_buffer) + free(bin_code); + +} + + +/****************************************************************************** +* * * Paramètres : line = ligne à venir compléter. * * psize = taille souhaitée de l'impression des positions. * * vsize = taille souhaitée de l'impression des adresses. * diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 3095086..9478404 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -117,6 +117,9 @@ void g_buffer_line_fill_virt(GBufferLine *, MemoryDataSize, const vmpa2t *); /* Construit le tronc commun d'une ligne autour de sa position. */ void g_buffer_line_fill_vmpa(GBufferLine *, const vmpa2t *, MemoryDataSize, MemoryDataSize); +/* Construit le tronc commun d'une ligne autour de son contenu. */ +void g_buffer_line_fill_content(GBufferLine *, const GBinContent *, const mrange_t *, phys_t); + /* Construit le tronc commun d'une ligne autour de sa position. */ void g_buffer_line_fill_mrange(GBufferLine *, MemoryDataSize, MemoryDataSize); -- cgit v0.11.2-87-g4458