summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-03-02 14:33:09 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-03-02 14:33:09 (GMT)
commitb3471e0c9ce6cc1becc9f56832fb4b93b337cb21 (patch)
treed32db80f05296ec918ad24d93634ea7d3832e49e
parent027305c2447b05de2c576e3f5ee32ced400f439f (diff)
Filled rendering lines with relative binary contents.
-rw-r--r--ChangeLog16
-rw-r--r--src/analysis/disass/area.c3
-rw-r--r--src/arch/instruction-int.h1
-rw-r--r--src/arch/instruction.c26
-rw-r--r--src/arch/instruction.h3
-rw-r--r--src/arch/raw.c2
-rw-r--r--src/arch/undefined.c2
-rw-r--r--src/glibext/gbufferline.c96
-rw-r--r--src/glibext/gbufferline.h3
9 files changed, 152 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 09e5a32..e36de8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+17-03-02 Cyrille Bagard <nocbos@gmail.com>
+
+ * 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 <nocbos@gmail.com>
* 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);