summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2011-10-01 17:20:50 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2011-10-01 17:20:50 (GMT)
commit02cb3aa4e7b18b644b034a5c659c332becf99c9b (patch)
tree8d816e5f93820c6ef5ba804d7c0776a65d78329a
parente0266175537ec220544c050874be215b11c902fa (diff)
Defined the first real [python] plugin.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@210 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog36
-rw-r--r--plugins/pyoida/plugin.c250
-rw-r--r--plugins/pyoida/plugin.h2
-rw-r--r--plugins/pyoida/pyoida.c118
-rw-r--r--plugins/python/apkfiles/__init__.py2
-rw-r--r--plugins/python/apkfiles/apkfiles.py34
-rw-r--r--src/analysis/binary.c41
-rw-r--r--src/common/environment.c2
-rwxr-xr-xsrc/format/dex/dex.c2
-rw-r--r--src/format/format.c54
-rw-r--r--src/format/format.h2
-rw-r--r--src/gtkext/gtksourceview.c3
-rw-r--r--src/plugins/plugin-def.h27
-rw-r--r--src/plugins/plugin-int.h12
-rw-r--r--src/plugins/plugin.c81
-rw-r--r--src/plugins/plugin.h6
16 files changed, 622 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 565f288..b2b399e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+11-10-01 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/pyoida/plugin.c:
+ * plugins/pyoida/plugin.h:
+ Properly load a Python plugin and define some needed functions
+ for format recognition.
+
+ * plugins/pyoida/pyoida.c:
+ Browse directories for finding Python plugins.
+
+ * plugins/python/apkfiles/apkfiles.py:
+ * plugins/python/apkfiles/__init__.py:
+ New entries: define the first real [python] plugin.
+
+ * src/analysis/binary.c:
+ Start to update call to load_new_format().
+
+ * src/common/environment.c:
+ Fix a bug when getting an environment variable.
+
+ * src/format/dex/dex.c:
+ Dummy fix.
+
+ * src/format/format.c:
+ * src/format/format.h:
+ Load formats usings plugins too.
+
+ * src/gtkext/gtksourceview.c:
+ Dummy fix.
+
+ * src/plugins/plugin.c:
+ * src/plugins/plugin-def.h:
+ * src/plugins/plugin.h:
+ * src/plugins/plugin-int.h:
+ Update interfaces for plugins (mainly those which are looking for formats).
+
11-07-11 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
diff --git a/plugins/pyoida/plugin.c b/plugins/pyoida/plugin.c
index 23934a9..e652949 100644
--- a/plugins/pyoida/plugin.c
+++ b/plugins/pyoida/plugin.c
@@ -46,6 +46,7 @@ struct _GPythonPlugin
GPluginModule parent; /* Instance parente */
PyObject *module; /* Script Python chargé */
+ PyObject *instance; /* Instance Python du greffon */
};
@@ -64,6 +65,12 @@ static void g_python_plugin_class_init(GPythonPluginClass *);
/* Initialise l'instance d'un greffon Python. */
static void g_python_plugin_init(GPythonPlugin *);
+/* 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(GPythonPlugin *, GOpenidaBinary *, PluginAction);
@@ -94,7 +101,11 @@ static PyObject *pyoida_plugin_run(PyObject *, PyObject *);
/* Définit les constantes pour les greffons en Python. */
static bool pyoida_plugin_define_constants(PyObject *);
+/* Définit le comportement par défaut d'un greffon Python. */
+static PyObject *pyoida_plugin_get_action(PyObject *, PyObject *);
+/* Définit l'issue de la recherche d'un format par défaut. */
+static PyObject *pyoida_plugin_is_matching(PyObject *, PyObject *);
@@ -260,7 +271,8 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args
/******************************************************************************
* *
-* Paramètres : filename = chemin d'accès au code Python à charger. *
+* Paramètres : modname = nom du module à charger. *
+* filename = chemin d'accès au code Python à charger. *
* *
* Description : Crée un greffon à partir de code Python. *
* *
@@ -270,18 +282,20 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args
* *
******************************************************************************/
-GPluginModule *g_python_plugin_new(const char *filename)
+GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
{
GPythonPlugin *result; /* Structure à retourner */
PyObject *name; /* Chemin d'accès pour Python */
PyObject *module; /* Script Python chargé */
+ PyObject *dict; /* Dictionnaire associé */
+ PyObject *class; /* Classe à instancier */
+ PyObject *instance; /* Instance Python du greffon */
#if PY_VERSION_HEX >= 0x03000000
name = PyUnicode_FromString(filename);
#else
name = PyString_FromString(filename);
#endif
- name = PyString_FromString/*PyUnicode_FromString*/(filename);
if (name == NULL) goto gppn_bad_exit;
module = PyImport_Import(name);
@@ -293,20 +307,37 @@ GPluginModule *g_python_plugin_new(const char *filename)
goto gppn_bad_exit;
}
+ dict = PyModule_GetDict(module);
+ class = PyDict_GetItemString(dict, modname);
+ Py_DECREF(dict);
+ if (class == NULL) goto gppn_no_class;
+ if (!PyType_Check(class->ob_type)) goto gppn_no_class;
- //Py_DECREF(module);
-
+ instance = PyObject_CallFunction(class, NULL);
+ if (instance == NULL) goto gppn_no_instance;
+ Py_DECREF(class);
result = g_object_new(G_TYPE_PYTHON_PLUGIN, NULL);
- G_PLUGIN_MODULE(result)->action = PGA_CODE_PROCESS;
+ G_PLUGIN_MODULE(result)->get_action = g_python_plugin_get_action;
+
+ G_PLUGIN_MODULE(result)->is_matching = g_python_plugin_is_matching;
result->module = module;
+ result->instance = instance;
return G_PLUGIN_MODULE(result);
+ gppn_no_instance:
+
+ Py_DECREF(class);
+
+ gppn_no_class:
+
+ Py_DECREF(module);
+
gppn_bad_exit:
return NULL;
@@ -317,6 +348,138 @@ GPluginModule *g_python_plugin_new(const char *filename)
/******************************************************************************
* *
* Paramètres : plugin = greffon de prise en charge à utiliser. *
+* *
+* Description : Indique l'utilité pratique du greffon. *
+* *
+* Retour : Action(s) codifiée(s), PGA_NONE par défaut. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PluginAction g_python_plugin_get_action(const GPythonPlugin *plugin)
+{
+ PluginAction result; /* Valeur à retourner */
+ PyObject *value; /* Valeur obtenue */
+
+ value = run_python_method(plugin->instance, "get_action", NULL);
+
+ result = PyLong_AsLong(value);
+ Py_DECREF(value);
+
+ 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)
+{
+ MatchingFormatAction result; /* Valeur à retourner */
+ 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 */
+
+ if (*filename == NULL)
+ return MFA_NONE;
+
+ args = PyTuple_New(2);
+
+ PyTuple_SetItem(args, 0, PyString_FromString(*filename));
+ PyTuple_SetItem(args, 1, PyByteArray_FromStringAndSize(*data, *length));
+
+ value = run_python_method(plugin->instance, "is_matching", args);
+
+ if (value != NULL && PyTuple_Check(value) && PyTuple_Size(value) == 3)
+ {
+ 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)
+ *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)
+ *filename = NULL;
+
+ /**
+ * Pareil que précédemment.
+ */
+ if (new_data != Py_None)
+ {
+ tmp = PyByteArray_AsString(new_data);
+ *length = PyByteArray_Size(new_data);
+
+ *data = (bin_t *)calloc(*length, sizeof(bin_t));
+ memcpy(*data, tmp, *length * sizeof(bin_t));
+
+ }
+
+ goto is_matching_ok;
+
+ }
+
+ is_matching_bad:
+
+ printf("<LOG>Bad result from is_matching() plugin function.\n");
+
+ result = MFA_NONE;
+
+ is_matching_ok:
+
+ Py_XDECREF(value);
+ Py_DECREF(args);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon de prise en charge à utiliser. *
* binary = représentation binaire à traiter. *
* action = action attendue. *
* *
@@ -421,12 +584,29 @@ static bool pyoida_plugin_define_constants(PyObject *dict)
{
int ret; /* Bilan d'un ajout */
+ ret = PyDict_SetItemString(dict, "PGA_NONE", PyInt_FromLong(PGA_NONE));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "PGA_FORMAT_MATCHER", PyInt_FromLong(PGA_FORMAT_MATCHER));
+ if (ret == -1) return false;
+
ret = PyDict_SetItemString(dict, "PGA_DISASSEMBLE", PyInt_FromLong(PGA_DISASSEMBLE));
if (ret == -1) return false;
ret = PyDict_SetItemString(dict, "PGA_CODE_PROCESS", PyInt_FromLong(PGA_CODE_PROCESS));
if (ret == -1) return false;
+ /* PGA_FORMAT_MATCHER */
+
+ ret = PyDict_SetItemString(dict, "MFA_NONE", PyInt_FromLong(MFA_NONE));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "MFA_MATCHED", PyInt_FromLong(MFA_MATCHED));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "MFA_RELOAD", PyInt_FromLong(MFA_RELOAD));
+ if (ret == -1) return false;
+
return true;
}
@@ -437,6 +617,58 @@ static bool pyoida_plugin_define_constants(PyObject *dict)
* Paramètres : self = classe assurant le lien avec l'éditeur de messages. *
* args = arguments fournis à l'appel. *
* *
+* Description : Définit le comportement par défaut d'un greffon Python. *
+* *
+* Retour : Rien en équivalent Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *pyoida_plugin_get_action(PyObject *self, PyObject *args)
+{
+ return PyInt_FromLong(PGA_NONE);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe assurant le lien avec l'éditeur de messages. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Définit l'issue de la recherche d'un format par défaut. *
+* *
+* Retour : Rien en équivalent Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *pyoida_plugin_is_matching(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Liste à retourner */
+
+ result = PyTuple_New(3);
+
+ PyTuple_SetItem(result, 0, PyInt_FromLong(MFA_NONE));
+ PyTuple_SetItem(result, 1, Py_None);
+ PyTuple_SetItem(result, 2, Py_None);
+
+ return result;
+
+}
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe assurant le lien avec l'éditeur de messages. *
+* args = arguments fournis à l'appel. *
+* *
* Description : Exécute une action valide pour le greffon Python. *
* *
* Retour : Rien en équivalent Python. *
@@ -474,6 +706,12 @@ bool add_plugin_to_python_module(PyObject *module)
static PyMethodDef pyoida_plugin_methods[] = {
+ { "get_action", (PyCFunction)pyoida_plugin_get_action, METH_NOARGS,
+ "Register the plugin for given actions."
+ },
+ { "is_matching", (PyCFunction)pyoida_plugin_is_matching, METH_VARARGS,
+ "Define if the given file can be handled."
+ },
{ "run", (PyCFunction)pyoida_plugin_run, METH_VARARGS,
"Run the plugin for a specific action."
},
diff --git a/plugins/pyoida/plugin.h b/plugins/pyoida/plugin.h
index f5d4ab4..b8b76d9 100644
--- a/plugins/pyoida/plugin.h
+++ b/plugins/pyoida/plugin.h
@@ -60,7 +60,7 @@ typedef struct _GPythonPluginClass GPythonPluginClass;
GType g_python_plugin_get_type(void);
/* Crée un greffon à partir de code Python. */
-GPluginModule *g_python_plugin_new(const char *);
+GPluginModule *g_python_plugin_new(const char *, const char *);
diff --git a/plugins/pyoida/pyoida.c b/plugins/pyoida/pyoida.c
index 4a79bfd..be75b7c 100644
--- a/plugins/pyoida/pyoida.c
+++ b/plugins/pyoida/pyoida.c
@@ -24,6 +24,10 @@
#include "pyoida.h"
+#include <config.h>
+#include <dirent.h>
+
+
#include <Python.h>
@@ -69,6 +73,7 @@ static PyMethodDef SpamMethods[] = {
+static PyObject *__mod;
/******************************************************************************
@@ -85,17 +90,37 @@ static PyMethodDef SpamMethods[] = {
bool init_plugin(GObject *ref)
{
+ char *paths; /* Emplacements de greffons */
+ char *path; /* Chemin à fouiller */
+ char *save; /* Sauvegarde pour ré-entrance */
+ DIR *dir; /* Répertoire à parcourir */
+ struct dirent entry; /* Elément trouvé */
+ struct dirent *next; /* Prochain élément fourni */
+ int ret; /* Bilan d'un appel système */
+ char *filename; /* Chemin d'accès reconstruit */
+
+
+
+
GPluginModule *plugin;
- int ret;
+
+
printf("Init pyoida\n");
_ref = ref;
- add_to_env_var("PYTHONPATH", "/home/ocb/prog/openida/plugins/python", ";");
+
+ /* Définition des zones d'influence */
+
+ add_to_env_var("PYTHONPATH", PLUGINS_DIR G_DIR_SEPARATOR_S "python", ";");
+
+ paths = get_env_var("PYTHONPATH");
+
+ /* Intialisations Python */
- return false;
+ //return false;
Py_Initialize();
@@ -104,33 +129,92 @@ bool init_plugin(GObject *ref)
+ /* Chargement des greffons */
- plugin = g_python_plugin_new("lnxsyscalls/lnxsyscalls");
- add_plugin_to_main_list(plugin);
+ printf("Paths :: '%s'\n", paths);
+ for (path = strtok_r(paths, ";", &save);
+ path != NULL;
+ path = strtok_r(NULL, ";", &save))
+ {
+ dir = opendir(path);
+ if (dir == NULL)
+ {
+ perror("opendir");
+ continue;
+ }
+ printf("CHEMIN :: '%s'\n", path);
-#if 0
+ for (ret = readdir_r(dir, &entry, &next);
+ ret == 0 && next != NULL;
+ ret = readdir_r(dir, &entry, &next))
+ {
+ if (entry.d_name[0] == '.') continue;
-#if 0
- //main2("/home/ocb/prog/openida/plugins/pyoida/lnxsyscalls/lnxsyscalls.py", "get_instance");
- main2("lnxsyscalls", "get_instance");
-#else
- //main2("/home/ocb/prog/openida/plugins/pyoida/lnxsyscalls/lnxsyscalls.py", "get_instance");
- main2("lnxsyscalls/lnxsyscalls", "get_instance");
-#endif
+ filename = strdup(entry.d_name);
+ filename = stradd(filename, ".");
+ filename = stradd(filename, "__init__");
-#endif
+ printf(" - entry :: '%s'\n", filename);
- //Py_Finalize();
- //exit(-1);
+ plugin = g_python_plugin_new(entry.d_name, filename);
+
+ if (plugin == NULL)
+ printf("No suitable Python plugin found in '%s'\n", filename); /* FIXME : LOG(...) */
+ else
+ {
+ printf("ok pour %s\n", filename);
+ add_plugin_to_main_list(plugin);
+ }
+
+ free(filename);
+
+ }
+
+ closedir(dir);
+
+ break; /* FIXME */
+
+ }
+
+ //Py_Finalize();
return true;
}
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à consulter. *
+* *
+* Description : Indique les opérations offertes par un greffon donné. *
+* *
+* Retour : Action(s) offerte(s) par le greffon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PluginAction get_plugin_action(const GPluginModule *plugin)
+{
+ PluginAction result; /* Combinaison à retourner */
+
+ result = PGA_NONE;
+
+
+
+
+ return result;
+
+}
+
+
+
+
+
#if PY_VERSION_HEX >= 0x03000000
/* Python 3.x code */
@@ -169,6 +253,8 @@ initpyoida(void)
printf("Passage 2\n");
module = Py_InitModule("pyoida", SpamMethods);
+ __mod = module;
+
//add_analysis_roptions_to_python_module(module);
add_analysis_module_to_python_module(module);
add_arch_module_to_python_module(module);
diff --git a/plugins/python/apkfiles/__init__.py b/plugins/python/apkfiles/__init__.py
new file mode 100644
index 0000000..2ebf824
--- /dev/null
+++ b/plugins/python/apkfiles/__init__.py
@@ -0,0 +1,2 @@
+
+from apkfiles import ApkFiles as apkfiles
diff --git a/plugins/python/apkfiles/apkfiles.py b/plugins/python/apkfiles/apkfiles.py
new file mode 100644
index 0000000..fe7deb8
--- /dev/null
+++ b/plugins/python/apkfiles/apkfiles.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from pyoida import Plugin
+
+import zipfile
+
+
+class ApkFiles(Plugin):
+ """Open and process APK files."""
+
+ def get_action(self):
+ """Register the plugin for given actions."""
+
+ return Plugin.PGA_FORMAT_MATCHER
+
+ def is_matching(self, filename, data):
+ """Define if the given file can be handled."""
+
+ if not zipfile.is_zipfile(filename):
+ return Plugin.MFA_NONE, None, None
+
+ zf = zipfile.ZipFile(filename)
+
+ if zf.namelist().count('classes.dex') > 0:
+
+ f = zf.open('classes.dex', 'r')
+ data = f.read()
+ f.closed
+
+ return Plugin.MFA_RELOAD, None, bytearray(data)
+
+ else:
+ return Plugin.MFA_NONE, None, None
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 15be43e..f5ff3fb 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -365,17 +365,56 @@ static void g_openida_binary_init(GOpenidaBinary *binary)
GOpenidaBinary *g_openida_binary_new_from_file(const char *filename)
{
GOpenidaBinary *result; /* Adresse à retourner */
+ GPluginModule **pglist; /* Liste de greffons */
+ size_t pgcount; /* Taille de cette liste */
+ size_t i; /* Boucle de parcours */
+
+
+ char *file = strdup(filename);
result = g_object_new(G_TYPE_OPENIDA_BINARY, NULL);
+
+
+
+ printf("%s\n", filename);
+
+
+
+ pglist = get_all_plugins_for_action(PGA_FORMAT_MATCHER, &pgcount);
+
+ if (pgcount > 0)
+ {
+ printf("===>>>> FOUND :: %d\n", pgcount);
+
+
+ /*
+ for (i = 0; i < pgcount; i++)
+ g_plugin_module_execute_action_on_binary(pglist[i], binary, PGA_CODE_PROCESS);
+ */
+ free(pglist);
+
+ }
+
+
+
+
+
+
+
+
+
log_variadic_message(LMT_PROCESS, _("Opening '%s' file..."), filename);
result->filename = strdup(filename);
+ /*
result->bin_data = map_binary_file(filename, &result->bin_length);
if (result->bin_data == NULL) goto lbf_error;
+ */
- result->format = G_EXE_FORMAT(load_new_format(FMT_EXEC, result->bin_data, result->bin_length));
+ result->format = G_EXE_FORMAT(load_new_format(FMT_EXEC, file,
+ &result->bin_data, &result->bin_length));
if (result->format == NULL)
{
log_simple_message(LMT_INFO, _("Unknown binary format"));
diff --git a/src/common/environment.c b/src/common/environment.c
index a0fa568..633d3e2 100644
--- a/src/common/environment.c
+++ b/src/common/environment.c
@@ -52,7 +52,7 @@ char *get_env_var(const char *name)
result = getenv(name);
if (result == NULL) result = strdup("");
- else result = strdup(name);
+ else result = strdup(result);
return result;
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index 174bd2b..287c9ea 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -224,6 +224,8 @@ static void g_dex_format_find_all_sources(GDexFormat *format)
bf = G_BIN_FORMAT(format);
+ return; /* FIXME */
+
for (i = 0; i < format->classes_count; i++)
{
source = g_dex_class_get_source_file(format->classes[i], format);
diff --git a/src/format/format.c b/src/format/format.c
index 053a7aa..8e1d864 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -35,6 +35,7 @@
#include "pe/pe.h"
#include "../decomp/expr/block.h"
#include "../panels/log.h"
+#include "../plugins/pglist.h"
@@ -497,9 +498,10 @@ bool init_all_formats(void)
/******************************************************************************
* *
-* Paramètres : type = type de format recherché. *
-* content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
+* Paramètres : type = type de format recherché. *
+* filename = fichier d'origine des données initiales. *
+* content = contenu binaire à parcourir. [OUT] *
+* length = taille du contenu en question. [OUT] *
* *
* Description : Charge si possible un nouveau format binaire. *
* *
@@ -509,22 +511,62 @@ bool init_all_formats(void)
* *
******************************************************************************/
-GBinFormat *load_new_format(FormatType type, const uint8_t *content, off_t length)
+GBinFormat *load_new_format(FormatType type, char *filename, bin_t **content, off_t *length)
{
GBinFormat *result; /* Adresse à retourner */
+ GPluginModule **pglist; /* Liste de greffons */
+ size_t pgcount; /* Taille de cette liste */
size_t i; /* Boucle de parcours */
result = NULL;
+ printf("analysing... %s\n", filename);
+
+
+
+ pglist = get_all_plugins_for_action(PGA_FORMAT_MATCHER, &pgcount);
+
+ if (pgcount > 0)
+ {
+ lnf_rescan:
+
+ for (i = 0; i < pgcount; i++)
+ switch (g_plugin_module_is_matching(pglist[i], &filename, content, length))
+ {
+ case MFA_MATCHED:
+ /* FIXME */
+ break;
+
+ case MFA_RELOAD:
+ //goto lnf_rescan;
+ break;
+
+ default:
+ break;
+
+ }
+
+ free(pglist);
+
+ }
+
+
+
for (i = 0; i < FID_COUNT && result == NULL; i++)
- if (_formats[i].type == type && _formats[i].match(type, content, length))
+ if (_formats[i].type == type && _formats[i].match(type, *content, *length))
{
log_variadic_message(LMT_INFO, _("%s is matching..."), _formats[i].name);
- result = _formats[i].load(content, length);
+ result = _formats[i].load(*content, *length);
}
+
+
+ printf("FINAL FORMAT :: %p\n", result);
+
+ //exit(0);
+
return result;
}
diff --git a/src/format/format.h b/src/format/format.h
index dd05dd2..7f0b649 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -121,7 +121,7 @@ typedef GBinFormat * (* format_load_fc) (const bin_t *, off_t);
bool init_all_formats(void);
/* Charge si possible un nouveau format binaire. */
-GBinFormat *load_new_format(FormatType, const uint8_t *, off_t);
+GBinFormat *load_new_format(FormatType, char *filename, bin_t **, off_t *);
diff --git a/src/gtkext/gtksourceview.c b/src/gtkext/gtksourceview.c
index 33b61c5..5dea05f 100644
--- a/src/gtkext/gtksourceview.c
+++ b/src/gtkext/gtksourceview.c
@@ -149,6 +149,9 @@ static void gtk_source_view_attach_binary(GtkSourceView *view, GOpenidaBinary *b
buffer = g_openida_binary_get_decompiled_buffer(binary, -1);
+ /* FIXME */
+ if (buffer != NULL)
+
gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), buffer);
}
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index 50b8df2..43ec28e 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -42,9 +42,13 @@ typedef enum _PluginType
/* Action(s) menée(s) par le greffon */
typedef enum _PluginAction
{
- PGA_DISASSEMBLE = (1 << 0), /* Désassemblage (non trivial) */
+ PGA_NONE = (0 << 0), /* Aucun intérêt */
- PGA_CODE_PROCESS = (1 << 1) /* Traitement du code existant */
+ PGA_FORMAT_MATCHER = (1 << 0), /* Détection et chargement */
+
+ PGA_DISASSEMBLE = (1 << 1), /* Désassemblage (non trivial) */
+
+ PGA_CODE_PROCESS = (1 << 2) /* Traitement du code existant */
} PluginAction;
@@ -54,11 +58,28 @@ typedef enum _PluginAction
typedef PluginType (* get_plugin_type_fc) (void);
/* Fournit une indication sur le type d'opération(s) menée(s). */
-typedef PluginAction (* get_plugin_action_fc) (void);
+//typedef PluginAction (* get_plugin_action_fc) (void);
/* Exécute une action définie sur un binaire chargé. */
typedef bool (* execute_action_on_binary_fc) (GOpenidaBinary *, PluginAction);
+/* PGA_FORMAT_MATCHER */
+
+/* Bilans d'une reconnaissance */
+typedef enum _MatchingFormatAction
+{
+ MFA_NONE, /* Aucune détection */
+ MFA_MATCHED, /* Format reconnu */
+ MFA_RELOAD, /* Rechargemet opéré */
+
+ MFA_COUNT
+
+} MatchingFormatAction;
+
+
+
+
+
#endif /* _PLUGINS_PLUGIN_DEF_H */
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 929dbf9..a0b5758 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -36,6 +36,11 @@
/* Procède à l'initialisation du greffon */
typedef bool (* init_plugin_fc) (GObject *);
+/* Fournit une indication sur le type d'opération(s) menée(s). */
+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 *);
/* Greffon pour OpenIDA (instance) */
@@ -46,9 +51,11 @@ struct _GPluginModule
GModule *module; /* Abstration de manipulation */
PluginType type; /* Type(s) du greffon */
- PluginAction action; /* Opération(s) menée(s) */
init_plugin_fc init; /* Procédure d'initialisation */
+ 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 */
@@ -66,6 +73,9 @@ struct _GPluginModuleClass
+
+
+
/* Ajoute un greffon à la liste principale de greffons. */
void add_plugin_to_main_list(GPluginModule *);
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 2443768..ce8ef37 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -99,7 +99,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
{
GPluginModule *result; /* Structure à retourner */
get_plugin_action_fc __get_type; /* Type(s) de greffon */
- get_plugin_action_fc __get_action; /* Actions du greffon */
+ get_plugin_action_fc get_action; /* Actions du greffon */
result = g_object_new(G_TYPE_PLUGIN_MODULE, NULL);
@@ -107,6 +107,21 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
result->module = g_module_open(filename, G_MODULE_BIND_LAZY);
+ if (!result->module)
+ {
+ printf("err null mod\n");
+ return NULL;
+
+ }
+
+
+ if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init))
+ {
+ printf("Err plugin init sym\n");
+ /* TODO */
+ }
+
+ /*
if (!g_module_symbol(result->module, "get_plugin_type", (gpointer *)&__get_type))
@@ -119,20 +134,20 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
printf("Plugin type :: 0x%08x\n", result->type);
+ */
-
-#if 1
- if (!g_module_symbol(result->module, "get_plugin_action", (gpointer *)&__get_action))
+ if (!g_module_symbol(result->module, "get_plugin_action", (gpointer *)&get_action))
{
printf("Err plugin get_action sym\n");
//g_object_destroy(result);
return NULL;
}
- result->action = __get_action();
+ result->get_action = get_action;
+ /*
if (result->action & (PGA_DISASSEMBLE | PGA_CODE_PROCESS))
{
if (!g_module_symbol(result->module, "execute_action_on_binary", (gpointer *)&result->exec_on_bin))
@@ -144,14 +159,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
}
-#endif
-
-
- if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init))
- {
- printf("Err plugin init sym\n");
- /* TODO */
- }
+ */
@@ -188,11 +196,56 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
PluginAction g_plugin_module_get_action(const GPluginModule *plugin)
{
- return plugin->action;
+ return plugin->get_action(plugin);
+
+}
+
+
+/******************************************************************************
+* *
+* 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 : Identifie un format à associer à un contenu binaire. *
+* *
+* Retour : Bilan de la recherche de correspondances. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+MatchingFormatAction g_plugin_module_is_matching(const GPluginModule *plugin, char **filename, bin_t **data, off_t *length)
+{
+ MatchingFormatAction result; /* Valeur à retourner */
+ char *old_filename; /* Ancien nom de fichier */
+ bin_t *old_data; /* Ancien contenu binaire */
+
+ if (plugin->is_matching == NULL)
+ return MFA_NONE;
+
+ old_filename = *filename;
+ old_data = *data;
+
+ result = plugin->is_matching(plugin, filename, data, length);
+
+ if (result == MFA_RELOAD)
+ {
+ if (old_filename != NULL)
+ free(old_filename);
+ free(old_data);
+ }
+
+ return result;
}
+
+
+
+
/******************************************************************************
* *
* Paramètres : plugin = greffon à consulter. *
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index d17cee5..8df0e0e 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -57,9 +57,15 @@ GPluginModule *g_plugin_module_new(const gchar *, GObject *);
/* Indique les opérations offertes par un greffon donné. */
PluginAction g_plugin_module_get_action(const GPluginModule *);
+/* Identifie un format à associer à un contenu binaire. */
+MatchingFormatAction g_plugin_module_is_matching(const GPluginModule *, char **, bin_t **, off_t *);
+
/* Exécute une action définie sur un binaire chargé. */
bool g_plugin_module_execute_action_on_binary(const GPluginModule *, GOpenidaBinary *, PluginAction);
+
+
+
#endif /* _PLUGINS_PLUGIN_H */