diff options
Diffstat (limited to 'plugins/pychrysalide/format/program.c')
-rw-r--r-- | plugins/pychrysalide/format/program.c | 188 |
1 files changed, 174 insertions, 14 deletions
diff --git a/plugins/pychrysalide/format/program.c b/plugins/pychrysalide/format/program.c index d96c2db..28c1540 100644 --- a/plugins/pychrysalide/format/program.c +++ b/plugins/pychrysalide/format/program.c @@ -35,6 +35,8 @@ #include "../access.h" #include "../constants.h" #include "../helpers.h" +#include "../analysis/content.h" +#include "../arch/vmpa.h" /* @@ -44,7 +46,6 @@ #include "symiter.h" #include "../analysis/constants.h" #include "../analysis/content.h" -#include "../arch/vmpa.h" #include "../arch/constants.h" */ @@ -64,6 +65,9 @@ static int py_program_format_init(PyObject *, PyObject *, PyObject *); /* Indique le boutisme employé par le format binaire analysé. */ static SourceEndian py_program_format_get_endianness_wrapper(const GProgramFormat *); +/* Fournit l'emplacement d'une section donnée. */ +static bool py_program_format_get_section_range_by_name_wrapper(const GProgramFormat *, const char *, mrange_t *); + /* ---------------------------- FORMAT BINAIRE GENERIQUE ---------------------------- */ @@ -78,7 +82,14 @@ static PyObject *py_program_format_unset_flag(PyObject *, PyObject *); /* Détermine si un format possède un fanion particulier. */ static PyObject *py_program_format_has_flag(PyObject *, PyObject *); +#endif + + +/* Fournit l'emplacement d'une section donnée. */ +static PyObject *py_program_format_get_section_range_by_name(PyObject *, PyObject *); + +#if 0 /* Enregistre une adresse comme début d'une zone de code. */ static PyObject *py_program_format_register_code_point(PyObject *, PyObject *); @@ -143,6 +154,7 @@ static PyObject *py_program_format_get_errors(PyObject *, void *); static void py_program_format_init_gclass(GProgramFormatClass *class, gpointer unused) { class->get_endian = py_program_format_get_endianness_wrapper; + class->get_range_by_name = py_program_format_get_section_range_by_name_wrapper; } @@ -163,25 +175,42 @@ static void py_program_format_init_gclass(GProgramFormatClass *class, gpointer u static int py_program_format_init(PyObject *self, PyObject *args, PyObject *kwds) { + GBinContent *content; /* Contenu à intégrer au format*/ int ret; /* Bilan de lecture des args. */ - -#define PROGRAM_FORMAT_DOC \ - "The ProgramFormat class is the major part of binary format" \ - " support. It is the core class used by loading most of the binary" \ - " files.\n" \ - "\n" \ - "\n" \ - "The following method has to be defined for new classes:\n" \ - "* pychrysalide.format.ProgramFormat._get_endianness().\n" \ - "\n" \ - "Calls to the *__init__* constructor of this abstract object expect"\ - " no particular argument." + GProgramFormat *format; /* Format à manipuler */ + +#define PROGRAM_FORMAT_DOC \ + "The ProgramFormat class is the major part of binary format" \ + " support. It is the core class used by loading most of the binary" \ + " files.\n" \ + "\n" \ + "The following method has to be defined for new classes:\n" \ + "* pychrysalide.format.ProgramFormat._get_endianness().\n" \ + "\n" \ + "Other optional method may be defined for new classes:\n" \ + "* pychrysalide.format.ProgramFormat._get_section_range_by_name().\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_PROGRAM_FORMAT(pygobject_get(self)); + + if (!g_program_format_create(format, content)) + return -1; + return 0; } @@ -252,11 +281,84 @@ static SourceEndian py_program_format_get_endianness_wrapper(const GProgramForma } +/****************************************************************************** +* * +* Paramètres : format = description du programme à consulter. * +* name = nom de la section recherchée. * +* range = emplacement en mémoire à renseigner. [OUT] * +* * +* Description : Fournit l'emplacement d'une section donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_program_format_get_section_range_by_name_wrapper(const GProgramFormat *format, const char *name, mrange_t *range) +{ + bool result; /* Bilan à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pyret; /* Valeur retournée */ + int ret; /* Bilan d'une conversion */ + +#define PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _get_section_range_by_name_wrapper, "$self, name", \ + METH_VARARGS, \ + "Abstract method used to compute the area of a section identified by" \ + " its name.\n" \ + "\n" \ + "The expected returned value is a pychrysalide.arch.mrange instance or" \ + " *None* in case of failure." \ +) + + result = false; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(format)); + + if (has_python_method(pyobj, "_get_section_range_by_name")) + { + pyret = run_python_method(pyobj, "_get_section_range_by_name", NULL); + + if (pyret != NULL) + { + if (pyret == Py_None) + result = false; + + else + { + ret = convert_any_to_mrange(pyret, range); + + result = (ret == 1); + + if (!result) + PyErr_Clear(); + + } + + Py_DECREF(pyret); + + } + + } + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* FORMAT BINAIRE GENERIQUE */ /* ---------------------------------------------------------------------------------- */ - #if 0 /****************************************************************************** * * @@ -402,10 +504,66 @@ static PyObject *py_program_format_has_flag(PyObject *self, PyObject *args) return result; } +#endif /****************************************************************************** * * +* Paramètres : self = serveur à manipuler. * +* args = arguments d'appel non utilisés ici. * +* * +* Description : Fournit l'emplacement d'une section donnée. * +* * +* Retour : Emplacement ou None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_program_format_get_section_range_by_name(PyObject *self, PyObject *args) +{ + PyObject *result; /* Emplacement à retourner */ + const char *name; /* Nom de section ciblée */ + int ret; /* Bilan de lecture des args. */ + GProgramFormat *format; /* Elément à manipuler */ + mrange_t range; /* Emplacement obtenu ? */ + bool status; /* Bilan de l'opération */ + +#define PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_METHOD PYTHON_METHOD_DEF \ +( \ + get_section_range_by_name, "$self, name, /", \ + METH_VARARGS, py_program_format, \ + "Compute the area of a section identified by its name.\n" \ + "\n" \ + "The *name* argument is a string value.\n" \ + "\n" \ + "The returned value is a pychrysalide.arch.mrange instance or" \ + " *None* in case of failure." \ +) + + ret = PyArg_ParseTuple(args, "s", &name); + if (!ret) return NULL; + + format = G_PROGRAM_FORMAT(pygobject_get(self)); + + status = g_program_format_get_section_range_by_name(format, name, &range); + + if (status) + result = build_from_internal_mrange(&range); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + +#if 0 +/****************************************************************************** +* * * Paramètres : self = classe représentant un format. * * args = arguments fournis à l'appel. * * * @@ -1036,6 +1194,8 @@ PyTypeObject *get_python_program_format_type(void) { static PyMethodDef py_program_format_methods[] = { PROGRAM_FORMAT_GET_ENDIANNESS_WRAPPER, + PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_WRAPPER, + PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_METHOD, /* PROGRAM_FORMAT_SET_FLAG_METHOD, PROGRAM_FORMAT_UNSET_FLAG_METHOD, |