/* Chrysalide - Outil d'analyse de fichiers binaires * binary.c - traitement des flots de code binaire * * Copyright (C) 2008-2014 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 Foobar. If not, see . */ #include "binary.h" #include #include #include #include #include #include #include #include "routine.h" #include "db/client.h" #include "decomp/decompiler.h" #include "disass/disassembler.h" #include "../common/extstr.h" #include "../common/cpp.h" #include "../common/xdg.h" #include "../core/collections.h" #include "../core/formats.h" #include "../core/params.h" #include "../core/processors.h" #include "../glibext/chrysamarshal.h" #include "../gui/panels/log.h" /* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */ /* Description de fichier binaire (instance) */ struct _GLoadedBinary { GObject parent; /* A laisser en premier */ char *username; /* Identifiant de l'utilisateur*/ bool username_changed; /* Mémorise les changements */ bool local_storage; /* Enregistrements locaux ? */ char *remote_host; /* Nom du serveur distant */ unsigned short remote_port; /* Port du serveur distant */ GDbClient *local; /* Enregistrements locaux */ GDbClient *remote; /* Enregistrements distants */ DBStorage storages[DBF_COUNT]; /* Lieux d'enregistrement */ GList *collections; /* Ensemble de modifications */ GBinContent *content; /* Contenu binaire chargé */ //// REMME GExeFormat *format; /* Format du binaire */ GDbgFormat *debug; /* Informations de débogage */ //// REMME GArchProcessor *proc; /* Architecture du binaire */ GArchInstruction *instrs; /* Instructions d'assemblage */ GCodeBuffer *disass_buffer; /* Instructions lisibles */ GCodeBuffer **dec_buffers; /* Sources sous forme de texte */ size_t decbuf_count; /* Taille des tableaux */ size_t defsrc; /* Fichier source principal */ bool col_display[BVW_COUNT][BLC_DISPLAY];/* Position et code binaire */ bool lines_display; /* Affichage des lignes */ }; /* Description de fichier binaire (classe) */ struct _GLoadedBinaryClass { GObjectClass parent; /* A laisser en premier */ /* Signaux */ void (* disassembly_done) (GLoadedBinary *); void (* display_changed) (GLoadedBinary *, BinaryView, BufferLineColumn); }; /* Initialise la classe des descriptions de fichier binaire. */ static void g_loaded_binary_class_init(GLoadedBinaryClass *); /* Initialise une description de fichier binaire. */ static void g_loaded_binary_init(GLoadedBinary *); /* Supprime toutes les références externes. */ static void g_loaded_binary_dispose(GLoadedBinary *); /* Procède à la libération totale de la mémoire. */ static void g_loaded_binary_finalize(GLoadedBinary *); /* Acquitte la fin d'un désasemblage différé et complet. */ static void ack_completed_disassembly(GDelayedDisassembly *, GLoadedBinary *); /* ------------------------- INFORMATIONS D'ENREGISTREMENTS ------------------------- */ /* Charge en mémoire les formes d'enregistrement du XML. */ static bool g_loaded_binary_load_storage(GLoadedBinary *, xmlXPathContextPtr, const char *); /* Ecrit les formes d'enregistrement du binaire dans du XML. */ static bool g_loaded_binary_save_storage(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *); /* Etablit une connexion au serveur interne en tant que client. */ static bool g_loaded_binary_connect_internal(GLoadedBinary *); /* Etablit une connexion à un serveur distant comme client. */ static bool g_loaded_binary_connect_remote(GLoadedBinary *); /* -------------------------- MANIPULATION DES COLLECTIONS -------------------------- */ /* Indique le type défini pour une description de fichier binaire. */ G_DEFINE_TYPE(GLoadedBinary, g_loaded_binary, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des descriptions de fichier binaire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_loaded_binary_class_init(GLoadedBinaryClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_loaded_binary_dispose; object->finalize = (GObjectFinalizeFunc)g_loaded_binary_finalize; g_signal_new("disassembly-done", G_TYPE_LOADED_BINARY, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GLoadedBinaryClass, disassembly_done), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_signal_new("display-changed", G_TYPE_LOADED_BINARY, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GLoadedBinaryClass, display_changed), NULL, NULL, g_cclosure_user_marshal_VOID__ENUM_ENUM, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); } /****************************************************************************** * * * Paramètres : binary = instance à initialiser. * * * * Description : Initialise une description de fichier binaire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_loaded_binary_init(GLoadedBinary *binary) { binary->username = strdup("default"); binary->local_storage = true; binary->remote_host = strdup("localhost"); binary->remote_port = 1337; binary->storages[DBF_BOOKMARKS] = DBS_ALL_LOCAL; binary->storages[DBF_COMMENTS] = DBS_ALL_LOCAL; binary->storages[DBF_MOVES] = DBS_ALL_LOCAL; binary->storages[DBF_DISPLAY_SWITCHERS] = DBS_ALL_LOCAL; binary->collections = create_collections_list(); attach_binary_to_collections(binary->collections, binary); binary->col_display[BVW_BLOCK][BLC_PHYSICAL] = true; binary->col_display[BVW_BLOCK][BLC_VIRTUAL] = true; binary->col_display[BVW_BLOCK][BLC_BINARY] = true; binary->col_display[BVW_GRAPH][BLC_PHYSICAL] = false; binary->col_display[BVW_GRAPH][BLC_VIRTUAL] = false; binary->col_display[BVW_GRAPH][BLC_BINARY] = false; binary->col_display[BVW_SOURCE][BLC_PHYSICAL] = false; binary->col_display[BVW_SOURCE][BLC_VIRTUAL] = false; binary->col_display[BVW_SOURCE][BLC_BINARY] = false; binary->lines_display = true; } /****************************************************************************** * * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_loaded_binary_dispose(GLoadedBinary *binary) { g_object_unref(G_OBJECT(binary->content)); if (binary->format != NULL) g_object_unref(G_OBJECT(binary->format)); if (binary->proc != NULL) g_object_unref(G_OBJECT(binary->proc)); /* TODO... */ G_OBJECT_CLASS(g_loaded_binary_parent_class)->dispose(G_OBJECT(binary)); } /****************************************************************************** * * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_loaded_binary_finalize(GLoadedBinary *binary) { free(binary->username); /* TODO... */ G_OBJECT_CLASS(g_loaded_binary_parent_class)->finalize(G_OBJECT(binary)); } /****************************************************************************** * * * Paramètres : content = contenu binaire chargé en mémoire. * * * * Description : Interprète un contenu binaire chargé. * * * * Retour : Adresse de la représentation ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GLoadedBinary *g_loaded_binary_new(GBinContent *content) { GLoadedBinary *result; /* Adresse à retourner */ FormatMatchStatus status; /* Statut d'une reconnaissance */ char *target; /* Sous-traitance requise */ const char *desc; /* Description humaine associée*/ const char *arch; /* Architecture d'exécution */ result = g_object_new(G_TYPE_LOADED_BINARY, NULL); log_variadic_message(LMT_PROCESS, _("Opening binary data from '%s'..."), g_binary_content_describe(content, true)); result->content = content; /* Format d'exécutable */ status = find_matching_format(content, NULL, &target); assert(status == FMS_MATCHED); desc = get_binary_format_name(target); if (desc == NULL) { free(target); log_simple_message(LMT_INFO, _("Unknown binary format")); goto lbf_error; } else log_variadic_message(LMT_INFO, _("Detected format: %s"), desc); result->format = G_EXE_FORMAT(load_new_named_format(target, content, NULL)); free(target); if (result->format == NULL) { log_simple_message(LMT_ERROR, _("Error while loading the binary")); goto lbf_error; } /* Informations de débogage associées */ g_loaded_binary_attach_debug_info(result, content); /* Architecture visée */ arch = g_exe_format_get_target_machine(result->format); desc = get_arch_processor_name(arch); if (desc == NULL) { log_simple_message(LMT_INFO, _("Unknown architecture")); goto lbf_error; } else log_variadic_message(LMT_INFO, _("Detected architecture: %s"), desc); result->proc = get_arch_processor_for_type(arch); if (result->proc == NULL) { log_simple_message(LMT_ERROR, _("Unable to load the required processor")); goto lbf_error; } return G_LOADED_BINARY(result); lbf_error: g_object_unref(G_OBJECT(result)); return NULL; } /****************************************************************************** * * * Paramètres : content = contenu binaire chargé en mémoire. * * context = contexte pour les recherches XPath. * * path = chemin d'accès au noeud XML à lire. * * project = projet dans lequel venir rechercher les contenus. * * * * Description : Interprète un contenu binaire chargé avec un appui XML. * * * * Retour : Adresse de la représentation ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const char *path, GStudyProject *project) { GLoadedBinary *result; /* Adresse à retourner */ char *content_path; /* Partie "Contenus" */ char *access; /* Chemin d'accès à un élément */ char *hash; /* Empreinte à retrouver */ GBinContent *content; /* Contenu à référencer */ xmlXPathObjectPtr xobject; /* Cible d'une recherche */ unsigned int i; /* Boucle de parcours */ /* Contenus binaires associés */ content_path = strdup(path); content_path = stradd(content_path, "/Contents"); access = strdup(content_path); access = stradd(access, "/Main"); hash = get_node_text_value(context, access); free(access); if (hash == NULL) { free(content_path); return NULL; } content = g_study_project_find_binary_content_by_hash(project, hash); free(hash); if (content == NULL) { free(content_path); return NULL; } result = g_loaded_binary_new(content); if (result == NULL) { free(content_path); return NULL; } asprintf(&access, "%s/DebugInfo", content_path); xobject = get_node_xpath_object(context, access); free(access); for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++) { asprintf(&access, "%s/DebugInfo[position()=%u]", content_path, i + 1); hash = get_node_text_value(context, access); free(access); if (hash == NULL) { free(content_path); goto glbnfx_error; } content = g_study_project_find_binary_content_by_hash(project, hash); free(hash); if (content == NULL) { free(content_path); goto glbnfx_error; } if (!g_loaded_binary_attach_debug_info(result, content)) { free(content_path); goto glbnfx_error; } } if(xobject != NULL) xmlXPathFreeObject(xobject); free(content_path); /* Elément divers associés au binaire */ if (!g_loaded_binary_load_storage(result, context, path)) goto glbnfx_error; return result; glbnfx_error: g_object_unref(G_OBJECT(result)); return NULL; } /****************************************************************************** * * * Paramètres : binary = élément binaire à traiter. * * xdoc = structure XML en cours d'édition. * * context = contexte à utiliser pour les recherches. * * path = chemin d'accès réservé au binaire. * * * * Description : Ecrit une sauvegarde du binaire dans un fichier XML. * * * * Retour : true si l'opération a bien tourné, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) { bool result; /* Bilan à faire remonter */ char *content_path; /* Partie "Contenus" */ char *access; /* Chemin d'accès à un élément */ GBinContent *content; /* Contenu à référencer */ const gchar *hash; /* Empreinte à mémoriser */ size_t debugs_count; /* Quantité de formats liés */ size_t i; /* Boucle de parcours */ GDbgFormat *debug; /* Informations de débogage */ /* Contenus binaires associés */ content_path = strdup(path); content_path = stradd(content_path, "/Contents"); access = strdup(content_path); access = stradd(access, "/Main"); content = g_binary_format_get_content(G_BIN_FORMAT(binary->format)); hash = g_binary_content_get_checksum(content); g_object_unref(G_OBJECT(content)); result = add_content_to_node(xdoc, context, access, hash); free(access); debugs_count = g_exe_format_count_debug_info(binary->format); for (i = 0; i < debugs_count; i++) { asprintf(&access, "%s/DebugInfo[position()=%zu]", content_path, i); debug = g_exe_format_get_debug_info(binary->format, i); content = g_binary_format_get_content(G_BIN_FORMAT(debug)); hash = g_binary_content_get_checksum(content); g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(debug)); result &= add_content_to_node(xdoc, context, access, hash); free(access); } free(content_path); /* Elément divers associés au binaire */ result = g_loaded_binary_save_storage(binary, xdoc, context, path); /* Sauvegarde côté serveur */ g_db_client_save(binary->local); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * full = précise s'il s'agit d'une version longue ou non. * * * * Description : Fournit le nom associé à l'élément binaire. * * * * Retour : Nom de fichier avec chemin absolu. * * * * Remarques : - * * * ******************************************************************************/ const char *g_loaded_binary_get_name(const GLoadedBinary *binary, bool full) { const char *result; /* Description à retourner */ GBinContent *content; /* Contenu binaire mannipulé */ content = g_binary_format_get_content(G_BIN_FORMAT(binary->format)); result = g_binary_content_describe(content, full); g_object_unref(G_OBJECT(content)); return result; } /* ---------------------------------------------------------------------------------- */ /* INFORMATIONS D'ENREGISTREMENTS */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : binary = élément binaire à traiter. * * context = contexte pour les recherches XPath. * * path = chemin d'accès au noeud XML à lire. * * * * Description : Charge en mémoire les formes d'enregistrement du XML. * * * * Retour : true si l'opération a bien tourné, false sinon. * * * * Remarques : - * * * ******************************************************************************/ static bool g_loaded_binary_load_storage(GLoadedBinary *binary, xmlXPathContextPtr context, const char *path) { bool result; /* Bilan à faire remonter */ char *storage_path; /* Partie "Enregistrement" */ char *value; /* Valeur lue à partie du XML */ char *access; /* Chemin d'accès à un élément */ unsigned short port; /* Port de communication */ bool use; /* Usage d'un serveur distant */ DBFeatures i; /* Boucle de parcours */ result = true; storage_path = strdup(path); storage_path = stradd(storage_path, "/Storage"); value = get_node_prop_value(context, storage_path, "local"); if (value == NULL) goto glbls_no_storage_config; binary->local_storage = (strcmp(value, "true") == 0); free(value); /* Nom d'utilisateur */ access = strdup(storage_path); access = stradd(access, "/Username"); value = get_node_text_value(context, access); if (value != NULL) { g_loaded_binary_set_username(binary, value); free(value); } free(access); /* Serveur distant */ access = strdup(storage_path); access = stradd(access, "/RemoteServer"); value = get_node_prop_value(context, access, "port"); if (value == NULL) goto glbls_features; port = atoi(value); free(value); value = get_node_prop_value(context, access, "host"); if (value == NULL) goto glbls_features; g_loaded_binary_set_remote_server(binary, value, port); free(value); glbls_features: free(access); /* Fonctionnalités */ for (i = 0; i < DBF_COUNT; i++) { access = strdup(storage_path); access = stradd(access, "/Features/"); switch (i) { case DBF_BOOKMARKS: access = stradd(access, "Bookmarks"); break; case DBF_COMMENTS: access = stradd(access, "Comments"); break; case DBF_MOVES: access = stradd(access, "Moves"); break; case DBF_DISPLAY_SWITCHERS: access = stradd(access, "Segments"); break; default: /* Pour GCC */ assert(false); break; } value = get_node_text_value(context, access); if (value != NULL) { if (atoi(value) <= DBS_MAX) g_loaded_binary_set_storage(binary, i, atoi(value)); } free(access); } glbls_no_storage_config: free(storage_path); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à traiter. * * xdoc = structure XML en cours d'édition. * * context = contexte à utiliser pour les recherches. * * path = chemin d'accès réservé au binaire. * * * * Description : Ecrit les formes d'enregistrement du binaire dans du XML. * * * * Retour : true si l'opération a bien tourné, false sinon. * * * * Remarques : - * * * ******************************************************************************/ static bool g_loaded_binary_save_storage(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) { bool result; /* Bilan à faire remonter */ char *storage_path; /* Partie "Enregistrement" */ char *access; /* Chemin d'accès à un élément */ char port_str[sizeof(XSTR(USHRT_MAX)) + 1]; /* Version chaînée */ DBFeatures i; /* Boucle de parcours */ result = true; storage_path = strdup(path); storage_path = stradd(storage_path, "/Storage"); result &= add_string_attribute_to_node(xdoc, context, storage_path, "local", binary->local_storage ? "true" : "false"); /* Nom d'utilisateur */ access = strdup(storage_path); access = stradd(access, "/Username"); result &= add_content_to_node(xdoc, context, access, binary->username); free(access); /* Serveur distant */ access = strdup(storage_path); access = stradd(access, "/RemoteServer"); result &= add_string_attribute_to_node(xdoc, context, access, "host", binary->remote_host); sprintf(port_str, "%hu", binary->remote_port); result &= add_string_attribute_to_node(xdoc, context, access, "port", port_str); free(access); /* Fonctionnalités */ for (i = 0; i < DBF_COUNT; i++) { access = strdup(storage_path); access = stradd(access, "/Features/"); switch (i) { case DBF_BOOKMARKS: access = stradd(access, "Bookmarks"); break; case DBF_COMMENTS: access = stradd(access, "Comments"); break; case DBF_MOVES: access = stradd(access, "Moves"); break; case DBF_DISPLAY_SWITCHERS: access = stradd(access, "Segments"); break; default: /* Pour GCC */ assert(false); break; } result &= add_uint_content_to_node(xdoc, context, access, binary->storages[i]); free(access); } free(storage_path); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Identifie l'utilisateur analysant le binaire courant. * * * * Retour : Nom de l'utilisateur manipulant le binaire. * * * * Remarques : - * * * ******************************************************************************/ const char *g_loaded_binary_get_username(const GLoadedBinary *binary) { return binary->username; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * username = nom de l'utilisateur manipulant le binaire. * * * * Description : Définit l'utilisateur analysant le binaire courant. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_loaded_binary_set_username(GLoadedBinary *binary, const char *username) { bool changed; /* Note les changements */ changed = (strcmp(binary->username, username) != 0); free(binary->username); binary->username = strdup(username); binary->username_changed = changed; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Détermine si tous les enregistrements sont locaux ou non. * * * * Retour : Statut de l'utilisation du serveur local. * * * * Remarques : - * * * ******************************************************************************/ bool g_loaded_binary_get_local_storage(const GLoadedBinary *binary) { return binary->local_storage; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * local = statut de l'utilisation du serveur local. * * * * Description : Définit si tous les enregistrements sont locaux ou non. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_loaded_binary_set_local_storage(GLoadedBinary *binary, bool local) { binary->local_storage = local; if (local) /* TODO : reload conn ! */; else /* TODO : stop conn ! */; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * host = nom du serveur distant à contacter. [OUT] * * port = port de communication avec le serveur distant. [OUT]* * * * Description : Identifie le serveur distant associé au binaire courant. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_loaded_binary_get_remote_server(const GLoadedBinary *binary, const char **host, unsigned short *port) { *host = binary->remote_host; *port = binary->remote_port; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * host = nom du serveur distant à contacter. * * port = port de communication avec le serveur distant. * * * * Description : Définit le serveur distant associé au binaire courant. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_loaded_binary_set_remote_server(GLoadedBinary *binary, const char *host, unsigned short port) { free(binary->remote_host); binary->remote_host = strdup(host); binary->remote_port = port; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * feature = fonctionnalité visée par la requête. * * * * Description : Indique la forme d'enregistrement d'une fonctionnalité. * * * * Retour : Type d'enregistrement sélectionné. * * * * Remarques : - * * * ******************************************************************************/ DBStorage g_loaded_binary_get_storage(const GLoadedBinary *binary, DBFeatures feature) { return binary->storages[feature]; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * feature = fonctionnalité visée par la requête. * * storage = type d'enregistrement sélectionné. * * * * Description : Définit la forme d'enregistrement d'une fonctionnalité. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_loaded_binary_set_storage(GLoadedBinary *binary, DBFeatures feature, DBStorage storage) { binary->storages[feature] = storage; } /****************************************************************************** * * * Paramètres : binary = élément binaire à manipuler. * * * * Description : Etablit une connexion au serveur interne en tant que client. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ static bool g_loaded_binary_connect_internal(GLoadedBinary *binary) { bool result; /* Bilan à retourner */ const char *tmp; /* Stockage temporaire */ char *author; /* Identification à diffuser */ char *priv; /* Chemin de la clef privée */ GBinContent *content; /* Contenu bianire manipulé */ const gchar *checksum; /* Identifiant de binaire */ char *host; /* Nom du serveur à contacter */ int port; /* Numéro du port associé */ result = false; /* Utilisateur représenté */ if (!g_generic_config_get_value(get_main_configuration(), MPK_AUTHOR_NAME, &tmp)) goto glbcl_exit; author = strdup(tmp); /* Chemin vers la clef privée */ priv = get_xdg_config_dir("chrysalide" G_DIR_SEPARATOR_S "id_rsa.priv"); /* Détermination de l'identifiant */ content = g_binary_format_get_content(G_BIN_FORMAT(binary->format)); checksum = g_binary_content_get_checksum(content); g_object_unref(G_OBJECT(content)); /* Tentative de connexion */ binary->local = g_db_client_new(author, priv, g_loaded_binary_get_name(binary, false), checksum, binary->collections); if (!g_generic_config_get_value(get_main_configuration(), MPK_LOCAL_HOST, &host)) /* ... */; if (!g_generic_config_get_value(get_main_configuration(), MPK_LOCAL_PORT, &port)) /* ... */; result = g_db_client_start_internal(binary->local); printf("DB status :: %d\n", result); glbcl_exit: return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à manipuler. * * * * Description : Etablit une connexion à un serveur distant comme client. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ static bool g_loaded_binary_connect_remote(GLoadedBinary *binary) { bool result; /* Bilan à retourner */ const char *tmp; /* Stockage temporaire */ char *author; /* Identification à diffuser */ char *priv; /* Chemin de la clef privée */ GBinContent *content; /* Contenu bianire manipulé */ const gchar *checksum; /* Identifiant de binaire */ char *host; /* Nom du serveur à contacter */ int port; /* Numéro du port associé */ result = false; /* Utilisateur représenté */ if (!g_generic_config_get_value(get_main_configuration(), MPK_AUTHOR_NAME, &tmp)) goto glbcl_exit; author = strdup(tmp); /* Chemin vers la clef privée */ priv = get_xdg_config_dir("chrysalide" G_DIR_SEPARATOR_S "id_rsa.priv"); /* Détermination de l'identifiant */ content = g_binary_format_get_content(G_BIN_FORMAT(binary->format)); checksum = g_binary_content_get_checksum(content); g_object_unref(G_OBJECT(content)); /* Tentative de connexion */ binary->local = g_db_client_new(author, priv, g_loaded_binary_get_name(binary, false), checksum, binary->collections); if (!g_generic_config_get_value(get_main_configuration(), MPK_LOCAL_HOST, &host)) /* ... */; if (!g_generic_config_get_value(get_main_configuration(), MPK_LOCAL_PORT, &port)) /* ... */; result = g_db_client_start_remote(binary->local, host, port); printf("DB status :: %d\n", result); glbcl_exit: return result; } /* ---------------------------------------------------------------------------------- */ /* MANIPULATION DES COLLECTIONS */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Fournit le client assurant la liaison avec un serveur. * * * * Retour : Client connecté ou NULL. * * * * Remarques : - * * * ******************************************************************************/ GDbClient *g_loaded_binary_get_db_client(const GLoadedBinary *binary) { GDbClient *result; /* Instance à retourner */ result = binary->local; if (result != NULL) g_object_ref(G_OBJECT(result)); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Fournit l'ensemble des collections utilisées par un binaire. * * * * Retour : Collections en place. * * * * Remarques : - * * * ******************************************************************************/ GList *g_loaded_binary_get_all_collections(const GLoadedBinary *binary) { return binary->collections; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * feature = fonctionnalité assurée par la collection visée. * * * * Description : Trouve une collection assurant une fonctionnalité donnée. * * * * Retour : Collection trouvée ou NULL. * * * * Remarques : Le résultat est à déréfrencer après usage. * * * ******************************************************************************/ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *binary, DBFeatures feature) { GDbCollection *result; /* Collection à retourner */ /* TODO : lock */ result = find_collection_in_list(binary->collections, feature); if (result != NULL) g_object_ref(G_OBJECT(result)); /* TODO : unlock */ return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * item = élémnent à pousser vers un serveur de collection. * * lock = indique si le verrou d'écriture doit être posé. * * * * Description : Demande l'intégration d'une modification dans une collection.* * * * Retour : Bilan partiel de l'opération demandée. * * * * Remarques : L'appelant perd la propriété de l'élément à ajouté. * * * ******************************************************************************/ bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ DBFeatures feature; /* Domaine de fonctionnalité */ GDbCollection *collec; /* Collection visée au final */ DBStorage storage; /* Forme d'enregistrement */ GDbClient *client; /* Liaison à utiliser */ int fd; /* Identifiant du canal de com.*/ feature = g_db_item_get_feature(item); collec = g_loaded_binary_find_collection(binary, feature); if (collec == NULL) return false; /* S'il n'y a pas besoin de sauvegarde... */ if (g_db_item_is_volatile(item)) result = _g_db_collection_add_item(collec, item, lock); /* Sinon on envoie par le réseau ! */ else { storage = g_loaded_binary_get_storage(binary, feature); /* TODO : sélection du bon client... */ client = binary->local; fd = g_db_client_get_fd(client); result = g_db_collection_send(collec, fd, DBA_ADD_ITEM, item); g_db_client_put_fd(client); } g_object_unref(G_OBJECT(collec)); g_object_unref(G_OBJECT(item)); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * feature = fonctionnalité visée par la requête. * * item = élémnent à retirer d'un serveur de collection. * * lock = indique si le verrou d'écriture doit être posé. * * * * Description : Demande la suppression de modification dans une collection. * * * * Retour : Bilan partiel de l'opération demandée. * * * * Remarques : - * * * ******************************************************************************/ bool _g_loaded_binary_remove_from_collection(GLoadedBinary *binary, DBFeatures feature, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ GDbCollection *collec; /* Collection visée au final */ DBStorage storage; /* Forme d'enregistrement */ GDbClient *client; /* Liaison à utiliser */ int fd; /* Identifiant du canal de com.*/ collec = g_loaded_binary_find_collection(binary, feature); if (collec == NULL) return false; /* S'il n'y a pas besoin de sauvegarde... */ if (g_db_item_is_volatile(item)) result = _g_db_collection_remove_item(collec, item, lock); /* Sinon on envoie par le réseau ! */ else { storage = g_loaded_binary_get_storage(binary, feature); /* TODO : sélection du bon client... */ client = binary->local; fd = g_db_client_get_fd(client); result = g_db_collection_send(collec, fd, DBA_REM_ITEM, item); g_db_client_put_fd(client); } g_object_unref(G_OBJECT(collec)); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à traiter. * * * * Description : Lance l'analyse d'un élément binaire chargé. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_loaded_binary_analyse(GLoadedBinary *binary) { /* Détermination de l'identifiant */ /* Contacts avec les serveurs */ // Déconnexion... g_loaded_binary_connect_internal(binary); disassemble_binary(binary, &binary->instrs, &binary->disass_buffer, ack_completed_disassembly); /* TODO : remme ! */ //ack_completed_disassembly(NULL, binary); } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Fournit le format de fichier reconnu dans le contenu binaire.* * * * Retour : Instance du format reconnu. * * * * Remarques : - * * * ******************************************************************************/ bool g_loaded_binary_attach_debug_info(GLoadedBinary *binary, GBinContent *content) { bool result; /* Bilan à retourner pour info */ FormatMatchStatus status; /* Statut d'une reconnaissance */ char *target; /* Sous-traitance requise */ const char *desc; /* Description humaine associée*/ GDbgFormat *debug; /* Format de débogage trouvé */ status = find_matching_format(content, binary->format, &target); if (status == FMS_MATCHED) { result = false; desc = get_binary_format_name(target); if (desc == NULL) log_simple_message(LMT_INFO, _("Unknown binary debug format")); else { log_variadic_message(LMT_INFO, _("Detected debug format: %s"), desc); debug = G_DBG_FORMAT(load_new_named_format(target, content, binary->format)); if (debug == NULL) log_simple_message(LMT_ERROR, _("Error while loading the debug information for binary")); else { result = true; g_exe_format_add_debug_info(binary->format, debug); } } free(target); } else result = true; return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Fournit le format de fichier reconnu dans le contenu binaire.* * * * Retour : Instance du format reconnu. * * * * Remarques : - * * * ******************************************************************************/ GExeFormat *g_loaded_binary_get_format(const GLoadedBinary *binary) { GExeFormat *result; /* Instance à retourner */ result = binary->format; g_object_ref(G_OBJECT(result)); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Fournit le processeur de l'architecture liée au binaire. * * * * Retour : Instance du processeur associé. * * * * Remarques : - * * * ******************************************************************************/ GArchProcessor *g_loaded_binary_get_processor(const GLoadedBinary *binary) { GArchProcessor *result; /* Instance à retourner */ result = binary->proc; g_object_ref(G_OBJECT(result)); return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Fournit le tampon associé au contenu assembleur d'un binaire.* * * * Retour : Tampon mis en place ou NULL si aucun (!). * * * * Remarques : - * * * ******************************************************************************/ GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary) { return binary->disass_buffer; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * index = indice du fichier à retrouver. * * * * Description : Fournit le tampon associé au contenu d'un fichier source. * * * * Retour : Tampon mis en place ou NULL si aucun (!). * * * * Remarques : - * * * ******************************************************************************/ GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *binary, size_t index) { GCodeBuffer *result; /* Tampon à retourner */ if (binary->decbuf_count == 0) result = NULL; else if (index >= binary->decbuf_count) result = binary->dec_buffers[binary->defsrc]; else result = binary->dec_buffers[index]; return result; } /****************************************************************************** * * * Paramètres : binary = élément binaire à mettre à jour. * * view = type de représentation visée. * * col = indice de colonne dont l'affichage est à modifier. * * state = nouvel état de l'affichage. * * * * Description : Définit si une colonne donnée doit apparaître dans le rendu. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_loaded_binary_set_column_display(GLoadedBinary *binary, BinaryView view, BufferLineColumn col, bool state) { bool old; /* Ancien état à remplacer */ old = binary->col_display[view][col]; if (state != old) { binary->col_display[view][col] = state; g_signal_emit_by_name(binary, "display-changed", view, col); } } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * view = type de représentation visée. * * * * Description : Indique quelles colonnes doivent apparaître dans le rendu. * * * * Retour : Consigne d'affichage. [OUT] * * * * Remarques : - * * * ******************************************************************************/ const bool *g_loaded_binary_get_column_display(GLoadedBinary *binary, BinaryView view) { return binary->col_display[view]; } /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * * * * Description : Indique si les lignes doivent apparaître dans le rendu. * * * * Retour : Consigne d'affichage. [OUT] * * * * Remarques : - * * * ******************************************************************************/ bool *g_loaded_binary_display_decomp_lines(GLoadedBinary *binary) { return &binary->lines_display; } /****************************************************************************** * * * Paramètres : disass = travail de désassemblage mené à bien. * * binary = représentation de binaire à l'origine de l'opérat°. * * * * Description : Acquitte la fin d'un désasemblage différé et complet. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binary) { //GRenderingLine *line; /* "Première" ligne de rendu */ size_t i; /* Boucle de parcours */ const char * const *files; /* Liste de fichiers source */ g_object_unref(G_OBJECT(disass)); #ifdef DEBUG_DUMP_STATS display_share_stats(binary->proc); #endif /* ... = *///g_loaded_binary_connect_internal(binary); /* Décompilation... */ files = g_binary_format_get_source_files(G_BIN_FORMAT(binary->format), &binary->decbuf_count, &binary->defsrc); if (binary->decbuf_count > 0) { binary->dec_buffers = (GCodeBuffer **)calloc(binary->decbuf_count, sizeof(GCodeBuffer *)); /* for (i = 0; i < binary->decbuf_count; i++) binary->dec_buffers[i] = decompile_all_from_file(binary, files[i]); */ } #if 0 g_rendering_line_merge(&binary->lines, &disass->lines); line = g_rendering_line_find_by_address(disass->lines, NULL, g_exe_format_get_entry_point(binary->format)); if (line != NULL) g_rendering_line_add_flag(line, RLF_ENTRY_POINT); /* On réintègre le flot premier */ #endif g_signal_emit_by_name(binary, "disassembly-done"); }