diff options
Diffstat (limited to 'src/analysis/db/items/switcher.c')
-rw-r--r-- | src/analysis/db/items/switcher.c | 138 |
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; |