summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-05-21 12:08:29 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-05-21 12:08:29 (GMT)
commit7e5b1add6fdeb74b2356acf8ccf7009f45cfa85e (patch)
treeb7373554017e97fcbe24db79d9818272764e858d /plugins/pychrysalide/format
parent5dd935b27a765177960bdfe4d2fcb296cbbd41da (diff)
Changed the hierarchy of format objects.
Diffstat (limited to 'plugins/pychrysalide/format')
-rw-r--r--plugins/pychrysalide/format/format.c167
-rw-r--r--plugins/pychrysalide/format/known.c177
-rw-r--r--plugins/pychrysalide/format/known.h3
-rw-r--r--plugins/pychrysalide/format/strsym.c8
4 files changed, 186 insertions, 169 deletions
diff --git a/plugins/pychrysalide/format/format.c b/plugins/pychrysalide/format/format.c
index 6c1d2da..34826cf 100644
--- a/plugins/pychrysalide/format/format.c
+++ b/plugins/pychrysalide/format/format.c
@@ -33,6 +33,7 @@
#include "constants.h"
#include "executable.h"
+#include "known.h"
#include "symbol.h"
#include "symiter.h"
#include "../access.h"
@@ -53,9 +54,6 @@ static PyObject *py_binary_format_unset_flag(PyObject *, PyObject *);
/* Détermine si un format possède un fanion particulier. */
static PyObject *py_binary_format_has_flag(PyObject *, PyObject *);
-/* Assure l'interprétation d'un format en différé. */
-static PyObject *py_binary_format_analyze(PyObject *, PyObject *, PyObject *);
-
/* Enregistre une adresse comme début d'une zone de code. */
static PyObject *py_binary_format_register_code_point(PyObject *, PyObject *);
@@ -80,15 +78,6 @@ static PyObject *py_binary_format_resolve_symbol(PyObject *, PyObject *);
/* Fournit les particularités du format. */
static PyObject *py_binary_format_get_flags(PyObject *, void *);
-/* Indique la désignation interne du format. */
-static PyObject *py_binary_format_get_name(PyObject *, void *);
-
-/* Indique la désignation humaine du format. */
-static PyObject *py_binary_format_get_description(PyObject *, void *);
-
-/* Fournit une référence vers le contenu binaire analysé. */
-static PyObject *py_binary_format_get_content(PyObject *, void *);
-
/* Fournit la liste de tous les symboles détectés. */
static PyObject *py_binary_format_get_symbols(PyObject *, void *);
@@ -263,50 +252,6 @@ static PyObject *py_binary_format_has_flag(PyObject *self, PyObject *args)
/******************************************************************************
* *
-* Paramètres : self = contenu binaire à manipuler. *
-* args = arguments fournis à l'appel. *
-* kwds = arguments de type key=val fournis. *
-* *
-* Description : Assure l'interprétation d'un format en différé. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_binary_format_analyze(PyObject *self, PyObject *args, PyObject *kwds)
-{
- PyObject *result; /* Bilan à retourner */
- GBinFormat *format; /* Version GLib de l'élément */
- bool status; /* Bilan d'analyse à recevoir */
-
-#define BINARY_FORMAT_ANALYZE_METHOD PYTHON_METHOD_DEF \
-( \
- analyze, "$self", \
- METH_NOARGS, py_binary_format, \
- "Analyze the the format recognized from a binary content.\n" \
- "\n" \
- "Once this analysis is done, a few early symbols and the mapped" \
- " sections are expected to be defined.\n" \
- "\n" \
- "The return value is a boolean status of the operation." \
-)
-
- format = G_BIN_FORMAT(pygobject_get(self));
-
- status = g_binary_format_analyze(format, 0, NULL);
-
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : self = classe représentant un format. *
* args = arguments fournis à l'appel. *
* *
@@ -642,98 +587,6 @@ static PyObject *py_binary_format_get_flags(PyObject *self, void *closure)
/******************************************************************************
* *
-* Paramètres : self = objet Python concerné par l'appel. *
-* closure = non utilisé ici. *
-* *
-* Description : Indique la désignation interne du format. *
-* *
-* Retour : Description du format. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_binary_format_get_name(PyObject *self, void *closure)
-{
- PyObject *result; /* Trouvailles à retourner */
- GBinFormat *format; /* Format de binaire manipulé */
- const char *name; /* Description interne */
-
- format = G_BIN_FORMAT(pygobject_get(self));
-
- name = g_binary_format_get_name(format);
-
- result = PyUnicode_FromString(name);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = objet Python concerné par l'appel. *
-* closure = non utilisé ici. *
-* *
-* Description : Indique la désignation humaine du format. *
-* *
-* Retour : Description du format. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_binary_format_get_description(PyObject *self, void *closure)
-{
- PyObject *result; /* Trouvailles à retourner */
- GBinFormat *format; /* Format de binaire manipulé */
- const char *desc; /* Description humaine */
-
- format = G_BIN_FORMAT(pygobject_get(self));
-
- desc = g_binary_format_get_description(format);
-
- result = PyUnicode_FromString(desc);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = objet Python concerné par l'appel. *
-* closure = non utilisé ici. *
-* *
-* Description : Fournit une référence vers le contenu binaire analysé. *
-* *
-* Retour : Gestionnaire de contenu binaire en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_binary_format_get_content(PyObject *self, void *closure)
-{
- PyObject *result; /* Trouvailles à retourner */
- GBinFormat *format; /* Format de binaire manipulé */
- GBinContent *content; /* Instance GLib correspondante*/
-
- format = G_BIN_FORMAT(pygobject_get(self));
-
- content = g_binary_format_get_content(format);
-
- result = pygobject_new(G_OBJECT(content));
-
- g_object_unref(content);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : self = classe représentant un format binaire. *
* closure = adresse non utilisée ici. *
* *
@@ -884,7 +737,6 @@ PyTypeObject *get_python_binary_format_type(void)
BINARY_FORMAT_SET_FLAG_METHOD,
BINARY_FORMAT_UNSET_FLAG_METHOD,
BINARY_FORMAT_HAS_FLAG_METHOD,
- BINARY_FORMAT_ANALYZE_METHOD,
{
"register_code_point", py_binary_format_register_code_point,
METH_VARARGS,
@@ -931,18 +783,6 @@ PyTypeObject *get_python_binary_format_type(void)
static PyGetSetDef py_bin_format_getseters[] = {
BINARY_FORMAT_FLAGS_ATTRIB,
{
- "name", py_binary_format_get_name, NULL,
- "Internal name of the binary format.", NULL
- },
- {
- "description", py_binary_format_get_description, NULL,
- "Human description of the binary format.", NULL
- },
- {
- "content", py_binary_format_get_content, NULL,
- "Content of the binary format.", NULL
- },
- {
"symbols", py_binary_format_get_symbols, NULL,
"Iterable list of all symbols found in the binary format.", NULL
},
@@ -1002,7 +842,10 @@ bool ensure_python_binary_format_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, G_TYPE_BIN_FORMAT, type, &PyGObject_Type))
+ if (!ensure_python_known_format_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_BIN_FORMAT, type, get_python_known_format_type()))
return false;
if (!define_binary_format_constants(type))
diff --git a/plugins/pychrysalide/format/known.c b/plugins/pychrysalide/format/known.c
index c3b5b9d..d75dd05 100644
--- a/plugins/pychrysalide/format/known.c
+++ b/plugins/pychrysalide/format/known.c
@@ -60,6 +60,9 @@ 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 *);
+/* Réalise un traitement post-désassemblage. */
+static void py_known_format_complete_analysis_wrapper(GKnownFormat *, wgroup_id_t, GtkStatusStack *);
+
/* --------------------------- DEFINITION DU FORMAT CONNU --------------------------- */
@@ -68,6 +71,9 @@ static bool py_known_format_analyze_wrapper(GKnownFormat *, wgroup_id_t, GtkStat
/* Assure l'interprétation d'un format en différé. */
static PyObject *py_known_format_analyze(PyObject *, PyObject *);
+/* Réalise un traitement post-désassemblage. */
+static PyObject *py_known_format_complete_analysis(PyObject *, PyObject *);
+
/* Indique la désignation interne du format. */
static PyObject *py_known_format_get_key(PyObject *, void *);
@@ -166,6 +172,7 @@ static void py_known_format_init_gclass(GKnownFormatClass *class, gpointer unuse
class->get_desc = py_known_format_get_description_wrapper;
class->analyze = py_known_format_analyze_wrapper;
+ class->complete = py_known_format_complete_analysis_wrapper;
}
@@ -203,6 +210,9 @@ static int py_known_format_init(PyObject *self, PyObject *args, PyObject *kwds)
"* pychrysalide.format.KnownFormat._get_description();\n" \
"* pychrysalide.format.KnownFormat._analyze().\n" \
"\n" \
+ "The following method may also be defined for new classes too:\n" \
+ "* pychrysalide.format.KnownFormat._complete_analysis().\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."
@@ -401,6 +411,62 @@ static bool py_known_format_analyze_wrapper(GKnownFormat *format, wgroup_id_t gi
}
+/******************************************************************************
+* *
+* 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 : Réalise un traitement post-désassemblage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_known_format_complete_analysis_wrapper(GKnownFormat *format, wgroup_id_t gid, GtkStatusStack *status)
+{
+ 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_COMPLETE_ANALYSIS_WRAPPER PYTHON_VOID_WRAPPER_DEF \
+( \
+ _complete_analysis, "$self, gid, status, /", \
+ METH_VARARGS, \
+ "Abstract method used to complete an analysis of a known format.\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" \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(format));
+
+ if (has_python_method(pyobj, "_complete_analysis"))
+ {
+ 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, "_complete_analysis", args);
+
+ Py_DECREF(args);
+ Py_XDECREF(pyret);
+
+ }
+
+ PyGILState_Release(gstate);
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* DEFINITION DU FORMAT CONNU */
@@ -461,6 +527,57 @@ static PyObject *py_known_format_analyze(PyObject *self, PyObject *args)
/******************************************************************************
* *
+* Paramètres : self = objet représentant un format connu. *
+* args = arguments fournis pour l'opération. *
+* *
+* Description : Réalise un traitement post-désassemblage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_known_format_complete_analysis(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ int ret; /* Bilan de lecture des args. */
+ GKnownFormat *format; /* Format connu manipulé */
+
+#define KNOWN_FORMAT_COMPLETE_ANALYSIS_METHOD PYTHON_METHOD_DEF \
+( \
+ complete_analysis, "$self, gid, status, /", \
+ METH_VARARGS, py_known_format, \
+ "Complete an analysis of a known format.\n" \
+ "\n" \
+ "This process is usually done once the disassembling process" \
+ " is completed.\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);
+ if (!ret) return NULL;
+
+ format = G_KNOWN_FORMAT(pygobject_get(self));
+
+ g_known_format_complete_analysis(format, 0, NULL);
+
+ result = Py_None;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
@@ -566,9 +683,16 @@ static PyObject *py_known_format_get_content(PyObject *self, void *closure)
content = g_known_format_get_content(format);
- result = pygobject_new(G_OBJECT(content));
-
- g_object_unref(content);
+ if (content != NULL)
+ {
+ result = pygobject_new(G_OBJECT(content));
+ g_object_unref(content);
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
@@ -592,7 +716,9 @@ PyTypeObject *get_python_known_format_type(void)
static PyMethodDef py_known_format_methods[] = {
KNOWN_FORMAT_GET_DESCRIPTION_WRAPPER,
KNOWN_FORMAT_ANALYZE_WRAPPER,
+ KNOWN_FORMAT_COMPLETE_ANALYSIS_WRAPPER,
KNOWN_FORMAT_ANALYZE_METHOD,
+ KNOWN_FORMAT_COMPLETE_ANALYSIS_METHOD,
{ NULL }
};
@@ -661,3 +787,48 @@ bool ensure_python_known_format_is_registered(void)
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en format connu. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_known_format(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_known_format_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to known format");
+ break;
+
+ case 1:
+ *((GKnownFormat **)dst) = G_KNOWN_FORMAT(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/format/known.h b/plugins/pychrysalide/format/known.h
index 16cbf83..45d0e2c 100644
--- a/plugins/pychrysalide/format/known.h
+++ b/plugins/pychrysalide/format/known.h
@@ -37,6 +37,9 @@ PyTypeObject *get_python_known_format_type(void);
/* Prend en charge l'objet 'pychrysalide.format.KnownFormat'. */
bool ensure_python_known_format_is_registered(void);
+/* Tente de convertir en format connu. */
+int convert_to_known_format(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_FORMAT_KNOWN_H */
diff --git a/plugins/pychrysalide/format/strsym.c b/plugins/pychrysalide/format/strsym.c
index 2824677..9c86df4 100644
--- a/plugins/pychrysalide/format/strsym.c
+++ b/plugins/pychrysalide/format/strsym.c
@@ -37,7 +37,7 @@
#include "constants.h"
-#include "format.h"
+#include "known.h"
#include "symbol.h"
#include "../access.h"
#include "../helpers.h"
@@ -159,7 +159,7 @@ static PyObject *py_string_symbol_new(PyTypeObject *type, PyObject *args, PyObje
static int py_string_symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
{
StringEncodingType encoding; /* Encodage spécifié */
- GBinFormat *format; /* Format au contenu à relire */
+ GKnownFormat *format; /* Format au contenu à relire */
mrange_t range; /* Version native d'un espace */
const char *string; /* Chaîne de caractères soumise*/
vmpa2t *addr; /* Emplacement de chaîne */
@@ -173,7 +173,7 @@ static int py_string_symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
"\n" \
"Instances can be created using one of the following constructors:\n" \
"\n" \
- " StrSymbol(encoding, format=pychrysalide.format.BinFormat," \
+ " StrSymbol(encoding, format=pychrysalide.format.KnownFormat," \
" range=pychrysalide.arch.mrange)" \
"\n" \
" StrSymbol(encoding, string=string, addr=pychrysalide.arch.vmpa)" \
@@ -198,7 +198,7 @@ static int py_string_symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&sO&", kwlist,
convert_to_string_encoding_type, &encoding,
- convert_to_binary_format, &format,
+ convert_to_known_format, &format,
convert_any_to_mrange, &range,
&string, convert_any_to_vmpa, &addr);
if (!ret) return -1;