diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/bootimg/format.c | 20 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/processor.c | 48 | ||||
-rw-r--r-- | plugins/pychrysalide/format/known.c | 427 | ||||
-rw-r--r-- | plugins/pychrysalide/plugin.c | 7 |
4 files changed, 438 insertions, 64 deletions
diff --git a/plugins/bootimg/format.c b/plugins/bootimg/format.c index 99b8f27..feeb9f7 100644 --- a/plugins/bootimg/format.c +++ b/plugins/bootimg/format.c @@ -48,10 +48,10 @@ static void g_bootimg_format_dispose(GBootImgFormat *); static void g_bootimg_format_finalize(GBootImgFormat *); /* Indique la désignation interne du format. */ -static const char *g_bootimg_format_get_name(const GBootImgFormat *); +static char *g_bootimg_format_get_key(const GBootImgFormat *); /* Fournit une description humaine du format. */ -static const char *g_bootimg_format_get_description(const GBootImgFormat *); +static char *g_bootimg_format_get_description(const GBootImgFormat *); /* Assure l'interprétation d'un format en différé. */ static bool g_bootimg_format_analyze(GBootImgFormat *, wgroup_id_t, GtkStatusStack *); @@ -116,7 +116,7 @@ static void g_bootimg_format_class_init(GBootImgFormatClass *klass) known = G_KNOWN_FORMAT_CLASS(klass); - known->get_name = (known_get_name_fc)g_bootimg_format_get_name; + known->get_key = (known_get_key_fc)g_bootimg_format_get_key; known->get_desc = (known_get_desc_fc)g_bootimg_format_get_description; known->analyze = (known_analyze_fc)g_bootimg_format_analyze; @@ -213,17 +213,17 @@ GBootImgFormat *g_bootimg_format_new(GBinContent *content) * * * Description : Indique la désignation interne du format. * * * -* Retour : Description du format. * +* Retour : Désignation du format. * * * * Remarques : - * * * ******************************************************************************/ -static const char *g_bootimg_format_get_name(const GBootImgFormat *format) +static char *g_bootimg_format_get_key(const GBootImgFormat *format) { - const char *result; /* Désignation à retourner */ + char *result; /* Désignation à retourner */ - result = "bootimg"; + result = strdup("bootimg"); return result; @@ -242,11 +242,11 @@ static const char *g_bootimg_format_get_name(const GBootImgFormat *format) * * ******************************************************************************/ -static const char *g_bootimg_format_get_description(const GBootImgFormat *format) +static char *g_bootimg_format_get_description(const GBootImgFormat *format) { - const char *result; /* Désignation à retourner */ + char *result; /* Description à retourner */ - result = "Android Boot Image"; + result = strdup("Android Boot Image"); return result; diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c index 557e7a7..71ef153 100644 --- a/plugins/pychrysalide/arch/processor.c +++ b/plugins/pychrysalide/arch/processor.c @@ -45,31 +45,6 @@ -#define ARCH_PROCESSOR_DOC \ - "The ArchProcessor object aims to get subclassed to create" \ - " processors for new architectures.\n" \ - "\n" \ - "Several items have to be defined as class attributes in the final" \ - " class:\n" \ - "* *_key*: a string providing a small name used to identify the" \ - " architecture;\n" \ - "* *_desc*: a string for a human readable description of the" \ - " new architecture;\n" \ - "* *_memory_size*: size of the memory space, as a" \ - " pychrysalide.analysis.BinContent.MemoryDataSize value;\n" \ - "* *_ins_min_size*: size of the smallest instruction, as a" \ - " pychrysalide.analysis.BinContent.MemoryDataSize value;\n" \ - "* *_virtual_space*: a boolean value indicating if the architecture"\ - " supports a virtual space.\n" \ - "\n" \ - "Calls to the *__init__* constructor of this abstract object expect"\ - " the following arguments as keyword parameters:\n" \ - "* *endianness*: endianness to apply to the binary content to" \ - " disassemble, as a pychrysalide.analysis.BinContent.SourceEndian" \ - " value.\n" - - - /* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ @@ -308,6 +283,29 @@ static int py_arch_processor_init(PyObject *self, PyObject *args, PyObject *kwds static char *kwlist[] = { "endianness", NULL }; +#define ARCH_PROCESSOR_DOC \ + "The ArchProcessor object aims to get subclassed to create" \ + " processors for new architectures.\n" \ + "\n" \ + "Several items have to be defined as class attributes in the final" \ + " class:\n" \ + "* *_key*: a string providing a small name used to identify the" \ + " architecture;\n" \ + "* *_desc*: a string for a human readable description of the" \ + " new architecture;\n" \ + "* *_memory_size*: size of the memory space, as a" \ + " pychrysalide.analysis.BinContent.MemoryDataSize value;\n" \ + "* *_ins_min_size*: size of the smallest instruction, as a" \ + " pychrysalide.analysis.BinContent.MemoryDataSize value;\n" \ + "* *_virtual_space*: a boolean value indicating if the architecture"\ + " supports a virtual space.\n" \ + "\n" \ + "Calls to the *__init__* constructor of this abstract object expect"\ + " the following arguments as keyword parameters:\n" \ + "* *endianness*: endianness to apply to the binary content to" \ + " disassemble, as a pychrysalide.analysis.BinContent.SourceEndian" \ + " value." + /* Récupération des paramètres */ ret = PyArg_ParseTupleAndKeywords(args, kwds, "I", kwlist, &endianness); diff --git a/plugins/pychrysalide/format/known.c b/plugins/pychrysalide/format/known.c index e19a4a2..c3b5b9d 100644 --- a/plugins/pychrysalide/format/known.c +++ b/plugins/pychrysalide/format/known.c @@ -28,19 +28,48 @@ #include <pygobject.h> -#include <format/known.h> +#include <i18n.h> +#include <format/known-int.h> +#include <plugins/dt.h> #include "../access.h" #include "../helpers.h" +#include "../analysis/content.h" +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + + +/* Accompagne la création d'une instance dérivée en Python. */ +static PyObject *py_known_format_new(PyTypeObject *, PyObject *, PyObject *); + +/* Initialise la classe des descriptions de fichier binaire. */ +static void py_known_format_init_gclass(GKnownFormatClass *, gpointer); + +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_known_format_init(PyObject *, PyObject *, PyObject *); + +/* Indique la désignation interne du format. */ +static char *py_known_format_get_key_wrapper(const GKnownFormat *); + +/* Fournit une description humaine du format. */ +static char *py_known_format_get_description_wrapper(const GKnownFormat *); + +/* Assure l'interprétation d'un format en différé. */ +static bool py_known_format_analyze_wrapper(GKnownFormat *, wgroup_id_t, GtkStatusStack *); + + + +/* --------------------------- DEFINITION DU FORMAT CONNU --------------------------- */ + + /* Assure l'interprétation d'un format en différé. */ static PyObject *py_known_format_analyze(PyObject *, PyObject *); /* Indique la désignation interne du format. */ -static PyObject *py_known_format_get_name(PyObject *, void *); +static PyObject *py_known_format_get_key(PyObject *, void *); /* Indique la désignation humaine du format. */ static PyObject *py_known_format_get_description(PyObject *, void *); @@ -50,9 +79,332 @@ static PyObject *py_known_format_get_content(PyObject *, void *); -#define KNOWN_FORMAT_DOC \ - "KnownFormat is a small class providing basic features for recognized formats." +/* ---------------------------------------------------------------------------------- */ +/* GLUE POUR CREATION DEPUIS PYTHON */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : type = type du nouvel objet à mettre en place. * +* args = éventuelle liste d'arguments. * +* kwds = éventuel dictionnaire de valeurs mises à disposition. * +* * +* Description : Accompagne la création d'une instance dérivée en Python. * +* * +* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_known_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Objet à retourner */ + PyTypeObject *base; /* Type de base à dériver */ + bool first_time; /* Evite les multiples passages*/ + GType gtype; /* Nouveau type de processeur */ + bool status; /* Bilan d'un enregistrement */ + + /* Validations diverses */ + + base = get_python_known_format_type(); + + if (type == base) + { + result = NULL; + PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name); + goto exit; + } + + /* Mise en place d'un type dédié */ + + first_time = (g_type_from_name(type->tp_name) == 0); + + gtype = build_dynamic_type(G_TYPE_KNOWN_FORMAT, type->tp_name, + (GClassInitFunc)py_known_format_init_gclass, NULL, NULL); + + if (first_time) + { + status = register_class_for_dynamic_pygobject(gtype, type, base); + + if (!status) + { + result = NULL; + goto exit; + } + + } + + /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ + + result = PyType_GenericNew(type, args, kwds); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe à initialiser. * +* unused = données non utilisées ici. * +* * +* Description : Initialise la classe générique des processeurs. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_known_format_init_gclass(GKnownFormatClass *class, gpointer unused) +{ + class->get_key = py_known_format_get_key_wrapper; + class->get_desc = py_known_format_get_description_wrapper; + + class->analyze = py_known_format_analyze_wrapper; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet à initialiser (théoriquement). * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Initialise une instance sur la base du dérivé de GObject. * +* * +* Retour : 0. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_known_format_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + GBinContent *content; /* Contenu à intégrer au format*/ + int ret; /* Bilan de lecture des args. */ + GKnownFormat *format; /* Format à manipuler */ + +#define KNOWN_FORMAT_DOC \ + "KnownFormat is a small class providing basic features for" \ + " recognized formats.\n" \ + "\n" \ + "One item has to be defined as class attribute in the final" \ + " class:\n" \ + "* *_key*: a string providing a small name used to identify the" \ + " format.\n" \ + "\n" \ + "The following methods have to be defined for new classes:\n" \ + "* pychrysalide.format.KnownFormat._get_description();\n" \ + "* pychrysalide.format.KnownFormat._analyze().\n" \ + "\n" \ + "Calls to the *__init__* constructor of this abstract object expect"\ + " only one argument: a binary content, provided as a" \ + " pychrysalide.analysis.BinContent instance." + + /* Récupération des paramètres */ + + ret = PyArg_ParseTuple(args, "O&", convert_to_binary_content, &content); + if (!ret) return -1; + + /* Initialisation d'un objet GLib */ + + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; + + /* Eléments de base */ + + format = G_KNOWN_FORMAT(pygobject_get(self)); + + g_known_format_set_content(format, content); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description du format connu à consulter. * +* * +* Description : Indique la désignation interne du format. * +* * +* Retour : Désignation du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *py_known_format_get_key_wrapper(const GKnownFormat *format) +{ + char *result; /* Désignation à renvoyer */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pykey; /* Clef en objet Python */ + int ret; /* Bilan d'une conversion */ + + result = NULL; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(format)); + + if (PyObject_HasAttrString(pyobj, "_key")) + { + pykey = PyObject_GetAttrString(pyobj, "_key"); + + if (pykey != NULL) + { + ret = PyUnicode_Check(pykey); + + if (ret) + result = strdup(PyUnicode_AsUTF8(pykey)); + + Py_DECREF(pykey); + + } + + } + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description du format connu à consulter. * +* * +* Description : Fournit une description humaine du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *py_known_format_get_description_wrapper(const GKnownFormat *format) +{ + char *result; /* Description à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pyret; /* Bilan de consultation */ + int ret; /* Bilan d'une conversion */ + +#define KNOWN_FORMAT_GET_DESCRIPTION_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _get_description, "$self, /", \ + METH_NOARGS, \ + "Abstract method used to build a description of the format.\n" \ + "\n" \ + "The result is expected to be a string." \ +) + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(format)); + + if (has_python_method(pyobj, "_get_description")) + { + pyret = run_python_method(pyobj, "_get_description", NULL); + + if (pyret != NULL) + { + ret = PyUnicode_Check(pyret); + + if (ret) + result = strdup(PyUnicode_AsUTF8(pyret)); + + Py_DECREF(pyret); + + } + + } + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format chargé dont l'analyse est lancée. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * +* * +* Description : Assure l'interprétation d'un format en différé. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_known_format_analyze_wrapper(GKnownFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + bool result; /* Bilan à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan d'exécution */ + +#define KNOWN_FORMAT_ANALYZE_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _analyze, "$self, gid, status, /", \ + METH_VARARGS, \ + "Abstract method used to start the analysis of the known" \ + " format and return its status.\n" \ + "\n" \ + "The identifier refers to the working queue used to process" \ + " the analysis. A reference to the main status bar may also be" \ + " provided, as a pychrysalide.gtkext.StatusStack instance if" \ + " running in graphical mode or None otherwise.\n" \ + "\n" \ + "The expected result of the call is a boolean." \ +) + + result = false; + + gstate = PyGILState_Ensure(); + pyobj = pygobject_new(G_OBJECT(format)); + + if (has_python_method(pyobj, "_analyze")) + { + args = PyTuple_New(2); + + PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(gid)); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(status))); + + pyret = run_python_method(pyobj, "_analyze", args); + + result = (pyret == Py_True); + + Py_DECREF(args); + Py_XDECREF(pyret); + + } + + PyGILState_Release(gstate); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DU FORMAT CONNU */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** @@ -75,11 +427,21 @@ static PyObject *py_known_format_analyze(PyObject *self, PyObject *args) GKnownFormat *format; /* Format connu manipulé */ bool status; /* Bilan de l'opération */ -#define KNOWN_FORMAT_ANALYZE_METHOD PYTHON_METHOD_DEF \ -( \ - analyze, "$self, /, gid, status", \ - METH_VARARGS, py_known_format, \ - "Start the analysis of the known format and return its status." \ +#define KNOWN_FORMAT_ANALYZE_METHOD PYTHON_METHOD_DEF \ +( \ + analyze, "$self, gid, status, /", \ + METH_VARARGS, py_known_format, \ + "Start the analysis of the known format and return its status." \ + "\n" \ + "Once this analysis is done, a few early symbols and the" \ + " mapped sections are expected to be defined, if any.\n" \ + "\n" \ + "The identifier refers to the working queue used to process" \ + " the analysis. A reference to the main status bar may also be" \ + " provided, as a pychrysalide.gtkext.StatusStack instance if" \ + " running in graphical mode or None otherwise.\n" \ + "\n" \ + "The return value is a boolean status of the operation." \ ) ret = PyArg_ParseTuple(args, "");//|KO!", &gid, &status); @@ -104,29 +466,31 @@ static PyObject *py_known_format_analyze(PyObject *self, PyObject *args) * * * Description : Indique la désignation interne du format. * * * -* Retour : Description du format. * +* Retour : Désignation du format. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_known_format_get_name(PyObject *self, void *closure) +static PyObject *py_known_format_get_key(PyObject *self, void *closure) { PyObject *result; /* Trouvailles à retourner */ GKnownFormat *format; /* Format de binaire manipulé */ - const char *name; /* Description interne */ + char *key; /* Désignation interne */ -#define KNOWN_FORMAT_NAME_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - name, py_known_format, \ - "Internal name of the known format." \ +#define KNOWN_FORMAT_KEY_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + key, py_known_format, \ + "Internal name of the known format, provided as a (tiny) string." \ ) format = G_KNOWN_FORMAT(pygobject_get(self)); - name = g_known_format_get_name(format); + key = g_known_format_get_key(format); + + result = PyUnicode_FromString(key); - result = PyUnicode_FromString(name); + free(key); return result; @@ -150,12 +514,12 @@ static PyObject *py_known_format_get_description(PyObject *self, void *closure) { PyObject *result; /* Trouvailles à retourner */ GKnownFormat *format; /* Format de binaire manipulé */ - const char *desc; /* Description humaine */ + char *desc; /* Description humaine */ #define KNOWN_FORMAT_DESCRIPTION_ATTRIB PYTHON_GET_DEF_FULL \ ( \ description, py_known_format, \ - "Human description of the known format." \ + "Human description of the known format, as a string." \ ) format = G_KNOWN_FORMAT(pygobject_get(self)); @@ -164,6 +528,8 @@ static PyObject *py_known_format_get_description(PyObject *self, void *closure) result = PyUnicode_FromString(desc); + free(desc); + return result; } @@ -188,10 +554,12 @@ static PyObject *py_known_format_get_content(PyObject *self, void *closure) GKnownFormat *format; /* Format de binaire manipulé */ GBinContent *content; /* Instance GLib correspondante*/ -#define KNOWN_FORMAT_CONTENT_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - content, py_known_format, \ - "Binary content linked to the known format." \ +#define KNOWN_FORMAT_CONTENT_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + content, py_known_format, \ + "Binary content linked to the known format." \ + "\n" \ + "The result is a pychrysalide.analysis.BinContent instance." \ ) format = G_KNOWN_FORMAT(pygobject_get(self)); @@ -222,12 +590,14 @@ static PyObject *py_known_format_get_content(PyObject *self, void *closure) PyTypeObject *get_python_known_format_type(void) { static PyMethodDef py_known_format_methods[] = { + KNOWN_FORMAT_GET_DESCRIPTION_WRAPPER, + KNOWN_FORMAT_ANALYZE_WRAPPER, KNOWN_FORMAT_ANALYZE_METHOD, { NULL } }; static PyGetSetDef py_known_format_getseters[] = { - KNOWN_FORMAT_NAME_ATTRIB, + KNOWN_FORMAT_KEY_ATTRIB, KNOWN_FORMAT_DESCRIPTION_ATTRIB, KNOWN_FORMAT_CONTENT_ATTRIB, { NULL } @@ -245,7 +615,10 @@ PyTypeObject *get_python_known_format_type(void) .tp_doc = KNOWN_FORMAT_DOC, .tp_methods = py_known_format_methods, - .tp_getset = py_known_format_getseters + .tp_getset = py_known_format_getseters, + + .tp_init = py_known_format_init, + .tp_new = py_known_format_new, }; @@ -278,8 +651,6 @@ bool ensure_python_known_format_is_registered(void) { module = get_access_to_python_module("pychrysalide.format"); - APPLY_ABSTRACT_FLAG(type); - dict = PyModule_GetDict(module); if (!register_class_for_pygobject(dict, G_TYPE_KNOWN_FORMAT, type, &PyGObject_Type)) diff --git a/plugins/pychrysalide/plugin.c b/plugins/pychrysalide/plugin.c index 0d24f8c..208c46a 100644 --- a/plugins/pychrysalide/plugin.c +++ b/plugins/pychrysalide/plugin.c @@ -676,6 +676,7 @@ static void py_plugin_module_handle_loaded_content_wrapper(const GPluginModule * static bool py_plugin_module_handle_binary_format_analysis_wrapper(const GPluginModule *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status) { + bool result; /* Bilan à retourner */ PyGILState_STATE gstate; /* Sauvegarde d'environnement */ PyObject *pyobj; /* Objet Python concerné */ PyObject *args; /* Arguments pour l'appel */ @@ -701,6 +702,8 @@ static bool py_plugin_module_handle_binary_format_analysis_wrapper(const GPlugin " *FORMAT_POST_ANALYSIS_STARTED* or *FORMAT_POST_ANALYSIS_ENDED*." \ ) + result = false; + gstate = PyGILState_Ensure(); pyobj = pygobject_new(G_OBJECT(plugin)); @@ -716,6 +719,8 @@ static bool py_plugin_module_handle_binary_format_analysis_wrapper(const GPlugin pyret = run_python_method(pyobj, "_handle_format_analysis", args); + result = (pyret == Py_True); + Py_XDECREF(pyret); Py_DECREF(args); @@ -725,7 +730,7 @@ static bool py_plugin_module_handle_binary_format_analysis_wrapper(const GPlugin PyGILState_Release(gstate); - return true; + return result; } |