summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog72
-rw-r--r--plugins/devdbg/speed.c3
-rw-r--r--plugins/mobicore/mclf.c14
-rw-r--r--plugins/mobicore/mclf.h3
-rw-r--r--plugins/mobicore/mobicore.c6
-rw-r--r--plugins/pychrysa/core/Makefile.am1
-rw-r--r--plugins/pychrysa/core/module.c2
-rw-r--r--plugins/pychrysa/plugin.c340
-rw-r--r--plugins/python/apkfiles/__init__.py4
-rw-r--r--plugins/python/apkfiles/apkfiles.py27
-rw-r--r--plugins/ropgadgets/select.c12
-rw-r--r--src/analysis/binaries/file.c8
-rw-r--r--src/analysis/binary-int.h12
-rw-r--r--src/analysis/binary.c307
-rw-r--r--src/analysis/binary.h32
-rw-r--r--src/analysis/content-int.h10
-rw-r--r--src/analysis/content.c86
-rw-r--r--src/analysis/content.h10
-rw-r--r--src/analysis/contents/file.c128
-rw-r--r--src/analysis/contents/file.h3
-rw-r--r--src/analysis/disass/disassembler.c2
-rw-r--r--src/analysis/project.c530
-rw-r--r--src/analysis/project.h52
-rw-r--r--src/common/xml.c108
-rw-r--r--src/common/xml.h11
-rw-r--r--src/core/formats.c34
-rw-r--r--src/core/formats.h20
-rw-r--r--src/format/dwarf/dwarf.c31
-rw-r--r--src/format/dwarf/dwarf.h4
-rw-r--r--src/format/elf/elf.c16
-rw-r--r--src/format/elf/elf.h5
-rw-r--r--src/format/executable-int.h3
-rw-r--r--src/format/executable.c78
-rw-r--r--src/format/executable.h9
-rw-r--r--src/gui/menus/project.c13
-rw-r--r--src/plugins/plugin-int.h29
-rw-r--r--src/plugins/plugin.c26
37 files changed, 1689 insertions, 362 deletions
diff --git a/ChangeLog b/ChangeLog
index 166ef5d..6b28940 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,75 @@
+15-09-19 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/devdbg/speed.c:
+ Remove debug code.
+
+ * plugins/mobicore/mclf.c:
+ * plugins/mobicore/mclf.h:
+ * plugins/mobicore/mobicore.c:
+ Update code.
+
+ * plugins/pychrysa/core/Makefile.am:
+ Add the missing 'formats.[ch]' files to libpychrysacore_la_SOURCES.
+
+ * plugins/pychrysa/core/module.c:
+ Load formats core into Python.
+
+ * plugins/pychrysa/plugin.c:
+ * plugins/python/apkfiles/apkfiles.py:
+ * plugins/python/apkfiles/__init__.py:
+ * plugins/ropgadgets/select.c:
+ Update code.
+
+ * src/analysis/binaries/file.c:
+ Disable this specific kind of instances for loaded binaries.
+
+ * src/analysis/binary.c:
+ * src/analysis/binary.h:
+ * src/analysis/binary-int.h:
+ Build a standalone generic binary. Use binary contents as external
+ entities. Only reference the main binary format and attach debug
+ info to it.
+
+ * src/analysis/content.c:
+ * src/analysis/content.h:
+ * src/analysis/content-int.h:
+ * src/analysis/contents/file.c:
+ * src/analysis/contents/file.h:
+ Describe, save and restore binary contents.
+
+ * src/analysis/disass/disassembler.c:
+ Update code.
+
+ * src/analysis/project.c:
+ * src/analysis/project.h:
+ Store binary contents as well as loaded binaries. Update the storing and
+ restoring routines.
+
+ * src/common/xml.c:
+ * src/common/xml.h:
+ Handle long values for nodes attributes.
+
+ * src/core/formats.c:
+ * src/core/formats.h:
+ Extend the prototype for matching formats in order to get it suitable
+ for plugins.
+
+ * src/format/dwarf/dwarf.c:
+ * src/format/dwarf/dwarf.h:
+ * src/format/elf/elf.c:
+ * src/format/elf/elf.h:
+ Update code.
+
+ * src/format/executable.c:
+ * src/format/executable.h:
+ * src/format/executable-int.h:
+ Store debug information when requested.
+
+ * src/gui/menus/project.c:
+ * src/plugins/plugin.c:
+ * src/plugins/plugin-int.h:
+ Update code.
+
15-09-11 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
diff --git a/plugins/devdbg/speed.c b/plugins/devdbg/speed.c
index e5042ea..538a741 100644
--- a/plugins/devdbg/speed.c
+++ b/plugins/devdbg/speed.c
@@ -79,7 +79,6 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, Plu
}
-
switch (action)
{
case PGA_DISASSEMBLY_STARTED:
@@ -115,6 +114,4 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, Plu
}
- printf("##########\n\nPassage 0x%08x !!!\n\n################\n", action);
-
}
diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c
index 99ff7ed..4ff44bb 100644
--- a/plugins/mobicore/mclf.c
+++ b/plugins/mobicore/mclf.c
@@ -56,6 +56,8 @@ static void g_mclf_format_refine_portions(const GMCLFFormat *, GBinPortion *);
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+* unused = adresse non utilisée ici. *
+* key = identifiant de format trouvé ou NULL. [OUT] *
* *
* Description : Indique si le format peut être pris en charge ici. *
* *
@@ -65,9 +67,9 @@ static void g_mclf_format_refine_portions(const GMCLFFormat *, GBinPortion *);
* *
******************************************************************************/
-const char *mclf_is_matching(GBinContent *content, GExeFormat *parent)
+FormatMatchStatus mclf_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key)
{
- const char *result; /* Format détecté à renvoyer */
+ FormatMatchStatus result; /* Bilan à renvoyer */
vmpa2t addr; /* Tête de lecture initiale */
bool status; /* Bilan des accès mémoire */
char magic[4]; /* Idenfiant standard */
@@ -78,7 +80,13 @@ const char *mclf_is_matching(GBinContent *content, GExeFormat *parent)
status &= (memcmp(magic, MC_SERVICE_HEADER_MAGIC_STR, 4) == 0);
- result = status ? "mclf" : NULL;
+ if (status)
+ {
+ result = FMS_MATCHED;
+ *key = strdup("mclf");
+ }
+ else
+ result = FMS_UNKNOWN;
return result;
diff --git a/plugins/mobicore/mclf.h b/plugins/mobicore/mclf.h
index 5ac0926..78ed57b 100644
--- a/plugins/mobicore/mclf.h
+++ b/plugins/mobicore/mclf.h
@@ -30,6 +30,7 @@
#include <sys/types.h>
+#include <core/formats.h>
#include <format/executable.h>
#include <format/format.h>
@@ -51,7 +52,7 @@ typedef struct _GMCLFFormatClass GMCLFFormatClass;
/* Indique si le format peut être pris en charge ici. */
-const char *mclf_is_matching(GBinContent *, GExeFormat *);
+FormatMatchStatus mclf_is_matching(GBinContent *, GExeFormat *, void *, char **);
/* Indique le type défini pour un format d'exécutable MCLF. */
GType g_mclf_format_get_type(void);
diff --git a/plugins/mobicore/mobicore.c b/plugins/mobicore/mobicore.c
index 087297b..8a28a76 100644
--- a/plugins/mobicore/mobicore.c
+++ b/plugins/mobicore/mobicore.c
@@ -54,9 +54,11 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin, GObject *ref)
{
bool result; /* Bilan à retourner */
- result &= register_format_matcher(mclf_is_matching);
+ result = true;
- result = register_format_loader("mclf", "MobiCore Load Format", g_mclf_format_new);
+ result &= register_format_matcher(mclf_is_matching, NULL);
+
+ result &= register_format_loader("mclf", "MobiCore Load Format", g_mclf_format_new);
return result;
diff --git a/plugins/pychrysa/core/Makefile.am b/plugins/pychrysa/core/Makefile.am
index 1ffacf4..129b5af 100644
--- a/plugins/pychrysa/core/Makefile.am
+++ b/plugins/pychrysa/core/Makefile.am
@@ -2,6 +2,7 @@
noinst_LTLIBRARIES = libpychrysacore.la
libpychrysacore_la_SOURCES = \
+ formats.h formats.c \
module.h module.c \
params.h params.c
diff --git a/plugins/pychrysa/core/module.c b/plugins/pychrysa/core/module.c
index a866c05..9fcede9 100644
--- a/plugins/pychrysa/core/module.c
+++ b/plugins/pychrysa/core/module.c
@@ -28,6 +28,7 @@
#include <assert.h>
+#include "formats.h"
#include "params.h"
@@ -78,6 +79,7 @@ bool add_core_module_to_python_module(PyObject *super)
result = true;
+ result &= register_python_formats(module);
result &= register_python_params(module);
loading_failed:
diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c
index 44cb0d8..5e968e2 100644
--- a/plugins/pychrysa/plugin.c
+++ b/plugins/pychrysa/plugin.c
@@ -30,6 +30,8 @@
#include <common/extstr.h>
+#include "../../src/core/formats.h"
+//#include <core/formats.h>
#include <plugins/plugin-int.h>
@@ -74,23 +76,11 @@ static bool g_python_plugin_do_init(GPythonPlugin *, GObject *);
/* Procède à l'extinction du greffon. */
static bool g_python_plugin_do_exit(GPythonPlugin *, GObject *);
+/* Indique si le format peut être pris en charge ici. */
+FormatMatchStatus python_plugin_is_matching(GBinContent *, GExeFormat *, GPythonPlugin *, char **);
-
-
-
-
-/* Indique l'utilité pratique du greffon. */
-static PluginAction g_python_plugin_get_action(const GPythonPlugin *);
-
-/* Indentifie un format à associer à un contenu binaire. */
-static MatchingFormatAction g_python_plugin_is_matching(const GPythonPlugin *, char **, bin_t **, off_t *);
-
-/* Exécute une action définie sur un binaire chargé. */
-static bool g_python_plugin_execute_on_binary(GPythonPlugin *, GLoadedBinary *, PluginAction);
-
-
-/* Exécute une action relative à un débogueur. */
-//static bool g_python_plugin_handle_debugger(const GPythonPlugin *, GBinaryDebugger *, PluginAction);
+/* Exécute une action pendant un désassemblage de binaire. */
+static void g_python_plugin_process_disass(const GPythonPlugin *, PluginAction, GLoadedBinary *);
@@ -143,19 +133,10 @@ static void g_python_plugin_class_init(GPythonPluginClass *klass)
static void g_python_plugin_init(GPythonPlugin *plugin)
{
- GPluginModule *plugin_parent; /* Instance parente */
-
- plugin_parent = G_PLUGIN_MODULE(plugin);
-
- plugin_parent->exec_on_bin = (execute_action_on_binary_fc)g_python_plugin_execute_on_binary;
- //plugin_parent->handle_debugger = (execute_on_debugger_fc)g_python_plugin_handle_debugger;
}
-
-
-
/******************************************************************************
* *
* Paramètres : modname = nom du module à charger. *
@@ -184,6 +165,7 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO
PyObject *class; /* Classe à instancier */
PyObject *instance; /* Instance Python du greffon */
size_t i; /* Boucle de parcours */
+ uint32_t action; /* Identifiant d'une action */
uint32_t category; /* Catégorie principale */
uint32_t sub; /* Sous-catégorie visée */
@@ -246,17 +228,6 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO
goto gppn_interface_error;
}
-
- //G_PLUGIN_MODULE(result)->get_action = (get_plugin_action_fc)g_python_plugin_get_action;
-
- //G_PLUGIN_MODULE(result)->is_matching = (is_matching_fc)g_python_plugin_is_matching;
-
-
-
-
-
-
-
/* Localisation des différents points d'entrée déclarés */
#define register_python_binding(inst, sym, binding) \
@@ -279,8 +250,9 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO
for (i = 0; i < G_PLUGIN_MODULE(result)->interface->actions_count; i++)
{
- category = MASK_PLUGIN_CATEGORY(G_PLUGIN_MODULE(result)->interface->actions[i]);
- sub = MASK_PLUGIN_SUB_CATEGORY(G_PLUGIN_MODULE(result)->interface->actions[i]);
+ action = G_PLUGIN_MODULE(result)->interface->actions[i];
+ category = MASK_PLUGIN_CATEGORY(action);
+ sub = MASK_PLUGIN_SUB_CATEGORY(action);
switch (category)
{
@@ -309,26 +281,39 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO
}
break;
-#if 0
+
case DPC_BINARY_PROCESSING:
switch (sub)
{
case DPS_FORMAT:
- switch (result->interface->actions[i])
+ switch (action)
{
+ case PGA_FORMAT_MATCHER:
+
+ if (!has_python_method(instance, "is_format_matching"))
+ {
+ log_variadic_message(LMT_ERROR,
+ _("No '%s' entry in plugin candidate '%s'"),
+ "is_format_matching",
+ G_PLUGIN_MODULE(result)->filename);
+ goto gppn_bad_plugin;
+ }
+
+ if (!register_format_matcher((format_match_fc)python_plugin_is_matching, result))
+ goto gppn_bad_plugin;
+
+ break;
case PGA_FORMAT_LOADER_LAST:
- if (!load_plugin_symbol(result->module,
- "handle_binary_format", &result->handle_format))
- goto bad_plugin;
+ /* TODO */
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- result->interface->actions[i], filename);
+ action, filename);
break;
}
@@ -336,9 +321,9 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO
break;
case DPS_DISASSEMBLY:
- if (!load_plugin_symbol(result->module,
- "process_binary_disassembly", &result->proc_disass))
- goto bad_plugin;
+ if (!register_python_binding(instance, process_disass,
+ (pg_process_disassembly_fc)g_python_plugin_process_disass))
+ goto gppn_bad_plugin;
break;
default:
@@ -349,7 +334,7 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO
}
break;
-#endif
+
default:
log_variadic_message(LMT_WARNING,
_("Unknown category '0x%02x' in plugin '%s'..."), category, filename);
@@ -555,234 +540,152 @@ static bool g_python_plugin_do_exit(GPythonPlugin *plugin, GObject *ref)
}
-
-
-
-
-
-
/******************************************************************************
* *
-* Paramètres : plugin = greffon de prise en charge à utiliser. *
+* Paramètres : content = contenu binaire à parcourir. *
+* parent = éventuel format exécutable déjà chargé. *
+* plugin = grefon C interne représentant le grefon Python. *
+* key = identifiant de format trouvé ou NULL. [OUT] *
* *
-* Description : Indique l'utilité pratique du greffon. *
+* Description : Indique si le format peut être pris en charge ici. *
* *
-* Retour : Action(s) codifiée(s), PGA_NONE par défaut. *
+* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PluginAction g_python_plugin_get_action(const GPythonPlugin *plugin)
+FormatMatchStatus python_plugin_is_matching(GBinContent *content, GExeFormat *parent, GPythonPlugin *plugin, char **key)
{
- PluginAction result; /* Valeur à retourner */
- PyObject *value; /* Valeur obtenue */
-
- value = run_python_method(plugin->instance, "get_action", NULL);
-
- if (value != NULL)
- {
- result = PyLong_AsLong(value);
- Py_DECREF(value);
- }
- else
- result = 0;//PGA_NONE;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : plugin = greffon de prise en charge à utiliser. *
-* filename = éventuel nom de fichier associé ou NULL. [OUT] *
-* data = données chargées. [OUT] *
-* length = quantité de ces données. [OUT] *
-* *
-* Description : Indentifie un format à associer à un contenu binaire. *
-* *
-* Retour : Bilan de la recherche de correspondances. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static MatchingFormatAction g_python_plugin_is_matching(const GPythonPlugin *plugin, char **filename, bin_t **data, off_t *length)
-{
- return MFA_NONE;
-
-#if 0
- MatchingFormatAction result; /* Valeur à retourner */
+ FormatMatchStatus result; /* Bilan à renvoyer */
PyObject *args; /* Arguments pour l'appel */
- PyObject *value; /* Valeurs obtenues */
- PyObject *action; /* Action à faire suivre */
- PyObject *new_filename; /* Nouveau fichier */
- PyObject *new_data; /* Nouvelles données */
- char *tmp; /* Stockage avant recopie */
+ PyObject *value; /* Valeur obtenue */
+ PyObject *arg; /* Argument en élément de tuple*/
- if (*filename == NULL)
- return MFA_NONE;
+ result = FMS_UNKNOWN;
args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(content)));
+ PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(parent)));
- PyTuple_SetItem(args, 0, PyString_FromString(*filename));
- PyTuple_SetItem(args, 1, PyByteArray_FromStringAndSize((char *)*data, *length));
-
- value = run_python_method(plugin->instance, "is_matching", args);
+ value = run_python_method(plugin->instance, "is_format_matching", args);
- if (value != NULL && PyTuple_Check(value) && PyTuple_Size(value) == 3)
+ if (PyTuple_Check(value))
{
- action = PyTuple_GetItem(value, 0);
- new_filename = PyTuple_GetItem(value, 1);
- new_data = PyTuple_GetItem(value, 2);
-
- if (action == NULL || new_filename == NULL || new_data == NULL)
- goto is_matching_bad;
-
- if (!PyInt_Check(action)
- || (new_filename != Py_None && !PyString_Check(new_filename))
- || (new_data != Py_None && !PyByteArray_Check(new_data)))
- goto is_matching_bad;
-
- result = PyInt_AsLong(action);
- if (result >= MFA_COUNT) goto is_matching_bad;
-
- if (result != MFA_NONE && new_data == Py_None) goto is_matching_bad;
-
- if (new_filename != Py_None)
- {
- free(*filename);
- *filename = strdup(PyString_AsString(new_filename));
- }
-
- /**
- * La suppression de la part du greffon n'est permise que
- * si une prise en charge est assurée.
- */
- else if (result != MFA_NONE)
- {
- free(*filename);
- *filename = NULL;
- }
-
- /**
- * Pareil que précédemment.
- */
- if (new_data != Py_None)
+ if (PyTuple_Size(value) > 0)
{
- tmp = PyByteArray_AsString(new_data);
- *length = PyByteArray_Size(new_data);
-
- free(*data);
-
- *data = (bin_t *)calloc(*length, sizeof(bin_t));
- memcpy(*data, tmp, *length * sizeof(bin_t));
-
- }
+ arg = PyTuple_GetItem(value, 0);
- goto is_matching_ok;
+ if (PyLong_Check(arg))
+ {
+ result = PyLong_AsLong(arg);
- }
-
- is_matching_bad:
-
- printf("<LOG>Bad result from is_matching() plugin function.\n");
+ switch (result)
+ {
+ case FMS_MATCHED:
- result = MFA_NONE;
+ if (PyTuple_Size(value) != 2)
+ {
+ g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR,
+ _("Expecting only a tuple [ status, key ] " \
+ "as result for format matching."));
+ result = FMS_UNKNOWN;
+ break;
+ }
- is_matching_ok:
+ arg = PyTuple_GetItem(value, 1);
- Py_XDECREF(value);
- Py_DECREF(args);
+ if (PyUnicode_Check(arg))
+ *key = strdup(PyUnicode_AsUTF8(arg));
- return result;
-#endif
-}
+ else
+ {
+ g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR,
+ _("Expecting a key string for format matching."));
+ result = FMS_UNKNOWN;
+ }
+ break;
+ case FMS_FORWARDED:
+ case FMS_UNKNOWN:
+ if (PyTuple_Size(value) != 1)
+ {
+ g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_WARNING,
+ _("Unused second item for format matching."));
+ }
+ break;
-/******************************************************************************
-* *
-* Paramètres : plugin = greffon de prise en charge à utiliser. *
-* binary = représentation binaire à traiter. *
-* action = action attendue. *
-* *
-* Description : Exécute une action définie sur un binaire chargé. *
-* *
-* Retour : true si une action a été menée, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ default:
+ g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR,
+ _("Unexpected result for format matching."));
+ result = FMS_UNKNOWN;
+ break;
-static bool g_python_plugin_execute_on_binary(GPythonPlugin *plugin, GLoadedBinary *binary, PluginAction action)
-{
- bool result; /* Bilan à remonter */
- PyObject *args; /* Arguments pour l'appel */
- PyObject *value; /* Valeurs obtenues */
+ }
- args = PyTuple_New(2);
+ }
- PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary)));
- PyTuple_SetItem(args, 1, Py_None);//PyInt_FromLong(action));
+ else
+ {
+ g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR,
+ _("Unexpected result status for format matching."));
+ result = FMS_UNKNOWN;
+ }
- value = run_python_method(plugin->instance, "execute_on_binary", args);
+ }
+ else
+ g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_WARNING,
+ _("Interpreting a empty tuple as FMS_UNKNOWN " \
+ "for format matching."));
- result = (value == Py_True);
+ }
+ else
+ g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR,
+ _("Expected a tuple containing [ status, key ] as result " \
+ "for format matching."));
Py_XDECREF(value);
Py_DECREF(args);
return result;
-}
+}
-#if 0
/******************************************************************************
* *
-* Paramètres : plugin = greffon à consulter. *
-* debugger = débogueur à l'origine de l'opération. *
-* action = action attendue. *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* binary = binaire dont le contenu est en cours de traitement. *
* *
-* Description : Exécute une action relative à un débogueur. *
+* Description : Exécute une action pendant un désassemblage de binaire. *
* *
-* Retour : true si une action a été menée, false sinon. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_python_plugin_handle_debugger(const GPythonPlugin *plugin, GBinaryDebugger *debugger, PluginAction action)
+static void g_python_plugin_process_disass(const GPythonPlugin *plugin, PluginAction action, GLoadedBinary *binary)
{
- bool result; /* Bilan à remonter */
PyObject *args; /* Arguments pour l'appel */
PyObject *value; /* Valeurs obtenues */
args = PyTuple_New(2);
- PyTuple_SetItem(args, 0, py_binary_debugger_from_c(debugger));
- PyTuple_SetItem(args, 1, Py_None);//PyInt_FromLong(action));
+ PyTuple_SetItem(args, 0, PyLong_FromLong(action));
+ PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(binary)));
- value = run_python_method(plugin->instance, "handle_debugger", args);
-
- result = (value == Py_True);
+ value = run_python_method(plugin->instance, "process_binary_disassembly", args);
Py_XDECREF(value);
Py_DECREF(args);
- return result;
-
}
-#endif
-
-
-
-
@@ -791,19 +694,6 @@ static bool g_python_plugin_handle_debugger(const GPythonPlugin *plugin, GBinary
/* ---------------------------------------------------------------------------------- */
-
-
-
-
-
-
-
-
-
-
-
-
-
/******************************************************************************
* *
* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
diff --git a/plugins/python/apkfiles/__init__.py b/plugins/python/apkfiles/__init__.py
index 2ebf824..7da894e 100644
--- a/plugins/python/apkfiles/__init__.py
+++ b/plugins/python/apkfiles/__init__.py
@@ -1,2 +1,4 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
-from apkfiles import ApkFiles as apkfiles
+from apkfiles.apkfiles import ApkFiles as AutoLoad
diff --git a/plugins/python/apkfiles/apkfiles.py b/plugins/python/apkfiles/apkfiles.py
index 7c05ca9..b85b0c8 100644
--- a/plugins/python/apkfiles/apkfiles.py
+++ b/plugins/python/apkfiles/apkfiles.py
@@ -1,15 +1,36 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-from pychrysalide import Plugin
-
+from pychrysalide import PluginModule
import zipfile
-class ApkFiles(Plugin):
+class ApkFiles(PluginModule):
"""Open and process APK files."""
+ def get_interface(self):
+ """Provide the full plugin description."""
+
+ desc = {
+
+ 'name' : 'Welcome',
+ 'desc' : 'Add suppport for the APK file format',
+ 'version' : '0.1',
+
+ 'actions' : [ PluginModule.PGA_PLUGIN_INIT ]
+
+ }
+
+ return desc
+
+
+ def init(self, ref):
+ """Initialise l'extension."""
+
+ return True
+
+
def get_action(self):
"""Register the plugin for given actions."""
diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c
index 53995e5..2497dd1 100644
--- a/plugins/ropgadgets/select.c
+++ b/plugins/ropgadgets/select.c
@@ -1316,7 +1316,8 @@ static GBinFormat *load_external_format_for_rop_gadgets(GObject *ref)
GtkEntry *entry; /* Zone de saisie de texte */
const gchar *filename; /* Nom du fichier à charger */
GBinContent *content; /* Contenu binaire chargé */
- const char *target; /* Sous-traitance requise */
+ FormatMatchStatus status; /* Statut d'une reconnaissance */
+ char *target; /* Sous-traitance requise */
const char *desc; /* Description humaine associée*/
/* Récupération du nom de fichier */
@@ -1338,18 +1339,21 @@ static GBinFormat *load_external_format_for_rop_gadgets(GObject *ref)
/* Récupération du format de fichier associé */
- target = find_matching_format(content, NULL);
- desc = get_binary_format_name(target);
+ status = find_matching_format(content, NULL, &target);
- if (desc == NULL)
+ if (status != FMS_MATCHED)
{
g_object_unref(G_OBJECT(content));
push_status_printing_of_rop_search_step(ref, "format", _("unknown binary format"), false);
goto leffrg_error;
}
+ desc = get_binary_format_name(target);
+
result = load_new_named_format(target, content, NULL);
+ free(target);
+
if (result == NULL)
{
push_status_printing_of_rop_search_step(ref, "format", _("error while loading the binary"), false);
diff --git a/src/analysis/binaries/file.c b/src/analysis/binaries/file.c
index 32cd41f..c31828c 100644
--- a/src/analysis/binaries/file.c
+++ b/src/analysis/binaries/file.c
@@ -116,8 +116,8 @@ static void g_file_binary_init(GFileBinary *binary)
loaded = G_LOADED_BINARY(binary);
- loaded->save = (save_binary_fc)g_file_binary_save;
- loaded->get_name = (get_binary_name_fc)g_file_binary_get_name;
+ //loaded->save = (save_binary_fc)g_file_binary_save;
+ //loaded->get_name = (get_binary_name_fc)g_file_binary_get_name;
}
@@ -173,7 +173,7 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename)
content = g_file_content_new(filename);
if (content == NULL) goto lbf_error;
- target = find_matching_format(content, NULL);
+ target = "";//find_matching_format(content, NULL);
desc = get_binary_format_name(target);
if (desc == NULL)
@@ -194,7 +194,7 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename)
goto lbf_error;
}
- target = find_matching_format(content, loaded->format);
+ target = "";//find_matching_format(content, loaded->format);
desc = get_binary_format_name(target);
if (desc != NULL)
diff --git a/src/analysis/binary-int.h b/src/analysis/binary-int.h
index 4bfb14e..60b9662 100644
--- a/src/analysis/binary-int.h
+++ b/src/analysis/binary-int.h
@@ -33,11 +33,8 @@
-/* Ecrit une sauvegarde du binaire dans un fichier XML. */
-typedef bool (* save_binary_fc) (const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *);
-
/* Fournit le fichier correspondant à l'élément binaire. */
-typedef const char * (* get_binary_name_fc) (const GLoadedBinary *, bool);
+typedef const char * (* get_binary_name_fc) (const GLoadedBinary *, bool); //// REMME
/* Description de fichier binaire (instance) */
@@ -57,11 +54,12 @@ struct _GLoadedBinary
DBStorage storages[DBF_COUNT]; /* Lieux d'enregistrement */
GList *collections; /* Ensemble de modifications */
- save_binary_fc save; /* Sauvegarde au format XML */
- get_binary_name_fc get_name; /* Obtention d'une description */
+ get_binary_name_fc get_name; /* Obtention d'une description */ //// REMME
+
+ GBinContent *content; /* Contenu binaire chargé */ //// REMME
GExeFormat *format; /* Format du binaire */
- GDbgFormat *debug; /* Informations de débogage */
+ GDbgFormat *debug; /* Informations de débogage */ //// REMME
GArchProcessor *proc; /* Architecture du binaire */
GArchInstruction *instrs; /* Instructions d'assemblage */
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 615e72e..c94f4f6 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -24,12 +24,14 @@
#include "binary.h"
+#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+
#include <i18n.h>
@@ -41,8 +43,11 @@
#include "../common/extstr.h"
#include "../common/cpp.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"
@@ -185,8 +190,11 @@ static void g_loaded_binary_init(GLoadedBinary *binary)
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));
@@ -222,10 +230,103 @@ static void g_loaded_binary_finalize(GLoadedBinary *binary)
/******************************************************************************
* *
-* Paramètres : context = contexte pour les recherches XPath. *
+* 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));
+
+ g_object_ref(G_OBJECT(content));
+ 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 */
+
+ if (!g_loaded_binary_attach_debug_info(result, content))
+ goto lbf_error;
+
+ /* 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 : Charge en mémoire le contenu d'un fichier à partir d'XML. *
+* Description : Interprète un contenu binaire chargé avec un appui XML. *
* *
* Retour : Adresse de la représentation ou NULL en cas d'échec. *
* *
@@ -233,39 +334,94 @@ static void g_loaded_binary_finalize(GLoadedBinary *binary)
* *
******************************************************************************/
-GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const char *path)
+GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const char *path, GStudyProject *project)
{
GLoadedBinary *result; /* Adresse à retourner */
- char *type; /* Type de binaire à charger */
+ 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);
- result = NULL;
+ if (hash == NULL)
+ {
+ free(content_path);
+ return NULL;
+ }
- type = get_node_prop_value(context, path, "type");
+ content = g_study_project_find_binary_content_by_hash(project, hash);
+ free(hash);
- if (strcmp(type, "file") == 0)
- result = g_file_binary_new_from_xml(context, path);
+ if (content == NULL)
+ {
+ free(content_path);
+ return NULL;
+ }
- free(type);
+ result = g_loaded_binary_new(content);
if (result == NULL)
+ {
+ free(content_path);
return NULL;
+ }
- /* --------- %< --------- TODO : à bouger pour + de générique --------- %< --------- */
+ xobject = get_node_xpath_object(context, "/ChrysalideProject/Contents/Content");
+ for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
+ {
+ asprintf(&access, "%s/DebugInfo[position()=%u]", content_path, i + 1);
- // -> init()
- //result->collections = create_collections_list();
+ hash = get_node_text_value(context, access);
+ free(access);
- if (!g_loaded_binary_load_storage(result, context, path))
- goto glbnfx_error;
+ 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);
- /* --------- %< --------- TODO : à bouger pur + de générique --------- %< --------- */
+ free(content_path);
+ /* Elément divers associés au binaire */
+ if (!g_loaded_binary_load_storage(result, context, path))
+ goto glbnfx_error;
return result;
@@ -296,15 +452,88 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch
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 */
- result = binary->save(binary, xdoc, context, path);
+ 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_cheksum(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_cheksum(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;
@@ -961,19 +1190,53 @@ void g_loaded_binary_analyse(GLoadedBinary *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. *
+* Description : Fournit le format de fichier reconnu dans le contenu binaire.*
* *
-* Retour : Nom de fichier avec chemin absolu. *
+* Retour : Instance du format reconnu. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *g_loaded_binary_get_name(const GLoadedBinary *binary, bool full)
+bool g_loaded_binary_attach_debug_info(GLoadedBinary *binary, GBinContent *content)
{
- return binary->get_name(binary, full);
+ 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é */
+
+ result = false;
+
+ status = find_matching_format(content, binary->format, &target);
+
+ if (status == FMS_MATCHED)
+ {
+ desc = get_binary_format_name(target);
+
+ if (desc != NULL)
+ {
+ 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);
+
+ }
+
+ return result;
}
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 6b7d338..4ef3a0d 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -28,6 +28,7 @@
#include <glib-object.h>
#include <stdbool.h>
+#include "content.h"
#include "db/collection.h"
#include "db/client.h"
#include "db/protocol.h"
@@ -39,6 +40,23 @@
+/* Redéfinition depuis project.c : projet d'étude regroupant les binaires analysés (instance) */
+typedef struct _GStudyProject GStudyProject;
+
+
+
+#define G_TYPE_LOADED_BINARY g_loaded_binary_get_type()
+#define G_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_loaded_binary_get_type(), GLoadedBinary))
+#define G_IS_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_loaded_binary_get_type()))
+#define G_LOADED_BINARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LOADED_BINARY, GLoadedBinaryClass))
+#define G_IS_LOADED_BINARY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LOADED_BINARY))
+#define G_LOADED_BINARY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LOADED_BINARY, GLoadedBinaryClass))
+
+
+
+
+
+
#define G_TYPE_LOADED_BINARY g_loaded_binary_get_type()
#define G_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_loaded_binary_get_type(), GLoadedBinary))
#define G_IS_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_loaded_binary_get_type()))
@@ -79,12 +97,18 @@ typedef enum _BinaryView
/* Indique le type défini pour une description de fichier binaire. */
GType g_loaded_binary_get_type(void);
-/* Charge en mémoire le contenu d'un fichier à partir d'XML. */
-GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr, const char *);
+/* Interprète un contenu binaire chargé. */
+GLoadedBinary *g_loaded_binary_new(GBinContent *);
+
+/* Interprète un contenu binaire chargé avec un appui XML. */
+GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr, const char *, GStudyProject *);
/* Ecrit une sauvegarde du binaire dans un fichier XML. */
bool g_loaded_binary_save(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *);
+/* Fournit le nom associé à l'élément binaire. */
+const char *g_loaded_binary_get_name(const GLoadedBinary *, bool);
+
/* ------------------------- INFORMATIONS D'ENREGISTREMENTS ------------------------- */
@@ -155,8 +179,8 @@ bool _g_loaded_binary_remove_from_collection(GLoadedBinary *, DBFeatures, GDbIte
/* Lance l'analyse d'un élément binaire chargé. */
void g_loaded_binary_analyse(GLoadedBinary *);
-/* Fournit le nom associé à l'élément binaire. */
-const char *g_loaded_binary_get_name(const GLoadedBinary *, bool);
+/* Fournit le format de fichier reconnu dans le contenu binaire. */
+bool g_loaded_binary_attach_debug_info(GLoadedBinary *, GBinContent *);
/* Fournit le format de fichier reconnu dans le contenu binaire. */
GExeFormat *g_loaded_binary_get_format(const GLoadedBinary *);
diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h
index 7734916..c5b1659 100644
--- a/src/analysis/content-int.h
+++ b/src/analysis/content-int.h
@@ -29,6 +29,12 @@
+/* Fournit le nom associé au contenu binaire. */
+typedef const char * (* describe_content_fc) (const GBinContent *, bool);
+
+/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
+typedef bool (* save_content_fc) (const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *);
+
/* Fournit une empreinte unique (SHA256) pour les données. */
typedef const gchar * (* get_checksum_fc) (GBinContent *);
@@ -62,6 +68,10 @@ struct _GBinContentIface
{
GTypeInterface base_iface; /* A laisser en premier */
+ describe_content_fc describe; /* Fournit une description */
+
+ save_content_fc save; /* Sauvegarde du contenu */
+
get_checksum_fc get_checksum; /* Calcul de l'empreinte */
compute_size_fc compute_size; /* Calcul de la taille totale */
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 5a4c899..d314d0c 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -24,7 +24,11 @@
#include "content.h"
+#include <string.h>
+
+
#include "content-int.h"
+#include "contents/file.h"
@@ -57,6 +61,88 @@ static void g_binary_content_default_init(GBinContentInterface *iface)
/******************************************************************************
* *
+* Paramètres : context = contexte pour les recherches XPath. *
+* path = chemin d'accès au noeud XML à lire. *
+* *
+* Description : Charge en mémoire un contenu binaire à partir d'XML. *
+* *
+* Retour : Adresse de la représentation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr context, const char *path)
+{
+ GBinContent *result; /* Contenu en place à renvoyer */
+ char *type; /* Type de binaire à charger */
+
+ result = NULL;
+
+ type = get_node_prop_value(context, path, "type");
+
+ if (strcmp(type, "file") == 0)
+ result = g_file_content_new_from_xml(context, path);
+
+ free(type);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à consulter. *
+* full = précise s'il s'agit d'une version longue ou non. *
+* *
+* Description : Fournit le nom associé au contenu binaire. *
+* *
+* Retour : Nom de fichier avec chemin absolu au besoin. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *g_binary_content_describe(const GBinContent *content, bool full)
+{
+ GBinContentIface *iface; /* Interface utilisée */
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
+
+ return iface->describe(content, full);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu 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 de contenu binaire dans un fichier XML. *
+* *
+* Retour : true si l'opération a bien tourné, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_save(const GBinContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
+{
+ GBinContentIface *iface; /* Interface utilisée */
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
+
+ return iface->save(content, xdoc, context, path);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : content = contenu binaire à venir lire. *
* *
* Description : Fournit une empreinte unique (SHA256) pour les données. *
diff --git a/src/analysis/content.h b/src/analysis/content.h
index d422dc6..0d991b9 100644
--- a/src/analysis/content.h
+++ b/src/analysis/content.h
@@ -31,6 +31,7 @@
#include "../arch/vmpa.h"
#include "../common/endianness.h"
+#include "../common/xml.h"
@@ -52,6 +53,15 @@ typedef struct _GBinContentIface GBinContentIface;
/* Détermine le type d'une interface pour la lecture de binaire. */
GType g_binary_content_get_type(void) G_GNUC_CONST;
+/* Charge en mémoire un contenu binaire à partir d'XML. */
+GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr, const char *);
+
+/* Fournit le nom associé au contenu binaire. */
+const char *g_binary_content_describe(const GBinContent *, bool);
+
+/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
+bool g_binary_content_save(const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *);
+
/* Fournit une empreinte unique (SHA256) pour les données. */
const gchar *g_binary_content_get_cheksum(GBinContent *);
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index eb0d488..9f1c10c 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -27,12 +27,14 @@
#include <assert.h>
#include <fcntl.h>
#include <malloc.h>
+#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "../content-int.h"
+#include "../../common/extstr.h"
@@ -41,6 +43,8 @@ struct _GFileContent
{
GObject parent; /* A laisser en premier */
+ char *filename; /* Fichier chargé en mémoire */
+
bin_t *data; /* Contenu binaire représenté */
mrange_t range; /* Couverture du binaire */
@@ -72,6 +76,12 @@ static void g_file_content_dispose(GFileContent *);
/* Procède à la libération totale de la mémoire. */
static void g_file_content_finalize(GFileContent *);
+/* Fournit le nom associé au contenu binaire. */
+static const char *g_file_content_describe(const GFileContent *, bool);
+
+/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
+static bool g_file_content_save(const GFileContent *, xmlDocPtr, xmlXPathContextPtr, const char *);
+
/* Fournit une empreinte unique (SHA256) pour les données. */
static const gchar *g_file_content_get_checksum(GFileContent *);
@@ -166,6 +176,10 @@ static void g_file_content_init(GFileContent *content)
static void g_file_content_interface_init(GBinContentInterface *iface)
{
+ iface->describe = (describe_content_fc)g_file_content_describe;
+
+ iface->save = (save_content_fc)g_file_content_save;
+
iface->get_checksum = (get_checksum_fc)g_file_content_get_checksum;
iface->compute_size = (compute_size_fc)g_file_content_compute_size;
@@ -217,6 +231,8 @@ static void g_file_content_dispose(GFileContent *content)
static void g_file_content_finalize(GFileContent *content)
{
+ free(content->filename);
+
if (content->data != NULL)
free(content->data);
@@ -275,6 +291,8 @@ GBinContent *g_file_content_new(const char *filename)
result = g_object_new(G_TYPE_FILE_CONTENT, NULL);
+ result->filename = strdup(filename);
+
result->data = (bin_t *)malloc(info.st_size);
memcpy(result->data, content, info.st_size);
@@ -295,6 +313,116 @@ GBinContent *g_file_content_new(const char *filename)
/******************************************************************************
* *
+* 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 : - *
+* *
+******************************************************************************/
+
+GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr context, const char *path)
+{
+ GBinContent *result; /* Adresse à retourner */
+ char *access; /* Chemin pour une sous-config.*/
+ char *filename; /* Chemin du binaire à charger */
+
+ result = NULL;
+
+ /* Chemin du fichier à retrouver */
+
+ access = strdup(path);
+ access = stradd(access, "/Filename");
+
+ filename = get_node_text_value(context, access);
+
+ free(access);
+
+ /* Chargement */
+
+ if (filename != NULL)
+ {
+ result = g_file_content_new(filename);
+ free(filename);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à consulter. *
+* full = précise s'il s'agit d'une version longue ou non. *
+* *
+* Description : Fournit le nom associé au contenu binaire. *
+* *
+* Retour : Nom de fichier avec chemin absolu au besoin. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const char *g_file_content_describe(const GFileContent *content, bool full)
+{
+ const char *result; /* Description à retourner */
+
+ if (full)
+ result = content->filename;
+ else
+ result = strrchr(content->filename, G_DIR_SEPARATOR) + 1;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu 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 de contenu binaire dans un fichier XML. *
+* *
+* Retour : true si l'opération a bien tourné, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
+{
+ bool result; /* Bilan à faire remonter */
+ char *access; /* Chemin d'accès à un élément */
+
+ result = true;
+
+ /* Type */
+
+ result &= add_string_attribute_to_node(xdoc, context, path, "type", "file");
+
+ /* Nom du fichier associé */
+
+ access = strdup(path);
+ access = stradd(access, "/Filename");
+
+ result &= add_content_to_node(xdoc, context, access, content->filename);
+
+ free(access);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : content = contenu binaire à venir lire. *
* *
* Description : Fournit une empreinte unique (SHA256) pour les données. *
diff --git a/src/analysis/contents/file.h b/src/analysis/contents/file.h
index 2e3cfef..0985f6b 100644
--- a/src/analysis/contents/file.h
+++ b/src/analysis/contents/file.h
@@ -53,6 +53,9 @@ GType g_file_content_get_type(void);
/* Charge en mémoire le contenu d'un fichier donné. */
GBinContent *g_file_content_new(const char *);
+/* Charge en mémoire le contenu d'un fichier à partir d'XML. */
+GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr, const char *);
+
#endif /* _ANALYSIS_CONTENTS_FILE_H */
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index cd16429..990ab0f 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -705,7 +705,7 @@ void disassemble_binary(GLoadedBinary *binary, GArchInstruction **instrs, GCodeB
checksum = g_binary_content_get_cheksum(content);
g_object_unref(G_OBJECT(content));
- build_disass_prologue(*buffer, g_loaded_binary_get_name(binary, true), checksum);
+ build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum);
disass = g_delayed_disassembly_new(binary, instrs, *buffer);
g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary);
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 5bb028f..db00f09 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -29,14 +29,20 @@
#include <string.h>
+#include <i18n.h>
+
+
#include "binaries/file.h"
#include "../common/xml.h"
+#include "../core/formats.h"
#include "../core/params.h"
#include "../glibext/signal.h"
#include "../gtkext/easygtk.h"
+#include "../glibext/delayed-int.h"
#include "../gtkext/gtkblockview.h"
#include "../gtkext/gtkgraphview.h"
#include "../gtkext/gtksourceview.h"
+#include "../gui/panels/log.h"
#include "../gui/panels/panel.h"
@@ -44,6 +50,14 @@
/* ------------------------- DEFINITION D'UN PROJET INTERNE ------------------------- */
+/* Conservation d'un contenu chargé */
+typedef struct _loaded_content
+{
+ GBinContent *content; /* Contenu binaire en place */
+ ProjectContentState state; /* Renseigne le type de contenu*/
+
+} loaded_content;
+
/* Conservation d'un binaire chargé */
typedef struct _loaded_binary
{
@@ -65,9 +79,13 @@ struct _GStudyProject
char *filename; /* Lieu d'enregistrement */
+ loaded_content *contents; /* Contenus binaires chargés */
+ size_t contents_count; /* Nombre de ces contenus */
+ GMutex cnt_mutex; /* Modification de la liste */
+
loaded_binary **binaries; /* Fichiers binaires associés */
size_t binaries_count; /* Nombre de ces fichiers */
- GMutex mutex; /* Modification de la liste */
+ GMutex bin_mutex; /* Modification de la liste */
};
@@ -91,6 +109,49 @@ static void g_study_project_hide(const GStudyProject *);
+
+
+/* ----------------------- AMORCE POUR CHARGEMENT DE CONTENUS ----------------------- */
+
+
+/* Ensembles binaires à désassembler (instance) */
+struct _GDelayedStudy
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ GStudyProject *project; /* Projet de rattachement */
+ GBinContent *content; /* Contenu binaire à traiter */
+ ProjectContentState state; /* Renseigne le type de contenu*/
+
+ bool only_preload; /* Enregistrement seulement ? */
+
+};
+
+/* Ensembles binaires à désassembler (classe) */
+struct _GDelayedStudyClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des intégrations de binaires à étudier. */
+static void g_delayed_study_class_init(GDelayedStudyClass *);
+
+/* Initialise une intégration de binaire à étudier. */
+static void g_delayed_study_init(GDelayedStudy *);
+
+/* Supprime toutes les références externes. */
+static void g_delayed_study_dispose(GDelayedStudy *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_delayed_study_finalize(GDelayedStudy *);
+
+/* Prépare une intégration de binaire au projet courant. */
+static void g_delayed_study_process(GDelayedStudy *, GtkExtStatusBar *);
+
+
+
/* ---------------------------------------------------------------------------------- */
/* DEFINITION D'UN PROJET INTERNE */
/* ---------------------------------------------------------------------------------- */
@@ -132,7 +193,9 @@ static void g_study_project_class_init(GStudyProjectClass *klass)
static void g_study_project_init(GStudyProject *project)
{
- g_mutex_init(&project->mutex);
+ g_mutex_init(&project->cnt_mutex);
+
+ g_mutex_init(&project->bin_mutex);
}
@@ -180,11 +243,17 @@ GStudyProject *g_study_project_open(GObject *ref, const char *filename)
GStudyProject *result; /* Adresse à retourner */
xmlDocPtr xdoc; /* Structure XML chargée */
xmlXPathContextPtr context; /* Contexte pour les XPath */
+ unsigned int root_contents; /* Quantité de contenus majeurs*/
+ GAsyncQueue *sema; /* Sémaphore taisant son nom */
xmlXPathObjectPtr xobject; /* Cible d'une recherche */
unsigned int i; /* Boucle de parcours */
size_t access_len; /* Taille d'un chemin interne */
char *access; /* Chemin pour une sous-config.*/
- GLoadedBinary *binary; /* Représentation à intégrer */
+ GBinContent *content; /* Contenu binaire retrouvé */
+ long state; /* Etat de ce contenu binaire */
+ bool status; /* Bilan d'une lecture */
+ GDelayedStudy *dstudy; /* Etude complémentaire à mener*/
+ GLoadedBinary *binary; /* Représentation à intégrer */
if (!open_xml_file(filename, &xdoc, &context)) return NULL;
@@ -192,19 +261,78 @@ GStudyProject *g_study_project_open(GObject *ref, const char *filename)
result->filename = strdup(filename);
- /* Chargement des éléments binaires attachés */
+ /* Préparations aux traitements parallèles */
+
+ root_contents = 0;
+
+ sema = g_async_queue_new();
+
+ void ack_content_processing(GDelayedStudy *dstudy, GAsyncQueue *aqueue)
+ {
+ g_async_queue_push(aqueue, GINT_TO_POINTER(1));
+ }
+
+ /* Chargement des contenus binaires attachés */
+
+ xobject = get_node_xpath_object(context, "/ChrysalideProject/Contents/Content");
+
+ for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
+ {
+ access_len = strlen("/ChrysalideProject/Contents/Content[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
+
+ access = calloc(access_len, sizeof(char));
+ snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%u]", i + 1);
+
+ content = g_binary_content_new_from_xml(context, access);
+ status = get_node_prop_long_value(context, access, "state", &state);
+
+ free(access);
+
+ if (!status)
+ {
+ log_variadic_message(LMT_PROCESS, _("bad state for content '%s' ; skipping..."),
+ g_binary_content_describe(content, true));
+ continue;
+ }
+
+ /* Le contenu peut être un conteneur ? */
+ if (state == PCS_ROOT)
+ {
+ dstudy = g_delayed_study_new(result, content, state);
+ g_signal_connect(dstudy, "work-completed", G_CALLBACK(ack_content_processing), sema);
+
+ g_delayed_study_preload_only(dstudy);
+
+ root_contents++;
+
+ study_new_content(dstudy);
+
+ }
+
+ }
+
+ if(xobject != NULL)
+ xmlXPathFreeObject(xobject);
+
+ /* Attente pour la réception de contenus supplémentaires éventuels */
+
+ for (i = 0; i < root_contents; i++)
+ g_async_queue_pop(sema);
+
+ g_async_queue_unref(sema);
- xobject = get_node_xpath_object(context, "/OpenIDAProject/Binaries/Binary");
+ /* Chargement des binaires analysés */
+
+ xobject = get_node_xpath_object(context, "/ChrysalideProject/Binaries/Binary");
for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
{
- access_len = strlen("/OpenIDAProject/Binaries/Binary[position()=")
- + strlen("4294967295" /* UINT_MAX */) + strlen("]") + 1;
+ access_len = strlen("/ChrysalideProject/Binaries/Binary[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
access = calloc(access_len, sizeof(char));
- snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%u]", i + 1);
+ snprintf(access, access_len, "/ChrysalideProject/Binaries/Binary[position()=%u]", i + 1);
- binary = g_loaded_binary_new_from_xml(context, access);
+ binary = g_loaded_binary_new_from_xml(context, access, result);
free(access);
@@ -254,17 +382,36 @@ bool g_study_project_save(GStudyProject *project, const char *filename)
result = create_new_xml_file(&xdoc, &context);
- result &= (ensure_node_exist(xdoc, context, "/OpenIDAProject") != NULL);
+ result &= (ensure_node_exist(xdoc, context, "/ChrysalideProject") != NULL);
+
+ /* Enregistrement des contenus binaires attachés */
- /* Enregistrement des éléments binaires attachés */
+ for (i = 0; i < project->contents_count && result; i++)
+ {
+ if (!project->contents[i].state == PCS_INTERNAL) continue;
+
+ access_len = strlen("/ChrysalideProject/Contents/Content[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
+
+ access = calloc(access_len, sizeof(char));
+ snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%zu]", i + 1);
+
+ result = g_binary_content_save(project->contents[i].content, xdoc, context, access);
+
+ if (result)
+ result = add_long_attribute_to_node(xdoc, context, access, "state", project->contents[i].state);
+
+ free(access);
+
+ }
+
+ /* Enregistrement des binaires analysés */
for (i = 0; i < project->binaries_count && result; i++)
{
- access_len = strlen("/OpenIDAProject/Binaries/Binary[position()=")
- + strlen("4294967295" /* UINT_MAX */) + strlen("]") + 1;
+ access_len = strlen("/ChrysalideProject/Binaries/Binary[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
access = calloc(access_len, sizeof(char));
- snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%zu]", i + 1);
+ snprintf(access, access_len, "/ChrysalideProject/Binaries/Binary[position()=%zu]", i + 1);
result = g_loaded_binary_save(project->binaries[i]->binary, xdoc, context, access);
@@ -311,6 +458,88 @@ const char *g_study_project_get_filename(const GStudyProject *project)
/******************************************************************************
* *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* content = contenu binaire à mémoriser pour le projet. *
+* state = état du contenu à conserver. *
+* *
+* Description : Assure l'intégration d'un contenu binaire dans un projet. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_study_project_add_binary_content(GStudyProject *project, GBinContent *content, ProjectContentState state)
+{
+ loaded_content *new; /* Nouveau contenu à définir */
+
+ g_mutex_lock(&project->cnt_mutex);
+
+ project->contents = (loaded_content *)realloc(project->contents,
+ ++project->contents_count * sizeof(loaded_content));
+
+ new = &project->contents[project->contents_count - 1];
+
+ g_object_ref(G_OBJECT(content));
+
+ new->content = content;
+ new->state = state;
+
+ g_mutex_unlock(&project->cnt_mutex);
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* hash = empreinte du contenu à retrouver. *
+* *
+* Description : Recherche un contenu binaire du projet selon son empreinte. *
+* *
+* Retour : Contenu avec propriété transférée ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *project, const char *hash)
+{
+ GBinContent *result; /* Trouvaille à retourner */
+ size_t i; /* Boucle de parcours */
+ GBinContent *iter; /* Contenu binaire analysé */
+ const gchar *other; /* Autre empreinte à comparer */
+
+ result = NULL;
+
+ g_mutex_lock(&project->cnt_mutex);
+
+ for (i = 0; i < project->contents_count && result == NULL; i++)
+ {
+ iter = project->contents[i].content;
+ other = g_binary_content_get_cheksum(iter);
+
+ if (strcmp(hash, other) == 0)
+ {
+ g_object_ref(G_OBJECT(iter));
+ result = iter;
+ }
+
+ }
+
+ g_mutex_unlock(&project->cnt_mutex);
+
+ return result;
+
+}
+
+
+
+
+/******************************************************************************
+* *
* Paramètres : binary = élément binaire tout juste désassemblé. *
* project = projet dont le contenu est à compléter. *
* *
@@ -431,7 +660,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
/* Enregistrement dans le projet */
- g_mutex_lock(&project->mutex);
+ g_mutex_lock(&project->bin_mutex);
project->binaries = (loaded_binary **)realloc(project->binaries,
++project->binaries_count * sizeof(loaded_binary *));
@@ -440,7 +669,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
project->binaries[result] = loaded;
- g_mutex_unlock(&project->mutex);
+ g_mutex_unlock(&project->bin_mutex);
update_project_area(project);
@@ -714,3 +943,272 @@ void push_project_into_recent_list(const GStudyProject *project)
g_generic_config_set_value(get_main_configuration(), MPK_LAST_PROJECT, project->filename);
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* AMORCE POUR CHARGEMENT DE CONTENUS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour les tâches de préparations d'étude. */
+G_DEFINE_TYPE(GDelayedStudy, g_delayed_study, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des intégrations de binaires à étudier. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_class_init(GDelayedStudyClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_delayed_study_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_delayed_study_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dstudy = instance à initialiser. *
+* *
+* Description : Initialise une intégration de binaire à étudier. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_init(GDelayedStudy *dstudy)
+{
+ G_DELAYED_WORK(dstudy)->run = (run_task_fc)g_delayed_study_process;
+
+ dstudy->only_preload = false;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_dispose(GDelayedStudy *dstudy)
+{
+ g_object_unref(G_OBJECT(dstudy->project));
+ g_object_unref(G_OBJECT(dstudy->content));
+
+ G_OBJECT_CLASS(g_delayed_study_parent_class)->dispose(G_OBJECT(dstudy));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_finalize(GDelayedStudy *dstudy)
+{
+ G_OBJECT_CLASS(g_delayed_study_parent_class)->finalize(G_OBJECT(dstudy));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* content = contenu binaire chargé à analyser. *
+* state = état du contenu à conserver. *
+* *
+* Description : Crée une tâche d'intégration de contenu binaire. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : L'appelant perd la propriété du contenu. *
+* *
+******************************************************************************/
+
+GDelayedStudy *g_delayed_study_new(GStudyProject *project, GBinContent *content, ProjectContentState state)
+{
+ GDelayedStudy *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_DELAYED_STUDY, NULL);
+
+ g_object_ref(G_OBJECT(project));
+ result->project = project;
+
+ g_object_ref(G_OBJECT(content));
+ result->content = content;
+
+ result->state = state;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dstudy = intégration à mener. *
+* statusbar = barre de statut à tenir informée. *
+* *
+* Description : Prépare une intégration de binaire au projet courant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_process(GDelayedStudy *dstudy, GtkExtStatusBar *statusbar)
+{
+ FormatMatchStatus status; /* Statut d'une reconnaissance */
+ char *target; /* Sous-traitance requise */
+ GLoadedBinary *binary; /* Représentation chargée */
+
+ status = find_matching_format(dstudy->content, NULL, &target);
+
+ switch (status)
+ {
+ case FMS_MATCHED:
+
+ if (dstudy->only_preload)
+ g_study_project_add_binary_content(dstudy->project, dstudy->content, dstudy->state);
+
+ else
+ {
+ binary = g_loaded_binary_new(dstudy->content);
+
+ if (binary != NULL)
+ {
+ g_study_project_add_binary_content(dstudy->project, dstudy->content, dstudy->state);
+
+ g_signal_connect_to_main(binary, "disassembly-done",
+ G_CALLBACK(g_study_project_add_loaded_binary),
+ dstudy->project, g_cclosure_marshal_VOID__VOID);
+
+ g_loaded_binary_analyse(binary);
+
+ }
+
+ }
+
+ break;
+
+ case FMS_FORWARDED:
+ /**
+ * L'émetteur de ce type de réponse a pour charge de
+ * reprogrammer lui même l'analyse de nouveaux contenus.
+ */
+ log_variadic_message(LMT_PROCESS, _("binary '%s' contains other binaries..."),
+ g_binary_content_describe(dstudy->content, true));
+
+ if (dstudy->state == PCS_ROOT)
+ g_study_project_add_binary_content(dstudy->project, dstudy->content, PCS_ROOT);
+
+ break;
+
+ default:
+ /**
+ * Les jeux sont faits pour le contenu binaire courant.
+ */
+ log_variadic_message(LMT_PROCESS, _("Unknown binary format for '%s'..."),
+ g_binary_content_describe(dstudy->content, true));
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dstudy = tâche d'analyse de contenu pour projet à mener. *
+* *
+* Description : Limite l'étude et l'intégration d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_delayed_study_preload_only(GDelayedStudy *dstudy)
+{
+ dstudy->only_preload = true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire chargé à analyser. *
+* state = état du contenu à conserver. *
+* *
+* Description : Programme l'étude et l'intégration d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void qck_study_new_content(GBinContent *content, ProjectContentState state)
+{
+ GDelayedStudy *dstudy; /* Etude à conduire */
+
+ dstudy = g_delayed_study_new(get_current_project(), content, state);
+
+ study_new_content(dstudy);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire chargé à analyser. *
+* state = état du contenu à conserver. *
+* *
+* Description : Programme l'étude et l'intégration d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void study_new_content(GDelayedStudy *dstudy)
+{
+ GWorkQueue *queue; /* Gestionnaire de différés */
+
+ queue = get_work_queue();
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(dstudy));
+
+}
diff --git a/src/analysis/project.h b/src/analysis/project.h
index 05e7f12..5f5b38c 100644
--- a/src/analysis/project.h
+++ b/src/analysis/project.h
@@ -66,6 +66,23 @@ bool g_study_project_save(GStudyProject *, const char *);
/* Indique le chemin du fichier destiné à la sauvegarde. */
const char *g_study_project_get_filename(const GStudyProject *);
+/* Etat d'un contenu binaire du projet */
+typedef enum _ProjectContentState
+{
+ PCS_ROOT, /* Contenu principal */
+ PCS_INTERNAL, /* Contenu dérivé */
+ PCS_ATTACHED, /* Contenu complémentaire */
+
+ PCS_COUNT
+
+} ProjectContentState;
+
+/* Assure l'intégration d'un contenu binaire dans un projet. */
+void g_study_project_add_binary_content(GStudyProject *, GBinContent *, ProjectContentState);
+
+/* Recherche un contenu binaire du projet selon son empreinte. */
+GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *, const char *);
+
/* Assure l'intégration d'un élément binaire dans un projet. */
void g_study_project_add_loaded_binary(GLoadedBinary *, GStudyProject *);
@@ -103,4 +120,39 @@ void push_project_into_recent_list(const GStudyProject *);
+/* ----------------------- AMORCE POUR CHARGEMENT DE CONTENUS ----------------------- */
+
+
+#define G_TYPE_DELAYED_STUDY g_delayed_study_get_type()
+#define G_DELAYED_STUDY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_delayed_study_get_type(), GDelayedStudy))
+#define G_IS_DELAYED_STUDY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_delayed_study_get_type()))
+#define G_DELAYED_STUDY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DELAYED_STUDY, GDelayedStudyClass))
+#define G_IS_DELAYED_STUDY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DELAYED_STUDY))
+#define G_DELAYED_STUDY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DELAYED_STUDY, GDelayedStudyClass))
+
+
+/* Ensembles binaires à désassembler (instance) */
+typedef struct _GDelayedStudy GDelayedStudy;
+
+/* Ensembles binaires à désassembler (classe) */
+typedef struct _GDelayedStudyClass GDelayedStudyClass;
+
+
+/* Indique le type défini pour les tâches de préparations d'étude. */
+GType g_delayed_study_get_type(void);
+
+/* Crée une tâche d'intégration de contenu binaire. */
+GDelayedStudy *g_delayed_study_new(GStudyProject *, GBinContent *, ProjectContentState);
+
+/* Limite l'étude et l'intégration d'un contenu binaire. */
+void g_delayed_study_preload_only(GDelayedStudy *);
+
+/* Programme l'étude et l'intégration d'un contenu binaire. */
+void qck_study_new_content(GBinContent *, ProjectContentState);
+
+/* Programme l'étude et l'intégration d'un contenu binaire. */
+void study_new_content(GDelayedStudy *);
+
+
+
#endif /* _PROJECT_H */
diff --git a/src/common/xml.c b/src/common/xml.c
index 1e2871b..a9c65b5 100644
--- a/src/common/xml.c
+++ b/src/common/xml.c
@@ -27,6 +27,7 @@
#include <stdarg.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
@@ -322,6 +323,43 @@ char *qck_get_node_prop_value(xmlNodePtr node, const char *name)
/******************************************************************************
* *
+* Paramètres : node = noeud dont une propriété est à lire. *
+* name = nom de la propriété à lire. *
+* out = valeur entière lue depuis le contenu textuel. [OUT] *
+* *
+* Description : Obtient la valeur entière d'une propriété d'un élément. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool qck_get_node_prop_long_value(xmlNodePtr node, const char *name, long *out)
+{
+ bool result; /* Bilan à retourner */
+ char *value; /* Valeur brute lue */
+
+ value = qck_get_node_prop_value(node, name);
+
+ if (value)
+ {
+ result = true;
+
+ *out = strtol(value, NULL, 10);
+ free(value);
+
+ }
+ else
+ result = false;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : xpathCtx = contexte à utiliser pour les recherches. *
* path = chemin d'accès au noeud à traiter. *
* name = nom de la propriété à lire. *
@@ -356,6 +394,41 @@ char *get_node_prop_value(xmlXPathContextPtr xpathCtx, const char *path, const c
/******************************************************************************
* *
+* Paramètres : xpathCtx = contexte à utiliser pour les recherches. *
+* path = chemin d'accès au noeud à traiter. *
+* name = nom de la propriété à lire. *
+* out = valeur entière obtenue via contenu textuel. [OUT] *
+* *
+* Description : Obtient la valeur entière d'une propriété d'un élément. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool get_node_prop_long_value(xmlXPathContextPtr xpathCtx, const char *path, const char *name, long *out)
+{
+ bool result; /* Bilan à retourner */
+ xmlXPathObjectPtr xpathObj; /* Point de départ XML */
+
+ result = NULL;
+
+ xpathObj = get_node_xpath_object(xpathCtx, path);
+ if (xpathObj == NULL) return NULL;
+
+ if (xpathObj->nodesetval->nodeNr > 0)
+ result = qck_get_node_prop_long_value(xpathObj->nodesetval->nodeTab[0], name, out);
+
+ xmlXPathFreeObject(xpathObj);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : node = noeud de texte avec un lien avec le document XML. *
* *
* Description : Construit un chemin d'accès complet selon le fichier XML. *
@@ -965,16 +1038,13 @@ bool _add_string_attribute_to_node(xmlNodePtr node, const char *name, const char
bool add_string_attribute_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *name, const char *value)
{
xmlNodePtr node; /* Noeud à modifier */
- xmlAttrPtr attrib; /* Attribut créé et en place */
if (value == NULL) return true;
node = ensure_node_exist(xdoc, context, path);
if (node == NULL) return false;
- attrib = xmlSetProp(node, BAD_CAST name, BAD_CAST value);
-
- return (attrib != NULL);
+ return _add_string_attribute_to_node(node, name, value);
}
@@ -993,7 +1063,7 @@ bool add_string_attribute_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, co
* *
******************************************************************************/
-bool add_long_attribute_to_node(xmlNodePtr node, const char *name, long value)
+bool _add_long_attribute_to_node(xmlNodePtr node, const char *name, long value)
{
char tmp[11/*strlen("2147483647")*/]; /* Stockage temporaire */
@@ -1002,3 +1072,31 @@ bool add_long_attribute_to_node(xmlNodePtr node, const char *name, long value)
return _add_string_attribute_to_node(node, name, tmp);
}
+
+
+/******************************************************************************
+* *
+* Paramètres : xdoc = structure XML chargée. *
+* context = contexte à utiliser pour les recherches. *
+* path = chemin d'accès au noeud visé. *
+* name = nom de la propriété à créer. *
+* value = valeur numérique à placer. *
+* *
+* Description : Ajoute une propriété à un noeud existant donné. *
+* *
+* Retour : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_long_attribute_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *name, long value)
+{
+ xmlNodePtr node; /* Noeud à modifier */
+
+ node = ensure_node_exist(xdoc, context, path);
+ if (node == NULL) return false;
+
+ return _add_long_attribute_to_node(node, name, value);
+
+}
diff --git a/src/common/xml.h b/src/common/xml.h
index 8cb8c0e..60891f7 100644
--- a/src/common/xml.h
+++ b/src/common/xml.h
@@ -68,9 +68,15 @@ char *get_node_text_value(xmlXPathContextPtr, const char *);
/* Obtient la valeur d'une propriété d'un élément. */
char *qck_get_node_prop_value(xmlNodePtr, const char *);
+/* Obtient la valeur entière d'une propriété d'un élément. */
+bool qck_get_node_prop_long_value(xmlNodePtr, const char *, long *);
+
/* Obtient la valeur d'une propriété d'un élément. */
char *get_node_prop_value(xmlXPathContextPtr, const char *, const char *);
+/* Obtient la valeur entière d'une propriété d'un élément. */
+bool get_node_prop_long_value(xmlXPathContextPtr, const char *, const char *, long *);
+
/* Construit un chemin d'accès complet selon le fichier XML. */
char *qck_build_filename_with_doc_url(xmlNodePtr);
@@ -133,7 +139,10 @@ bool _add_string_attribute_to_node(xmlNodePtr, const char *, const char *);
bool add_string_attribute_to_node(xmlDocPtr, xmlXPathContextPtr, const char *, const char *, const char *);
/* Ajoute une propriété à un noeud existant donné. */
-bool add_long_attribute_to_node(xmlNodePtr, const char *, long);
+bool _add_long_attribute_to_node(xmlNodePtr, const char *, long);
+
+/* Ajoute une propriété à un noeud existant donné. */
+bool add_long_attribute_to_node(xmlDocPtr, xmlXPathContextPtr, const char *, const char *, long);
diff --git a/src/core/formats.c b/src/core/formats.c
index 891fc12..1326fc4 100644
--- a/src/core/formats.c
+++ b/src/core/formats.c
@@ -41,6 +41,7 @@
typedef struct _format_matcher_t
{
format_match_fc func; /* Recherche de correspondance */
+ void *data; /* Eventuelle donnée à y lier */
} format_matcher_t;
@@ -76,6 +77,7 @@ static format_loader_t *find_format_by_key(const char *);
/******************************************************************************
* *
* Paramètres : func = procédure de détection à utiliser. *
+* data = éventuelle donnée à associer aux opérations. *
* *
* Description : Enregistre un détection de format(s) binaire(s). *
* *
@@ -85,18 +87,24 @@ static format_loader_t *find_format_by_key(const char *);
* *
******************************************************************************/
-bool register_format_matcher(format_match_fc func)
+bool register_format_matcher(format_match_fc func, void *data)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
+ const format_matcher_t *cur; /* Elément parcouru et analysé */
format_matcher_t *new; /* Nouvel élément à définir */
g_rw_lock_writer_lock(&_formats_lock);
for (i = 0; i < _formats_matchers_count; i++)
- if (_formats_matchers[i].func == func)
+ {
+ cur = &_formats_matchers[i];
+
+ if (cur->func == func && cur->data == data)
break;
+ }
+
result = (i == _formats_matchers_count);
if (result)
@@ -107,6 +115,7 @@ bool register_format_matcher(format_match_fc func)
new = &_formats_matchers[_formats_matchers_count - 1];
new->func = func;
+ new->data = data;
}
@@ -186,9 +195,9 @@ bool load_hard_coded_formats_definitions(void)
/* Détections */
- result &= register_format_matcher(dwarf_is_matching);
+ result &= register_format_matcher(dwarf_is_matching, NULL);
- result &= register_format_matcher(elf_is_matching);
+ result &= register_format_matcher(elf_is_matching, NULL);
/* Chargements */
@@ -315,27 +324,32 @@ const char *get_binary_format_name(const char *key)
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+* key = identifiant de format trouvé ou NULL. [OUT] *
* *
* Description : Identifie un format binaire par son contenu. *
* *
-* Retour : Identifiant du format binaire trouvé ou NULL si échec. *
+* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *find_matching_format(GBinContent *content, GExeFormat *parent)
+FormatMatchStatus find_matching_format(GBinContent *content, GExeFormat *parent, char **key)
{
- const char *result; /* Identifiant à retourner */
+ FormatMatchStatus result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
+ const format_matcher_t *cur; /* Elément parcouru et analysé */
- result = NULL;
+ result = FMS_UNKNOWN;
g_rw_lock_reader_lock(&_formats_lock);
- for (i = 0; i < _formats_matchers_count && result == NULL; i++)
+ for (i = 0; i < _formats_matchers_count && result == FMS_UNKNOWN; i++)
{
- result = _formats_matchers[i].func(content, parent);
+ cur = &_formats_matchers[i];
+
+ result = cur->func(content, parent, cur->data, key);
+
}
g_rw_lock_reader_unlock(&_formats_lock);
diff --git a/src/core/formats.h b/src/core/formats.h
index 8857217..76b57d0 100644
--- a/src/core/formats.h
+++ b/src/core/formats.h
@@ -34,15 +34,27 @@
+/* Conclusion d'une opération de reconnaissance */
+typedef enum _FormatMatchStatus
+{
+ FMS_MATCHED, /* Correspondance établie */
+ FMS_FORWARDED, /* Sous-formats détectés */
+ FMS_UNKNOWN, /* Aucun format reconnu */
+
+ FMS_COUNT
+
+} FormatMatchStatus;
+
+
/* Indication à propos du support d'un format */
-typedef const char * (* format_match_fc) (GBinContent *, GExeFormat *);
+typedef FormatMatchStatus (* format_match_fc) (GBinContent *, GExeFormat *, void *, char **);
/* Méthode de chargement d'un format */
typedef GBinFormat * (* format_load_fc) (GBinContent *, GExeFormat *);
/* Enregistre un détection de format(s) binaire(s). */
-bool register_format_matcher(format_match_fc);
+bool register_format_matcher(format_match_fc, void *);
/* Enregistre un format de contenu binaire donné. */
bool register_format_loader(const char *, const char *, format_load_fc);
@@ -57,11 +69,11 @@ void unload_formats_definitions(void);
const char *get_binary_format_name(const char *);
/* Identifie un format binaire par son contenu. */
-const char *find_matching_format(GBinContent *, GExeFormat *);
+FormatMatchStatus find_matching_format(GBinContent *, GExeFormat *, char **);
/* Charge le format binaire correspondant à un type. */
GBinFormat *load_new_named_format(const char *, GBinContent *, GExeFormat *);
-#endif /* _ANALYSIS_DB_COLLECTION_H */
+#endif /* _CORE_FORMATS_H */
diff --git a/src/format/dwarf/dwarf.c b/src/format/dwarf/dwarf.c
index db8335b..519aa49 100644
--- a/src/format/dwarf/dwarf.c
+++ b/src/format/dwarf/dwarf.c
@@ -47,18 +47,20 @@ static void g_dwarf_format_finalize(GDwarfFormat *);
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+* unused = adresse non utilisée ici. *
+* key = identifiant de format trouvé ou NULL. [OUT] *
* *
* Description : Indique si le format peut être pris en charge ici. *
* *
-* Retour : Désignation du format reconnu ou NULL si aucun. *
+* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *dwarf_is_matching(GBinContent *content, GExeFormat *parent)
+FormatMatchStatus dwarf_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key)
{
- const char *result; /* Format détecté à renvoyer */
+ FormatMatchStatus result; /* Bilan à renvoyer */
size_t i; /* Boucle de parcours */
mrange_t range; /* Couverture d'une section */
dw_section_header header; /* En-tête DWARF de section */
@@ -114,10 +116,10 @@ const char *dwarf_is_matching(GBinContent *content, GExeFormat *parent)
0 /* .debug_types */
};
- result = NULL;
+ result = FMS_UNKNOWN;
if (parent == NULL)
- return NULL;
+ return FMS_UNKNOWN;
/* Lecture des indices présents */
@@ -159,23 +161,32 @@ const char *dwarf_is_matching(GBinContent *content, GExeFormat *parent)
found = check_dwarf_version(dwarf_v4_versions, current_versions, ARRAY_SIZE(section_names));
if (found)
- result = "dwarf_v4";
+ {
+ result = FMS_MATCHED;
+ *key = strdup("dwarf_v4");
+ }
- if (result == NULL)
+ if (result == FMS_UNKNOWN)
{
found = check_dwarf_version(dwarf_v3_versions, current_versions, ARRAY_SIZE(section_names));
if (found)
- result = "dwarf_v3";
+ {
+ result = FMS_MATCHED;
+ *key = strdup("dwarf_v3");
+ }
}
- if (result == NULL)
+ if (result == FMS_UNKNOWN)
{
found = check_dwarf_version(dwarf_v2_versions, current_versions, ARRAY_SIZE(section_names));
if (found)
- result = "dwarf_v2";
+ {
+ result = FMS_MATCHED;
+ *key = strdup("dwarf_v2");
+ }
}
diff --git a/src/format/dwarf/dwarf.h b/src/format/dwarf/dwarf.h
index a5e988b..da5b70a 100644
--- a/src/format/dwarf/dwarf.h
+++ b/src/format/dwarf/dwarf.h
@@ -25,7 +25,7 @@
#define _FORMAT_DWARF_DWARF_H
-#include "../executable.h"
+#include "../../core/formats.h"
@@ -45,7 +45,7 @@ typedef struct _GDwarfFormatClass GDwarfFormatClass;
/* Indique si le format peut être pris en charge ici. */
-const char *dwarf_is_matching(GBinContent *, GExeFormat *);
+FormatMatchStatus dwarf_is_matching(GBinContent *, GExeFormat *, void *, char **);
/* Indique le type défini pour un format de débogage DWARF. */
GType g_dwarf_format_get_type(void);
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 5c81b2f..50df077 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -84,18 +84,20 @@ bool g_elf_format_get_section_range_by_name(const GElfFormat *, const char *, mr
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+* unused = adresse non utilisée ici. *
+* key = identifiant de format trouvé ou NULL. [OUT] *
* *
* Description : Indique si le format peut être pris en charge ici. *
* *
-* Retour : Désignation du format reconnu ou NULL si aucun. *
+* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *elf_is_matching(GBinContent *content, GExeFormat *parent)
+FormatMatchStatus elf_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key)
{
- const char *result; /* Format détecté à renvoyer */
+ FormatMatchStatus result; /* Bilan à renvoyer */
vmpa2t addr; /* Tête de lecture initiale */
bool status; /* Bilan des accès mémoire */
char magic[4]; /* Idenfiant standard */
@@ -106,7 +108,13 @@ const char *elf_is_matching(GBinContent *content, GExeFormat *parent)
status &= (memcmp(magic, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0);
- result = status ? "elf" : NULL;
+ if (status)
+ {
+ result = FMS_MATCHED;
+ *key = strdup("elf");
+ }
+ else
+ result = FMS_UNKNOWN;
return result;
diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h
index 8e9a2cc..a557927 100644
--- a/src/format/elf/elf.h
+++ b/src/format/elf/elf.h
@@ -31,8 +31,7 @@
#include "elf_def.h"
-#include "../executable.h"
-#include "../format.h"
+#include "../../core/formats.h"
@@ -51,7 +50,7 @@ typedef struct _GElfFormatClass GElfFormatClass;
/* Indique si le format peut être pris en charge ici. */
-const char *elf_is_matching(GBinContent *, GExeFormat *);
+FormatMatchStatus elf_is_matching(GBinContent *, GExeFormat *, void *, char **);
/* Indique le type défini pour un format d'exécutable ELF. */
GType g_elf_format_get_type(void);
diff --git a/src/format/executable-int.h b/src/format/executable-int.h
index 704466e..f5a25b5 100644
--- a/src/format/executable-int.h
+++ b/src/format/executable-int.h
@@ -62,6 +62,9 @@ struct _GExeFormat
{
GBinFormat parent; /* A laisser en premier */
+ GDbgFormat **debugs; /* Informations de débogage */
+ size_t debugs_count; /* Nombre de ces informations */
+
get_target_machine_fc get_machine; /* Architecture ciblée */
refine_portions_fc refine_portions; /* Décrit les portions binaires*/
diff --git a/src/format/executable.c b/src/format/executable.c
index aae182a..5ff773c 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -84,6 +84,84 @@ static void g_executable_format_init(GExeFormat *format)
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à compléter. *
+* info = informations de débogage à lier. *
+* *
+* Description : Rajoute des informations de débogage à un exécutable. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_exe_format_add_debug_info(GExeFormat *format, GDbgFormat *info)
+{
+ /* Ajout dans la liste */
+
+ format->debugs = (GDbgFormat **)realloc(format->debugs,
+ ++format->debugs_count * sizeof(GDbgFormat *));
+
+ format->debugs[format->debugs_count - 1] = info;
+
+ /* Intégration des symboles */
+
+ /* TODO */
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* *
+* Description : Compte le nombre de formats de débogage liés à l'exécutable. *
+* *
+* Retour : Nombre de formats de débogage attachés. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_exe_format_count_debug_info(const GExeFormat *format)
+{
+ return format->debugs_count;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* index = indice des informations à transmettre. *
+* *
+* Description : Fournit un format de débogage attaché à l'exécutable. *
+* *
+* Retour : Informations de débogage attachées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbgFormat *g_exe_format_get_debug_info(const GExeFormat *format, size_t index)
+{
+ GDbgFormat *result; /* Format à retourner */
+
+ if (index >= format->debugs_count)
+ result = NULL;
+
+ else
+ {
+ result = format->debugs[index];
+ g_object_ref(G_OBJECT(result));
+ }
+
+ return result;
+
+}
+
diff --git a/src/format/executable.h b/src/format/executable.h
index 45c736b..48a8139 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -28,6 +28,7 @@
#include <glib-object.h>
+#include "debuggable.h"
#include "../glibext/gbinportion.h"
@@ -52,6 +53,14 @@ typedef struct _GExeFormatClass GExeFormatClass;
GType g_executable_format_get_type(void);
+/* Rajoute des informations de débogage à un exécutable. */
+void g_exe_format_add_debug_info(GExeFormat *, GDbgFormat *);
+
+/* Compte le nombre de formats de débogage liés à l'exécutable. */
+size_t g_exe_format_count_debug_info(const GExeFormat *);
+
+/* Fournit un format de débogage attaché à l'exécutable. */
+GDbgFormat *g_exe_format_get_debug_info(const GExeFormat *, size_t);
/* Indique le type d'architecture visée par le format. */
diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c
index a68b137..6b7e6b4 100644
--- a/src/gui/menus/project.c
+++ b/src/gui/menus/project.c
@@ -32,7 +32,7 @@
#include "../editem-int.h"
-#include "../../analysis/binaries/file.h"
+#include "../../analysis/contents/file.h"
#include "../../dialogs/shellcode.h"
#include "../../gtkext/easygtk.h"
@@ -270,7 +270,7 @@ static void mcb_project_add_binary_file(GtkMenuItem *menuitem, GMenuBar *bar)
GtkWidget *dialog; /* Boîte à afficher */
char *dir; /* Répertoire courant */
gchar *filename; /* Nom du fichier à intégrer */
- GLoadedBinary *binary; /* Représentation chargée */
+ GBinContent *content; /* Contenu binaire à charger */
dialog = gtk_file_chooser_dialog_new(_("Open a binary file"),
GTK_WINDOW(G_EDITOR_ITEM(bar)->ref),
@@ -299,14 +299,9 @@ static void mcb_project_add_binary_file(GtkMenuItem *menuitem, GMenuBar *bar)
{
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- binary = g_file_binary_new_from_file(filename);
+ content = g_file_content_new(filename);
- if (binary != NULL)
- {
- g_signal_connect(binary, "disassembly-done",
- G_CALLBACK(g_study_project_add_loaded_binary), get_current_project());
- g_loaded_binary_analyse(binary);
- }
+ qck_study_new_content(content, PCS_ROOT);
g_free(filename);
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index acaf735..f786c08 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -39,37 +39,40 @@
/* Prend acte du [dé]chargement du greffon. */
typedef bool (* pg_management_fc) (GPluginModule *, GObject *);
+/* Exécute une action pendant un désassemblage de binaire. */
+typedef void (* pg_process_disassembly_fc) (const GPluginModule *, PluginAction, GLoadedBinary *);
+
+
+
+
/* Indique si le format peut être pris en charge ici. */
-typedef bool (* pg_format_is_matching) (const GPluginModule *, GBinContent **);
+//typedef bool (* pg_format_is_matching) (const GPluginModule *, GBinContent **);
/* Procède à une opération liée au format de fichier uniquement. */
typedef bool (* pg_handle_format) (const GPluginModule *, PluginAction, GBinFormat *);
-/* Exécute une action pendant un désassemblage de binaire. */
-typedef void (* pg_process_disassembly) (const GPluginModule *, PluginAction, GLoadedBinary *);
-
/* Précise le nom associé au greffon. */
-typedef char * (* get_plugin_name_fc) (void);
+//typedef char * (* get_plugin_name_fc) (void);
/* Procède à l'initialisation du greffon. */
-typedef bool (* init_plugin_fc) (GPluginModule *, GObject *);
+//typedef bool (* init_plugin_fc) (GPluginModule *, GObject *);
/* Procède à l'extinction du greffon. */
-typedef void (* exit_plugin_fc) (GPluginModule *);
+//typedef void (* exit_plugin_fc) (GPluginModule *);
/* Fournit une indication sur le type d'opération(s) menée(s). */
-typedef PluginAction (* get_plugin_action_fc) (const GPluginModule *);
+//typedef PluginAction (* get_plugin_action_fc) (const GPluginModule *);
/* Identifie un format à associer à un contenu binaire. */
//typedef MatchingFormatAction (* is_matching_fc) (const GPluginModule *, char **, bin_t **, off_t *);
/* Exécute une action définie sur un binaire chargé. */
-typedef bool (* execute_action_on_binary_fc) (const GPluginModule *, GLoadedBinary *, PluginAction);
+//typedef bool (* execute_action_on_binary_fc) (const GPluginModule *, GLoadedBinary *, PluginAction);
/* Exécute une action relative à un débogueur. */
//typedef bool (* execute_on_debugger_fc) (const GPluginModule *, GBinaryDebugger *, PluginAction);
@@ -88,6 +91,7 @@ struct _GPluginModule
pg_management_fc init; /* Procédure d'initialisation */
pg_management_fc exit; /* Procédure d'extinction */
+ pg_process_disassembly_fc process_disass; /* Catégorie 'désassemblage' */
//char *name; /* Nom associé au greffon */
@@ -95,18 +99,17 @@ struct _GPluginModule
//init_plugin_fc init; /* Procédure d'initialisation */
//exit_plugin_fc exit; /* Procédure d'extinction */
- get_plugin_action_fc get_action; /* Opération(s) menée(s) */
+ //get_plugin_action_fc get_action; /* Opération(s) menée(s) */
//is_matching_fc is_matching; /* Recherche de correspondance */
- execute_action_on_binary_fc exec_on_bin;/* Action sur un binaire */
+ //execute_action_on_binary_fc exec_on_bin;/* Action sur un binaire */
//execute_on_debugger_fc handle_debugger; /* Action liée à un débogueur */
- pg_format_is_matching is_matching; /* Recherche de correspondance */
+ //pg_format_is_matching is_matching; /* Recherche de correspondance */
pg_handle_format handle_format; /* Manipulation du format */
- pg_process_disassembly proc_disass; /* Catégorie 'désassemblage' */
};
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 9322bcb..c0e9fd1 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -37,6 +37,9 @@
#include "plugin-int.h"
+#include "../core/formats.h"
+
+
/* Initialise la classe des greffons. */
static void g_plugin_module_class_init(GPluginModuleClass *);
@@ -162,8 +165,10 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
GPluginModule *result; /* Structure à retourner */
plugin_abi_version_t current; /* Version de l'ABI actuelle */
size_t i; /* Boucle de parcours */
+ uint32_t action; /* Identifiant d'une action */
uint32_t category; /* Catégorie principale */
uint32_t sub; /* Sous-catégorie visée */
+ format_match_fc matcher; /* Routine de reconnaissance */
result = g_object_new(G_TYPE_PLUGIN_MODULE, NULL);
@@ -215,8 +220,9 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
for (i = 0; i < result->interface->actions_count; i++)
{
- category = MASK_PLUGIN_CATEGORY(result->interface->actions[i]);
- sub = MASK_PLUGIN_SUB_CATEGORY(result->interface->actions[i]);
+ action = result->interface->actions[i];
+ category = MASK_PLUGIN_CATEGORY(action);
+ sub = MASK_PLUGIN_SUB_CATEGORY(action);
switch (category)
{
@@ -254,8 +260,18 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
{
case DPS_FORMAT:
- switch (result->interface->actions[i])
+ switch (action)
{
+ case PGA_FORMAT_MATCHER:
+
+ if (!load_plugin_symbol(result->module,
+ "is_format_matching", &matcher))
+ goto bad_plugin;
+
+ if (!register_format_matcher(matcher, result))
+ goto bad_plugin;
+
+ break;
case PGA_FORMAT_LOADER_LAST:
if (!load_plugin_symbol(result->module,
@@ -275,7 +291,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
case DPS_DISASSEMBLY:
if (!load_plugin_symbol(result->module,
- "process_binary_disassembly", &result->proc_disass))
+ "process_binary_disassembly", &result->process_disass))
goto bad_plugin;
break;
@@ -504,6 +520,6 @@ bool g_plugin_module_handle_binary_format(const GPluginModule *plugin, PluginAct
void g_plugin_module_process_disassembly_event(const GPluginModule *plugin, PluginAction action, GLoadedBinary *binary)
{
- plugin->proc_disass(plugin, action, binary);
+ plugin->process_disass(plugin, action, binary);
}