/* 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.
*
* OpenIDA 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.
*
* OpenIDA 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 "binary-int.h"
#include "routine.h"
#include "binaries/file.h"
#include "decomp/decompiler.h"
#include "disass/disassembler.h"
#include "../common/extstr.h"
#include "../common/cpp.h"
#include "../core/params.h"
#include "../glibext/chrysamarshal.h"
/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
/* 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 *);
/* Charge les parties intéressantes du binaire à partir d'XML. */
static bool g_loaded_binary_load_parts_from_xml(GLoadedBinary *, xmlXPathContextPtr, const char *);
/* Ecrit les parties de valeur du binaire dans un fichier XML. */
static bool g_loaded_binary_save_parts(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *);
/* 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 *);
/* 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->remote_host = strdup("localhost");
binary->remote_port = 9999;
binary->use_remote_server = false;
binary->storages[DBF_COMMENTS] = DBS_ALL_LOCAL;
binary->storages[DBF_SEGMENTS_DISPLAY] = DBS_ALL_LOCAL;
binary->storages[DBF_BOOKMARKS] = DBS_ALL_LOCAL;
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)
{
if (binary->checksum != NULL)
g_checksum_free(binary->checksum);
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);
if (binary->bin_data != NULL)
free(binary->bin_data);
/* TODO... */
G_OBJECT_CLASS(g_loaded_binary_parent_class)->finalize(G_OBJECT(binary));
}
/******************************************************************************
* *
* Paramètres : context = contexte pour les recherches XPath. *
* path = chemin d'accès au noeud XML à lire. *
* *
* Description : Charge en mémoire le contenu d'un fichier à partir d'XML. *
* *
* Retour : Adresse de la représentation ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
#include "db/items/bookmark.h"
GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const char *path)
{
GLoadedBinary *result; /* Adresse à retourner */
char *type; /* Type de binaire à charger */
char *host; /* Nom du serveur à contacter */
int port; /* Numéro du port associé */
char *author; /* Identification à diffuser */
bool status; /* Etat de la connexion à la BD*/
result = NULL;
type = get_node_prop_value(context, path, "type");
if (strcmp(type, "file") == 0)
result = g_file_binary_new_from_xml(context, path);
free(type);
if (result == NULL)
return NULL;
/* --------- %< --------- TODO : à bouger pur + de générique --------- %< --------- */
result->collections = create_collections_list();
if (!g_loaded_binary_load_storage(result, context, path))
goto glbnfx_error;
/* --------- %< --------- TODO : à bouger pur + de générique --------- %< --------- */
/*
if (!g_loaded_binary_load_parts_from_xml(result, context, path))
goto glbnfx_error;
*/
printf("data :: %p length :: %d\n", result->bin_data, result->bin_length);
/* Détermination de l'identifiant */
result->checksum = g_checksum_new(G_CHECKSUM_SHA256);
g_checksum_update(result->checksum, result->bin_data, result->bin_length);
result->local = g_db_client_new(g_loaded_binary_get_name(result, false),
g_loaded_binary_get_cheksum(result),
result->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))
/* ... */;
if (!g_generic_config_get_value(get_main_configuration(), MPK_AUTHOR_NAME, &author))
/* ... */;
status = g_db_client_start(result->local, host, port, author);
/* --------- %< --------- %< --------- %< --------- %< --------- */
do
{
vmpa2t addr;
GDbBookmark *bm;
bool status;
init_vmpa(&addr, 0xaeb4, VMPA_NO_VIRTUAL);
bm = g_db_bookmark_new(&addr, "Premier commentaire");
status = g_loaded_binary_add_to_collection(result, DBF_BOOKMARKS, G_DB_ITEM(bm));
if (status)
printf("send OK\n");
else
printf("send nok\n");
g_db_client_save(result->local);
/*
safe_send(client->fd, (uint32_t []) { htobe32(DBC_COLLECTION) }, sizeof(uint32_t), MSG_MORE);
safe_send(client->fd, (uint32_t []) { htobe32(DBF_BOOKMARKS) }, sizeof(uint32_t), MSG_MORE);
safe_send(client->fd, (uint32_t []) { htobe32(DBA_ADD_ITEM) }, sizeof(uint32_t), MSG_MORE);
if (g_db_item_send(G_DB_ITEM(bm), client->fd, 0))
printf("send OK\n");
else
printf("send nok\n");
*/
}
while (0);
/* --------- %< --------- %< --------- %< --------- %< --------- */
printf("DB status :: %d\n", status);
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 */
result = binary->save(binary, xdoc, context, path);
result = g_loaded_binary_save_storage(binary, xdoc, context, path);
/* Parties à désassembler */
result = g_loaded_binary_save_parts(binary, xdoc, context, path);
return result;
}
/******************************************************************************
* *
* Paramètres : context = contexte pour les recherches XPath. *
* path = chemin d'accès au noeud XML à lire. *
* *
* Description : Charge les parties intéressantes du binaire à partir d'XML. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
static bool g_loaded_binary_load_parts_from_xml(GLoadedBinary *binary, xmlXPathContextPtr context, const char *path)
{
bool result; /* Bilan à retourner */
char *access; /* Chemin pour une sous-config.*/
xmlXPathObjectPtr xobjects; /* Cible d'une recherche */
int i; /* Boucle de parcours */
GBinPart *part; /* Partie binaire à traiter */
off_t offset; /* Position de cette partie */
vmpa_t addr; /* Adresse correspondante */
result = NULL;
/* Parties à désassembler : default */
access = strdup(path);
access = stradd(access, "/BinParts/Default/Part");
xobjects = get_node_xpath_object(context, access);
for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobjects); i++)
{
part = g_binary_part_load_from_xml(NODE_FROM_PATH_OBJ(xobjects, i));
if (part != NULL)
{
g_binary_part_get_values(part, &offset, NULL, NULL);
if (!g_exe_format_translate_offset_into_address(G_EXE_FORMAT(binary->format), offset, &addr))
{
g_object_unref(G_OBJECT(part));
continue;
}
binary->parts_count[BPM_DEFAULT]++;
binary->parts[BPM_DEFAULT] = (GBinPart **)realloc(binary->parts[BPM_DEFAULT],
binary->parts_count[BPM_DEFAULT] * sizeof(GBinPart *));
binary->parts[BPM_DEFAULT][binary->parts_count[BPM_DEFAULT] - 1] = part;
}
}
if(xobjects != NULL)
xmlXPathFreeObject(xobjects);
free(access);
qsort(binary->parts[BPM_DEFAULT], binary->parts_count[BPM_DEFAULT],
sizeof(GBinPart *), (__compar_fn_t)g_binary_part_compare);
/* Parties à désassembler : routines */
access = strdup(path);
access = stradd(access, "/BinParts/Routines/Part");
xobjects = get_node_xpath_object(context, access);
for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobjects); i++)
{
part = g_binary_part_load_from_xml(NODE_FROM_PATH_OBJ(xobjects, i));
if (part != NULL)
{
g_binary_part_get_values(part, &offset, NULL, NULL);
if (!g_exe_format_translate_offset_into_address(G_EXE_FORMAT(binary->format), offset, &addr))
{
g_object_unref(G_OBJECT(part));
continue;
}
else g_binary_part_set_address(part, addr);
binary->parts_count[BPM_ROUTINES]++;
binary->parts[BPM_ROUTINES] = (GBinPart **)realloc(binary->parts[BPM_ROUTINES],
binary->parts_count[BPM_ROUTINES] * sizeof(GBinPart *));
binary->parts[BPM_ROUTINES][binary->parts_count[BPM_ROUTINES] - 1] = part;
}
}
if(xobjects != NULL)
xmlXPathFreeObject(xobjects);
free(access);
qsort(binary->parts[BPM_ROUTINES], binary->parts_count[BPM_ROUTINES],
sizeof(GBinPart *), (__compar_fn_t)g_binary_part_compare);
/* Parties à désassembler : utilisateur */
access = strdup(path);
access = stradd(access, "/BinParts/User/Part");
xobjects = get_node_xpath_object(context, access);
for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobjects); i++)
{
part = g_binary_part_load_from_xml(NODE_FROM_PATH_OBJ(xobjects, i));
if (part != NULL)
{
g_binary_part_get_values(part, &offset, NULL, NULL);
if (!g_exe_format_translate_offset_into_address(G_EXE_FORMAT(binary->format), offset, &addr))
{
g_object_unref(G_OBJECT(part));
continue;
}
binary->parts_count[BPM_USER]++;
binary->parts[BPM_USER] = (GBinPart **)realloc(binary->parts[BPM_USER],
binary->parts_count[BPM_USER] * sizeof(GBinPart *));
binary->parts[BPM_USER][binary->parts_count[BPM_USER] - 1] = part;
}
}
if(xobjects != NULL)
xmlXPathFreeObject(xobjects);
free(access);
qsort(binary->parts[BPM_USER], binary->parts_count[BPM_USER],
sizeof(GBinPart *), (__compar_fn_t)g_binary_part_compare);
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 parties de valeur du binaire dans un fichier XML. *
* *
* Retour : true si l'opération a bien tourné, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
static bool g_loaded_binary_save_parts(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
{
bool result; /* Bilan à faire remonter */
char *access; /* Chemin d'accès à un élément */
xmlNodePtr node; /* Point d'insertion XML */
size_t i; /* Boucle de parcours */
result = true;
if (binary->parts_count[BPM_DEFAULT] > 0)
{
access = strdup(path);
access = stradd(access, "/BinParts/Default");
node = ensure_node_exist(xdoc, context, access);
free(access);
for (i = 0; i < binary->parts_count[BPM_DEFAULT] && result; i++)
result &= g_binary_part_save_to_xml(binary->parts[BPM_DEFAULT][i], xdoc, node);
}
if (binary->parts_count[BPM_ROUTINES] > 0)
{
access = strdup(path);
access = stradd(access, "/BinParts/Routines");
node = ensure_node_exist(xdoc, context, access);
free(access);
for (i = 0; i < binary->parts_count[BPM_ROUTINES] && result; i++)
result &= g_binary_part_save_to_xml(binary->parts[BPM_ROUTINES][i], xdoc, node);
}
if (binary->parts_count[BPM_USER] > 0)
{
access = strdup(path);
access = stradd(access, "/BinParts/User");
node = ensure_node_exist(xdoc, context, access);
free(access);
for (i = 0; i < binary->parts_count[BPM_USER] && result; i++)
result &= g_binary_part_save_to_xml(binary->parts[BPM_USER][i], xdoc, node);
}
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 *access; /* Chemin d'accès à un élément */
char *value; /* Valeur lue à partie du XML */
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");
/* 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, "use");
if (value == NULL) goto glbls_features;
use = (strcmp(value, "true") == 0);
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, use);
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_COMMENTS:
access = stradd(access, "Comments");
break;
case DBF_SEGMENTS_DISPLAY:
access = stradd(access, "Segments");
break;
case DBF_BOOKMARKS:
access = stradd(access, "Bookmarks");
break;
case DBF_COUNT:
/* Pour GCC */
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);
}
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(STR(USHRT_MAX)) + 1]; /* Version chaînée */
DBFeatures i; /* Boucle de parcours */
result = true;
storage_path = strdup(path);
storage_path = stradd(storage_path, "/Storage");
/* 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);
result &= add_string_attribute_to_node(xdoc, context, access, "use",
binary->use_remote_server ? "true" : "false");
free(access);
/* Fonctionnalités */
for (i = 0; i < DBF_COUNT; i++)
{
access = strdup(storage_path);
access = stradd(access, "/Features/");
switch (i)
{
case DBF_COMMENTS:
access = stradd(access, "Comments");
break;
case DBF_SEGMENTS_DISPLAY:
access = stradd(access, "Segments");
break;
case DBF_BOOKMARKS:
access = stradd(access, "Bookmarks");
break;
case DBF_COUNT:
/* Pour GCC */
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. *
* 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 : Statut de l'utilisation du serveur distant. *
* *
* Remarques : - *
* *
******************************************************************************/
bool g_loaded_binary_get_remote_server(const GLoadedBinary *binary, const char **host, unsigned short *port)
{
*host = binary->remote_host;
*port = binary->remote_port;
return binary->use_remote_server;
}
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
* host = nom du serveur distant à contacter. *
* port = port de communication avec le serveur distant. *
* use = statut de l'utilisation du 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, bool use)
{
free(binary->remote_host);
binary->remote_host = strdup(host);
binary->remote_port = port;
binary->use_remote_server = use;
if (use)
/* TODO : reload conn ! */;
else
/* TODO : stop conn ! */;
}
/******************************************************************************
* *
* 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;
}
/* ---------------------------------------------------------------------------------- */
/* MANIPULATION DES 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(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. *
* feature = fonctionnalité visée par la requête. *
* item = élémnent à pousser vers un serveur de collection. *
* *
* 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, DBFeatures feature, GDbItem *item)
{
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))
g_db_collection_add_item(collec, item);
/* 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. *
* parts = liste des zones binaires à analyser. *
* model = modèle de sélection des zones. *
* count = quantité de zones listées. *
* *
* Description : Définit les parties de binaire à analyser. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_loaded_binary_set_parts(GLoadedBinary *binary, BinaryPartModel model, GBinPart **parts, size_t count)
{
qsort(parts, count, sizeof(GBinPart *), (__compar_fn_t)g_binary_part_compare);
binary->parts[model] = parts;
binary->parts_count[model] = count;
}
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
* model = modèle de sélection des zones. [OUT] *
* count = quantité de zones listées. [OUT] *
* *
* Description : Fournit les parties de binaire analysées. *
* *
* Retour : Zones binaires à analyser. *
* *
* Remarques : - *
* *
******************************************************************************/
GBinPart ***g_loaded_binary_get_parts(const GLoadedBinary *binary, BinaryPartModel *model, size_t **count)
{
*model = binary->model;
*count = binary->parts_count;
return binary->parts;
}
/******************************************************************************
* *
* 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)
{
GBinPart **parts; /* Parties d'élément binaire */
size_t parts_count; /* Nombre de ces parties */
/* Détermination de l'identifiant */
/* déplacé
binary->checksum = g_checksum_new(G_CHECKSUM_SHA256);
g_checksum_update(binary->checksum, binary->bin_data, binary->bin_length);
*/
/* Contacts avec les serveurs */
if (binary->parts_count[BPM_ROUTINES] > 0)
binary->model = BPM_ROUTINES;
if (binary->parts[binary->model] != NULL)
{
parts = binary->parts[binary->model];
parts_count = binary->parts_count[binary->model];
}
else
{
if (binary->parts[BPM_DEFAULT] != NULL)
{
parts = binary->parts[BPM_DEFAULT];
parts_count = binary->parts_count[BPM_DEFAULT];
}
else
{
parts = g_exe_format_get_parts(binary->format, &parts_count);
qsort(parts, parts_count, sizeof(GBinPart *), (__compar_fn_t)g_binary_part_compare);
}
}
disassemble_binary(binary, parts, parts_count,
&binary->instrs, &binary->disass_buffer,
ack_completed_disassembly);
/* TODO : remme ! */
//ack_completed_disassembly(NULL, binary);
}
/******************************************************************************
* *
* 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)
{
return binary->get_name(binary, full);
}
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
* *
* Description : Fournit une empreinte unique (SHA256) pour le binaire. *
* *
* Retour : Chaîne représentant l'empreinte du binaire. *
* *
* Remarques : - *
* *
******************************************************************************/
const gchar *g_loaded_binary_get_cheksum(const GLoadedBinary *binary)
{
return g_checksum_get_string(binary->checksum);
}
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
* length = taille en octets des données chargées. [OUT] *
* *
* Description : Fournit les détails du contenu binaire chargé en mémoire. *
* *
* Retour : Pointeur vers le début des données. *
* *
* Remarques : - *
* *
******************************************************************************/
bin_t *g_loaded_binary_get_data(const GLoadedBinary *binary, off_t *length)
{
if (length != NULL)
*length = binary->bin_length;
return binary->bin_data;
}
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
* *
* Description : Fournit le format de fichier reconnu dans le contenu binaire.*
* *
* Retour : Adresse du format reconnu. *
* *
* Remarques : - *
* *
******************************************************************************/
GExeFormat *g_loaded_binary_get_format(const GLoadedBinary *binary)
{
return binary->format;
}
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
* *
* Description : Fournit les instructions issues du désassemblage. *
* *
* Retour : Instructions issues du désassemblage. *
* *
* Remarques : - *
* *
******************************************************************************/
GArchInstruction *g_loaded_binary_get_instructions(const GLoadedBinary *binary)
{
return binary->instrs;
}
/******************************************************************************
* *
* 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));
/* 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");
}