summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/analysis/content.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/analysis/content.c')
-rw-r--r--plugins/pychrysalide/analysis/content.c832
1 files changed, 797 insertions, 35 deletions
diff --git a/plugins/pychrysalide/analysis/content.c b/plugins/pychrysalide/analysis/content.c
index c30cdd8..dd9c1c1 100644
--- a/plugins/pychrysalide/analysis/content.c
+++ b/plugins/pychrysalide/analysis/content.c
@@ -35,13 +35,12 @@
#include <analysis/content-int.h>
-#include <common/endianness.h>
-#include "cattribs.h"
-#include "constants.h"
-#include "storage/serialize.h"
+//#include "cattribs.h"
+//#include "storage/serialize.h"
#include "../access.h"
+#include "../constants.h"
#include "../helpers.h"
#include "../arch/vmpa.h"
@@ -61,6 +60,21 @@ static int py_binary_content_init(PyObject *, PyObject *, PyObject *);
/* Fournit le nom associé au contenu binaire. */
static char *py_binary_content_describe_wrapper(const GBinContent *, bool);
+/* Calcule une empreinte unique (SHA256) pour les données. */
+static void py_binary_content_compute_checksum_wrapper(const GBinContent *, GChecksum *);
+
+/* Détermine le nombre d'octets lisibles. */
+static phys_t py_binary_content_compute_size_wrapper(const GBinContent *);
+
+/* Détermine la position initiale d'un contenu. */
+static bool py_binary_content_compute_start_pos_wrapper(const GBinContent *, vmpa2t *);
+
+/* Détermine la position finale d'un contenu. */
+static bool py_binary_content_compute_end_pos_wrapper(const GBinContent *, vmpa2t *);
+
+/* Avance la tête de lecture d'une certaine quantité de données. */
+static bool py_binary_content_seek_wrapper(const GBinContent *, vmpa2t *, phys_t);
+
/* Fournit une portion des données représentées. */
static bool py_binary_content_read_raw_wrapper(const GBinContent *, vmpa2t *, phys_t, bin_t *);;
@@ -76,6 +90,12 @@ static bool py_binary_content_read_u32_wrapper(const GBinContent *, vmpa2t *, So
/* Lit un nombre non signé sur huit octets. */
static bool py_binary_content_read_u64_wrapper(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *);
+/* Lit un nombre non signé encodé au format LEB128. */
+static bool py_binary_content_read_uleb128_wrapper(const GBinContent *, vmpa2t *, uleb128_t *);
+
+/* Lit un nombre signé encodé au format LEB128. */
+static bool py_binary_content_read_leb128_wrapper(const GBinContent *, vmpa2t *, leb128_t *);
+
/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
@@ -84,6 +104,9 @@ static bool py_binary_content_read_u64_wrapper(const GBinContent *, vmpa2t *, So
/* Fournit le nom associé au contenu binaire. */
static PyObject *py_binary_content_describe(PyObject *, PyObject *);
+/* Avance la tête de lecture d'une certaine quantité de données. */
+static PyObject *py_binary_content_seek(PyObject *, PyObject *);
+
/* Fournit une portion des données représentées. */
static PyObject *py_binary_content_read_raw(PyObject *, PyObject *);
@@ -99,11 +122,19 @@ static PyObject *py_binary_content_read_u32(PyObject *, PyObject *);
/* Lit un nombre non signé sur huit octets. */
static PyObject *py_binary_content_read_u64(PyObject *, PyObject *);
+/* Lit un nombre non signé encodé au format LEB128. */
+static PyObject *py_binary_content_read_uleb128(PyObject *, PyObject *);
+
+/* Lit un nombre signé encodé au format LEB128. */
+static PyObject *py_binary_content_read_leb128(PyObject *, PyObject *);
+
+#if 0
/* Associe un ensemble d'attributs au contenu binaire. */
static int py_binary_content_set_attributes(PyObject *, PyObject *, void *);
/* Fournit l'ensemble des attributs associés à un contenu. */
static PyObject *py_binary_content_get_attributes(PyObject *, void *);
+#endif
/* Donne l'origine d'un contenu binaire. */
static PyObject *py_binary_content_get_root(PyObject *, void *);
@@ -147,12 +178,23 @@ static void py_binary_content_init_gclass(GBinContentClass *class, gpointer unus
{
class->describe = py_binary_content_describe_wrapper;
+ class->compute_checksum = py_binary_content_compute_checksum_wrapper;
+
+ class->compute_size = py_binary_content_compute_size_wrapper;
+ class->compute_start_pos = py_binary_content_compute_start_pos_wrapper;
+ class->compute_end_pos = py_binary_content_compute_end_pos_wrapper;
+
+ class->seek = py_binary_content_seek_wrapper;
+
class->read_raw = py_binary_content_read_raw_wrapper;
class->read_u8 = py_binary_content_read_u8_wrapper;
class->read_u16 = py_binary_content_read_u16_wrapper;
class->read_u32 = py_binary_content_read_u32_wrapper;
class->read_u64 = py_binary_content_read_u64_wrapper;
+ class->read_uleb128 = py_binary_content_read_uleb128_wrapper;
+ class->read_leb128 = py_binary_content_read_leb128_wrapper;
+
}
@@ -184,12 +226,19 @@ static int py_binary_content_init(PyObject *self, PyObject *args, PyObject *kwds
"\n" \
"The following methods have to be defined for new implementations:\n" \
"* pychrysalide.analysis.BinContent._describe();\n" \
+ "* pychrysalide.analysis.BinContent._compute_checksum();\n" \
+ "* pychrysalide.analysis.BinContent._compute_size();\n" \
+ "* pychrysalide.analysis.BinContent._compute_start_pos();\n" \
+ "* pychrysalide.analysis.BinContent._compute_end_pos();\n" \
+ "* pychrysalide.analysis.BinContent._seek();\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"
+ "* pychrysalide.analysis.BinContent._read_u64();\n" \
+ "* pychrysalide.analysis.BinContent._read_uleb128();\n" \
+ "* pychrysalide.analysis.BinContent._read_leb128();\n"
/* Initialisation d'un objet GLib */
@@ -276,6 +325,349 @@ static char *py_binary_content_describe_wrapper(const GBinContent *content, bool
/******************************************************************************
* *
+* Paramètres : content = contenu binaire à venir lire. *
+* checksum = empreinte de zone mémoire à compléter. *
+* *
+* Description : Calcule une empreinte unique (SHA256) pour les données. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_binary_content_compute_checksum_wrapper(const GBinContent *content, GChecksum *checksum)
+{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define BINARY_CONTENT_COMPUTE_CHECKSUM_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _compute_checksum, "$self, checksum", \
+ METH_VARARGS, \
+ "Abstract method used to build a fingerprint of the current" \
+ " content.\n" \
+ "\n" \
+ "The *checksum* argument is a Glib.Checksum instance to update."\
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_compute_checksum"))
+ {
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, pyg_boxed_new(G_TYPE_CHECKSUM, checksum, FALSE, FALSE));
+
+ pyret = run_python_method(pyobj, "_compute_checksum", args);
+
+ if (pyret != NULL)
+ {
+ assert(pyret == Py_None);
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* *
+* Description : Détermine le nombre d'octets lisibles. *
+* *
+* Retour : Quantité représentée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static phys_t py_binary_content_compute_size_wrapper(const GBinContent *content)
+{
+ phys_t result; /* Quantité à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_COMPUTE_SIZE_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _compute_size, "$self", \
+ METH_NOARGS, \
+ "Abstract method used to provide the quantity of available bytes.\n"\
+ "\n" \
+ "The returned value should greater than 0." \
+)
+
+ result = 0;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_compute_size"))
+ {
+ pyret = run_python_method(pyobj, "_compute_size", NULL);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ result = PyLong_AsUnsignedLong(pyret);
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* pos = position initiale. [OUT] *
+* *
+* Description : Détermine la position initiale d'un contenu. *
+* *
+* Retour : Validité finale de la position fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_compute_start_pos_wrapper(const GBinContent *content, vmpa2t *pos)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ vmpa2t *pypos; /* Position retournée */
+
+#define BINARY_CONTENT_COMPUTE_START_POS_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _compute_start_pos, "$self", \
+ METH_NOARGS, \
+ "Abstract method computing the effective position at the" \
+ " beginning of the binary content.\n" \
+ "\n" \
+ "The computed position has to get returned as a" \
+ " pychrysalide.arch.vmpa instance." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_compute_start_pos"))
+ {
+ pyret = run_python_method(pyobj, "_compute_start_pos", NULL);
+
+ if (pyret != NULL)
+ {
+ pypos = get_internal_vmpa(pyret);
+
+ if (pypos != NULL)
+ {
+ copy_vmpa(pos, pypos);
+ result = true;
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* pos = position finale (exclusive). [OUT] *
+* *
+* Description : Détermine la position finale d'un contenu. *
+* *
+* Retour : Validité finale de la position fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_compute_end_pos_wrapper(const GBinContent *content, vmpa2t *pos)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ vmpa2t *pypos; /* Position retournée */
+
+#define BINARY_CONTENT_COMPUTE_END_POS_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _compute_end_pos, "$self", \
+ METH_NOARGS, \
+ "Abstract method computing the effective position at the" \
+ " beginning of the binary content.\n" \
+ "\n" \
+ "The computed position has to get returned as a" \
+ " pychrysalide.arch.vmpa instance." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_compute_end_pos"))
+ {
+ pyret = run_python_method(pyobj, "_compute_end_pos", NULL);
+
+ if (pyret != NULL)
+ {
+ pypos = get_internal_vmpa(pyret);
+
+ if (pypos != NULL)
+ {
+ copy_vmpa(pos, pypos);
+ result = true;
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
+
+ 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 à provisionner. *
+* *
+* Description : Avance la tête de lecture d'une certaine quantité de données.*
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_seek_wrapper(const GBinContent *content, vmpa2t *addr, phys_t length)
+{
+ 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_SEEK_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_raw, "$self, addr, length", \
+ METH_VARARGS, \
+ "Abstract method used to move a given location.\n" \
+ "\n" \
+ "The *addr* argument is a pychrysalide.arch.vmpa object," \
+ " and *length* is the offset for the expected move.\n" \
+ "\n" \
+ "The returned value provide the status of the operation:" \
+ " *True* if *addr* has been update to a valid position," \
+ " *False* otherwise." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(content));
+
+ if (has_python_method(pyobj, "_seek"))
+ {
+ 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, "_seek", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyBool_Check(pyret);
+
+ if (ret)
+ {
+ /* Bilan à retenir */
+
+ result = (pyret == Py_True);
+
+ /* Avancement de la tête de lecture */
+
+ if (result)
+ copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+ }
+
+ 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. *
@@ -401,8 +793,9 @@ static bool py_binary_content_read_u8_wrapper(const GBinContent *content, vmpa2t
"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" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument needs" \
+ " to get updated in order to reflect the read progress.\n" \
"\n" \
"The returned value is the read data or None is case of error." \
)
@@ -492,8 +885,10 @@ static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2
"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" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument needs" \
+ " to get updated in order to reflect the read progress. 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." \
@@ -508,8 +903,7 @@ static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2
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);
+ endianness_obj = cast_source_endian_to_python(endian);
args = PyTuple_New(2);
PyTuple_SetItem(args, 0, addr_obj);
@@ -587,8 +981,10 @@ static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2
"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" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument needs" \
+ " to get updated in order to reflect the read progress. 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." \
@@ -603,8 +999,7 @@ static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2
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);
+ endianness_obj = cast_source_endian_to_python(endian);
args = PyTuple_New(2);
PyTuple_SetItem(args, 0, addr_obj);
@@ -682,8 +1077,10 @@ static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2
"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" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument needs" \
+ " to get updated in order to reflect the read progress. 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." \
@@ -698,8 +1095,7 @@ static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2
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);
+ endianness_obj = cast_source_endian_to_python(endian);
args = PyTuple_New(2);
PyTuple_SetItem(args, 0, addr_obj);
@@ -744,6 +1140,186 @@ static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2
}
+/******************************************************************************
+* *
+* 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é encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_read_uleb128_wrapper(const GBinContent *content, vmpa2t *addr, uleb128_t *val)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *addr_obj; /* Position en version Python */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_READ_ULEB128_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_uleb128, "$self, addr", \
+ METH_VARARGS, \
+ "Abstract method used to read an unsigned LEB128-encoded number" \
+ " from a given position.\n" \
+ "\n" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument needs" \
+ " to get updated in order to reflect the read progress.\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_uleb128"))
+ {
+ addr_obj = build_from_internal_vmpa(addr);
+
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, addr_obj);
+
+ pyret = run_python_method(pyobj, "_read_uleb128", 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;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_binary_content_read_leb128_wrapper(const GBinContent *content, vmpa2t *addr, leb128_t *val)
+{
+ bool result; /* Bilan à remonter */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *addr_obj; /* Position en version Python */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Validité d'une conversion */
+
+#define BINARY_CONTENT_READ_LEB128_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _read_leb128, "$self, addr", \
+ METH_VARARGS, \
+ "Abstract method used to read an unsigned LEB128-encoded number" \
+ " from a given position.\n" \
+ "\n" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument needs" \
+ " to get updated in order to reflect the read progress.\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_leb128"))
+ {
+ addr_obj = build_from_internal_vmpa(addr);
+
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, addr_obj);
+
+ pyret = run_python_method(pyobj, "_read_leb128", 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_AsLongLong(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 */
@@ -801,6 +1377,53 @@ static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
* Paramètres : self = contenu binaire à manipuler. *
* args = non utilisé ici. *
* *
+* Description : Avance la tête de lecture d'une certaine quantité de données.*
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_content_seek(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ vmpa2t *addr; /* Position interne associée */
+ unsigned long long length; /* Quantité de données à lire */
+ int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Version GLib du format */
+ bool valid; /* Validité de la position */
+
+#define BINARY_CONTENT_SEEK_METHOD PYTHON_METHOD_DEF \
+( \
+ seek, "$self, addr, length, /", \
+ METH_VARARGS, py_binary_content, \
+ "Move the current position into a new one.\n" \
+ "\n" \
+)
+
+ ret = PyArg_ParseTuple(args, "O&K", convert_any_to_vmpa, &addr, &length);
+ if (!ret) return NULL;
+
+ content = G_BIN_CONTENT(pygobject_get(self));
+
+ valid = g_binary_content_seek(content, addr, length);
+
+ result = (valid ? Py_True : Py_False);
+ Py_INCREF(result);
+
+ clean_vmpa_arg(addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = non utilisé ici. *
+* *
* Description : Fournit une portion des données représentées. *
* *
* Retour : Bilan de l'opération. *
@@ -877,8 +1500,9 @@ static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
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" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument gets" \
+ " updated in order to reflect the read progress.\n" \
"\n" \
"The returned value is the read data or None is case of error." \
)
@@ -936,8 +1560,10 @@ 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 location of the data to read is a pychrysalide.arch.vmpa" \
- " instance. The endianness of the data can be provided using" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument gets" \
+ " updated in order to reflect the read progress. 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." \
@@ -996,8 +1622,10 @@ 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 location of the data to read is a pychrysalide.arch.vmpa" \
- " instance. The endianness of the data can be provided using" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument gets" \
+ " updated in order to reflect the read progress. 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." \
@@ -1026,6 +1654,7 @@ static PyObject *py_binary_content_read_u32(PyObject *self, PyObject *args)
}
+
/******************************************************************************
* *
* Paramètres : self = contenu binaire à manipuler. *
@@ -1055,8 +1684,10 @@ static PyObject *py_binary_content_read_u64(PyObject *self, PyObject *args)
METH_VARARGS, py_binary_content, \
"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" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument gets" \
+ " updated in order to reflect the read progress. 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." \
@@ -1088,6 +1719,127 @@ static PyObject *py_binary_content_read_u64(PyObject *self, PyObject *args)
/******************************************************************************
* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Lit un nombre non signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_content_read_uleb128(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ vmpa2t *addr; /* Position interne associée */
+ int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Version GLib du format */
+ uleb128_t val; /* Valeur lue à faire suivre */
+ bool status; /* Bilan de l'opération */
+
+#define BINARY_CONTENT_READ_ULEB128_METHOD PYTHON_METHOD_DEF \
+( \
+ read_uleb128, "$self, addr, /", \
+ METH_VARARGS, py_binary_content, \
+ "Read an unsigned LEB128-encoded number from a given position.\n" \
+ "\n" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument gets" \
+ " updated in order to reflect the read progress.\n" \
+ "\n" \
+ "The returned value is the read data in case of success, or an" \
+ " exception is raised otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
+
+ content = G_BIN_CONTENT(pygobject_get(self));
+
+ status = g_binary_content_read_uleb128(content, addr, &val);
+ if (!status)
+ {
+ clean_vmpa_arg(addr);
+
+ PyErr_SetString(PyExc_Exception, _("Invalid read access."));
+ return NULL;
+
+ }
+
+ result = PyLong_FromUnsignedLongLong(val);
+
+ clean_vmpa_arg(addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Lit un nombre signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_content_read_leb128(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ vmpa2t *addr; /* Position interne associée */
+ int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Version GLib du format */
+ leb128_t val; /* Valeur lue à faire suivre */
+ bool status; /* Bilan de l'opération */
+
+#define BINARY_CONTENT_READ_LEB128_METHOD PYTHON_METHOD_DEF \
+( \
+ read_leb128, "$self, addr, /", \
+ METH_VARARGS, py_binary_content, \
+ "Read an unsigned LEB128-encoded number from a given position.\n" \
+ "\n" \
+ "The location *addr* of the data to read is a" \
+ " pychrysalide.arch.vmpa instance, and this *addr* argument gets" \
+ " updated in order to reflect the read progress.\n" \
+ "\n" \
+ "The returned value is the read data in case of success, or an" \
+ " exception is raised otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
+
+ content = G_BIN_CONTENT(pygobject_get(self));
+
+ status = g_binary_content_read_leb128(content, addr, &val);
+ if (!status)
+ {
+ clean_vmpa_arg(addr);
+
+ PyErr_SetString(PyExc_Exception, _("Invalid read access."));
+ return NULL;
+
+ }
+
+ result = PyLong_FromLongLong(val);
+
+ clean_vmpa_arg(addr);
+
+ return result;
+
+}
+
+
+#if 0 // FIXME
+/******************************************************************************
+* *
* Paramètres : self = contenu binaire à manipuler. *
* value = jeu d'attributs à lier au contenu courant. *
* closure = adresse non utilisée ici. *
@@ -1158,6 +1910,7 @@ static PyObject *py_binary_content_get_attributes(PyObject *self, void *closure)
return result;
}
+#endif
/******************************************************************************
@@ -1177,7 +1930,7 @@ static PyObject *py_binary_content_get_root(PyObject *self, void *closure)
{
PyObject *result; /* Instance à retourner */
GBinContent *content; /* Version GLib du format */
- GContentAttributes *attribs; /* Attributs à transmettre */
+ GBinContent *root; /* COntenu parent */
#define BINARY_CONTENT_ROOT_ATTRIB PYTHON_GET_DEF_FULL \
( \
@@ -1191,11 +1944,11 @@ static PyObject *py_binary_content_get_root(PyObject *self, void *closure)
content = G_BIN_CONTENT(pygobject_get(self));
- attribs = g_binary_content_get_attributes(content);
+ root = g_binary_content_get_root(content);
- result = pygobject_new(G_OBJECT(attribs));
+ result = pygobject_new(G_OBJECT(root));
- g_object_unref(attribs);
+ g_object_unref(root);
return result;
@@ -1405,22 +2158,32 @@ PyTypeObject *get_python_binary_content_type(void)
{
static PyMethodDef py_binary_content_methods[] = {
BINARY_CONTENT_DESCRIBE_WRAPPER,
+ BINARY_CONTENT_COMPUTE_CHECKSUM_WRAPPER,
+ BINARY_CONTENT_COMPUTE_SIZE_WRAPPER,
+ BINARY_CONTENT_COMPUTE_START_POS_WRAPPER,
+ BINARY_CONTENT_COMPUTE_END_POS_WRAPPER,
+ BINARY_CONTENT_SEEK_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_READ_ULEB128_WRAPPER,
+ BINARY_CONTENT_READ_LEB128_WRAPPER,
BINARY_CONTENT_DESCRIBE_METHOD,
+ BINARY_CONTENT_SEEK_METHOD,
BINARY_CONTENT_READ_RAW_METHOD,
BINARY_CONTENT_READ_U8_METHOD,
BINARY_CONTENT_READ_U16_METHOD,
BINARY_CONTENT_READ_U32_METHOD,
BINARY_CONTENT_READ_U64_METHOD,
+ BINARY_CONTENT_READ_ULEB128_METHOD,
+ BINARY_CONTENT_READ_LEB128_METHOD,
{ NULL }
};
static PyGetSetDef py_binary_content_getseters[] = {
- BINARY_CONTENT_ATTRIBUTES_ATTRIB,
+ //BINARY_CONTENT_ATTRIBUTES_ATTRIB,
BINARY_CONTENT_ROOT_ATTRIB,
BINARY_CONTENT_CHECKSUM_ATTRIB,
BINARY_CONTENT_SIZE_ATTRIB,
@@ -1476,8 +2239,10 @@ bool ensure_python_binary_content_is_registered(void)
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
+ /* FIXME
if (!ensure_python_serializable_object_is_registered())
return false;
+ */
module = get_access_to_python_module("pychrysalide.analysis");
@@ -1486,9 +2251,6 @@ bool ensure_python_binary_content_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_BIN_CONTENT, type))
return false;
- if (!define_analysis_content_constants(type))
- return false;
-
}
return true;