diff options
Diffstat (limited to 'src/analysis/db/items')
| -rw-r--r-- | src/analysis/db/items/switcher.c | 373 | ||||
| -rw-r--r-- | src/analysis/db/items/switcher.h | 20 | 
2 files changed, 259 insertions, 134 deletions
| diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index 9c6a2a3..3ae9358 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -34,6 +34,7 @@  #include "../collection-int.h"  #include "../item-int.h" +#include "../../../glibext/gbinarycursor.h" @@ -46,10 +47,9 @@ struct _GDbSwitcher      GDbItem parent;                         /* A laisser en premier        */      vmpa2t addr;                            /* Adresse de l'instruction    */ -    size_t index;                           /* Indice de l'opérande visé   */ +    rle_string path;                        /* Chemin vers l'opérande visé */      ImmOperandDisplay display;              /* Type de bascule             */ -    ImmOperandDisplay old;                  /* Type de bascule précédente  */  }; @@ -74,6 +74,12 @@ static void g_db_switcher_dispose(GDbSwitcher *);  /* Procède à la libération totale de la mémoire. */  static void g_db_switcher_finalize(GDbSwitcher *); +/* Calcule le condensat associé à l'élément vu comme clef. */ +static guint g_db_switcher_hash_key(const GDbSwitcher *); + +/* Compare deux éléments en tant que clefs. */ +static gboolean g_db_switcher_cmp_key(const GDbSwitcher *, const GDbSwitcher *); +  /* Effectue la comparaison entre deux signets de collection. */  static gint g_db_switcher_cmp(const GDbSwitcher *, const GDbSwitcher *); @@ -87,7 +93,7 @@ static bool g_db_switcher_pack(const GDbSwitcher *, packed_buffer *);  static char *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); +static bool g_db_switcher_run(GDbSwitcher *, GLoadedBinary *, ImmOperandDisplay);  /* Applique une bascule d'affichage d'opérande sur un binaire. */  static bool g_db_switcher_apply(GDbSwitcher *, GLoadedBinary *); @@ -173,6 +179,8 @@ static void g_db_switcher_class_init(GDbSwitcherClass *klass)      item->feature = DBF_DISPLAY_SWITCHERS; +    item->hash_key = (hash_db_item_key_fc)g_db_switcher_hash_key; +    item->cmp_key = (cmp_db_item_key_fc)g_db_switcher_cmp_key;      item->cmp = (cmp_db_item_fc)g_db_switcher_cmp;      item->unpack = (unpack_db_item_fc)g_db_switcher_unpack; @@ -202,6 +210,11 @@ static void g_db_switcher_class_init(GDbSwitcherClass *klass)  static void g_db_switcher_init(GDbSwitcher *switcher)  { +    init_vmpa(&switcher->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); + +    setup_empty_rle_string(&switcher->path); + +    switcher->display = IOD_COUNT;  } @@ -239,6 +252,8 @@ static void g_db_switcher_dispose(GDbSwitcher *switcher)  static void g_db_switcher_finalize(GDbSwitcher *switcher)  { +    exit_rle_string(&switcher->path); +      G_OBJECT_CLASS(g_db_switcher_parent_class)->finalize(G_OBJECT(switcher));  } @@ -246,12 +261,13 @@ static void g_db_switcher_finalize(GDbSwitcher *switcher)  /******************************************************************************  *                                                                             * -*  Paramètres  : addr    = adresse inamovible localisant une position donnée. * -*                comment = commentaire construit ou NULL.                     * +*  Paramètres  : instr   = instruction contenant l'opérande à traiter.        * +*                imm     = opérande de valeur immédiate concernée.            * +*                display = forme d'affichage à établir pour l'opérande.       *  *                                                                             * -*  Description : Crée une définition d'un signet dans une zone de texte.      * +*  Description : Crée une définition de bascule d'affichage pour un immédiat. *  *                                                                             * -*  Retour      : Signet mis en place ou NULL en cas d'erreur.                 * +*  Retour      : Bascule mise en place ou NULL en cas d'erreur.               *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             * @@ -260,53 +276,122 @@ static void g_db_switcher_finalize(GDbSwitcher *switcher)  GDbSwitcher *g_db_switcher_new(GArchInstruction *instr, const GImmOperand *imm, ImmOperandDisplay display)  {      GDbSwitcher *result;                    /* Instance à retourner        */ -    size_t count;                           /* Nombre d'opérandes à visiter*/ -    size_t i;                               /* Boucle de parcours          */ -    GArchOperand *op;                       /* Opérande manipulé           */ +    bool status;                            /* Bilan de l'initialisation   */ + +    result = g_object_new(G_TYPE_DB_SWITCHER, NULL); + +    status = g_db_switcher_fill(result, instr, imm, display); +    if (!status) goto error; + +    return result; + + error: + +    g_object_unref(G_OBJECT(result)); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : switcher = bascule à initialiser.                            * +*                instr    = instruction contenant l'opérande à traiter.       * +*                imm      = opérande de valeur immédiate concerné.            * +*                display  = forme d'affichage à établir pour l'opérande.      * +*                                                                             * +*  Description : Initialise la définition de bascule d'affichage.             * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_db_switcher_fill(GDbSwitcher *switcher, GArchInstruction *instr, const GImmOperand *imm, ImmOperandDisplay display) +{ +    bool result;                            /* Bilan à retourner           */ +    char *path;                             /* Chemin vers l'opérande visé */      const mrange_t *range;                  /* Localisation de l'instruct° */ +    /** +     * Cette fonction est principalement destinée aux initialisations +     * depuis l'extension Python. +     */ + +    result = false; +      /* Recherche de la position de l'opérande */ -    g_arch_instruction_lock_operands(instr); +    path = g_arch_instruction_find_operand_path(instr, G_ARCH_OPERAND(imm)); -    count = _g_arch_instruction_count_operands(instr); +    if (path == NULL) +        goto failure; -    for (i = 0; i < count; i++) -    { -        op = _g_arch_instruction_get_operand(instr, i); +    /* Sauvegarde des propriétés */ -        if (G_ARCH_OPERAND(imm) == op) -        { -            g_object_unref(G_OBJECT(op)); -            break; -        } +    range = g_arch_instruction_get_range(instr); +    copy_vmpa(&switcher->addr, get_mrange_addr(range)); -        else -            g_object_unref(G_OBJECT(op)); +    dup_into_rle_string(&switcher->path, path); +    free(path); -    } +    switcher->display = display; -    g_arch_instruction_unlock_operands(instr); +    result = true; -    if (i == count) -        return NULL; + failure: -    /* Sauvegarde des propriétés */ +    return result; -    result = g_object_new(G_TYPE_DB_SWITCHER, NULL); +} -    range = g_arch_instruction_get_range(instr); -    copy_vmpa(&result->addr, get_mrange_addr(range)); -    result->index = i; +/****************************************************************************** +*                                                                             * +*  Paramètres  : switcher = élément de collection à consulter.                * +*                                                                             * +*  Description : Calcule le condensat associé à l'élément vu comme clef.      * +*                                                                             * +*  Retour      : Condensat associé à l'élément.                               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static guint g_db_switcher_hash_key(const GDbSwitcher *switcher) +{ +    guint result;                           /* Valeur "unique" à renvoyer  */ + +    result = hash_vmpa(&switcher->addr); + +    return result; -    result->display = display; +} -    /* Création d'un intitulé adapté */ +/****************************************************************************** +*                                                                             * +*  Paramètres  : a = premier élément de collection à consulter.               * +*                b = second élément de collection à consulter.                * +*                                                                             * +*  Description : Compare deux éléments en tant que clefs.                     * +*                                                                             * +*  Retour      : Bilan de la comparaison.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +static gboolean g_db_switcher_cmp_key(const GDbSwitcher *a, const GDbSwitcher *b) +{ +    gboolean result;                        /* Bilan à retourner           */ +    int ret;                                /* Bilan intermédiaire         */ -    //g_db_switcher_set_comment(result, comment); +    ret = cmp_vmpa(&a->addr, &b->addr); + +    result = (ret == 0);      return result; @@ -333,14 +418,7 @@ static gint g_db_switcher_cmp(const GDbSwitcher *a, const GDbSwitcher *b)      result = cmp_vmpa(&a->addr, &b->addr);      if (result == 0) -    { -        if (a->index < b->index) -            result = -1; - -        else if (a->index > b->index) -            result = 1; - -    } +        result = cmp_rle_string(&a->path, &b->path);      if (result == 0)      { @@ -381,10 +459,7 @@ static bool g_db_switcher_unpack(GDbSwitcher *switcher, packed_buffer *pbuf)          result = unpack_vmpa(&switcher->addr, pbuf);      if (result) -    { -        result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true); -        switcher->index = tmp32; -    } +        result = unpack_rle_string(&switcher->path, pbuf);      if (result)      { @@ -424,7 +499,7 @@ static bool g_db_switcher_pack(const GDbSwitcher *switcher, packed_buffer *pbuf)          result = pack_vmpa(&switcher->addr, pbuf);      if (result) -        result = extend_packed_buffer(pbuf, (uint32_t []) { switcher->index }, sizeof(uint32_t), true); +        result = pack_rle_string(&switcher->path, pbuf);      if (result)          result = extend_packed_buffer(pbuf, (uint32_t []) { switcher->display }, sizeof(uint32_t), true); @@ -448,7 +523,7 @@ static bool g_db_switcher_pack(const GDbSwitcher *switcher, packed_buffer *pbuf)  static char *g_db_switcher_build_label(GDbSwitcher *switcher)  { -#if 0 +    char *result;                           /* Description à retourner     */      VMPA_BUFFER(loc);                       /* Indication de position      */      vmpa2_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL); @@ -456,26 +531,27 @@ static char *g_db_switcher_build_label(GDbSwitcher *switcher)      switch (switcher->display)      {          case IOD_BIN: -            asprintf(&G_DB_ITEM(switcher)->label, _("Switch to binary display at %s"), loc); +            asprintf(&result, _("Switch to binary display at %s"), loc);              break;          case IOD_OCT: -            asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc); +            asprintf(&result, _("Switch to octal display at %s"), loc);              break;          case IOD_DEC: -            asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc); +            asprintf(&result, _("Switch to octal display at %s"), loc);              break;          case IOD_HEX: -            asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc); +            asprintf(&result, _("Switch to octal display at %s"), loc);              break;          case IOD_COUNT: -            asprintf(&G_DB_ITEM(switcher)->label, _("Reset to default display at %s"), loc); +            asprintf(&result, _("Reset to default display at %s"), loc);              break;          default:              assert(false); +            result = NULL;              break;      } -#endif -    return NULL; + +    return result;  } @@ -484,7 +560,6 @@ static char *g_db_switcher_build_label(GDbSwitcher *switcher)  *                                                                             *  *  Paramètres  : switcher = bascule d'affichage à manipuler.                  *  *                binary   = binaire chargé en mémoire à modifier.             * -*                old      = état précédent à conserver. [OUT]                 *  *                new      = nouvel état à appliquer.                          *  *                                                                             *  *  Description : Exécute une bascule d'affichage d'opérande sur un binaire.   * @@ -495,73 +570,69 @@ static char *g_db_switcher_build_label(GDbSwitcher *switcher)  *                                                                             *  ******************************************************************************/ -static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmOperandDisplay *old, ImmOperandDisplay new) +static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmOperandDisplay new)  { -    return false; - -#if 0      bool result;                            /* Bilan à faire remonter      */      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   */      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é  */ +    GBufferCache *cache;                    /* Tampon de lignes à traiter  */ +    GLineCursor *cursor;                    /* Emplacement dans un tampon  */ +    size_t index;                           /* Indice de ligne à traiter   */ -    result = true; +    result = false;      /* 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_instr; -    } +    if (instr == NULL) goto exit_instr; -    op = g_arch_instruction_get_operand(instr, switcher->index); -    if (op == NULL) -    { -        result = false; -        goto exit_without_operand; -    } +    op = g_arch_instruction_get_operand_from_path(instr, get_rle_string(&switcher->path)); +    if (op == NULL) goto exit_without_operand;      result = G_IS_IMM_OPERAND(op);      if (!result) goto exit_operand; +    operand = G_IMM_OPERAND(op); + +    if (new == IOD_COUNT) +        new = g_imm_operand_get_default_display(operand); + +    g_imm_operand_set_display(operand, new); +      /* Traitement au niveau du rendu graphique */ -    buffer = g_loaded_binary_get_disassembled_buffer(binary); +    cache = g_loaded_binary_get_disassembly_cache(binary); +    if (cache == NULL) goto exit_operand; -    line = g_code_buffer_find_line_by_addr(buffer, &switcher->addr, BLF_HAS_CODE, NULL); -    if (line == NULL) -    { -        result = false; -        goto exit_gui; -    } +    cursor = g_binary_cursor_new(); +    g_binary_cursor_update(G_BINARY_CURSOR(cursor), &switcher->addr); -    operand = G_IMM_OPERAND(op); +    g_buffer_cache_lock(cache); -    *old = g_imm_operand_get_display(operand); +    index = g_buffer_cache_find_index_by_cursor(cache, cursor, true); -    if (new == IOD_COUNT) -        new = g_imm_operand_get_default_display(operand); +    g_object_unref(G_OBJECT(cursor)); + +    index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE); -    g_imm_operand_set_display(&operand, new, G_SHARE_CONTAINER(instr)); +    if (index == g_buffer_cache_count_lines(cache)) +        goto exit_gui; -    len = g_imm_operand_to_string(operand, value); +    g_buffer_cache_refresh_line(cache, index); -    result = g_buffer_line_replace_text(line, G_OBJECT(op), value, len); +    result = true; -    g_object_unref(G_OBJECT(line)); +    /* Phase de sortie propre */   exit_gui: -    /* TODO g_object_unref(G_OBJECT(buffer));*/ +    g_buffer_cache_unlock(cache); + +    g_object_unref(G_OBJECT(cache));   exit_operand: @@ -576,7 +647,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO      g_object_unref(G_OBJECT(proc));      return result; -#endif +  } @@ -597,7 +668,7 @@ static bool g_db_switcher_apply(GDbSwitcher *switcher, GLoadedBinary *binary)  {      bool result;                            /* Bilan à faire remonter      */ -    result = g_db_switcher_run(switcher, binary, &switcher->old, switcher->display); +    result = g_db_switcher_run(switcher, binary, switcher->display);      return result; @@ -621,7 +692,7 @@ static bool g_db_switcher_cancel(GDbSwitcher *switcher, GLoadedBinary *binary)  {      bool result;                            /* Bilan à faire remonter      */ -    result = g_db_switcher_run(switcher, binary, (ImmOperandDisplay []) { 0 }, switcher->old); +    result = g_db_switcher_run(switcher, binary, IOD_COUNT);      return result; @@ -649,17 +720,9 @@ static bool g_db_switcher_load(GDbSwitcher *switcher, const bound_value *values,      result = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->load(G_DB_ITEM(switcher), values, count); -    result &= load_vmpa(&switcher->addr, NULL, values, count); +    if (result) result = load_vmpa(&switcher->addr, NULL, values, count); -    if (result) -    { -        value = find_bound_value(values, count, "op_index"); -        result = (value != NULL && value->type == SQLITE_INTEGER); - -        if (result) -            switcher->index = value->integer; - -    } +    if (result) result = load_rle_string(&switcher->path, "path", values, count);      if (result)      { @@ -709,22 +772,13 @@ static bool g_db_switcher_store(const GDbSwitcher *switcher, bound_value **value      if (!status) return false; -    *count += 2; -    *values = realloc(*values, *count * sizeof(bound_value)); - -    value = &(*values)[*count - 2]; - -    value->cname = "op_index"; -    value->built_name = false; -    value->type = SQLITE_INTEGER; - -    value->has_value = (switcher != NULL); +    if (switcher == NULL) +        status &= store_rle_string(NULL, "path", values, count); +    else +        status &= store_rle_string(&switcher->path, "path", values, count); -    if (value->has_value) -    { -        value->integer = switcher->index; -        value->delete = NULL; -    } +    *count += 1; +    *values = realloc(*values, *count * sizeof(bound_value));      value = &(*values)[*count - 1]; @@ -745,6 +799,75 @@ static bool g_db_switcher_store(const GDbSwitcher *switcher, bound_value **value  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : switcher = informations à consulter.                         * +*                                                                             * +*  Description : Fournit l'adresse associée à une bascule.                    * +*                                                                             * +*  Retour      : Adresse mémoire.                                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const vmpa2t *g_db_switcher_get_address(const GDbSwitcher *switcher) +{ +    const vmpa2t *result;                   /* Localisation à retourner    */ + +    result = &switcher->addr; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : switcher = informations à consulter.                         * +*                                                                             * +*  Description : Fournit le chemin menant vers l'opérande basculé.            * +*                                                                             * +*  Retour      : Chemin de type "n[:n:n:n]".                                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *g_db_switcher_get_path(const GDbSwitcher *switcher) +{ +    const char *result;                     /* Chemin à renvoyer           */ + +    result = get_rle_string(&switcher->path); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : switcher = informations à consulter.                         * +*                                                                             * +*  Description : Indique l'affichage vers lequel un opérande a basculé.       * +*                                                                             * +*  Retour      : Type d'affichage forcé pour un opérande.                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +ImmOperandDisplay g_db_switcher_get_display(const GDbSwitcher *switcher) +{ +    ImmOperandDisplay result;               /* Type d'affichage à retourner*/ + +    result = switcher->display; + +    return result; + +} + +  /* ---------------------------------------------------------------------------------- */  /*                        DEFINITION DE LA COLLECTION ASSOCIEE                        */ @@ -887,11 +1010,11 @@ static bool g_switcher_collection_create_db_table(const GSwitcherCollection *col      char *msg;                              /* Message d'erreur            */      int ret;                                /* Bilan de la création        */ -    sql = "CREATE TABLE Switchers ("        \ -             SQLITE_DB_ITEM_CREATE ", "     \ -             "%s, "                         \ -             "op_index INTEGER, "           \ -             "type INTEGER"                 \ +    sql = "CREATE TABLE Switchers ("            \ +             SQLITE_DB_ITEM_CREATE ", "         \ +             "%s, "                             \ +             SQLITE_RLESTR_CREATE("path") ","   \ +             "type INTEGER"                     \            ");";      addr_fields = create_vmpa_db_table(NULL); diff --git a/src/analysis/db/items/switcher.h b/src/analysis/db/items/switcher.h index ecc6fd4..daf6154 100644 --- a/src/analysis/db/items/switcher.h +++ b/src/analysis/db/items/switcher.h @@ -54,19 +54,21 @@ typedef struct _GDbSwitcherClass GDbSwitcherClass;  /* Indique le type défini pour un signet à l'intérieur d'une zone de texte. */  GType g_db_switcher_get_type(void); -/* Crée une définition d'un signet dans une zone de texte. */ +/* Crée une définition de bascule d'affichage pour un immédiat. */  GDbSwitcher *g_db_switcher_new(GArchInstruction *, const GImmOperand *, ImmOperandDisplay); -#if 0 -/* Fournit l'adresse associée à un signet. */ -const vmpa2t *g_db_switcher_get_address(GDbSwitcher *); +/* Initialise la définition de bascule d'affichage. */ +bool g_db_switcher_fill(GDbSwitcher *, GArchInstruction *, const GImmOperand *, ImmOperandDisplay); -/* Fournit le commentaire associé à un signet. */ -const char *g_db_switcher_get_comment(const GDbSwitcher *); +/* Fournit l'adresse associée à une bascule. */ +const vmpa2t *g_db_switcher_get_address(const GDbSwitcher *); + +/* Fournit le chemin menant vers l'opérande basculé. */ +const char *g_db_switcher_get_path(const GDbSwitcher *); + +/* Indique l'affichage vers lequel un opérande a basculé. */ +ImmOperandDisplay g_db_switcher_get_display(const GDbSwitcher *); -/* Définit le commentaire associé à un signet. */ -void g_db_switcher_set_comment(GDbSwitcher *, const char *); -#endif  /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ | 
