summaryrefslogtreecommitdiff
path: root/src/analysis/db/items/switcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db/items/switcher.c')
-rw-r--r--src/analysis/db/items/switcher.c138
1 files changed, 120 insertions, 18 deletions
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 67187aa..7b72cf2 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -29,6 +29,9 @@
#include <sys/socket.h>
+#include <i18n.h>
+
+
#include "../collection-int.h"
#include "../item-int.h"
#include "../../../common/io.h"
@@ -83,6 +86,9 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *, int, int);
/* Exporte la définition d'un signet dans un flux réseau. */
static bool g_db_switcher_send_to_fd(const GDbSwitcher *, int, int);
+/* Construit la description humaine d'un signet sur un tampon. */
+static void g_db_switcher_build_label(GDbSwitcher *);
+
/* Exécute une bascule d'affichage d'opérande sur un binaire. */
static bool g_db_switcher_run(GDbSwitcher *, GLoadedBinary *, ImmOperandDisplay *, ImmOperandDisplay);
@@ -180,6 +186,7 @@ static void g_db_switcher_class_init(GDbSwitcherClass *klass)
item->recv = (recv_db_item_fc)g_db_switcher_recv_from_fd;
item->send = (send_db_item_fc)g_db_switcher_send_to_fd;
+ item->build_label = (build_item_label_fc)g_db_switcher_build_label;
item->apply = (run_item_fc)g_db_switcher_apply;
item->cancel = (run_item_fc)g_db_switcher_cancel;
@@ -364,7 +371,6 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *switcher, int fd, int flags)
{
bool status; /* Bilan d'opération initiale */
uint32_t val32; /* Valeur sur 32 bits */
- ssize_t got; /* Quantité de données reçues */
status = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->recv(G_DB_ITEM(switcher), fd, flags);
if (!status) return false;
@@ -372,17 +378,17 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *switcher, int fd, int flags)
if (!recv_vmpa(&switcher->addr, fd, flags))
return false;
- got = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL);
- if (got != sizeof(uint32_t)) return false;
+ status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags);
+ if (!status) return false;
switcher->index = be32toh(val32);
- got = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL);
- if (got != sizeof(uint32_t)) return false;
+ status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags);
+ if (!status) return false;
switcher->display = be32toh(val32);
- if (switcher->display >= IOD_COUNT)
+ if (switcher->display > IOD_COUNT)
return false;
return true;
@@ -428,6 +434,52 @@ static bool g_db_switcher_send_to_fd(const GDbSwitcher *switcher, int fd, int fl
/******************************************************************************
* *
* Paramètres : switcher = bascule d'affichage à manipuler. *
+* *
+* Description : Construit la description humaine d'un signet sur un tampon. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_switcher_build_label(GDbSwitcher *switcher)
+{
+ VMPA_BUFFER(loc); /* Indication de position */
+
+ if (has_virt_addr(&switcher->addr))
+ vmpa2_virt_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL);
+ else
+ vmpa2_phys_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL);
+
+ switch (switcher->display)
+ {
+ case IOD_BIN:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to binary display at %s"), loc);
+ break;
+ case IOD_OCT:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc);
+ break;
+ case IOD_DEC:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc);
+ break;
+ case IOD_HEX:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc);
+ break;
+ case IOD_COUNT:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Reset to default display at %s"), loc);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : switcher = bascule d'affichage à manipuler. *
* binary = binaire chargé en mémoire à modifier. *
* old = état précédent à conserver. *
* new = nouvel état à appliquer. *
@@ -446,31 +498,78 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
GArchProcessor *proc; /* Propriétaire d'instructions */
GArchInstruction *instr; /* Instruction à traiter */
GArchOperand *op; /* Opérande à modifier */
+ GCodeBuffer *buffer; /* Tampon de lignes à traiter */
+ GBufferLine *line; /* Ligne de tampon à marquer */
+ GBufferSegment *segment; /* Segment de texte à modifier*/
+ GImmOperand *operand; /* Opérande de valeur immédiate*/
+ char value[IMM_MAX_SIZE]; /* Chaîne à imprimer */
+ size_t len; /* Taille de l'élément inséré */
result = true;
+ /* Traitement au niveau des instructions */
+
proc = g_loaded_binary_get_processor(binary);
instr = g_arch_processor_find_instr_by_address(proc, &switcher->addr);
if (instr == NULL)
{
result = false;
- goto exit;
+ goto exit_instr;
}
op = g_arch_instruction_get_operand(instr, switcher->index);
if (op == NULL)
{
result = false;
- goto exit;
+ goto exit_instr;
}
result = G_IS_IMM_OPERAND(op);
+ if (!result) goto exit_instr;
+
+ /* Traitement au niveau du rendu graphique */
+
+ buffer = g_loaded_binary_get_disassembled_buffer(binary);
+
+ line = g_code_buffer_find_line_by_addr(buffer, &switcher->addr, BLF_HAS_CODE, NULL);
+ if (line == NULL)
+ {
+ result = false;
+ goto exit_gui;
+ }
+
+ segment = g_buffer_line_find_segment_from_creator(line, G_OBJECT(op));
+ result = (segment != NULL);
+
+ /* Applications globales finales */
if (result)
- g_imm_operand_set_display(G_IMM_OPERAND(op), new);
+ {
+ operand = G_IMM_OPERAND(op);
+
+ *old = g_imm_operand_get_display(operand);
+
+ if (new == IOD_COUNT)
+ new = g_imm_operand_get_default_display(operand);
+
+ g_imm_operand_set_display(operand, new);
+
+ len = g_imm_operand_to_string(operand, ASX_INTEL, value);
+
+ g_buffer_segment_update_text(segment, value, len);
+
+ g_object_unref(G_OBJECT(segment));
+
+ }
- exit:
+ g_object_unref(G_OBJECT(line));
+
+ exit_gui:
+
+ /* TODO g_object_unref(G_OBJECT(buffer));*/
+
+ exit_instr:
g_object_unref(G_OBJECT(proc));
@@ -562,7 +661,7 @@ static bool g_db_switcher_prepare_db_statement(const GDbSwitcher *switcher, boun
value->integer = switcher->index;
value->delete = NULL;
- value = &(*values)[*count - 2];
+ value = &(*values)[*count - 1];
value->name = "type";
value->type = SQLITE_INTEGER;
@@ -677,14 +776,10 @@ static void g_switcher_collection_class_init(GSwitcherCollectionClass *klass)
static void g_switcher_collection_init(GSwitcherCollection *collec)
{
-
-
- G_DB_COLLECTION(collec)->featuring = 0;
+ G_DB_COLLECTION(collec)->featuring = DBF_DISPLAY_SWITCHERS;
G_DB_COLLECTION(collec)->type = G_TYPE_DB_SWITCHER;
G_DB_COLLECTION(collec)->name = "Switchers";
-
-
}
@@ -804,6 +899,7 @@ static bool g_switcher_collection_create_db_table(const GSwitcherCollection *col
static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_value **values, size_t *count)
{
bool status; /* Bilan d'une préparation */
+ bound_value *value; /* Valeur à éditer / définir */
status = G_DB_COLLECTION_CLASS(g_switcher_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \
values, count);
@@ -815,9 +911,15 @@ static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_
*count += 2;
*values = (bound_value *)realloc(*values, *count * sizeof(bound_value));
- (*values)[*count - 2].name = "op_index";
+ value = &(*values)[*count - 2];
+
+ value->name = "op_index";
+ value->type = SQLITE_INTEGER;
+
+ value = &(*values)[*count - 1];
- (*values)[*count - 1].name = "type";
+ value->name = "type";
+ value->type = SQLITE_INTEGER;
return true;