summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-07-14 11:01:17 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-07-14 11:01:17 (GMT)
commitde82c8165e61e3c19be184dbc00f66bfc7479c76 (patch)
tree14a1f60c2c975bd2e8a637098ca5948c3637aed8
parent2bd3ea7249d1234204c1b70abac8bc46e221fb95 (diff)
Updated the code handling binary contents.
-rw-r--r--plugins/pychrysalide/analysis/binary.c37
-rw-r--r--plugins/pychrysalide/analysis/content.c687
-rw-r--r--plugins/ropgadgets/select.c12
-rw-r--r--src/analysis/binary.c29
-rw-r--r--src/analysis/binary.h3
-rw-r--r--src/analysis/content-int.h2
-rw-r--r--src/analysis/content.c44
-rw-r--r--src/analysis/content.h2
-rw-r--r--src/analysis/contents/encapsulated.c12
-rw-r--r--src/analysis/contents/file.c17
-rw-r--r--src/analysis/contents/memory.c8
-rw-r--r--src/analysis/disass/disassembler.c4
-rw-r--r--src/gui/dialogs/export_disass.c6
-rw-r--r--src/gui/panels/bintree.c7
14 files changed, 745 insertions, 125 deletions
diff --git a/plugins/pychrysalide/analysis/binary.c b/plugins/pychrysalide/analysis/binary.c
index acc3ae5..2f8af5f 100644
--- a/plugins/pychrysalide/analysis/binary.c
+++ b/plugins/pychrysalide/analysis/binary.c
@@ -58,9 +58,6 @@ static PyObject *py_loaded_binary_add_to_collection(PyObject *, PyObject *);
/* Active les éléments en amont d'un horodatage donné. */
static PyObject *py_loaded_binary_set_last_active(PyObject *, PyObject *);
-/* Fournit le nom associé à l'élément binaire. */
-static PyObject *py_loaded_binary_get_name(PyObject *, void *);
-
/* Fournit l'ensemble des collections utilisées par un binaire. */
static PyObject *py_loaded_binary_get_collections(PyObject *, void *);
@@ -322,36 +319,6 @@ static PyObject *py_loaded_binary_set_last_active(PyObject *self, PyObject *args
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
-* Description : Fournit le nom associé à l'élément binaire. *
-* *
-* Retour : Nom de fichier avec chemin absolu. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_loaded_binary_get_name(PyObject *self, void *closure)
-{
- PyObject *result; /* Trouvailles à retourner */
- GLoadedBinary *binary; /* Version native */
- const char *name; /* Désignation du binaire */
-
- binary = G_LOADED_BINARY(pygobject_get(self));
-
- name = g_loaded_binary_get_name(binary, true);
-
- result = PyUnicode_FromString(name);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = objet Python concerné par l'appel. *
-* closure = non utilisé ici. *
-* *
* Description : Fournit l'ensemble des collections utilisées par un binaire. *
* *
* Retour : Liste de collections en place. *
@@ -536,10 +503,6 @@ PyTypeObject *get_python_loaded_binary_type(void)
};
static PyGetSetDef py_loaded_binary_getseters[] = {
- {
- "name", py_loaded_binary_get_name, NULL,
- "Name of the loaded binary.", NULL
- },
LOADED_BINARY_COLLECTIONS_ATTRIB,
{
"format", py_loaded_binary_get_format, NULL,
diff --git a/plugins/pychrysalide/analysis/content.c b/plugins/pychrysalide/analysis/content.c
index 8a404ed..5b5608c 100644
--- a/plugins/pychrysalide/analysis/content.c
+++ b/plugins/pychrysalide/analysis/content.c
@@ -26,13 +26,15 @@
#include <assert.h>
+#include <malloc.h>
#include <pygobject.h>
+#include <string.h>
#include <i18n.h>
-#include <analysis/content.h>
+#include <analysis/content-int.h>
#include <common/endianness.h>
@@ -44,15 +46,34 @@
-#define BINARY_CONTENT_DOC \
- "The BinContent is an interface which handles access to a given" \
- " binary content." \
- "\n" \
- "All of its implementations are located in the" \
- " pychrysalide.analysis.contents module. The main implemantation" \
- " is the pychrysalide.analysis.contents.FileContent class."
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+/* Procède à l'initialisation de l'interface de génération. */
+static void py_binary_content_interface_init(GBinContentIface *, gpointer *);
+
+/* Fournit le nom associé au contenu binaire. */
+static char *py_binary_content_describe_wrapper(const GBinContent *, bool);
+
+/* Fournit une portion des données représentées. */
+static bool py_binary_content_read_raw_wrapper(const GBinContent *, vmpa2t *, phys_t, bin_t *);;
+
+/* Lit un nombre non signé sur un octet. */
+static bool py_binary_content_read_u8_wrapper(const GBinContent *, vmpa2t *, uint8_t *);
+
+/* Lit un nombre non signé sur deux octets. */
+static bool py_binary_content_read_u16_wrapper(const GBinContent *, vmpa2t *, SourceEndian, uint16_t *);
+
+/* Lit un nombre non signé sur quatre octets. */
+static bool py_binary_content_read_u32_wrapper(const GBinContent *, vmpa2t *, SourceEndian, uint32_t *);
+
+/* Lit un nombre non signé sur huit octets. */
+static bool py_binary_content_read_u64_wrapper(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
/* Fournit le nom associé au contenu binaire. */
static PyObject *py_binary_content_describe(PyObject *, PyObject *);
@@ -95,6 +116,608 @@ static PyObject *py_binary_content_get_data(PyObject *, void *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* unused = adresse non utilisée ici. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_binary_content_interface_init(GBinContentIface *iface, gpointer *unused)
+{
+#define BINARY_CONTENT_DOC \
+ "The BinContent is an interface which handles access to a given binary" \
+ " content.\n" \
+ "\n" \
+ "All of its implementations are located in the" \
+ " pychrysalide.analysis.contents module. The main implemantation is" \
+ " the pychrysalide.analysis.contents.FileContent class.\n" \
+ "\n" \
+ "A typical class declaration for a new implementation looks like:\n" \
+ "\n" \
+ " class NewImplem(GObject.Object, BinContent):\n" \
+ " ...\n" \
+ "\n" \
+ "The following methods have to be defined for new implementations:\n" \
+ "* pychrysalide.analysis.BinContent._describe();\n" \
+ "* pychrysalide.analysis.BinContent._read_raw();\n" \
+ "* pychrysalide.analysis.BinContent._read_u4();\n" \
+ "* pychrysalide.analysis.BinContent._read_u8();\n" \
+ "* pychrysalide.analysis.BinContent._read_u16();\n" \
+ "* pychrysalide.analysis.BinContent._read_u32();\n" \
+ "* pychrysalide.analysis.BinContent._read_u64();\n"
+
+ iface->describe = py_binary_content_describe_wrapper;
+
+ iface->read_raw = py_binary_content_read_raw_wrapper;
+ iface->read_u8 = py_binary_content_read_u8_wrapper;
+ iface->read_u16 = py_binary_content_read_u16_wrapper;
+ iface->read_u32 = py_binary_content_read_u32_wrapper;
+ iface->read_u64 = py_binary_content_read_u64_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = élément chargé à consulter. *
+* full = précise s'il s'agit d'une version longue ou non. *
+* *
+* Description : Fournit le nom associé au contenu binaire. *
+* *
+* Retour : Nom de fichier avec chemin absolu au besoin. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_binary_content_describe_wrapper(const GBinContent *content, bool full)
+{
+ char *result; /* Description à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *full_obj; /* Précision sur la longueur */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_DESCRIBE_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _describe, "$self, full", \
+ METH_VARARGS, \
+ "Abstract method used to build a (full ?) description of" \
+ " the binary content.describe the loaded content.\n" \
+ "\n" \
+ "The description is returned as a string." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_describe"))
+ {
+ full_obj = full ? Py_True : Py_False;
+ Py_INCREF(full_obj);
+
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, full_obj);
+
+ pyret = run_python_method(pyobj, "_describe", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyUnicode_Check(pyret);
+
+ if (ret)
+ result = strdup(PyUnicode_AsUTF8(pyret));
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* length = quantité d'octets à lire. *
+* out = réceptacle disponible pour ces données. [OUT] *
+* *
+* Description : Fournit une portion des données représentées. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_read_raw_wrapper(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *addr_obj; /* Position en version Python */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+ const char *data; /* Données brutes à copier */
+
+#define BINARY_CONTENT_READ_RAW_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_raw, "$self, addr, length", \
+ METH_VARARGS, \
+ "Abstract method used to provide the bytes read from a given position.\n" \
+ "\n" \
+ "The description is returned as a string." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_read_raw"))
+ {
+ addr_obj = build_from_internal_vmpa(addr);
+
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, addr_obj);
+ PyTuple_SetItem(args, 1, PyLong_FromUnsignedLongLong(length));
+
+ pyret = run_python_method(pyobj, "_read_raw", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyUnicode_Check(pyret);
+
+ if (ret)
+ {
+ assert((phys_t)PyBytes_Size(pyret) == length);
+
+ if ((phys_t)PyBytes_Size(pyret) == length)
+ {
+ /* Avancement de la tête de lecture */
+
+ copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+ /* Récupération des données */
+
+ data = PyBytes_AsString(pyret);
+
+ memcpy(out, data, length);
+
+ /* Bilan à retenir */
+
+ result = true;
+
+ }
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur un octet. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_read_u8_wrapper(const GBinContent *content, vmpa2t *addr, uint8_t *val)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *addr_obj; /* Position en version Python */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_READ_U8_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_u8, "$self, addr", \
+ METH_VARARGS, \
+ "Abstract method used to read an unsigned bytes from a given" \
+ " position.\n" \
+ "\n" \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance.\n" \
+ "\n" \
+ "The returned value is the read data or None is case of error." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_read_u8"))
+ {
+ addr_obj = build_from_internal_vmpa(addr);
+
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, addr_obj);
+
+ pyret = run_python_method(pyobj, "_read_u8", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ {
+ /* Avancement de la tête de lecture */
+
+ copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+ /* Récupération des données */
+
+ *val = PyLong_AsUnsignedLong(pyret);
+
+ /* Bilan à retenir */
+
+ result = true;
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur deux octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *addr_obj; /* Position en version Python */
+ PyObject *endianness_obj; /* Boutisme en version Python */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_READ_U16_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_u16, "$self, addr, endian", \
+ METH_VARARGS, \
+ "Abstract method used to read two unsigned bytes from a given" \
+ " position.\n" \
+ "\n" \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance. The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values.\n" \
+ "\n" \
+ "The returned value is the read data or None is case of error." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_read_u16"))
+ {
+ addr_obj = build_from_internal_vmpa(addr);
+ endianness_obj = cast_with_constants_group_from_type(get_python_binary_content_type(),
+ "SourceEndian", endian);
+
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, addr_obj);
+ PyTuple_SetItem(args, 1, endianness_obj);
+
+ pyret = run_python_method(pyobj, "_read_u16", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ {
+ /* Avancement de la tête de lecture */
+
+ copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+ /* Récupération des données */
+
+ *val = PyLong_AsUnsignedLong(pyret);
+
+ /* Bilan à retenir */
+
+ result = true;
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur quatre octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *addr_obj; /* Position en version Python */
+ PyObject *endianness_obj; /* Boutisme en version Python */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_READ_U32_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_u32, "$self, addr, endian", \
+ METH_VARARGS, \
+ "Abstract method used to read four unsigned bytes from a given" \
+ " position.\n" \
+ "\n" \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance. The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values.\n" \
+ "\n" \
+ "The returned value is the read data or None is case of error." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_read_u32"))
+ {
+ addr_obj = build_from_internal_vmpa(addr);
+ endianness_obj = cast_with_constants_group_from_type(get_python_binary_content_type(),
+ "SourceEndian", endian);
+
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, addr_obj);
+ PyTuple_SetItem(args, 1, endianness_obj);
+
+ pyret = run_python_method(pyobj, "_read_u32", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ {
+ /* Avancement de la tête de lecture */
+
+ copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+ /* Récupération des données */
+
+ *val = PyLong_AsUnsignedLong(pyret);
+
+ /* Bilan à retenir */
+
+ result = true;
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur huit octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *addr_obj; /* Position en version Python */
+ PyObject *endianness_obj; /* Boutisme en version Python */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_READ_U64_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_u64, "$self, addr, endian", \
+ METH_VARARGS, \
+ "Abstract method used to read eight unsigned bytes from a given" \
+ " position.\n" \
+ "\n" \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance. The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values.\n" \
+ "\n" \
+ "The returned value is the read data or None is case of error." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_read_u64"))
+ {
+ addr_obj = build_from_internal_vmpa(addr);
+ endianness_obj = cast_with_constants_group_from_type(get_python_binary_content_type(),
+ "SourceEndian", endian);
+
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, addr_obj);
+ PyTuple_SetItem(args, 1, endianness_obj);
+
+ pyret = run_python_method(pyobj, "_read_u64", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ {
+ /* Avancement de la tête de lecture */
+
+ copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+ /* Récupération des données */
+
+ *val = PyLong_AsUnsignedLongLong(pyret);
+
+ /* Bilan à retenir */
+
+ result = true;
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = contenu binaire à manipuler. *
@@ -114,7 +737,7 @@ static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
int full; /* Description complète ? */
int ret; /* Bilan de lecture des args. */
GBinContent *content; /* Version GLib du format */
- const char *desc; /* Description obtenue */
+ char *desc; /* Description obtenue */
#define BINARY_CONTENT_DESCRIBE_METHOD PYTHON_METHOD_DEF \
( \
@@ -134,6 +757,8 @@ static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
result = PyUnicode_FromString(desc);
+ free(desc);
+
return result;
}
@@ -219,6 +844,11 @@ static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
read_u8, "$self, addr, /", \
METH_VARARGS, py_binary_content, \
"Read an unsigned byte from a given position." \
+ "\n" \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance.\n" \
+ "\n" \
+ "The returned value is the read data or None is case of error." \
)
ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
@@ -274,8 +904,11 @@ static PyObject *py_binary_content_read_u16(PyObject *self, PyObject *args)
METH_VARARGS, py_binary_content, \
"Read two unsigned bytes from a given position." \
"\n" \
- "The endianness of the data can be provided using" \
- " pychrysalide.analysis.BinContent.SourceEndian values." \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance. The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values.\n" \
+ "\n" \
+ "The returned value is the read data or None is case of error." \
)
ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
@@ -331,8 +964,11 @@ static PyObject *py_binary_content_read_u32(PyObject *self, PyObject *args)
METH_VARARGS, py_binary_content, \
"Read four unsigned bytes from a given position." \
"\n" \
- "The endianness of the data can be provided using" \
- " pychrysalide.analysis.BinContent.SourceEndian values." \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance. The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values.\n" \
+ "\n" \
+ "The returned value is the read data or None is case of error." \
)
ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
@@ -385,10 +1021,13 @@ static PyObject *py_binary_content_read_u64(PyObject *self, PyObject *args)
( \
read_u64, "$self, addr, endian, /", \
METH_VARARGS, py_binary_content, \
- "Read eight unsigned bytes from a given position." \
+ "Read eight unsigned bytes from a given position.\n" \
+ "\n" \
+ "The location of the data to read is a pychrysalide.arch.vmpa" \
+ " instance. The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values.\n" \
"\n" \
- "The endianness of the data can be provided using" \
- " pychrysalide.analysis.BinContent.SourceEndian values." \
+ "The returned value is the read data or None is case of error." \
)
ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
@@ -691,6 +1330,12 @@ static PyObject *py_binary_content_get_data(PyObject *self, void *closure)
PyTypeObject *get_python_binary_content_type(void)
{
static PyMethodDef py_binary_content_methods[] = {
+ BINARY_CONTENT_DESCRIBE_WRAPPER,
+ BINARY_CONTENT_READ_RAW_WRAPPER,
+ BINARY_CONTENT_READ_U8_WRAPPER,
+ BINARY_CONTENT_READ_U16_WRAPPER,
+ BINARY_CONTENT_READ_U32_WRAPPER,
+ BINARY_CONTENT_READ_U64_WRAPPER,
BINARY_CONTENT_DESCRIBE_METHOD,
BINARY_CONTENT_READ_RAW_METHOD,
BINARY_CONTENT_READ_U8_METHOD,
@@ -749,6 +1394,14 @@ bool ensure_python_binary_content_is_registered(void)
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
+ static GInterfaceInfo info = { /* Paramètres d'inscription */
+
+ .interface_init = (GInterfaceInitFunc)py_binary_content_interface_init,
+ .interface_finalize = NULL,
+ .interface_data = NULL,
+
+ };
+
type = get_python_binary_content_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
@@ -757,7 +1410,7 @@ bool ensure_python_binary_content_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_BIN_CONTENT, type))
+ if (!register_interface_for_pygobject_2(dict, G_TYPE_BIN_CONTENT, type, &info))
return false;
if (!define_analysis_content_constants(type))
diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c
index aebe433..9df71bb 100644
--- a/plugins/ropgadgets/select.c
+++ b/plugins/ropgadgets/select.c
@@ -474,7 +474,7 @@ static GtkWidget *load_and_populate_current_project_binaries(GObject *ref, gint
GLoadedContent **contents; /* Liste de contenus chargés */
size_t count; /* Taille de cette liste */
size_t i; /* Boucle de parcours */
- GLoadedBinary *binary; /* Contenu de code binaire */
+ char *desc; /* Description de contenu */
GtkTreeIter iter; /* Point d'insertion */
GtkCellRenderer *renderer; /* Moteur de rendu de colonne */
@@ -498,15 +498,17 @@ static GtkWidget *load_and_populate_current_project_binaries(GObject *ref, gint
{
if (G_IS_LOADED_BINARY(contents[i]))
{
- binary = G_LOADED_BINARY(contents[i]);
+ desc = g_loaded_content_describe(contents[i], true);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- CPB_BINARY, binary,
- CPB_FILENAME, g_loaded_binary_get_name(binary, true),
+ CPB_BINARY, contents[i],
+ CPB_FILENAME, desc,
-1);
- if (binary == (GLoadedBinary *)current)
+ free(desc);
+
+ if (contents[i] == current)
*selected = i;
}
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index aee4499..c671827 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -400,35 +400,6 @@ GLoadedContent *g_loaded_binary_new(GExeFormat *format)
}
-/******************************************************************************
-* *
-* Paramètres : binary = élément binaire à consulter. *
-* full = précise s'il s'agit d'une version longue ou non. *
-* *
-* Description : Fournit le nom associé à l'élément binaire. *
-* *
-* Retour : Nom de fichier avec chemin absolu. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-const char *g_loaded_binary_get_name(const GLoadedBinary *binary, bool full)
-{
- const char *result; /* Description à retourner */
- GBinContent *content; /* Contenu binaire mannipulé */
-
- content = g_known_format_get_content(G_KNOWN_FORMAT(binary->format));
-
- result = g_binary_content_describe(content, full);
-
- g_object_unref(G_OBJECT(content));
-
- return result;
-
-}
-
-
/* ---------------------------------------------------------------------------------- */
/* INFORMATIONS D'ENREGISTREMENTS */
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 74c5f7f..178d186 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -76,9 +76,6 @@ GType g_loaded_binary_get_type(void);
/* Interprète un contenu binaire chargé. */
GLoadedContent *g_loaded_binary_new(GExeFormat *);
-/* Fournit le nom associé à l'élément binaire. */
-const char *g_loaded_binary_get_name(const GLoadedBinary *, bool);
-
/* ------------------------- INFORMATIONS D'ENREGISTREMENTS ------------------------- */
diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h
index ad13b8d..886c196 100644
--- a/src/analysis/content-int.h
+++ b/src/analysis/content-int.h
@@ -39,7 +39,7 @@ typedef GContentAttributes * (* get_content_attributes) (const GBinContent *);
typedef GBinContent * (* get_content_root_fc) (GBinContent *);
/* Fournit le nom associé au contenu binaire. */
-typedef const char * (* describe_content_fc) (const GBinContent *, bool);
+typedef char * (* describe_content_fc) (const GBinContent *, bool);
/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
typedef bool (* save_content_fc) (const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 86fa490..8b83261 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -197,14 +197,14 @@ GBinContent *g_binary_content_get_root(GBinContent *content)
* *
******************************************************************************/
-const char *g_binary_content_describe(const GBinContent *content, bool full)
+char *g_binary_content_describe(const GBinContent *content, bool full)
{
char *result; /* Description à retourner */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- result = strdup(iface->describe(content, full));
+ result = iface->describe(content, full);
return result;
@@ -418,11 +418,14 @@ const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t
bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_raw(content, addr, length, out);
+ result = iface->read_raw(content, addr, length, out);
+
+ return result;
}
@@ -444,11 +447,14 @@ bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t
bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, uint8_t *val)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_u4(content, addr, low, val);
+ result = iface->read_u4(content, addr, low, val);
+
+ return result;
}
@@ -470,11 +476,14 @@ bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *lo
bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t *val)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_u8(content, addr, val);
+ result = iface->read_u8(content, addr, val);
+
+ return result;
}
@@ -496,11 +505,14 @@ bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t
bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_u16(content, addr, endian, val);
+ result = iface->read_u16(content, addr, endian, val);
+
+ return result;
}
@@ -522,11 +534,14 @@ bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceE
bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_u32(content, addr, endian, val);
+ result = iface->read_u32(content, addr, endian, val);
+
+ return result;
}
@@ -548,11 +563,14 @@ bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceE
bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_u64(content, addr, endian, val);
+ result = iface->read_u64(content, addr, endian, val);
+
+ return result;
}
@@ -573,11 +591,14 @@ bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceE
bool g_binary_content_read_uleb128(const GBinContent *content, vmpa2t *addr, uleb128_t *val)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_uleb128(content, addr, val);
+ result = iface->read_uleb128(content, addr, val);
+
+ return result;
}
@@ -598,10 +619,13 @@ bool g_binary_content_read_uleb128(const GBinContent *content, vmpa2t *addr, ule
bool g_binary_content_read_leb128(const GBinContent *content, vmpa2t *addr, leb128_t *val)
{
+ bool result; /* Bilan à remonter */
GBinContentIface *iface; /* Interface utilisée */
iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->read_leb128(content, addr, val);
+ result = iface->read_leb128(content, addr, val);
+
+ return result;
}
diff --git a/src/analysis/content.h b/src/analysis/content.h
index 9f901e7..d7f5536 100644
--- a/src/analysis/content.h
+++ b/src/analysis/content.h
@@ -68,7 +68,7 @@ GContentAttributes *g_binary_content_get_attributes(const GBinContent *);
GBinContent *g_binary_content_get_root(GBinContent *);
/* Fournit le nom associé au contenu binaire. */
-const char *g_binary_content_describe(const GBinContent *, bool);
+char *g_binary_content_describe(const GBinContent *, bool);
/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
bool g_binary_content_save(const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
diff --git a/src/analysis/contents/encapsulated.c b/src/analysis/contents/encapsulated.c
index 569df10..59b0c9e 100644
--- a/src/analysis/contents/encapsulated.c
+++ b/src/analysis/contents/encapsulated.c
@@ -74,7 +74,7 @@ static void g_encaps_content_finalize(GEncapsContent *);
static GBinContent *g_encaps_content_get_root(GEncapsContent *);
/* Fournit le nom associé au contenu binaire. */
-static const char *g_encaps_content_describe(const GEncapsContent *, bool);
+static char *g_encaps_content_describe(const GEncapsContent *, bool);
/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
static bool g_encaps_content_save(const GEncapsContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
@@ -296,7 +296,7 @@ GBinContent *g_encaps_content_new(GBinContent *base, const char *path, GBinConte
/* Description complète */
- result->full_desc = stradd(result->full_desc, g_binary_content_describe(result->base, true));
+ result->full_desc = g_binary_content_describe(result->base, true);
result->full_desc = stradd(result->full_desc, G_DIR_SEPARATOR_S);
@@ -416,14 +416,14 @@ static GBinContent *g_encaps_content_get_root(GEncapsContent *content)
* *
******************************************************************************/
-static const char *g_encaps_content_describe(const GEncapsContent *content, bool full)
+static char *g_encaps_content_describe(const GEncapsContent *content, bool full)
{
- const char *result; /* Description à retourner */
+ char *result; /* Description à retourner */
if (full)
- result = content->full_desc;
+ result = strdup(content->full_desc);
else
- result = content->desc;
+ result = strdup(content->desc);
return result;
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index b133336..7bb0be8 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -86,7 +86,7 @@ static GContentAttributes *g_file_content_get_attributes(const GFileContent *);
static GBinContent *g_file_content_get_root(GFileContent *);
/* Fournit le nom associé au contenu binaire. */
-static const char *g_file_content_describe(const GFileContent *, bool);
+static char *g_file_content_describe(const GFileContent *, bool);
/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
static bool g_file_content_save(const GFileContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
@@ -489,22 +489,23 @@ static GBinContent *g_file_content_get_root(GFileContent *content)
* *
******************************************************************************/
-static const char *g_file_content_describe(const GFileContent *content, bool full)
+static char *g_file_content_describe(const GFileContent *content, bool full)
{
- const char *result; /* Description à retourner */
+ char *result; /* Description à retourner */
+ const char *sep; /* Caractère de séparation */
if (full)
- result = content->filename;
+ result = strdup(content->filename);
else
{
- result = strrchr(content->filename, G_DIR_SEPARATOR);
+ sep = strrchr(content->filename, G_DIR_SEPARATOR);
- if (result == NULL)
- result = content->filename;
+ if (sep == NULL)
+ result = strdup(content->filename);
else
- result++;
+ result = strdup(++sep);
}
diff --git a/src/analysis/contents/memory.c b/src/analysis/contents/memory.c
index 232a41d..a37a7d4 100644
--- a/src/analysis/contents/memory.c
+++ b/src/analysis/contents/memory.c
@@ -77,7 +77,7 @@ static void g_memory_content_finalize(GMemoryContent *);
static GBinContent *g_memory_content_get_root(GMemoryContent *);
/* Fournit le nom associé au contenu binaire. */
-static const char *g_memory_content_describe(const GMemoryContent *, bool);
+static char *g_memory_content_describe(const GMemoryContent *, bool);
/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
static bool g_memory_content_save(const GMemoryContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
@@ -399,11 +399,11 @@ static GBinContent *g_memory_content_get_root(GMemoryContent *content)
* *
******************************************************************************/
-static const char *g_memory_content_describe(const GMemoryContent *content, bool full)
+static char *g_memory_content_describe(const GMemoryContent *content, bool full)
{
- const char *result; /* Description à retourner */
+ char *result; /* Description à retourner */
- result = "In-memory content";
+ result = strdup("In-memory content");
return result;
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 607f1e4..af67fdf 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -389,7 +389,7 @@ void output_disassembly(GLoadedBinary *binary, GProcContext *context, GtkStatusS
GBinContent *content; /* Contenu bianire manipulé */
GCodingLanguage *lang; /* Langage de sortie préféré */
char **text; /* Contenu brute à imprimer */
- const char *desc; /* Désignation du binaire */
+ char *desc; /* Désignation du binaire */
const gchar *checksum; /* Identifiant de binaire */
GIntroGenerator *generator; /* Générateur constitué */
@@ -420,6 +420,8 @@ void output_disassembly(GLoadedBinary *binary, GProcContext *context, GtkStatusS
asprintf(&text[2], "%s%s", _("Source: "), desc);
+ free(desc);
+
/* Checksum SHA256 */
checksum = g_binary_content_get_checksum(content);
diff --git a/src/gui/dialogs/export_disass.c b/src/gui/dialogs/export_disass.c
index beaa3c8..314b9cf 100644
--- a/src/gui/dialogs/export_disass.c
+++ b/src/gui/dialogs/export_disass.c
@@ -875,7 +875,7 @@ static void register_output_panel(GtkAssistant *assistant)
GtkWidget *entry; /* Zone de saisie de texte */
GtkWidget *button; /* Sélection de fichier */
GLoadedBinary *binary; /* Binaire chargé à parcourir */
- const char *filename; /* Chemin d'accès par défaut */
+ char *filename; /* Chemin d'accès par défaut */
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
qck_set_margins(vbox, 8, 8, 8, 8);
@@ -907,11 +907,13 @@ static void register_output_panel(GtkAssistant *assistant)
/* Choix par défaut */
binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(assistant), "binary"));
- filename = g_loaded_binary_get_name(binary, true);
+ filename = g_loaded_content_describe(G_LOADED_CONTENT(binary), true);
gtk_entry_set_text(GTK_ENTRY(entry), filename);
gtk_editable_insert_text(GTK_EDITABLE(entry), ".html", -1, (gint []) { strlen(filename) });
+ free(filename);
+
g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(on_export_filename_changed), assistant);
}
diff --git a/src/gui/panels/bintree.c b/src/gui/panels/bintree.c
index 220a31d..a949b0d 100644
--- a/src/gui/panels/bintree.c
+++ b/src/gui/panels/bintree.c
@@ -688,6 +688,7 @@ static void reload_portions_for_new_tree_view(const GBintreePanel *panel, GtkSta
GBinPortion *portions; /* Couche première de portions */
size_t count; /* Compteur de portions */
GtkTreeIter top; /* Racine de l'arborescence */
+ char *desc; /* Description de contenu */
gint max_depth; /* Profondeur maximale */
GtkSpinButton *depth_spin; /* Bouton de variation */
GtkTreeView *treeview; /* Arborescence constituée */
@@ -708,11 +709,15 @@ static void reload_portions_for_new_tree_view(const GBintreePanel *panel, GtkSta
gtk_tree_store_append(store, &top, NULL);
+ desc = g_loaded_content_describe(G_LOADED_CONTENT(panel->binary), false);
+
gtk_tree_store_set(store, &top,
BTC_ICON, NULL,
- BTC_CAPTION, g_loaded_binary_get_name(panel->binary, false),
+ BTC_CAPTION, desc,
-1);
+ free(desc);
+
data->panel = panel;
data->top = &top;
data->status = status;