diff options
Diffstat (limited to 'plugins/lnxsyscalls/writer.c')
-rw-r--r-- | plugins/lnxsyscalls/writer.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/plugins/lnxsyscalls/writer.c b/plugins/lnxsyscalls/writer.c new file mode 100644 index 0000000..1263429 --- /dev/null +++ b/plugins/lnxsyscalls/writer.c @@ -0,0 +1,222 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * writer.c - mise en place de commentaires adaptés aux appels système + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "writer.h" + + +#include <malloc.h> +#include <string.h> + + +#include <analysis/db/items/comment.h> + + + +/* Empilement de commentaire à une adresse donnée */ +typedef struct _comment_data +{ + vmpa2t addr; /* Emplacement de l'insertion */ + + char **text; /* Pièces de texte rapportées */ + size_t count; /* Nombre de ces pièces */ + +} comment_data; + +/* Mémorisation des commentaires à insérer */ +struct _comment_writer +{ + comment_data *comments; /* Définitions de commentaire */ + size_t count; /* Nombre de ces commentaires */ + +}; + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un espace de conservation pour commentaires d'appels. * +* * +* Retour : Structure de mémorisation en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +comment_writer *create_comment_writer(void) +{ + comment_writer *result; /* Structure à retourner */ + + result = (comment_writer *)malloc(sizeof(comment_writer)); + + result->comments = NULL; + result->count = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : writer = ensemble de commentaires conservés à supprimer. * +* * +* Description : Détruit la conservation de commentaires pour appels. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_comment_writer(comment_writer *writer) +{ + size_t i; /* Boucle de parcours #1 */ + comment_data *data; /* Facilités d'accès */ + size_t k; /* Boucle de parcours #2 */ + + for (i = 0; i < writer->count; i++) + { + data = &writer->comments[i]; + + for (k = 0; k < data->count; k++) + free(data->text[k]); + + if (data->text != NULL) + free(data->text); + + } + + if (writer->comments != NULL) + free(writer->comments); + + free(writer); + +} + + +/****************************************************************************** +* * +* Paramètres : writer = ensemble de commentaires conservés. * +* text = commentaire humainement lisible à insérer. * +* at = instruction dont l'adresse est la destination visée.* +* * +* Description : Complète un commentaire ou en insére un nouveau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void add_comment_at(comment_writer *writer, const char *text, GArchInstruction *at) +{ + const mrange_t *range; /* Couverture d'une instruction*/ + const vmpa2t *addr; /* Adresse de début liée */ + size_t i; /* Boucle de parcours */ + comment_data *target; /* Commentaire à éditer */ + bool new; /* Age de ce commentaire */ + + range = g_arch_instruction_get_range(at); + addr = get_mrange_addr(range); + + for (i = 0; i < writer->count; i++) + { + target = &writer->comments[i]; + + if (cmp_vmpa(addr, &target->addr) == 0) + break; + + } + + new = (i == writer->count); + + if (new) + { + writer->comments = (comment_data *)realloc(writer->comments, ++writer->count * sizeof(comment_data)); + + target = &writer->comments[writer->count - 1]; + + copy_vmpa(&target->addr, addr); + + target->text = NULL; + target->count = 0; + + } + + for (i = 0; i < target->count; i++) + if (strcmp(target->text[i], text) == 0) + break; + + if (i == target->count) + { + target->text = (char **)realloc(target->text, ++target->count * sizeof(char *)); + + target->text[target->count - 1] = strdup(text); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : writer = ensemble de commentaires conservés. * +* preload = contexte de désassemblage avec info préchargées. * +* * +* Description : Applique tous les commentaires à l'écriture anticipée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void write_all_comments(comment_writer *writer, GPreloadInfo *preload) +{ + size_t i; /* Boucle de parcours #1 */ + comment_data *target; /* Commentaire à éditer */ + GDbComment *comment; /* Commentaire final à intégrer*/ + size_t k; /* Boucle de parcours #2 */ + + for (i = 0; i < writer->count; i++) + { + target = &writer->comments[i]; + + comment = g_db_comment_new_inlined(&target->addr, BLF_HAS_CODE, false); + g_db_item_set_volatile(G_DB_ITEM(comment), true); + + for (k = 0; k < target->count; k++) + { + if (k > 0) + g_db_comment_add_static_text(comment, " / "); + + g_db_comment_add_dynamic_text(comment, strdup(target->text[k])); + + } + + g_preload_info_add_comment(preload, comment); + + } + +} |