diff options
Diffstat (limited to 'plugins/pychrysa/analysis')
21 files changed, 565 insertions, 747 deletions
diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am index 7e18757..8b0609d 100644 --- a/plugins/pychrysa/analysis/Makefile.am +++ b/plugins/pychrysa/analysis/Makefile.am @@ -3,21 +3,14 @@ noinst_LTLIBRARIES = libpychrysaanalysis.la libpychrysaanalysis_la_SOURCES = \ binary.h binary.c \ - module.h module.c + block.h block.c \ + module.h module.c \ + routine.h routine.c libpychrysaanalysis_la_LIBADD = \ - binaries/libpychrysaanalysisbinaries.la - -# libpychrysaanalysis_la_SOURCES = \ -# binary.h binary.c \ -# block.h block.c \ -# module.h module.c \ -# roptions.h roptions.c \ -# routine.h routine.c - -# libpychrysaanalysis_la_LIBADD = \ -# binaries/libpychrysaanalysisbinaries.la \ -# blocks/libpychrysaanalysisblocks.la + binaries/libpychrysaanalysisbinaries.la \ + blocks/libpychrysaanalysisblocks.la \ + db/libpychrysaanalysisdb.la libpychrysaanalysis_la_LDFLAGS = diff --git a/plugins/pychrysa/analysis/binaries/file.c b/plugins/pychrysa/analysis/binaries/file.c index af285d9..40463ba 100644 --- a/plugins/pychrysa/analysis/binaries/file.c +++ b/plugins/pychrysa/analysis/binaries/file.c @@ -60,7 +60,7 @@ static PyObject *py_binary_file_get_filename(PyObject *, void *); static PyObject *py_binary_file_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *result; /* Instance à retourner */ - char *filename; /* Nom du fichier à charger */ + const char *filename; /* Nom du fichier à charger */ int ret; /* Bilan de lecture des args. */ GLoadedBinary *binary; /* Version GLib du format */ diff --git a/plugins/pychrysa/analysis/binaries/module.c b/plugins/pychrysa/analysis/binaries/module.c index c2adddf..b43d24f 100644 --- a/plugins/pychrysa/analysis/binaries/module.c +++ b/plugins/pychrysa/analysis/binaries/module.c @@ -25,6 +25,9 @@ #include "module.h" +#include <assert.h> + + #include "file.h" @@ -47,7 +50,7 @@ bool add_analysis_binaries_module_to_python_module(PyObject *super) PyObject *module; /* Sous-module mis en place */ int ret; /* Bilan d'un appel */ - static PyModuleDef py_chrysalide_arch_module = { + static PyModuleDef py_chrysalide_binaries_module = { .m_base = PyModuleDef_HEAD_INIT, @@ -60,31 +63,26 @@ bool add_analysis_binaries_module_to_python_module(PyObject *super) result = false; - module = PyModule_Create(&py_chrysalide_arch_module); + module = PyModule_Create(&py_chrysalide_binaries_module); if (module == NULL) return false; - ret = PyState_AddModule(super, &py_chrysalide_arch_module); - if (ret != 0) goto aabmtpm_exit; + ret = PyState_AddModule(super, &py_chrysalide_binaries_module); + if (ret != 0) goto loading_failed; ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.binaries"); - if (ret != 0) goto aabmtpm_exit; + if (ret != 0) goto loading_failed; Py_INCREF(module); ret = PyModule_AddObject(super, "binaries", module); - if (ret != 0) goto aabmtpm_exit; + if (ret != 0) goto loading_failed; result = true; result &= register_python_binary_file(module); - aabmtpm_exit: - - if (!result) - { - printf("something went wrong in %s...\n", __FUNCTION__); - /* ... */ + loading_failed: - } + assert(result); return result; diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c index 1a513eb..fad84cd 100644 --- a/plugins/pychrysa/analysis/binary.c +++ b/plugins/pychrysa/analysis/binary.c @@ -28,138 +28,62 @@ #include <pygobject.h> +#include <analysis/binary.h> +#include "../helpers.h" +/* Lance l'analyse d'un élément binaire chargé. */ +static PyObject *py_loaded_binary_analyse(PyObject *, PyObject *); +/* Fournit le nom associé à l'élément binaire. */ +static PyObject *py_loaded_binary_get_name(PyObject *, void *); -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_loaded_binary_type(void) -{ - static PyTypeObject py_loaded_binary_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.analysis.LoadedBinary", - - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - - .tp_doc = "PyChrysalide loaded binary", - - }; - - return &py_loaded_binary_type; - -} - +/* Fournit le format de fichier reconnu dans le contenu binaire. */ +static PyObject *py_loaded_binary_get_format(PyObject *, void *); +/* Fournit le processeur de l'architecture liée au binaire. */ +static PyObject *py_loaded_binary_get_processor(PyObject *, void *); -#include <analysis/binary.h> - +/* Fournit le tampon associé au contenu assembleur d'un binaire. */ +static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *); /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : self = contenu binaire à manipuler. * +* args = non utilisé ici. * * * -* Description : Prend en charge l'objet 'pychrysalide.arch.loaded_binary'. * +* Description : Lance l'analyse d'un élément binaire chargé. * * * -* Retour : Bilan de l'opération. * +* Retour : Rien (None). * * * * Remarques : - * * * ******************************************************************************/ -bool register_python_loaded_binary(PyObject *module) +static PyObject *py_loaded_binary_analyse(PyObject *self, PyObject *args) { - PyTypeObject *py_loaded_binary_type; /* Type Python 'LoadedBinary' */ - int ret; /* Bilan d'un appel */ - PyObject *dict; /* Dictionnaire du module */ + GLoadedBinary *binary; /* Version GLib du format */ - py_loaded_binary_type = get_python_loaded_binary_type(); - - py_loaded_binary_type->tp_base = &PyGObject_Type; - py_loaded_binary_type->tp_basicsize = py_loaded_binary_type->tp_base->tp_basicsize; + binary = G_LOADED_BINARY(pygobject_get(self)); - if (PyType_Ready(py_loaded_binary_type) != 0) - return false; + g_loaded_binary_analyse(binary); - Py_INCREF(py_loaded_binary_type); - ret = PyModule_AddObject(module, "LoadedBinary", (PyObject *)py_loaded_binary_type); - if (ret != 0) return false; - - dict = PyModule_GetDict(module); - pygobject_register_class(dict, "LoadedBinary", G_TYPE_LOADED_BINARY, py_loaded_binary_type, - Py_BuildValue("(O)", py_loaded_binary_type->tp_base)); - - return true; + Py_RETURN_NONE; } - - - - - - - - - - -#if 0 - - -#include <pygobject.h> - - -#include <analysis/binary.h> - - -#include "../quirks.h" -#include "../arch/instruction.h" -#include "../format/executable.h" -#include "../glibext/codebuffer.h" - - - -/* Fournit le fichier correspondant à l'élément binaire. */ -static PyObject *py_loaded_binary_get_filename(PyObject *self, PyObject *args); - -/* Fournit le format de fichier reconnu dans le contenu binaire. */ -static PyObject *py_loaded_binary_get_format(PyObject *, PyObject *); - -/* Fournit les instructions issues du désassemblage. */ -static PyObject *py_loaded_binary_get_instructions(PyObject *, PyObject *); - - - -/* Fournit le tampon associé au contenu assembleur d'un binaire. */ -static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *); - - - - /****************************************************************************** * * -* Paramètres : self = classe représentant un binaire. * -* args = arguments fournis à l'appel. * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * * * -* Description : Fournit le fichier correspondant à l'élément binaire. * +* Description : Fournit le nom associé à l'élément binaire. * * * * Retour : Nom de fichier avec chemin absolu. * * * @@ -167,17 +91,17 @@ static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *); * * ******************************************************************************/ -static PyObject *py_loaded_binary_get_name(PyObject *self, PyObject *args) +static PyObject *py_loaded_binary_get_name(PyObject *self, void *closure) { PyObject *result; /* Trouvailles à retourner */ GLoadedBinary *binary; /* Version native */ - const char *filename; /* Fichier associé au binaire */ + const char *name; /* Désignation du binaire */ binary = G_LOADED_BINARY(pygobject_get(self)); - filename = g_loaded_binary_get_name(binary, true); + name = g_loaded_binary_get_name(binary, true); - result = PyString_FromString(filename); + result = PyUnicode_FromString(name); return result; @@ -186,28 +110,30 @@ static PyObject *py_loaded_binary_get_name(PyObject *self, PyObject *args) /****************************************************************************** * * -* Paramètres : self = classe représentant un binaire. * -* args = arguments fournis à l'appel. * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * * * * Description : Fournit le format de fichier reconnu dans le contenu binaire.* * * -* Retour : Nom de fichier avec chemin absolu. * +* Retour : Instance du format reconnu. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_loaded_binary_get_format(PyObject *self, PyObject *args) +static PyObject *py_loaded_binary_get_format(PyObject *self, void *closure) { - PyObject *result; /* Trouvailles à retourner */ - GLoadedBinary *binary; /* Version native */ - GExeFormat *format; /* Format du binaire physique */ + PyObject *result; /* Instance Python à retourner */ + GLoadedBinary *binary; /* Binaire en cours d'analyse */ + GExeFormat *format; /* Format du binaire lié */ binary = G_LOADED_BINARY(pygobject_get(self)); format = g_loaded_binary_get_format(binary); result = pygobject_new(G_OBJECT(format)); + //g_object_unref(G_OBJECT(format)); + return result; } @@ -215,37 +141,35 @@ static PyObject *py_loaded_binary_get_format(PyObject *self, PyObject *args) /****************************************************************************** * * -* Paramètres : self = classe représentant un binaire. * -* args = arguments fournis à l'appel. * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * * * -* Description : Fournit les instructions issues du désassemblage. * +* Description : Fournit le processeur de l'architecture liée au binaire. * * * -* Retour : Instructions issues du désassemblage. * +* Retour : Instance du processeur associé. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_loaded_binary_get_instructions(PyObject *self, PyObject *args) +static PyObject *py_loaded_binary_get_processor(PyObject *self, void *closure) { - PyObject *result; /* Trouvailles à retourner */ - GLoadedBinary *binary; /* Version native */ - GArchInstruction *instr; /* Première instruction */ + PyObject *result; /* Instance Python à retourner */ + GLoadedBinary *binary; /* Binaire en cours d'analyse */ + GArchProcessor *proc; /* Architecture visée */ binary = G_LOADED_BINARY(pygobject_get(self)); + proc = g_loaded_binary_get_processor(binary); - instr = g_loaded_binary_get_instructions(binary); + result = pygobject_new(G_OBJECT(proc)); - result = pygobject_new(G_OBJECT(instr)); + g_object_unref(G_OBJECT(proc)); return result; } - - - /****************************************************************************** * * * Paramètres : self = classe représentant une instruction. * @@ -275,88 +199,106 @@ static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *self, void * } - - - - - - - /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : - * * * -* Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.* +* Description : Fournit un accès à une définition de type à diffuser. * * * -* Retour : Bilan de l'opération. * +* Retour : Définition d'objet pour Python. * * * * Remarques : - * * * ******************************************************************************/ -bool register_python_loaded_binary(PyObject *module) +PyTypeObject *get_python_loaded_binary_type(void) { - PyObject *pygobj_mod; /* Module Python-GObject */ - int ret; /* Bilan d'un appel */ - static PyMethodDef py_loaded_binary_methods[] = { { - "get_filename", (PyCFunction)py_loaded_binary_get_filename, + "analyse", py_loaded_binary_analyse, METH_NOARGS, - "Provide the filename of the loaded binary." - }, - { - "get_format", (PyCFunction)py_loaded_binary_get_format, - METH_NOARGS, - "Provide the file format recognized in the binary content." - }, - { - "get_instructions", (PyCFunction)py_loaded_binary_get_instructions, - METH_NOARGS, - "Give access to all disassembled instructions." + "analyse(/)\n--\n\nStart the analysis of the loaded binary and " \ + "send a \"disassembly-done\" signal when done." }, { NULL } }; static PyGetSetDef py_loaded_binary_getseters[] = { { - "disassembled_buffer", (getter)py_loaded_binary_get_disassembled_buffer, (setter)NULL, - "Give access to the disassembled code buffer.", NULL + "name", py_loaded_binary_get_name, NULL, + "Name of the loaded binary.", NULL + }, + { + "format", py_loaded_binary_get_format, NULL, + "File format recognized in the binary content.", NULL + }, + { + "processor", py_loaded_binary_get_processor, NULL, + "Handler for the current binary processor.", NULL + }, + { + "disassembled_buffer", py_loaded_binary_get_disassembled_buffer, NULL, + "Disassembled code buffer.", NULL }, { NULL } }; static PyTypeObject py_loaded_binary_type = { - PyObject_HEAD_INIT(NULL) + PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "pychrysalide.analysis.LoadedBinary", - .tp_basicsize = sizeof(PyGObject), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE, .tp_doc = "PyChrysalide loaded binary", .tp_methods = py_loaded_binary_methods, - .tp_getset = py_loaded_binary_getseters + .tp_getset = py_loaded_binary_getseters, }; - pygobj_mod = PyImport_ImportModule("gobject"); - if (pygobj_mod == NULL) return false; + return &py_loaded_binary_type; - py_loaded_binary_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); - Py_DECREF(pygobj_mod); +} - if (PyType_Ready(&py_loaded_binary_type) < 0) - return false; - Py_INCREF(&py_loaded_binary_type); - ret = PyModule_AddObject(module, "LoadedBinary", (PyObject *)&py_loaded_binary_type); +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ - return (ret == 0); +bool register_python_loaded_binary(PyObject *module) +{ + PyTypeObject *py_loaded_binary_type; /* Type Python 'LoadedBinary' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ -} + py_loaded_binary_type = get_python_loaded_binary_type(); + + py_loaded_binary_type->tp_base = &PyGObject_Type; + py_loaded_binary_type->tp_basicsize = py_loaded_binary_type->tp_base->tp_basicsize; + + APPLY_ABSTRACT_FLAG(py_loaded_binary_type); + + if (PyType_Ready(py_loaded_binary_type) != 0) + return false; -#endif + Py_INCREF(py_loaded_binary_type); + ret = PyModule_AddObject(module, "LoadedBinary", (PyObject *)py_loaded_binary_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "LoadedBinary", G_TYPE_LOADED_BINARY, py_loaded_binary_type, + Py_BuildValue("(O)", py_loaded_binary_type->tp_base)); + return true; + +} diff --git a/plugins/pychrysa/analysis/block.c b/plugins/pychrysa/analysis/block.c index bd8684d..4cbc353 100644 --- a/plugins/pychrysa/analysis/block.c +++ b/plugins/pychrysa/analysis/block.c @@ -54,7 +54,7 @@ static PyObject *py_instructions_block_visit(PyObject *, PyObject *); static PyObject *py_instructions_block_get_links_block(PyObject *, PyObject *); /* Définit les constantes pour les blocs basiques. */ -static bool py_instructions_block_define_constants(PyObject *); +static bool py_instructions_block_define_constants(PyTypeObject *); @@ -82,7 +82,7 @@ static bool py_block_visitor_glue(GInstrBlock *block, BlockVisitOrder order, py_ args = PyTuple_New(3); PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(block))); - PyTuple_SetItem(args, 1, PyInt_FromLong(order)); + PyTuple_SetItem(args, 1, PyLong_FromLong(order)); PyTuple_SetItem(args, 2, data->user); value = _run_python_method(data->func, args); @@ -96,6 +96,7 @@ static bool py_block_visitor_glue(GInstrBlock *block, BlockVisitOrder order, py_ } + /****************************************************************************** * * * Paramètres : self = classe représentant un binaire. * @@ -120,6 +121,8 @@ static PyObject *py_instructions_block_visit(PyObject *self, PyObject *args) ret = PyArg_ParseTuple(args, "OO", &data.func, &data.user); if (!ret) Py_RETURN_NONE; + if (PyCallable_Check(data.func) != 1) return NULL; + block = G_INSTR_BLOCK(pygobject_get(self)); status = g_instr_block_visit(block, (instr_block_visitor_cb)py_block_visitor_glue, &data); @@ -162,7 +165,7 @@ static PyObject *py_instructions_block_get_links_block(PyObject *self, PyObject /****************************************************************************** * * -* Paramètres : dict = dictionnaire à compléter. * +* Paramètres : obj_type = type dont le dictionnaire est à compléter. * * * * Description : Définit les constantes pour les blocs basiques. * * * @@ -172,90 +175,110 @@ static PyObject *py_instructions_block_get_links_block(PyObject *self, PyObject * * ******************************************************************************/ -static bool py_instructions_block_define_constants(PyObject *dict) +static bool py_instructions_block_define_constants(PyTypeObject *obj_type) { - int ret; /* Bilan d'un ajout */ - - ret = PyDict_SetItemString(dict, "BVO_IN", PyInt_FromLong(BVO_IN)); - if (ret == -1) return false; + bool result; /* Bilan à retourner */ - ret = PyDict_SetItemString(dict, "BVO_PENDING", PyInt_FromLong(BVO_PENDING)); - if (ret == -1) return false; + result = true; - ret = PyDict_SetItemString(dict, "BVO_OUT", PyInt_FromLong(BVO_OUT)); - if (ret == -1) return false; + result &= PyDict_AddIntMacro(obj_type, BVO_IN); + result &= PyDict_AddIntMacro(obj_type, BVO_PENDING); + result &= PyDict_AddIntMacro(obj_type, BVO_OUT); - return true; + return result; } /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : - * * * -* Description : Prend en charge l'objet 'pychrysalide.analysis.InstrBlock'. * +* Description : Fournit un accès à une définition de type à diffuser. * * * -* Retour : Bilan de l'opération. * +* Retour : Définition d'objet pour Python. * * * * Remarques : - * * * ******************************************************************************/ -bool register_python_instructions_block(PyObject *module) +PyTypeObject *get_python_instr_block_type(void) { - PyObject *parent_mod; /* Module de la classe parente */ - int ret; /* Bilan d'un appel */ - - static PyMethodDef py_instructions_block_methods[] = { + static PyMethodDef py_instr_block_methods[] = { { "visit", (PyCFunction)py_instructions_block_visit, METH_VARARGS, - "Visit all the basic blocks, starting at the provided one." + "visit($self, cb, data, /)\n--\n\nVisit all the basic blocks, starting at the provided one." }, { "get_links_block", (PyCFunction)py_instructions_block_get_links_block, METH_VARARGS, - "Get the block containing all blocks linked to the caller." + "get_links_block($self, /)\n--\n\nGet the block containing all blocks linked to the caller." }, { NULL } }; - static PyGetSetDef py_instructions_block_getseters[] = { + static PyGetSetDef py_instr_block_getseters[] = { { NULL } }; - static PyTypeObject py_instructions_block_type = { + static PyTypeObject py_instr_block_type = { - PyObject_HEAD_INIT(NULL) + PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "pychrysalide.analysis.InstrBlock", - .tp_basicsize = sizeof(PyGObject), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_doc = "PyChrysalide basic block", - .tp_methods = py_instructions_block_methods, - .tp_getset = py_instructions_block_getseters + .tp_methods = py_instr_block_methods, + .tp_getset = py_instr_block_getseters, }; - parent_mod = PyImport_ImportModule("gobject"); - if (parent_mod == NULL) return false; + return &py_instr_block_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.analysis.InstrBlock'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_instr_block(PyObject *module) +{ + PyTypeObject *py_instr_block_type; /* Type Python 'InstrBlock' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_instr_block_type = get_python_instr_block_type(); - py_instructions_block_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "GObject"); - Py_DECREF(parent_mod); + py_instr_block_type->tp_base = &PyGObject_Type; + py_instr_block_type->tp_basicsize = py_instr_block_type->tp_base->tp_basicsize; - if (PyType_Ready(&py_instructions_block_type) < 0) + if (PyType_Ready(py_instr_block_type) != 0) return false; - if (!py_instructions_block_define_constants(py_instructions_block_type.tp_dict)) + if (!py_instructions_block_define_constants(py_instr_block_type)) return false; - Py_INCREF(&py_instructions_block_type); - ret = PyModule_AddObject(module, "InstrBlock", (PyObject *)&py_instructions_block_type); + Py_INCREF(py_instr_block_type); + ret = PyModule_AddObject(module, "InstrBlock", (PyObject *)py_instr_block_type); + if (ret != 0) return false; - return (ret == 0); + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "InstrBlock", G_TYPE_INSTR_BLOCK, py_instr_block_type, + Py_BuildValue("(O)", py_instr_block_type->tp_base)); + + return true; } diff --git a/plugins/pychrysa/analysis/block.h b/plugins/pychrysa/analysis/block.h index 4752b9a..71e3160 100644 --- a/plugins/pychrysa/analysis/block.h +++ b/plugins/pychrysa/analysis/block.h @@ -31,8 +31,11 @@ +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_instr_block_type(void); + /* Prend en charge l'objet 'pychrysalide.analysis.InstrBlock'. */ -bool register_python_instructions_block(PyObject *); +bool register_python_instr_block(PyObject *); diff --git a/plugins/pychrysa/analysis/blocks/flow.c b/plugins/pychrysa/analysis/blocks/flow.c index a5ee99c..626d5c8 100644 --- a/plugins/pychrysa/analysis/blocks/flow.c +++ b/plugins/pychrysa/analysis/blocks/flow.c @@ -31,12 +31,15 @@ #include <analysis/blocks/flow.h> +#include "../block.h" +#if 0 + /* Fournit les adresses limites d'un bloc d'exécution. */ static PyObject *py_flow_block_get_boundary_addresses(PyObject *, void *); @@ -180,3 +183,103 @@ bool register_python_flow_block(PyObject *module) return (ret == 0); } + +#endif + + + + + + + + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_flow_block_type(void) +{ + static PyMethodDef py_flow_block_methods[] = { + { NULL } + }; + + static PyGetSetDef py_flow_block_getseters[] = { + { NULL } + }; + + static PyTypeObject py_flow_block_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.blocks.FlowBlock", + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide flow block", + + .tp_methods = py_flow_block_methods, + .tp_getset = py_flow_block_getseters, + + }; + + return &py_flow_block_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide...blocks.FlowBlock'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_flow_block(PyObject *module) +{ + PyTypeObject *py_flow_block_type; /* Type Python 'FlowBlock' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_flow_block_type = get_python_flow_block_type(); + + py_flow_block_type->tp_base = get_python_instr_block_type(); + py_flow_block_type->tp_basicsize = py_flow_block_type->tp_base->tp_basicsize; + + if (PyType_Ready(py_flow_block_type) != 0) + return false; + + Py_INCREF(py_flow_block_type); + ret = PyModule_AddObject(module, "FlowBlock", (PyObject *)py_flow_block_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "FlowBlock", G_TYPE_FLOW_BLOCK, py_flow_block_type, + Py_BuildValue("(O)", py_flow_block_type->tp_base)); + + return true; + +} diff --git a/plugins/pychrysa/analysis/blocks/flow.h b/plugins/pychrysa/analysis/blocks/flow.h index 20d649e..69b6c24 100644 --- a/plugins/pychrysa/analysis/blocks/flow.h +++ b/plugins/pychrysa/analysis/blocks/flow.h @@ -31,6 +31,9 @@ +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_flow_block_type(void); + /* Prend en charge l'objet 'pychrysalide.analysis.blocks.FlowBlock'. */ bool register_python_flow_block(PyObject *); diff --git a/plugins/pychrysa/analysis/blocks/module.c b/plugins/pychrysa/analysis/blocks/module.c index 881ebc7..4968e90 100644 --- a/plugins/pychrysa/analysis/blocks/module.c +++ b/plugins/pychrysa/analysis/blocks/module.c @@ -25,6 +25,9 @@ #include "module.h" +#include <assert.h> + + #include "flow.h" #include "virtual.h" @@ -42,27 +45,47 @@ * * ******************************************************************************/ -bool add_blocks_module_to_python_module(PyObject *super) +bool add_analysis_blocks_module_to_python_module(PyObject *super) { bool result; /* Bilan à retourner */ - PyObject *module; /* Module Python mis en place */ + PyObject *module; /* Sous-module mis en place */ int ret; /* Bilan d'un appel */ - static PyMethodDef py_blocks_methods[] = { - { NULL } + static PyModuleDef py_chrysalide_blocks_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.analysis.blocks", + .m_doc = "Python module for Chrysalide.analysis.blocks", + + .m_size = -1, + }; - module = Py_InitModule("pychrysalide.analysis.blocks", py_blocks_methods); + result = false; + + module = PyModule_Create(&py_chrysalide_blocks_module); if (module == NULL) return false; + ret = PyState_AddModule(super, &py_chrysalide_blocks_module); + if (ret != 0) goto loading_failed; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.blocks"); + if (ret != 0) goto loading_failed; + Py_INCREF(module); - ret = PyModule_AddObject(super, "pychrysalide.analysis.blocks", module); + ret = PyModule_AddObject(super, "blocks", module); + if (ret != 0) goto loading_failed; - result = (ret == 0); + result = true; result &= register_python_flow_block(module); result &= register_python_virtual_block(module); + loading_failed: + + assert(result); + return result; } diff --git a/plugins/pychrysa/analysis/blocks/module.h b/plugins/pychrysa/analysis/blocks/module.h index 395be19..dc2d17c 100644 --- a/plugins/pychrysa/analysis/blocks/module.h +++ b/plugins/pychrysa/analysis/blocks/module.h @@ -32,7 +32,7 @@ /* Ajoute le module 'blocks' au module Python. */ -bool add_blocks_module_to_python_module(PyObject *); +bool add_analysis_blocks_module_to_python_module(PyObject *); diff --git a/plugins/pychrysa/analysis/blocks/virtual.c b/plugins/pychrysa/analysis/blocks/virtual.c index 4f15371..bdc81b0 100644 --- a/plugins/pychrysa/analysis/blocks/virtual.c +++ b/plugins/pychrysa/analysis/blocks/virtual.c @@ -31,35 +31,24 @@ #include <analysis/blocks/virtual.h> - - - - - - - - - +#include "../block.h" /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : - * * * -* Description : Prend en charge l'objet 'pychrysalide.....VirtualBlock'. * +* Description : Fournit un accès à une définition de type à diffuser. * * * -* Retour : Bilan de l'opération. * +* Retour : Définition d'objet pour Python. * * * * Remarques : - * * * ******************************************************************************/ -bool register_python_virtual_block(PyObject *module) +PyTypeObject *get_python_virtual_block_type(void) { - PyObject *parent_mod; /* Module de la classe parente */ - int ret; /* Bilan d'un appel */ - static PyMethodDef py_virtual_block_methods[] = { { NULL } }; @@ -70,35 +59,58 @@ bool register_python_virtual_block(PyObject *module) static PyTypeObject py_virtual_block_type = { - PyObject_HEAD_INIT(NULL) + PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "pychrysalide.analysis.blocks.VirtualBlock", - .tp_basicsize = sizeof(PyGObject), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide basic virtual block", + .tp_doc = "PyChrysalide virtual block", .tp_methods = py_virtual_block_methods, - .tp_getset = py_virtual_block_getseters + .tp_getset = py_virtual_block_getseters, }; - parent_mod = PyImport_ImportModule("pychrysalide.analysis"); - if (parent_mod == NULL) return false; + return &py_virtual_block_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide...blocks.VirtualBlock'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_virtual_block(PyObject *module) +{ + PyTypeObject *py_virtual_block_type; /* Type Python 'VirtualBlock' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_virtual_block_type = get_python_virtual_block_type(); - py_virtual_block_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "InstrBlock"); - Py_DECREF(parent_mod); + py_virtual_block_type->tp_base = get_python_instr_block_type(); + py_virtual_block_type->tp_basicsize = py_virtual_block_type->tp_base->tp_basicsize; - if (PyType_Ready(&py_virtual_block_type) < 0) + if (PyType_Ready(py_virtual_block_type) != 0) return false; - Py_INCREF(&py_virtual_block_type); - ret = PyModule_AddObject(module, "VirtualBlock", (PyObject *)&py_virtual_block_type); + Py_INCREF(py_virtual_block_type); + ret = PyModule_AddObject(module, "VirtualBlock", (PyObject *)py_virtual_block_type); + if (ret != 0) return false; - pygobject_register_class(module, "GVirtualBlock", G_TYPE_VIRTUAL_BLOCK, &py_virtual_block_type, - Py_BuildValue("(O)", py_virtual_block_type.tp_base)); + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "VirtualBlock", G_TYPE_VIRTUAL_BLOCK, py_virtual_block_type, + Py_BuildValue("(O)", py_virtual_block_type->tp_base)); - return (ret == 0); + return true; } diff --git a/plugins/pychrysa/analysis/blocks/virtual.h b/plugins/pychrysa/analysis/blocks/virtual.h index 1c70b34..0bfaf82 100644 --- a/plugins/pychrysa/analysis/blocks/virtual.h +++ b/plugins/pychrysa/analysis/blocks/virtual.h @@ -31,6 +31,9 @@ +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_virtual_block_type(void); + /* Prend en charge l'objet 'pychrysalide.analysis.blocks.VirtualBlock'. */ bool register_python_virtual_block(PyObject *); diff --git a/plugins/pychrysa/analysis/db/Makefile.am b/plugins/pychrysa/analysis/db/Makefile.am index e33130f..2de2a16 100644 --- a/plugins/pychrysa/analysis/db/Makefile.am +++ b/plugins/pychrysa/analysis/db/Makefile.am @@ -6,7 +6,8 @@ libpychrysaanalysisdb_la_SOURCES = \ item.h item.c \ module.h module.c -libpychrysaanalysisdb_la_LDFLAGS = +libpychrysaanalysisdb_la_LDFLAGS = \ + items/libpychrysaanalysisdbitems.la AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ diff --git a/plugins/pychrysa/analysis/db/items/comment.c b/plugins/pychrysa/analysis/db/items/comment.c index 1bb2863..951f6ce 100644 --- a/plugins/pychrysa/analysis/db/items/comment.c +++ b/plugins/pychrysa/analysis/db/items/comment.c @@ -75,6 +75,9 @@ static PyObject *py_db_comment_new(PyTypeObject *type, PyObject *args, PyObject ret = PyArg_ParseTuple(args, "Osp", &py_vmpa, &text, &is_volatile); if (!ret) Py_RETURN_NONE; + ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type()); + if (!ret) return NULL; + addr = get_internal_vmpa(py_vmpa); if (py_vmpa == NULL) Py_RETURN_NONE; @@ -114,7 +117,7 @@ static PyObject *py_db_comment_get_text(PyObject *self, void *closure) } -/*********************d********************************************************* +/****************************************************************************** * * * Paramètres : self = objet Python concerné par l'appel. * * value = valeur fournie à intégrer ou prendre en compte. * diff --git a/plugins/pychrysa/analysis/db/items/module.c b/plugins/pychrysa/analysis/db/items/module.c index 3c634e3..009e823 100644 --- a/plugins/pychrysa/analysis/db/items/module.c +++ b/plugins/pychrysa/analysis/db/items/module.c @@ -25,6 +25,9 @@ #include "module.h" +#include <assert.h> + + #include "comment.h" @@ -64,27 +67,22 @@ bool add_analysis_db_items_module_to_python_module(PyObject *super) if (module == NULL) return false; ret = PyState_AddModule(super, &py_chrysalide_items_module); - if (ret != 0) goto aadimtpm_exit; + if (ret != 0) goto loading_failed; ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.db.items"); - if (ret != 0) goto aadimtpm_exit; + if (ret != 0) goto loading_failed; Py_INCREF(module); ret = PyModule_AddObject(super, "items", module); - if (ret != 0) goto aadimtpm_exit; + if (ret != 0) goto loading_failed; result = true; result &= register_python_db_comment(module); - aadimtpm_exit: - - if (!result) - { - printf("something went wrong in %s...\n", __FUNCTION__); - /* ... */ + loading_failed: - } + assert(result); return result; diff --git a/plugins/pychrysa/analysis/db/module.c b/plugins/pychrysa/analysis/db/module.c index 8c527a9..08c408c 100644 --- a/plugins/pychrysa/analysis/db/module.c +++ b/plugins/pychrysa/analysis/db/module.c @@ -25,8 +25,12 @@ #include "module.h" +#include <assert.h> + + #include "collection.h" #include "item.h" +#include "items/module.h" @@ -65,28 +69,25 @@ bool add_analysis_db_module_to_python_module(PyObject *super) if (module == NULL) return false; ret = PyState_AddModule(super, &py_chrysalide_db_module); - if (ret != 0) goto aadmtpm_exit; + if (ret != 0) goto loading_failed; ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.db"); - if (ret != 0) goto aadmtpm_exit; + if (ret != 0) goto loading_failed; Py_INCREF(module); ret = PyModule_AddObject(super, "db", module); - if (ret != 0) goto aadmtpm_exit; + if (ret != 0) goto loading_failed; result = true; result &= register_python_db_collection(module); result &= register_python_db_item(module); - aadmtpm_exit: + result &= add_analysis_db_items_module_to_python_module(module); - if (!result) - { - printf("something went wrong in %s...\n", __FUNCTION__); - /* ... */ + loading_failed: - } + assert(result); return result; diff --git a/plugins/pychrysa/analysis/module.c b/plugins/pychrysa/analysis/module.c index e13c8f8..d45a3f1 100644 --- a/plugins/pychrysa/analysis/module.c +++ b/plugins/pychrysa/analysis/module.c @@ -25,8 +25,15 @@ #include "module.h" +#include <assert.h> + + #include "binary.h" +#include "block.h" +#include "routine.h" #include "binaries/module.h" +#include "blocks/module.h" +#include "db/module.h" @@ -48,7 +55,7 @@ bool add_analysis_module_to_python_module(PyObject *super) PyObject *module; /* Sous-module mis en place */ int ret; /* Bilan d'un appel */ - static PyModuleDef py_chrysalide_arch_module = { + static PyModuleDef py_chrysalide_analysis_module = { .m_base = PyModuleDef_HEAD_INIT, @@ -61,106 +68,33 @@ bool add_analysis_module_to_python_module(PyObject *super) result = false; - module = PyModule_Create(&py_chrysalide_arch_module); + module = PyModule_Create(&py_chrysalide_analysis_module); if (module == NULL) return false; - ret = PyState_AddModule(super, &py_chrysalide_arch_module); - if (ret != 0) goto aamtpm_exit; + ret = PyState_AddModule(super, &py_chrysalide_analysis_module); + if (ret != 0) goto loading_failed; ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis"); - if (ret != 0) goto aamtpm_exit; + if (ret != 0) goto loading_failed; Py_INCREF(module); ret = PyModule_AddObject(super, "analysis", module); - if (ret != 0) goto aamtpm_exit; + if (ret != 0) goto loading_failed; result = true; result &= register_python_loaded_binary(module); + result &= register_python_instr_block(module); + result &= register_python_binary_routine(module); result &= add_analysis_binaries_module_to_python_module(module); + result &= add_analysis_blocks_module_to_python_module(module); + result &= add_analysis_db_module_to_python_module(module); - aamtpm_exit: - - if (!result) - { - printf("something went wrong in %s...\n", __FUNCTION__); - /* ... */ - - } - - return result; - -} - - - - - - - - - - - - - - - - - - - - - - + loading_failed: -#if 0 -#include "binary.h" -#include "block.h" -#include "routine.h" -#include "binaries/module.h" -#include "blocks/module.h" - - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Ajoute le module 'analysis' au module Python. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool add_analysis_module_to_python_module(PyObject *super) -{ - bool result; - PyObject *module; - int ret; /* Bilan d'un appel */ - - static PyMethodDef py_analysis_methods[] = { - { NULL } - }; - - module = Py_InitModule("pychrysalide.analysis", py_analysis_methods); - if (module == NULL) return false; - - Py_INCREF(module); - ret = PyModule_AddObject(super, "pychrysalide.analysis", module); - - result = (ret == 0); - - result &= register_python_loaded_binary(module); - result &= register_python_binary_routine(module); - result &= register_python_instructions_block(module); - result &= add_binaries_module_to_python_module(module); - result &= add_blocks_module_to_python_module(module); + assert(result); return result; } -#endif diff --git a/plugins/pychrysa/analysis/roptions.c b/plugins/pychrysa/analysis/roptions.c deleted file mode 100644 index 72e99e5..0000000 --- a/plugins/pychrysa/analysis/roptions.c +++ /dev/null @@ -1,276 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * roptions.c - équivalent Python du fichier "analysis/roptions.h" - * - * Copyright (C) 2010-2013 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "roptions.h" - - -#include <pygobject.h> - - -#include "../format/executable.h" - - - - -/* Classe 'analysis.roptions' pour Python */ -typedef struct _py_rendering_options -{ - PyObject_HEAD - - GRenderingOptions *glib; /* Options réelles manipulées */ - -} py_rendering_options; - - - - -/* Crée un nouvel objet Python de type 'py_rendering_options'. */ -static PyObject *py_rendering_options_new(PyTypeObject *, PyObject *, PyObject *); - - - -/* Indique si les adresses des instructions sont à afficher. */ -static PyObject *py_rendering_options_get_show_address(PyObject *, void *); - -/* Affiche (ou non) les adresses des instructions. */ -static int py_rendering_options_set_show_address(PyObject *, PyObject *, void *); - - - - -/* Affiche (ou non) le code des instructions. */ -static PyObject *py_rendering_options_show_code(PyObject *, PyObject *); - - - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'py_rendering_options'. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_rendering_options_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - py_rendering_options *result; /* Instance à retourner */ - PyObject *executable; /* Format d'exécutable joint */ - int ret; /* Bilan de lecture des args. */ - GExeFormat *_executable; /* Version GLib du format */ - - ret = PyArg_ParseTuple(args, "O", &executable); - if (!ret) Py_RETURN_NONE; - - result = (py_rendering_options *)type->tp_alloc(type, 0); - - _executable = G_EXE_FORMAT(pygobject_get(executable)); - if (_executable == NULL) return NULL; - - g_object_ref(G_OBJECT(_executable)); - result->glib = g_rendering_options_new(_executable); - - return (PyObject *)result; - -} - - -/****************************************************************************** -* * -* Paramètres : roptions = instance Python dont la référence est à donner. * -* * -* Description : Fournit l'instance GLib d'une instance Python. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GRenderingOptions *py_rendering_options_get_glib_instance(PyObject *roptions) -{ - return ((py_rendering_options *)roptions)->glib; - -} - - - - -/****************************************************************************** -* * -* Paramètres : self = classe présentant des options de représentation. * -* data = adresse non utilisée ici. * -* * -* Description : Indique si les adresses des instructions sont à afficher. * -* * -* Retour : Valeur booléenne indiquant le statut d'une option. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_rendering_options_get_show_address(PyObject *self, void *data) -{ - - printf(" -->> get address\n"); - - return Py_BuildValue("i", true); - -} - - -/****************************************************************************** -* * -* Paramètres : self = classe présentant des options de représentation. * -* value = nouvelle valeur affectée. * -* data = adresse non utilisée ici. * -* * -* Description : Affiche (ou non) les adresses des instructions. * -* * -* Retour : Bilan de la mise à jour. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int py_rendering_options_set_show_address(PyObject *self, PyObject *value, void *data) -{ - printf(" -->> set address\n"); - - return 0; - -} - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : self = classe assurant le lien avec l'éditeur de messages. * -* args = arguments fournis à l'appel. * -* * -* Description : Affiche (ou non) le code des instructions. * -* * -* Retour : Rien en équivalent Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_rendering_options_show_code(PyObject *self, PyObject *args) -{ - int state; /* Nouveau statut d'affichage */ - - if (!PyArg_ParseTuple(args, "i", &state)) - return NULL; - - - - - printf("show code :: %d\n", state); - - Py_RETURN_NONE; - -} - - - - - - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Ajoute l'objet 'analysis.roptions' au module Python. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool add_analysis_roptions_to_python_module(PyObject *module) -{ - int ret; /* Bilan d'un appel */ - - static PyMethodDef py_rendering_options_methods[] = { - { - "show_code", (PyCFunction)py_rendering_options_show_code, - METH_VARARGS, - "Define if the binary code has to be processed or not." - }, - { NULL } - }; - - static PyGetSetDef py_rendering_options_getset[] = { - { - "show_address", - (getter)py_rendering_options_get_show_address, - (setter)py_rendering_options_set_show_address, - "Define or retrieve if the instruction address need to be shown." - }, - { NULL } - }; - - static PyTypeObject py_rendering_options_type = { - - PyObject_HEAD_INIT(NULL) - - .tp_name = "pyoida.analysis.RenderingOptions", - .tp_basicsize = sizeof(py_rendering_options), - - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - - .tp_doc = "PyOIDA rendering options", - - .tp_methods = py_rendering_options_methods, - .tp_getset = py_rendering_options_getset, - .tp_new = (newfunc)py_rendering_options_new - - }; - - if (PyType_Ready(&py_rendering_options_type) < 0) - return false; - - Py_INCREF(&py_rendering_options_type); - ret = PyModule_AddObject(module, "RenderingOptions", (PyObject *)&py_rendering_options_type); - - return (ret == 0); - -} diff --git a/plugins/pychrysa/analysis/roptions.h b/plugins/pychrysa/analysis/roptions.h deleted file mode 100644 index 76ad2fe..0000000 --- a/plugins/pychrysa/analysis/roptions.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * roptions.h - prototypes pour l'équivalent Python du fichier "analysis/roptions.h" - * - * Copyright (C) 2010-2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_PYOIDA_ANALYSIS_ROPTIONS_H -#define _PLUGINS_PYOIDA_ANALYSIS_ROPTIONS_H - - -#include <Python.h> -#include <stdbool.h> - - -#include <analysis/roptions.h> - - - -/* Fournit l'instance GLib d'une instance Python. */ -GRenderingOptions *py_rendering_options_get_glib_instance(PyObject *); - -/* Ajoute l'objet 'analysis.roptions' au module Python. */ -bool add_analysis_roptions_to_python_module(PyObject *); - - - -#endif /* _PLUGINS_PYOIDA_ANALYSIS_ROPTIONS_H */ diff --git a/plugins/pychrysa/analysis/routine.c b/plugins/pychrysa/analysis/routine.c index 5cd56f5..2ca3560 100644 --- a/plugins/pychrysa/analysis/routine.c +++ b/plugins/pychrysa/analysis/routine.c @@ -25,25 +25,31 @@ #include "routine.h" +#include <string.h> #include <pygobject.h> -#include <analysis/routine.h> +#include <i18n.h> +#include <analysis/routine.h> -/* Crée un nouvel objet Python de type 'BinaryRoutine'. */ -static PyObject *py_binary_routine_new(PyTypeObject *, PyObject *, PyObject *); +#include "block.h" -/* Fournit les blocs basiques de la routine. */ -static PyObject *py_binary_routine_get_basic_blocks(PyObject *, void *); +/* Crée un nouvel objet Python de type 'BinRoutine'. */ +static PyObject *py_binary_routine_new(PyTypeObject *, PyObject *, PyObject *); -/* Décrit le prototype de la routine sous forme de caractères. */ -static PyObject *py_binary_routine_str(PyObject *); +/* Fournit le nom humain d'une routine. */ +static PyObject *py_binary_routine_get_name(PyObject *, void *); +/* Définit le nom humain d'une routine. */ +static int py_binary_routine_set_name(PyObject *, PyObject *, void *); + +/* Fournit les blocs basiques de la routine. */ +static PyObject *py_binary_routine_get_basic_blocks(PyObject *, void *); @@ -72,7 +78,75 @@ static PyObject *py_binary_routine_new(PyTypeObject *type, PyObject *args, PyObj } +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le nom humain d'une routine. * +* * +* Retour : Désignation humainement lisible ou None si non définie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_routine_get_name(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBinRoutine *routine; /* Elément à consulter */ + const char *name; /* Désignation courante */ + + routine = G_BIN_ROUTINE(pygobject_get(self)); + name = g_binary_routine_get_name(routine); + + if (name != NULL) + result = PyUnicode_FromString(name); + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Définit le nom humain d'une routine. * +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_binary_routine_set_name(PyObject *self, PyObject *value, void *closure) +{ + GBinRoutine *routine; /* Elément à consulter */ + + if (!PyUnicode_Check(value) && value != Py_None) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string.")); + return -1; + } + + routine = G_BIN_ROUTINE(pygobject_get(self)); + + if (!PyUnicode_Check(value)) + g_binary_routine_set_name(routine, strdup(PyUnicode_DATA(value))); + else + g_binary_routine_set_name(routine, NULL); + return 0; + +} /****************************************************************************** @@ -104,78 +178,76 @@ static PyObject *py_binary_routine_get_basic_blocks(PyObject *self, void *closur } - - - /****************************************************************************** * * -* Paramètres : self = classe représentant une routine binaire. * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * * * -* Description : Décrit le prototype de la routine sous forme de caractères. * +* Description : Définit les blocs basiques de la routine. * * * -* Retour : Chaîne de caractères. * +* Retour : Bilan de l'opération pour Python. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_binary_routine_str(PyObject *self) +static int py_binary_routine_set_basic_blocks(PyObject *self, PyObject *value, void *closure) { - PyObject *result; /* Chaîne à retourner */ - GBinRoutine *routine; /* Version native */ - char *string; /* Description à libérer */ + GBinRoutine *routine; /* Elément à consulter */ + int ret; /* Bilan de lecture des args. */ + GInstrBlock *blocks; /* Blocs basiques à intégrer */ - routine = G_BIN_ROUTINE(pygobject_get(self)); - string = g_binary_routine_to_string(routine); + ret = PyObject_IsInstance(value, (PyObject *)get_python_instr_block_type()); + if (!ret) return -1; - result = PyString_FromString(string); + routine = G_BIN_ROUTINE(pygobject_get(self)); + blocks = G_INSTR_BLOCK(pygobject_get(value)); - free(string); + g_binary_routine_set_basic_blocks(routine, blocks); - return result; + return 0; } /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : - * * * -* Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.* +* Description : Fournit un accès à une définition de type à diffuser. * * * -* Retour : Bilan de l'opération. * +* Retour : Définition d'objet pour Python. * * * * Remarques : - * * * ******************************************************************************/ -bool register_python_binary_routine(PyObject *module) +PyTypeObject *get_python_binary_routine_type(void) { - PyObject *pygobj_mod; /* Module Python-GObject */ - int ret; /* Bilan d'un appel */ - static PyMethodDef py_binary_routine_methods[] = { { NULL } }; static PyGetSetDef py_binary_routine_getseters[] = { { - "basic_blocks", (getter)py_binary_routine_get_basic_blocks, (setter)NULL, - "Provide the basic blocks of the binary routine.", NULL + "name", py_binary_routine_get_name, py_binary_routine_set_name, + "Name of the current routine.", NULL + }, + { + "basic_blocks", py_binary_routine_get_basic_blocks, py_binary_routine_set_basic_blocks, + "Basic blocks of the binary routine.", NULL }, { NULL } }; static PyTypeObject py_binary_routine_type = { - PyObject_HEAD_INIT(NULL) - - .tp_name = "pychrysalide.analysis.BinaryRoutine", - .tp_basicsize = sizeof(PyGObject), + PyVarObject_HEAD_INIT(NULL, 0) - .tp_str = py_binary_routine_str, + .tp_name = "pychrysalide.analysis.BinRoutine", - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = "PyChrysalide binary routine", @@ -185,21 +257,45 @@ bool register_python_binary_routine(PyObject *module) }; - pygobj_mod = PyImport_ImportModule("gobject"); - if (pygobj_mod == NULL) return false; + return &py_binary_routine_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.analysis.BinRoutine'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_binary_routine(PyObject *module) +{ + PyTypeObject *py_binary_routine_type; /* Type Python 'BinRoutine' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_binary_routine_type = get_python_binary_routine_type(); - py_binary_routine_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); - Py_DECREF(pygobj_mod); + py_binary_routine_type->tp_base = &PyGObject_Type; + py_binary_routine_type->tp_basicsize = py_binary_routine_type->tp_base->tp_basicsize; - if (PyType_Ready(&py_binary_routine_type) < 0) + if (PyType_Ready(py_binary_routine_type) != 0) return false; - Py_INCREF(&py_binary_routine_type); - ret = PyModule_AddObject(module, "BinaryRoutine", (PyObject *)&py_binary_routine_type); + Py_INCREF(py_binary_routine_type); + ret = PyModule_AddObject(module, "BinRoutine", (PyObject *)py_binary_routine_type); + if (ret != 0) return false; - pygobject_register_class(module, "GBinRoutine", G_TYPE_BIN_ROUTINE, &py_binary_routine_type, - Py_BuildValue("(O)", py_binary_routine_type.tp_base)); + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "BinRoutine", G_TYPE_BIN_ROUTINE, py_binary_routine_type, + Py_BuildValue("(O)", py_binary_routine_type->tp_base)); - return (ret == 0); + return true; } diff --git a/plugins/pychrysa/analysis/routine.h b/plugins/pychrysa/analysis/routine.h index 7c72fa4..ec61466 100644 --- a/plugins/pychrysa/analysis/routine.h +++ b/plugins/pychrysa/analysis/routine.h @@ -31,7 +31,10 @@ -/* Prend en charge l'objet 'pychrysalide.analysis.BinaryRoutine'. */ +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_binary_routine_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.BinRoutine'. */ bool register_python_binary_routine(PyObject *); |