From 79662ede83b35ad9d91b942218cf09e856e48b4c Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 20 May 2024 00:55:29 +0200 Subject: Restore full featured Python bindings for binary contents. --- plugins/pychrysalide/Makefile.am | 5 +- plugins/pychrysalide/analysis/Makefile.am | 17 +- plugins/pychrysalide/analysis/content.c | 978 ++++++++++++++++++--- .../pychrysalide/analysis/contents/encapsulated.c | 8 +- plugins/pychrysalide/analysis/contents/file.c | 2 +- plugins/pychrysalide/analysis/contents/memory.c | 2 +- .../pychrysalide/analysis/contents/restricted.c | 4 +- plugins/pychrysalide/analysis/module.c | 14 + plugins/pychrysalide/arch/Makefile.am | 40 +- plugins/pychrysalide/arch/constants.c | 8 +- plugins/pychrysalide/arch/constants.h | 5 +- plugins/pychrysalide/arch/module.c | 11 +- plugins/pychrysalide/constants.c | 215 +++++ plugins/pychrysalide/constants.h | 51 ++ plugins/pychrysalide/core.c | 11 +- plugins/pychrysalide/helpers.c | 79 +- plugins/pychrysalide/plugins/constants.c | 2 +- src/Makefile.am | 6 +- src/analysis/Makefile.am | 15 +- src/analysis/content-int.h | 20 +- src/analysis/content.c | 33 +- src/analysis/content.h | 11 +- src/analysis/contents/encapsulated.c | 46 +- src/analysis/contents/file.c | 9 +- src/analysis/contents/memory-int.h | 2 + src/analysis/contents/memory.c | 48 +- src/analysis/contents/restricted.c | 45 +- src/analysis/db/misc/rlestr.c | 3 +- src/analysis/db/misc/rlestr.h | 4 +- src/arch/Makefile.am | 13 +- src/arch/vmpa.c | 4 +- src/arch/vmpa.h | 4 +- src/common/Makefile.am | 4 +- src/common/leb128.h | 4 +- tests/analysis/contents/custom.py | 134 +++ tests/analysis/contents/endian.py | 27 +- tests/analysis/contents/memory.py | 7 +- tests/analysis/contents/restricted.py | 21 +- 38 files changed, 1640 insertions(+), 272 deletions(-) create mode 100644 plugins/pychrysalide/constants.c create mode 100644 plugins/pychrysalide/constants.h create mode 100644 tests/analysis/contents/custom.py diff --git a/plugins/pychrysalide/Makefile.am b/plugins/pychrysalide/Makefile.am index 1818613..888de8a 100644 --- a/plugins/pychrysalide/Makefile.am +++ b/plugins/pychrysalide/Makefile.am @@ -32,6 +32,7 @@ endif pychrysalide_la_SOURCES = \ access.h access.c \ + constants.h constants.c \ core.h core.c \ helpers.h helpers.c \ star.h star.c \ @@ -55,6 +56,8 @@ AM_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFL # plugins/libpychrysaplugins.la pychrysalide_la_LIBADD = \ + analysis/libpychrysaanalysis4.la \ + arch/libpychrysaarch4.la \ core/libpychrysacore.la \ plugins/libpychrysaplugins.la @@ -73,4 +76,4 @@ dev_HEADERS = $(pychrysalide_la_SOURCES:%c=) #SUBDIRS = analysis arch common core debug format glibext $(GTKEXT_SUBDIR) $(GUI_SUBDIR) mangling plugins -SUBDIRS = core plugins +SUBDIRS = analysis arch core plugins diff --git a/plugins/pychrysalide/analysis/Makefile.am b/plugins/pychrysalide/analysis/Makefile.am index 43e8ed2..dea825c 100644 --- a/plugins/pychrysalide/analysis/Makefile.am +++ b/plugins/pychrysalide/analysis/Makefile.am @@ -1,5 +1,5 @@ -noinst_LTLIBRARIES = libpychrysaanalysis.la +noinst_LTLIBRARIES = libpychrysaanalysis4.la # libpychrysaanalysis.la libpychrysaanalysis_la_SOURCES = \ binary.h binary.c \ @@ -23,7 +23,17 @@ libpychrysaanalysis_la_LIBADD = \ storage/libpychrysaanalysisstorage.la \ types/libpychrysaanalysistypes.la -libpychrysaanalysis_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + +libpychrysaanalysis4_la_SOURCES = \ + content.h content.c \ + module.h module.c + +libpychrysaanalysis4_la_LIBADD = \ + contents/libpychrysaanalysiscontents.la + +libpychrysaanalysis4_la_CFLAGS = \ + $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + $(TOOLKIT_CFLAGS) \ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT @@ -32,4 +42,5 @@ devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libpychrysaanalysis_la_SOURCES:%c=) -SUBDIRS = contents db disass scan storage types +#SUBDIRS = contents db disass scan storage types +SUBDIRS = contents 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 -#include -#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. * @@ -289,24 +681,217 @@ static char *py_binary_content_describe_wrapper(const GBinContent *content, bool * * ******************************************************************************/ -static bool py_binary_content_read_raw_wrapper(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out) +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 *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_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 */ - 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." \ +#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 *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." \ ) result = false; @@ -315,41 +900,34 @@ static bool py_binary_content_read_raw_wrapper(const GBinContent *content, vmpa2 pyobj = pygobject_new(G_OBJECT(content)); - if (has_python_method(pyobj, "_read_raw")) + if (has_python_method(pyobj, "_read_u16")) { addr_obj = build_from_internal_vmpa(addr); + endianness_obj = cast_source_endian_to_python(endian); args = PyTuple_New(2); PyTuple_SetItem(args, 0, addr_obj); - PyTuple_SetItem(args, 1, PyLong_FromUnsignedLongLong(length)); + PyTuple_SetItem(args, 1, endianness_obj); - pyret = run_python_method(pyobj, "_read_raw", args); + pyret = run_python_method(pyobj, "_read_u16", args); if (pyret != NULL) { - ret = PyUnicode_Check(pyret); + ret = PyLong_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 */ + /* Avancement de la tête de lecture */ - data = PyBytes_AsString(pyret); + copy_vmpa(addr, get_internal_vmpa(addr_obj)); - memcpy(out, data, length); + /* Récupération des données */ - /* Bilan à retenir */ + *val = PyLong_AsUnsignedLong(pyret); - result = true; + /* Bilan à retenir */ - } + result = true; } @@ -374,9 +952,10 @@ static bool py_binary_content_read_raw_wrapper(const GBinContent *content, vmpa2 * * * 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 un octet. * +* Description : Lit un nombre non signé sur quatre octets. * * * * Retour : Bilan de l'opération : true en cas de succès, false sinon. * * * @@ -384,25 +963,29 @@ static bool py_binary_content_read_raw_wrapper(const GBinContent *content, vmpa2 * * ******************************************************************************/ -static bool py_binary_content_read_u8_wrapper(const GBinContent *content, vmpa2t *addr, uint8_t *val) +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_U8_WRAPPER PYTHON_WRAPPER_DEF \ +#define BINARY_CONTENT_READ_U32_WRAPPER PYTHON_WRAPPER_DEF \ ( \ - _read_u8, "$self, addr", \ + _read_u32, "$self, addr, endian", \ METH_VARARGS, \ - "Abstract method used to read an unsigned bytes from a given" \ + "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.\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. 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." \ ) @@ -413,14 +996,16 @@ static bool py_binary_content_read_u8_wrapper(const GBinContent *content, vmpa2t pyobj = pygobject_new(G_OBJECT(content)); - if (has_python_method(pyobj, "_read_u8")) + if (has_python_method(pyobj, "_read_u32")) { addr_obj = build_from_internal_vmpa(addr); + endianness_obj = cast_source_endian_to_python(endian); - args = PyTuple_New(1); + args = PyTuple_New(2); PyTuple_SetItem(args, 0, addr_obj); + PyTuple_SetItem(args, 1, endianness_obj); - pyret = run_python_method(pyobj, "_read_u8", args); + pyret = run_python_method(pyobj, "_read_u32", args); if (pyret != NULL) { @@ -466,7 +1051,7 @@ static bool py_binary_content_read_u8_wrapper(const GBinContent *content, vmpa2t * endian = ordre des bits dans la source. * * val = lieu d'enregistrement de la lecture. [OUT] * * * -* Description : Lit un nombre non signé sur deux octets. * +* Description : Lit un nombre non signé sur huit octets. * * * * Retour : Bilan de l'opération : true en cas de succès, false sinon. * * * @@ -474,7 +1059,7 @@ static bool py_binary_content_read_u8_wrapper(const GBinContent *content, vmpa2t * * ******************************************************************************/ -static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) +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 */ @@ -485,15 +1070,17 @@ static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2 PyObject *pyret; /* Bilan de consultation */ int ret; /* Validité d'une conversion */ -#define BINARY_CONTENT_READ_U16_WRAPPER PYTHON_WRAPPER_DEF \ +#define BINARY_CONTENT_READ_U64_WRAPPER PYTHON_WRAPPER_DEF \ ( \ - _read_u16, "$self, addr, endian", \ + _read_u64, "$self, addr, endian", \ METH_VARARGS, \ - "Abstract method used to read two unsigned bytes from a given" \ + "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." \ @@ -505,17 +1092,16 @@ static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2 pyobj = pygobject_new(G_OBJECT(content)); - if (has_python_method(pyobj, "_read_u16")) + 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); PyTuple_SetItem(args, 1, endianness_obj); - pyret = run_python_method(pyobj, "_read_u16", args); + pyret = run_python_method(pyobj, "_read_u64", args); if (pyret != NULL) { @@ -529,7 +1115,7 @@ static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2 /* Récupération des données */ - *val = PyLong_AsUnsignedLong(pyret); + *val = PyLong_AsUnsignedLongLong(pyret); /* Bilan à retenir */ @@ -558,10 +1144,9 @@ static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2 * * * 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. * +* Description : Lit un nombre non signé encodé au format LEB128. * * * * Retour : Bilan de l'opération : true en cas de succès, false sinon. * * * @@ -569,27 +1154,26 @@ static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2 * * ******************************************************************************/ -static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) +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 *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 \ +#define BINARY_CONTENT_READ_ULEB128_WRAPPER PYTHON_WRAPPER_DEF \ ( \ - _read_u32, "$self, addr, endian", \ + _read_uleb128, "$self, addr", \ METH_VARARGS, \ - "Abstract method used to read four unsigned bytes from a given" \ - " position.\n" \ + "Abstract method used to read an unsigned LEB128-encoded number" \ + " 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" \ + "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." \ ) @@ -600,17 +1184,14 @@ static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2 pyobj = pygobject_new(G_OBJECT(content)); - if (has_python_method(pyobj, "_read_u32")) + if (has_python_method(pyobj, "_read_uleb128")) { 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); + args = PyTuple_New(1); PyTuple_SetItem(args, 0, addr_obj); - PyTuple_SetItem(args, 1, endianness_obj); - pyret = run_python_method(pyobj, "_read_u32", args); + pyret = run_python_method(pyobj, "_read_uleb128", args); if (pyret != NULL) { @@ -624,7 +1205,7 @@ static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2 /* Récupération des données */ - *val = PyLong_AsUnsignedLong(pyret); + *val = PyLong_AsUnsignedLongLong(pyret); /* Bilan à retenir */ @@ -653,10 +1234,9 @@ static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2 * * * 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. * +* Description : Lit un nombre signé encodé au format LEB128. * * * * Retour : Bilan de l'opération : true en cas de succès, false sinon. * * * @@ -664,27 +1244,26 @@ static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2 * * ******************************************************************************/ -static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) +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 *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 \ +#define BINARY_CONTENT_READ_LEB128_WRAPPER PYTHON_WRAPPER_DEF \ ( \ - _read_u64, "$self, addr, endian", \ + _read_leb128, "$self, addr", \ METH_VARARGS, \ - "Abstract method used to read eight unsigned bytes from a given" \ - " position.\n" \ + "Abstract method used to read an unsigned LEB128-encoded number" \ + " 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" \ + "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." \ ) @@ -695,17 +1274,14 @@ static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2 pyobj = pygobject_new(G_OBJECT(content)); - if (has_python_method(pyobj, "_read_u64")) + if (has_python_method(pyobj, "_read_leb128")) { 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); + args = PyTuple_New(1); PyTuple_SetItem(args, 0, addr_obj); - PyTuple_SetItem(args, 1, endianness_obj); - pyret = run_python_method(pyobj, "_read_u64", args); + pyret = run_python_method(pyobj, "_read_leb128", args); if (pyret != NULL) { @@ -719,7 +1295,7 @@ static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2 /* Récupération des données */ - *val = PyLong_AsUnsignedLongLong(pyret); + *val = PyLong_AsLongLong(pyret); /* Bilan à retenir */ @@ -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; diff --git a/plugins/pychrysalide/analysis/contents/encapsulated.c b/plugins/pychrysalide/analysis/contents/encapsulated.c index e9583e6..44eee3a 100644 --- a/plugins/pychrysalide/analysis/contents/encapsulated.c +++ b/plugins/pychrysalide/analysis/contents/encapsulated.c @@ -90,10 +90,10 @@ static int py_encaps_content_init(PyObject *self, PyObject *args, PyObject *kwds "\n" \ " EncapsulatedContent(base, path, endpoint)" \ "\n" \ - "Where base, path and endpoint are the previously described expected" \ - " properties. The base and the endpoint must be" \ - " pychrysalide.analysis.BinContent instances and the access path must" \ - " be provided as a string." + "Where *base*, *path* and *endpoint* are the previously described" \ + " expected properties. The *base* and the *endpoint* have to be" \ + " pychrysalide.analysis.BinContent instances and the access *path* has" \ + " to be provided as a string." /* Récupération des paramètres */ diff --git a/plugins/pychrysalide/analysis/contents/file.c b/plugins/pychrysalide/analysis/contents/file.c index 5bef069..aa4c5b2 100644 --- a/plugins/pychrysalide/analysis/contents/file.c +++ b/plugins/pychrysalide/analysis/contents/file.c @@ -75,7 +75,7 @@ static int py_file_content_init(PyObject *self, PyObject *args, PyObject *kwds) "\n" \ " FileContent(filename)" \ "\n" \ - "Where filename is a path to an existing file." + "Where *filename* is a path to an existing file." /* Récupération des paramètres */ diff --git a/plugins/pychrysalide/analysis/contents/memory.c b/plugins/pychrysalide/analysis/contents/memory.c index 7464779..9f2bc18 100644 --- a/plugins/pychrysalide/analysis/contents/memory.c +++ b/plugins/pychrysalide/analysis/contents/memory.c @@ -74,7 +74,7 @@ static int py_memory_content_init(PyObject *self, PyObject *args, PyObject *kwds "\n" \ " MemoryContent(data)" \ "\n" \ - "Where data is provided as string or read-only bytes-like object." \ + "Where *data* is provided as string or read-only bytes-like object." \ " The string may contain embedded null bytes." /* Récupération des paramètres */ diff --git a/plugins/pychrysalide/analysis/contents/restricted.c b/plugins/pychrysalide/analysis/contents/restricted.c index 4521578..629b4ff 100644 --- a/plugins/pychrysalide/analysis/contents/restricted.c +++ b/plugins/pychrysalide/analysis/contents/restricted.c @@ -80,8 +80,8 @@ static int py_restricted_content_init(PyObject *self, PyObject *args, PyObject * "\n" \ " RestrictedContent(content, range)" \ "\n" \ - "Where content is a pychrysalide.analysis.BinContent instance and range" \ - " a Python object which can be converted into pychrysalide.arch.mrange." + "Where *content* is a pychrysalide.analysis.BinContent instance and *range*"\ + " is a Python object which can be converted into pychrysalide.arch.mrange." /* Récupération des paramètres */ diff --git a/plugins/pychrysalide/analysis/module.c b/plugins/pychrysalide/analysis/module.c index 6b8e441..3976c94 100644 --- a/plugins/pychrysalide/analysis/module.c +++ b/plugins/pychrysalide/analysis/module.c @@ -28,22 +28,28 @@ #include +/* #include "binary.h" #include "block.h" #include "cattribs.h" +*/ #include "content.h" +/* #include "loaded.h" #include "loading.h" #include "project.h" #include "routine.h" #include "type.h" #include "variable.h" +*/ #include "contents/module.h" +/* #include "db/module.h" #include "disass/module.h" #include "scan/module.h" #include "storage/module.h" #include "types/module.h" +*/ #include "../helpers.h" @@ -85,11 +91,13 @@ bool add_analysis_module(PyObject *super) result = (module != NULL); if (result) result = add_analysis_contents_module(module); + /* if (result) result = add_analysis_db_module(module); if (result) result = add_analysis_disass_module(module); if (result) result = add_analysis_scan_module(module); if (result) result = add_analysis_storage_module(module); if (result) result = add_analysis_types_module(module); + */ if (!result) Py_XDECREF(module); @@ -117,11 +125,14 @@ bool populate_analysis_module(void) result = true; + /* if (result) result = ensure_python_loaded_binary_is_registered(); if (result) result = ensure_python_code_block_is_registered(); if (result) result = ensure_python_block_list_is_registered(); if (result) result = ensure_python_content_attributes_is_registered(); + */ if (result) result = ensure_python_binary_content_is_registered(); + /* if (result) result = ensure_python_loaded_content_is_registered(); if (result) result = ensure_python_content_explorer_is_registered(); if (result) result = ensure_python_content_resolver_is_registered(); @@ -129,13 +140,16 @@ bool populate_analysis_module(void) if (result) result = ensure_python_binary_routine_is_registered(); if (result) result = ensure_python_data_type_is_registered(); if (result) result = ensure_python_binary_variable_is_registered(); + */ if (result) result = populate_analysis_contents_module(); + /* if (result) result = populate_analysis_db_module(); if (result) result = populate_analysis_disass_module(); if (result) result = populate_analysis_scan_module(); if (result) result = populate_analysis_storage_module(); if (result) result = populate_analysis_types_module(); + */ assert(result); diff --git a/plugins/pychrysalide/arch/Makefile.am b/plugins/pychrysalide/arch/Makefile.am index c113f6e..d3ee3f0 100644 --- a/plugins/pychrysalide/arch/Makefile.am +++ b/plugins/pychrysalide/arch/Makefile.am @@ -1,22 +1,36 @@ -noinst_LTLIBRARIES = libpychrysaarch.la +noinst_LTLIBRARIES = libpychrysaarch4.la # libpychrysaarch.la -libpychrysaarch_la_SOURCES = \ +# libpychrysaarch_la_SOURCES = \ +# constants.h constants.c \ +# context.h context.c \ +# instriter.h instriter.c \ +# instruction.h instruction.c \ +# module.h module.c \ +# operand.h operand.c \ +# processor.h processor.c \ +# register.h register.c \ +# vmpa.h vmpa.c + +# libpychrysaarch_la_LIBADD = \ +# instructions/libpychrysaarchinstructions.la \ +# operands/libpychrysaarchoperands.la + +# libpychrysaarch_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ +# -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT + + +libpychrysaarch4_la_SOURCES = \ constants.h constants.c \ - context.h context.c \ - instriter.h instriter.c \ - instruction.h instruction.c \ module.h module.c \ - operand.h operand.c \ - processor.h processor.c \ - register.h register.c \ vmpa.h vmpa.c -libpychrysaarch_la_LIBADD = \ - instructions/libpychrysaarchinstructions.la \ - operands/libpychrysaarchoperands.la +# libpychrysaarch4_la_LIBADD = \ +# instructions/libpychrysaarchinstructions.la \ +# operands/libpychrysaarchoperands.la -libpychrysaarch_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ +libpychrysaarch4_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + $(TOOLKIT_CFLAGS) \ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT @@ -25,4 +39,4 @@ devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libpychrysaarch_la_SOURCES:%c=) -SUBDIRS = instructions operands +# SUBDIRS = instructions operands diff --git a/plugins/pychrysalide/arch/constants.c b/plugins/pychrysalide/arch/constants.c index 0402b03..3604795 100644 --- a/plugins/pychrysalide/arch/constants.c +++ b/plugins/pychrysalide/arch/constants.c @@ -25,14 +25,15 @@ #include "constants.h" -#include -#include +//#include +//#include #include #include "../helpers.h" +#if 0 // FIXME /****************************************************************************** * * @@ -207,6 +208,7 @@ int convert_to_arch_processing_error(PyObject *arg, void *dst) return result; } +#endif /****************************************************************************** @@ -247,6 +249,7 @@ bool define_arch_vmpa_constants(PyTypeObject *type) } +#if 0 // FIXME /****************************************************************************** * * * Paramètres : type = type dont le dictionnaire est à compléter. * @@ -343,3 +346,4 @@ int convert_to_disass_priority_level(PyObject *arg, void *dst) return result; } +#endif diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h index 03efc82..b12579e 100644 --- a/plugins/pychrysalide/arch/constants.h +++ b/plugins/pychrysalide/arch/constants.h @@ -30,7 +30,7 @@ #include - +#if 0 // FIXME /* Définit les constantes relatives aux instructions. */ bool define_arch_instruction_constants(PyTypeObject *); @@ -39,15 +39,18 @@ bool define_arch_processor_constants(PyTypeObject *); /* Tente de convertir en constante ArchProcessingError. */ int convert_to_arch_processing_error(PyObject *, void *); +#endif /* Définit les constantes relatives aux emplacements. */ bool define_arch_vmpa_constants(PyTypeObject *); +#if 0 // FIXME /* Définit les constantes relatives aux contextes. */ bool define_proc_context_constants(PyTypeObject *); /* Tente de convertir en constante DisassPriorityLevel. */ int convert_to_disass_priority_level(PyObject *, void *); +#endif diff --git a/plugins/pychrysalide/arch/module.c b/plugins/pychrysalide/arch/module.c index d0bc1f5..bbdaf76 100644 --- a/plugins/pychrysalide/arch/module.c +++ b/plugins/pychrysalide/arch/module.c @@ -29,18 +29,21 @@ #include -#include +/* #include "context.h" #include "instriter.h" #include "instruction.h" #include "operand.h" #include "processor.h" #include "register.h" +*/ #include "vmpa.h" +/* #include "instructions/module.h" #include "operands/module.h" +*/ #include "../helpers.h" @@ -77,8 +80,10 @@ bool add_arch_module(PyObject *super) result = (module != NULL); + /* if (result) result = add_arch_instructions_module(module); if (result) result = add_arch_operands_module(module); + */ return result; @@ -103,17 +108,21 @@ bool populate_arch_module(void) result = true; + /* if (result) result = ensure_python_proc_context_is_registered(); if (result) result = ensure_python_instr_iterator_is_registered(); if (result) result = ensure_python_arch_instruction_is_registered(); if (result) result = ensure_python_arch_operand_is_registered(); if (result) result = ensure_python_arch_processor_is_registered(); if (result) result = ensure_python_arch_register_is_registered(); + */ if (result) result = ensure_python_vmpa_is_registered(); if (result) result = ensure_python_mrange_is_registered(); + /* if (result) result = populate_arch_instructions_module(); if (result) result = populate_arch_operands_module(); + */ assert(result); diff --git a/plugins/pychrysalide/constants.c b/plugins/pychrysalide/constants.c new file mode 100644 index 0000000..8142284 --- /dev/null +++ b/plugins/pychrysalide/constants.c @@ -0,0 +1,215 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constants.c - ajout des constantes des définitions de base + * + * Copyright (C) 2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "constants.h" + + +#include +#include + + +#include "helpers.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes relatives aux définitions de base. * +* * +* Retour : true en cas de succès de l'opération, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_data_types_constants(PyObject *module) +{ + bool result; /* Bilan à retourner */ + PyObject *values; /* Groupe de valeurs à établir */ + + values = PyDict_New(); + + result = add_const_to_group(values, "LITTLE", SRE_LITTLE); + if (result) result = add_const_to_group(values, "LITTLE_WORD", SRE_LITTLE_WORD); + if (result) result = add_const_to_group(values, "BIG_WORD", SRE_BIG_WORD); + if (result) result = add_const_to_group(values, "BIG", SRE_BIG); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_module(module, false, "SourceEndian", values, + "Endianness of handled data."); + + values = PyDict_New(); + + result = add_const_to_group(values, "UNDEFINED", MDS_UNDEFINED); + if (result) result = add_const_to_group(values, "_4_BITS_UNSIGNED", MDS_4_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_8_BITS_UNSIGNED", MDS_8_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_16_BITS_UNSIGNED", MDS_16_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_32_BITS_UNSIGNED", MDS_32_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_64_BITS_UNSIGNED", MDS_64_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_4_BITS_SIGNED", MDS_4_BITS_SIGNED); + if (result) result = add_const_to_group(values, "_8_BITS_SIGNED", MDS_8_BITS_SIGNED); + if (result) result = add_const_to_group(values, "_16_BITS_SIGNED", MDS_16_BITS_SIGNED); + if (result) result = add_const_to_group(values, "_32_BITS_SIGNED", MDS_32_BITS_SIGNED); + if (result) result = add_const_to_group(values, "_64_BITS_SIGNED", MDS_64_BITS_SIGNED); + if (result) result = add_const_to_group(values, "_4_BITS", MDS_4_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_8_BITS", MDS_8_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_16_BITS", MDS_16_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_32_BITS", MDS_32_BITS_UNSIGNED); + if (result) result = add_const_to_group(values, "_64_BITS", MDS_64_BITS_UNSIGNED); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_module(module, false, "MemoryDataSize", values, + "Size of processed data."); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* 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 constante SourceEndian. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_source_endian(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + unsigned long value; /* Valeur transcrite */ + + result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 SourceEndian"); + break; + + case 1: + value = PyLong_AsUnsignedLong(arg); + + if (value > SRE_BIG) + { + PyErr_SetString(PyExc_TypeError, "invalid value for SourceEndian"); + result = 0; + } + + else + *((SourceEndian *)dst) = value; + + break; + + default: + assert(false); + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* 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 constante MemoryDataSize. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_memory_data_size(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + unsigned long value; /* Valeur transcrite */ + + result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 MemoryDataSize"); + break; + + case 1: + value = PyLong_AsUnsignedLong(arg); + + if (value != MDS_UNDEFINED + && (value < MDS_4_BITS_UNSIGNED && value > MDS_64_BITS_UNSIGNED) + && (value < MDS_4_BITS_SIGNED && value > MDS_64_BITS_SIGNED)) + { + PyErr_SetString(PyExc_TypeError, "invalid value for MemoryDataSize"); + result = 0; + } + + else + *((MemoryDataSize *)dst) = value; + + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/constants.h b/plugins/pychrysalide/constants.h new file mode 100644 index 0000000..332afe0 --- /dev/null +++ b/plugins/pychrysalide/constants.h @@ -0,0 +1,51 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constants.h - prototypes pour l'ajout des constantes des définitions de base + * + * Copyright (C) 2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_CONSTANTS_H +#define _PLUGINS_PYCHRYSALIDE_CONSTANTS_H + + +#include +#include + + +#include "helpers.h" + + + +/* Définit les constantes relatives aux définitions de base. */ +bool define_data_types_constants(PyObject *); + +/* Tente de convertir en constante SourceEndian. */ +int convert_to_source_endian(PyObject *, void *); + +#define cast_source_endian_to_python(v) \ + cast_with_constants_group_from_module("pychrysalide", "SourceEndian", v) + +/* Tente de convertir en constante MemoryDataSize. */ +int convert_to_memory_data_size(PyObject *, void *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_CONSTANTS_H */ diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c index c7ebf72..35c0e35 100644 --- a/plugins/pychrysalide/core.c +++ b/plugins/pychrysalide/core.c @@ -53,12 +53,13 @@ #include "access.h" +#include "constants.h" #include "helpers.h" #include "star.h" #include "strenum.h" #include "struct.h" -/* #include "analysis/module.h" */ -/* #include "arch/module.h" */ +#include "analysis/module.h" +#include "arch/module.h" /* #include "common/module.h" */ /* #include "core/module.h" */ /* #include "debug/module.h" */ @@ -642,9 +643,9 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) if (status) status = add_features_module(result); - /* if (status) status = add_analysis_module(result); if (status) status = add_arch_module(result); + /* if (status) status = add_common_module(result); if (status) status = add_core_module(result); if (status) status = add_debug_module(result); @@ -661,9 +662,13 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) /* if (status) status = ensure_python_string_enum_is_registered(); if (status) status = ensure_python_py_struct_is_registered(); + */ + + if (status) status = define_data_types_constants(result); if (status) status = populate_analysis_module(); if (status) status = populate_arch_module(); + /* if (status) status = populate_common_module(); if (status) status = populate_core_module(); if (status) status = populate_debug_module(); diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c index 179f03b..0ca133f 100644 --- a/plugins/pychrysalide/helpers.c +++ b/plugins/pychrysalide/helpers.c @@ -1570,27 +1570,46 @@ PyObject *_attach_constants_group(const char *owner, PyObject *dict, bool flags, kwargs = PyDict_New(); dot = rindex(owner, '.'); - assert(dot != NULL); - module = strndup(owner, dot - owner); + if (dot == NULL) + { + str_obj = PyUnicode_FromString(owner); + ret = PyDict_SetItemString(kwargs, "module", str_obj); + Py_DECREF(str_obj); - str_obj = PyUnicode_FromString(module); - ret = PyDict_SetItemString(kwargs, "module", str_obj); - Py_DECREF(str_obj); + if (ret != 0) goto kwargs_error; - free(module); + str_obj = PyUnicode_FromString(name); + ret = PyDict_SetItemString(kwargs, "qualname", str_obj); + Py_DECREF(str_obj); - asprintf(&qualname, "%s.%s", dot + 1, name); + if (ret != 0) goto kwargs_error; - if (ret != 0) goto kwargs_error; + } - str_obj = PyUnicode_FromString(qualname); - ret = PyDict_SetItemString(kwargs, "qualname", str_obj); - Py_DECREF(str_obj); + else + { + module = strndup(owner, dot - owner); - free(qualname); + str_obj = PyUnicode_FromString(module); + ret = PyDict_SetItemString(kwargs, "module", str_obj); + Py_DECREF(str_obj); - if (ret != 0) goto kwargs_error; + free(module); + + if (ret != 0) goto kwargs_error; + + asprintf(&qualname, "%s.%s", dot + 1, name); + + str_obj = PyUnicode_FromString(qualname); + ret = PyDict_SetItemString(kwargs, "qualname", str_obj); + Py_DECREF(str_obj); + + free(qualname); + + if (ret != 0) goto kwargs_error; + + } /* Constitution de l'énumération et enregistrement */ @@ -1762,19 +1781,35 @@ PyObject *_cast_with_constants_group(const char *owner, const char *name, unsign /* Recherche de la classe Python */ dot = strrchr(owner, '.'); - assert(dot != NULL); - modname = strndup(owner, dot - owner); + if (dot == NULL) + { + module = get_access_to_python_module(owner); + + if (module == NULL) + goto no_mod; - module = get_access_to_python_module(modname); + type = module; + Py_INCREF(type); - if (module == NULL) - goto no_mod; + } + else + { + modname = strndup(owner, dot - owner); - type = PyObject_GetAttrString(module, dot + 1); + module = get_access_to_python_module(modname); - if (type == NULL) - goto no_type; + free(modname); + + if (module == NULL) + goto no_mod; + + type = PyObject_GetAttrString(module, dot + 1); + + if (type == NULL) + goto no_type; + + } class = PyObject_GetAttrString(type, name); @@ -1798,8 +1833,6 @@ PyObject *_cast_with_constants_group(const char *owner, const char *name, unsign no_type: no_mod: - free(modname); - return result; } diff --git a/plugins/pychrysalide/plugins/constants.c b/plugins/pychrysalide/plugins/constants.c index 8791d91..7e20e4c 100644 --- a/plugins/pychrysalide/plugins/constants.c +++ b/plugins/pychrysalide/plugins/constants.c @@ -90,7 +90,7 @@ bool define_plugin_module_constants(PyTypeObject *type) goto exit; } - result = attach_constants_group_to_type(type, false, "PluginAction", values, + result = attach_constants_group_to_type(type, true, "PluginAction", values, "Features with which plugins can extend the core of Chrysalide."); exit: diff --git a/src/Makefile.am b/src/Makefile.am index 8df0b16..7ff4559 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -77,12 +77,14 @@ endif libchrysacore4_la_SOURCES = libchrysacore4_la_LIBADD = \ + analysis/libanalysis4.la \ + arch/libarch4.la \ common/libcommon4.la \ core/libcore4.la \ plugins/libplugins.la libchrysacore4_la_LDFLAGS = \ - $(TOOLKIT_LIBS) + $(TOOLKIT_LIBS) $(LIBSSL_LIBS) #--- libchrysacoreui @@ -176,4 +178,4 @@ rost_LDFLAGS = $(LIBGOBJ_LIBS) -L.libs -lchrysacore #SUBDIRS = core glibext $(GTKEXT_SUBDIR) analysis arch format common debug $(GUI_SUBDIR) mangling plugins schemas -SUBDIRS = common core glibext gtkext gui plugins +SUBDIRS = analysis arch common core glibext gtkext gui plugins diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index 909ced9..4eb0811 100644 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -1,5 +1,5 @@ -noinst_LTLIBRARIES = libanalysis.la +noinst_LTLIBRARIES = libanalysis4.la # libanalysis.la libanalysis_la_SOURCES = \ binary.h binary.c \ @@ -30,9 +30,20 @@ libanalysis_la_LIBADD = \ types/libanalysistypes.la +libanalysis4_la_SOURCES = \ + content-int.h \ + content.h content.c + +libanalysis4_la_CFLAGS = $(TOOLKIT_CFLAGS) + +libanalysis4_la_LIBADD = \ + contents/libanalysiscontents.la + + devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) dev_HEADERS = $(libanalysis_la_SOURCES:%c=) -SUBDIRS = contents db disass human scan storage types +#SUBDIRS = contents db disass human scan storage types +SUBDIRS = contents diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h index 3475b3f..36c95e7 100644 --- a/src/analysis/content-int.h +++ b/src/analysis/content-int.h @@ -26,16 +26,16 @@ #include "content.h" -#include "storage/serialize-int.h" - +//#include "storage/serialize-int.h" // FIXME +#if 0 // FIXME /* Associe un ensemble d'attributs au contenu binaire. */ typedef void (* set_content_attributes) (GBinContent *, GContentAttributes *); /* Fournit l'ensemble des attributs associés à un contenu. */ typedef GContentAttributes * (* get_content_attributes) (const GBinContent *); - +#endif /* Donne l'origine d'un contenu binaire. */ typedef GBinContent * (* get_content_root_fc) (GBinContent *); @@ -43,16 +43,16 @@ typedef GBinContent * (* get_content_root_fc) (GBinContent *); typedef char * (* describe_content_fc) (const GBinContent *, bool); /* Calcule une empreinte unique (SHA256) pour les données. */ -typedef void (* compute_checksum_fc) (GBinContent *, GChecksum *); +typedef void (* compute_checksum_fc) (const GBinContent *, GChecksum *); /* Détermine le nombre d'octets lisibles. */ typedef phys_t (* compute_size_fc) (const GBinContent *); /* Détermine la position initiale d'un contenu. */ -typedef void (* compute_start_pos_fc) (const GBinContent *, vmpa2t *); +typedef bool (* compute_start_pos_fc) (const GBinContent *, vmpa2t *); /* Détermine la position finale d'un contenu. */ -typedef void (* compute_end_pos_fc) (const GBinContent *, vmpa2t *); +typedef bool (* compute_end_pos_fc) (const GBinContent *, vmpa2t *); /* Avance la tête de lecture d'une certaine quantité de données. */ typedef bool (* seek_fc) (const GBinContent *, vmpa2t *, phys_t); @@ -83,13 +83,13 @@ typedef bool (* read_uleb128_fc) (const GBinContent *, vmpa2t *, uleb128_t *); /* Lit un nombre signé encodé au format LEB128. */ typedef bool (* read_leb128_fc) (const GBinContent *, vmpa2t *, leb128_t *); - +#if 0 // FIXME /* Charge un objet depuis une mémoire tampon. */ typedef bool (* load_content_cb) (GBinContent *, GObjectStorage *, packed_buffer_t *); /* Sauvegarde un objet dans une mémoire tampon. */ typedef bool (* store_content_cb) (const GBinContent *, GObjectStorage *, packed_buffer_t *); - +#endif /* Accès à un contenu binaire quelconque (instance) */ struct _GBinContent @@ -103,8 +103,10 @@ struct _GBinContentClass { GObjectClass parent; /* A laisser en premier */ +#if 0 // FIXME set_content_attributes set_attribs; /* Enregistrement d'attributs */ get_content_attributes get_attribs; /* Fourniture d'attributs */ +#endif get_content_root_fc get_root; /* Renvoie à l'origine */ @@ -130,8 +132,10 @@ struct _GBinContentClass read_uleb128_fc read_uleb128; /* Lecture d'un LEB non signé */ read_leb128_fc read_leb128; /* Lecture d'un LEB signé */ +#if 0 // FIXME load_content_cb load; /* Chargement */ store_content_cb store; /* Enregistrement */ +#endif }; diff --git a/src/analysis/content.c b/src/analysis/content.c index e12237f..89fc572 100644 --- a/src/analysis/content.c +++ b/src/analysis/content.c @@ -45,7 +45,9 @@ static void g_binary_content_class_init(GBinContentClass *); static void g_binary_content_init(GBinContent *); /* Procède à l'initialisation de l'interface de sérialisation. */ +#if 0 // FIXME static void g_binary_content_serializable_interface_init(GSerializableObjectIface *); +#endif /* Supprime toutes les références externes. */ static void g_binary_content_dispose(GBinContent *); @@ -58,11 +60,13 @@ static void g_binary_content_finalize(GBinContent *); /* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ +#if 0 // FIXME /* Charge un contenu depuis une mémoire tampon. */ static bool g_binary_content_load(GBinContent *, GObjectStorage *, packed_buffer_t *); /* Sauvegarde un contenu dans une mémoire tampon. */ static bool g_binary_content_store(const GBinContent *, GObjectStorage *, packed_buffer_t *); +#endif @@ -72,8 +76,11 @@ static bool g_binary_content_store(const GBinContent *, GObjectStorage *, packed /* Détermine le type d'un contenu binaire à parcourir. */ +#if 0 // FIXME G_DEFINE_TYPE_WITH_CODE(GBinContent, g_binary_content, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_binary_content_serializable_interface_init)); +#endif +G_DEFINE_TYPE(GBinContent, g_binary_content, G_TYPE_OBJECT); /****************************************************************************** @@ -130,12 +137,14 @@ static void g_binary_content_init(GBinContent *content) * * ******************************************************************************/ +#if 0 // FIXME static void g_binary_content_serializable_interface_init(GSerializableObjectIface *iface) { iface->load = (load_serializable_object_cb)g_binary_content_load; iface->store = (store_serializable_object_cb)g_binary_content_store; } +#endif /****************************************************************************** @@ -188,7 +197,7 @@ static void g_binary_content_finalize(GBinContent *content) * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME void g_binary_content_set_attributes(GBinContent *content, GContentAttributes *attribs) { GBinContentClass *class; /* Classe de l'instance */ @@ -224,7 +233,7 @@ GContentAttributes *g_binary_content_get_attributes(const GBinContent *content) return result; } - +#endif /****************************************************************************** * * @@ -351,19 +360,22 @@ phys_t g_binary_content_compute_size(const GBinContent *content) * * * Description : Détermine la position initiale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -void g_binary_content_compute_start_pos(const GBinContent *content, vmpa2t *pos) +bool g_binary_content_compute_start_pos(const GBinContent *content, vmpa2t *pos) { + bool result; /* Bilan à retourner */ GBinContentClass *class; /* Classe de l'instance */ class = G_BIN_CONTENT_GET_CLASS(content); - return class->compute_start_pos(content, pos); + result = class->compute_start_pos(content, pos); + + return result; } @@ -375,19 +387,22 @@ void g_binary_content_compute_start_pos(const GBinContent *content, vmpa2t *pos) * * * Description : Détermine la position finale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -void g_binary_content_compute_end_pos(const GBinContent *content, vmpa2t *pos) +bool g_binary_content_compute_end_pos(const GBinContent *content, vmpa2t *pos) { + bool result; /* Bilan à retourner */ GBinContentClass *class; /* Classe de l'instance */ class = G_BIN_CONTENT_GET_CLASS(content); - return class->compute_end_pos(content, pos); + result = class->compute_end_pos(content, pos); + + return result; } @@ -780,6 +795,7 @@ bool g_binary_content_read_leb128(const GBinContent *content, vmpa2t *addr, leb1 * * ******************************************************************************/ +#if 0 // FIXME static bool g_binary_content_load(GBinContent *content, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ @@ -820,3 +836,4 @@ static bool g_binary_content_store(const GBinContent *content, GObjectStorage *s return result; } +#endif diff --git a/src/analysis/content.h b/src/analysis/content.h index ee79a9c..ad50c02 100644 --- a/src/analysis/content.h +++ b/src/analysis/content.h @@ -29,9 +29,8 @@ #include -#include "cattribs.h" +//#include "cattribs.h" // FIXME #include "../arch/vmpa.h" -#include "../common/endianness.h" #include "../common/leb128.h" @@ -53,13 +52,13 @@ typedef struct _GBinContentClass GBinContentClass; /* Détermine le type d'un contenu binaire à parcourir. */ GType g_binary_content_get_type(void) G_GNUC_CONST; - +#if 0 // FIXME /* Associe un ensemble d'attributs au contenu binaire. */ void g_binary_content_set_attributes(GBinContent *, GContentAttributes *); /* Fournit l'ensemble des attributs associés à un contenu. */ GContentAttributes *g_binary_content_get_attributes(const GBinContent *); - +#endif /* Donne l'origine d'un contenu binaire. */ GBinContent *g_binary_content_get_root(GBinContent *); @@ -73,10 +72,10 @@ const gchar *g_binary_content_get_checksum(GBinContent *); phys_t g_binary_content_compute_size(const GBinContent *); /* Détermine la position initiale d'un contenu. */ -void g_binary_content_compute_start_pos(const GBinContent *, vmpa2t *); +bool g_binary_content_compute_start_pos(const GBinContent *, vmpa2t *); /* Détermine la position finale d'un contenu. */ -void g_binary_content_compute_end_pos(const GBinContent *, vmpa2t *); +bool g_binary_content_compute_end_pos(const GBinContent *, vmpa2t *); /* Avance la tête de lecture d'une certaine quantité de données. */ bool g_binary_content_seek(const GBinContent *, vmpa2t *, phys_t); diff --git a/src/analysis/contents/encapsulated.c b/src/analysis/contents/encapsulated.c index e0e6ed1..451c340 100644 --- a/src/analysis/contents/encapsulated.c +++ b/src/analysis/contents/encapsulated.c @@ -54,12 +54,13 @@ static void g_encaps_content_finalize(GEncapsContent *); /* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ - +#if 0 // FIXME /* Associe un ensemble d'attributs au contenu binaire. */ static void g_encaps_content_set_attributes(GEncapsContent *, GContentAttributes *); /* Fournit l'ensemble des attributs associés à un contenu. */ static GContentAttributes *g_encaps_content_get_attributes(const GEncapsContent *); +#endif /* Donne l'origine d'un contenu binaire. */ static GBinContent *g_encaps_content_get_root(GEncapsContent *); @@ -68,16 +69,16 @@ static GBinContent *g_encaps_content_get_root(GEncapsContent *); static char *g_encaps_content_describe(const GEncapsContent *, bool); /* Fournit une empreinte unique (SHA256) pour les données. */ -static void g_encaps_content_compute_checksum(GEncapsContent *, GChecksum *); +static void g_encaps_content_compute_checksum(const GEncapsContent *, GChecksum *); /* Détermine le nombre d'octets lisibles. */ static phys_t g_encaps_content_compute_size(const GEncapsContent *); /* Détermine la position initiale d'un contenu. */ -static void g_encaps_content_compute_start_pos(const GEncapsContent *, vmpa2t *); +static bool g_encaps_content_compute_start_pos(const GEncapsContent *, vmpa2t *); /* Détermine la position finale d'un contenu. */ -static void g_encaps_content_compute_end_pos(const GEncapsContent *, vmpa2t *); +static bool g_encaps_content_compute_end_pos(const GEncapsContent *, vmpa2t *); /* Avance la tête de lecture d'une certaine quantité de données. */ static bool g_encaps_content_seek(const GEncapsContent *, vmpa2t *, phys_t); @@ -108,13 +109,13 @@ static bool g_encaps_content_read_uleb128(const GEncapsContent *, vmpa2t *, uleb /* Lit un nombre signé encodé au format LEB128. */ static bool g_encaps_content_read_leb128(const GEncapsContent *, vmpa2t *, leb128_t *); - +#if 0 // FIXME /* Charge un contenu depuis une mémoire tampon. */ static bool g_encaps_content_load(GEncapsContent *, GObjectStorage *, packed_buffer_t *); /* Sauvegarde un contenu dans une mémoire tampon. */ static bool g_encaps_content_store(const GEncapsContent *, GObjectStorage *, packed_buffer_t *); - +#endif /* ---------------------------------------------------------------------------------- */ @@ -150,8 +151,10 @@ static void g_encaps_content_class_init(GEncapsContentClass *klass) content = G_BIN_CONTENT_CLASS(klass); +#if 0 // FIXME content->set_attribs = (set_content_attributes)g_encaps_content_set_attributes; content->get_attribs = (get_content_attributes)g_encaps_content_get_attributes; +#endif content->get_root = (get_content_root_fc)g_encaps_content_get_root; @@ -177,8 +180,10 @@ static void g_encaps_content_class_init(GEncapsContentClass *klass) content->read_uleb128 = (read_uleb128_fc)g_encaps_content_read_uleb128; content->read_leb128 = (read_leb128_fc)g_encaps_content_read_leb128; +#if 0 // FIXME content->load = (load_content_cb)g_encaps_content_load; content->store = (store_content_cb)g_encaps_content_store; +#endif } @@ -408,7 +413,7 @@ GBinContent *g_encaps_content_get_endpoint(const GEncapsContent *content) /* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ - +#if 0 // FIXME /****************************************************************************** * * * Paramètres : content = contenu binaire à actualiser. * @@ -450,7 +455,7 @@ static GContentAttributes *g_encaps_content_get_attributes(const GEncapsContent return result; } - +#endif /****************************************************************************** * * @@ -515,7 +520,7 @@ static char *g_encaps_content_describe(const GEncapsContent *content, bool full) * * ******************************************************************************/ -static void g_encaps_content_compute_checksum(GEncapsContent *content, GChecksum *checksum) +static void g_encaps_content_compute_checksum(const GEncapsContent *content, GChecksum *checksum) { GBinContentClass *class; /* Classe de l'instance */ @@ -556,15 +561,19 @@ static phys_t g_encaps_content_compute_size(const GEncapsContent *content) * * * Description : Détermine la position initiale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -static void g_encaps_content_compute_start_pos(const GEncapsContent *content, vmpa2t *pos) +static bool g_encaps_content_compute_start_pos(const GEncapsContent *content, vmpa2t *pos) { - g_binary_content_compute_start_pos(content->endpoint, pos); + bool result; /* Bilan à retourner */ + + result = g_binary_content_compute_start_pos(content->endpoint, pos); + + return result; } @@ -576,15 +585,19 @@ static void g_encaps_content_compute_start_pos(const GEncapsContent *content, vm * * * Description : Détermine la position finale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -static void g_encaps_content_compute_end_pos(const GEncapsContent *content, vmpa2t *pos) +static bool g_encaps_content_compute_end_pos(const GEncapsContent *content, vmpa2t *pos) { - g_binary_content_compute_end_pos(content->endpoint, pos); + bool result; /* Bilan à retourner */ + + result = g_binary_content_compute_end_pos(content->endpoint, pos); + + return result; } @@ -858,7 +871,7 @@ static bool g_encaps_content_read_leb128(const GEncapsContent *content, vmpa2t * * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME static bool g_encaps_content_load(GEncapsContent *content, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ @@ -979,3 +992,4 @@ static bool g_encaps_content_store(const GEncapsContent *content, GObjectStorage return result; } +#endif diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c index 545d869..791f8b6 100644 --- a/src/analysis/contents/file.c +++ b/src/analysis/contents/file.c @@ -62,13 +62,13 @@ static void g_file_content_finalize(GFileContent *); /* Fournit le nom associé au contenu binaire. */ static char *g_file_content_describe(const GFileContent *, bool); - +#if 0 // FIXME /* Charge un contenu depuis une mémoire tampon. */ static bool g_file_content_load(GFileContent *, GObjectStorage *, packed_buffer_t *); /* Sauvegarde un contenu dans une mémoire tampon. */ static bool g_file_content_store(const GFileContent *, GObjectStorage *, packed_buffer_t *); - +#endif /* ---------------------------------------------------------------------------------- */ @@ -106,8 +106,10 @@ static void g_file_content_class_init(GFileContentClass *klass) content->describe = (describe_content_fc)g_file_content_describe; +#if 0 // FIXME content->load = (load_content_cb)g_file_content_load; content->store = (store_content_cb)g_file_content_store; +#endif } @@ -359,7 +361,7 @@ static char *g_file_content_describe(const GFileContent *content, bool full) * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME static bool g_file_content_load(GFileContent *content, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ @@ -428,3 +430,4 @@ static bool g_file_content_store(const GFileContent *content, GObjectStorage *st return result; } +#endif diff --git a/src/analysis/contents/memory-int.h b/src/analysis/contents/memory-int.h index d3012c7..692feb7 100644 --- a/src/analysis/contents/memory-int.h +++ b/src/analysis/contents/memory-int.h @@ -37,7 +37,9 @@ struct _GMemoryContent { GBinContent parent; /* A laisser en premier */ +#if 0 // FIXME GContentAttributes *attribs; /* Attributs liés au contenu */ +#endif bin_t *data; /* Contenu binaire représenté */ phys_t length; /* Taille totale du contenu */ diff --git a/src/analysis/contents/memory.c b/src/analysis/contents/memory.c index f8ff863..f7d2bd0 100644 --- a/src/analysis/contents/memory.c +++ b/src/analysis/contents/memory.c @@ -62,11 +62,13 @@ static void g_memory_content_finalize(GMemoryContent *); /* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +#if 0 // FIXME /* Associe un ensemble d'attributs au contenu binaire. */ static void g_memory_content_set_attributes(GMemoryContent *, GContentAttributes *); /* Fournit l'ensemble des attributs associés à un contenu. */ static GContentAttributes *g_memory_content_get_attributes(const GMemoryContent *); +#endif /* Donne l'origine d'un contenu binaire. */ static GBinContent *g_memory_content_get_root(GMemoryContent *); @@ -75,16 +77,16 @@ static GBinContent *g_memory_content_get_root(GMemoryContent *); static char *g_memory_content_describe(const GMemoryContent *, bool); /* Fournit une empreinte unique (SHA256) pour les données. */ -static void g_memory_content_compute_checksum(GMemoryContent *, GChecksum *); +static void g_memory_content_compute_checksum(const GMemoryContent *, GChecksum *); /* Détermine le nombre d'octets lisibles. */ static phys_t g_memory_content_compute_size(const GMemoryContent *); /* Détermine la position initiale d'un contenu. */ -static void g_memory_content_compute_start_pos(const GMemoryContent *, vmpa2t *); +static bool g_memory_content_compute_start_pos(const GMemoryContent *, vmpa2t *); /* Détermine la position finale d'un contenu. */ -static void g_memory_content_compute_end_pos(const GMemoryContent *, vmpa2t *); +static bool g_memory_content_compute_end_pos(const GMemoryContent *, vmpa2t *); /* Avance la tête de lecture d'une certaine quantité de données. */ static bool g_memory_content_seek(const GMemoryContent *, vmpa2t *, phys_t); @@ -116,12 +118,13 @@ static bool g_memory_content_read_uleb128(const GMemoryContent *, vmpa2t *, uleb /* Lit un nombre signé encodé au format LEB128. */ static bool g_memory_content_read_leb128(const GMemoryContent *, vmpa2t *, leb128_t *); +#if 0 // FIXME /* Charge un contenu depuis une mémoire tampon. */ static bool g_memory_content_load(GMemoryContent *, GObjectStorage *, packed_buffer_t *); /* Sauvegarde un contenu dans une mémoire tampon. */ static bool g_memory_content_store(const GMemoryContent *, GObjectStorage *, packed_buffer_t *); - +#endif /* ---------------------------------------------------------------------------------- */ @@ -157,8 +160,10 @@ static void g_memory_content_class_init(GMemoryContentClass *klass) content = G_BIN_CONTENT_CLASS(klass); +#if 0 // FIXME content->set_attribs = (set_content_attributes)g_memory_content_set_attributes; content->get_attribs = (get_content_attributes)g_memory_content_get_attributes; +#endif content->get_root = (get_content_root_fc)g_memory_content_get_root; @@ -184,8 +189,10 @@ static void g_memory_content_class_init(GMemoryContentClass *klass) content->read_uleb128 = (read_uleb128_fc)g_memory_content_read_uleb128; content->read_leb128 = (read_leb128_fc)g_memory_content_read_leb128; +#if 0 // FIXME content->load = (load_content_cb)g_memory_content_load; content->store = (store_content_cb)g_memory_content_store; +#endif } @@ -204,6 +211,7 @@ static void g_memory_content_class_init(GMemoryContentClass *klass) static void g_memory_content_init(GMemoryContent *content) { +#if 0 // FIXME GContentAttributes *empty; /* Jeu d'attributs vide */ content->attribs = NULL; @@ -213,6 +221,7 @@ static void g_memory_content_init(GMemoryContent *content) g_binary_content_set_attributes(G_BIN_CONTENT(content), empty); g_object_unref(G_OBJECT(empty)); +#endif content->data = NULL; content->length = 0; @@ -238,7 +247,9 @@ static void g_memory_content_init(GMemoryContent *content) static void g_memory_content_dispose(GMemoryContent *content) { +#if 0 // FIXME g_clear_object(&content->attribs); +#endif G_OBJECT_CLASS(g_memory_content_parent_class)->dispose(G_OBJECT(content)); @@ -362,7 +373,7 @@ bool g_memory_content_create(GMemoryContent *content, const bin_t *data, phys_t * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME static void g_memory_content_set_attributes(GMemoryContent *content, GContentAttributes *attribs) { g_clear_object(&content->attribs); @@ -397,7 +408,7 @@ static GContentAttributes *g_memory_content_get_attributes(const GMemoryContent return result; } - +#endif /****************************************************************************** * * @@ -464,7 +475,7 @@ static char *g_memory_content_describe(const GMemoryContent *content, bool full) * * ******************************************************************************/ -static void g_memory_content_compute_checksum(GMemoryContent *content, GChecksum *checksum) +static void g_memory_content_compute_checksum(const GMemoryContent *content, GChecksum *checksum) { g_checksum_update(checksum, content->data, content->length); @@ -501,16 +512,22 @@ static phys_t g_memory_content_compute_size(const GMemoryContent *content) * * * Description : Détermine la position initiale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -static void g_memory_content_compute_start_pos(const GMemoryContent *content, vmpa2t *pos) +static bool g_memory_content_compute_start_pos(const GMemoryContent *content, vmpa2t *pos) { + bool result; /* Bilan à retourner */ + + result = true; + init_vmpa(pos, 0, VMPA_NO_VIRTUAL); + return result; + } @@ -521,18 +538,24 @@ static void g_memory_content_compute_start_pos(const GMemoryContent *content, vm * * * Description : Détermine la position finale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -static void g_memory_content_compute_end_pos(const GMemoryContent *content, vmpa2t *pos) +static bool g_memory_content_compute_end_pos(const GMemoryContent *content, vmpa2t *pos) { + bool result; /* Bilan à retourner */ + + result = true; + g_memory_content_compute_start_pos(content, pos); advance_vmpa(pos, content->length); + return result; + } @@ -898,7 +921,7 @@ static bool g_memory_content_read_leb128(const GMemoryContent *content, vmpa2t * * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME static bool g_memory_content_load(GMemoryContent *content, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ @@ -1004,3 +1027,4 @@ static bool g_memory_content_store(const GMemoryContent *content, GObjectStorage return result; } +#endif diff --git a/src/analysis/contents/restricted.c b/src/analysis/contents/restricted.c index 9b4e1c8..95f513b 100644 --- a/src/analysis/contents/restricted.c +++ b/src/analysis/contents/restricted.c @@ -55,12 +55,13 @@ static void g_restricted_content_finalize(GRestrictedContent *); /* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ - +#if 0 // FIXME /* Associe un ensemble d'attributs au contenu binaire. */ static void g_restricted_content_set_attributes(GRestrictedContent *, GContentAttributes *); /* Fournit l'ensemble des attributs associés à un contenu. */ static GContentAttributes *g_restricted_content_get_attributes(const GRestrictedContent *); +#endif /* Donne l'origine d'un contenu binaire. */ static GBinContent *g_restricted_content_get_root(GRestrictedContent *); @@ -69,16 +70,16 @@ static GBinContent *g_restricted_content_get_root(GRestrictedContent *); static char *g_restricted_content_describe(const GRestrictedContent *, bool); /* Calcule une empreinte unique (SHA256) pour les données. */ -static void g_restricted_content_compute_checksum(GRestrictedContent *, GChecksum *); +static void g_restricted_content_compute_checksum(const GRestrictedContent *, GChecksum *); /* Détermine le nombre d'octets lisibles. */ static phys_t g_restricted_content_compute_size(const GRestrictedContent *); /* Détermine la position initiale d'un contenu. */ -static void g_restricted_content_compute_start_pos(const GRestrictedContent *, vmpa2t *); +static bool g_restricted_content_compute_start_pos(const GRestrictedContent *, vmpa2t *); /* Détermine la position finale d'un contenu. */ -static void g_restricted_content_compute_end_pos(const GRestrictedContent *, vmpa2t *); +static bool g_restricted_content_compute_end_pos(const GRestrictedContent *, vmpa2t *); /* Avance la tête de lecture d'une certaine quantité de données. */ static bool g_restricted_content_seek(const GRestrictedContent *, vmpa2t *, phys_t); @@ -109,13 +110,13 @@ static bool g_restricted_content_read_uleb128(const GRestrictedContent *, vmpa2t /* Lit un nombre signé encodé au format LEB128. */ static bool g_restricted_content_read_leb128(const GRestrictedContent *, vmpa2t *, leb128_t *); - +#if 0 // FIXME /* Charge un contenu depuis une mémoire tampon. */ static bool g_restricted_content_load(GRestrictedContent *, GObjectStorage *, packed_buffer_t *); /* Sauvegarde un contenu dans une mémoire tampon. */ static bool g_restricted_content_store(const GRestrictedContent *, GObjectStorage *, packed_buffer_t *); - +#endif /* ---------------------------------------------------------------------------------- */ @@ -151,8 +152,10 @@ static void g_restricted_content_class_init(GRestrictedContentClass *klass) content = G_BIN_CONTENT_CLASS(klass); +#if 0 // FIXME content->set_attribs = (set_content_attributes)g_restricted_content_set_attributes; content->get_attribs = (get_content_attributes)g_restricted_content_get_attributes; +#endif content->get_root = (get_content_root_fc)g_restricted_content_get_root; @@ -178,8 +181,10 @@ static void g_restricted_content_class_init(GRestrictedContentClass *klass) content->read_uleb128 = (read_uleb128_fc)g_restricted_content_read_uleb128; content->read_leb128 = (read_leb128_fc)g_restricted_content_read_leb128; +#if 0 // FIXME content->load = (load_content_cb)g_restricted_content_load; content->store = (store_content_cb)g_restricted_content_store; +#endif } @@ -344,7 +349,7 @@ void g_restricted_content_get_range(const GRestrictedContent *content, mrange_t * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME static void g_restricted_content_set_attributes(GRestrictedContent *content, GContentAttributes *attribs) { g_binary_content_set_attributes(content->internal, attribs); @@ -373,6 +378,7 @@ static GContentAttributes *g_restricted_content_get_attributes(const GRestricted return result; } +#endif /****************************************************************************** @@ -462,7 +468,7 @@ static char *g_restricted_content_describe(const GRestrictedContent *content, bo * * ******************************************************************************/ -static void g_restricted_content_compute_checksum(GRestrictedContent *content, GChecksum *checksum) +static void g_restricted_content_compute_checksum(const GRestrictedContent *content, GChecksum *checksum) { vmpa2t start; /* Point de départ */ phys_t i; /* Boucle de parcours */ @@ -516,16 +522,22 @@ static phys_t g_restricted_content_compute_size(const GRestrictedContent *conten * * * Description : Détermine la position initiale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -static void g_restricted_content_compute_start_pos(const GRestrictedContent *content, vmpa2t *pos) +static bool g_restricted_content_compute_start_pos(const GRestrictedContent *content, vmpa2t *pos) { + bool result; /* Bilan à retourner */ + + result = true; + copy_vmpa(pos, get_mrange_addr(&content->range)); + return result; + } @@ -536,16 +548,22 @@ static void g_restricted_content_compute_start_pos(const GRestrictedContent *con * * * Description : Détermine la position finale d'un contenu. * * * -* Retour : - * +* Retour : Validité finale de la position fournie. * * * * Remarques : - * * * ******************************************************************************/ -static void g_restricted_content_compute_end_pos(const GRestrictedContent *content, vmpa2t *pos) +static bool g_restricted_content_compute_end_pos(const GRestrictedContent *content, vmpa2t *pos) { + bool result; /* Bilan à retourner */ + + result = true; + compute_mrange_end_addr(&content->range, pos); + return result; + } @@ -977,7 +995,7 @@ static bool g_restricted_content_read_leb128(const GRestrictedContent *content, * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME static bool g_restricted_content_load(GRestrictedContent *content, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ @@ -1019,3 +1037,4 @@ static bool g_restricted_content_store(const GRestrictedContent *content, GObjec return result; } +#endif diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c index a211723..4c767c4 100644 --- a/src/analysis/db/misc/rlestr.c +++ b/src/analysis/db/misc/rlestr.c @@ -354,7 +354,7 @@ bool pack_rle_string(const rle_string *str, packed_buffer_t *pbuf) * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME bool load_rle_string(rle_string *str, const char *name, const bound_value *values, size_t count) { const bound_value *value; /* Valeur à intégrer */ @@ -426,3 +426,4 @@ bool store_rle_string(const rle_string *str, const char *name, bound_value **val return true; } +#endif diff --git a/src/analysis/db/misc/rlestr.h b/src/analysis/db/misc/rlestr.h index aa2aa73..53c1055 100644 --- a/src/analysis/db/misc/rlestr.h +++ b/src/analysis/db/misc/rlestr.h @@ -96,13 +96,13 @@ bool pack_rle_string(const rle_string *, packed_buffer_t *); /* Définition du tronc commun pour les créations SQLite */ #define SQLITE_RLESTR_CREATE(n) \ n " TEXT" - +#if 0 // FIXME /* Charge les valeurs utiles pour une chaîne de caractères. */ bool load_rle_string(rle_string *, const char *, const bound_value *, size_t); /* Constitue les champs destinés à une insertion / modification. */ bool store_rle_string(const rle_string *, const char *, bound_value **, size_t *); - +#endif #endif /* _ANALYSIS_DB_MISC_RLESTR_H */ diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index bdfceb7..6ee2690 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -1,5 +1,5 @@ -noinst_LTLIBRARIES = libarch.la +noinst_LTLIBRARIES = libarch4.la # libarch.la libarch_la_SOURCES = \ archbase.h archbase.c \ @@ -26,9 +26,18 @@ libarch_la_LIBADD = \ operands/libarchoperands.la +libarch4_la_SOURCES = \ + vmpa.h vmpa.c + +libarch4_la_CFLAGS = $(TOOLKIT_CFLAGS) + +libarch4_la_LIBADD = + + devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) dev_HEADERS = $(libarch_la_SOURCES:%c=) -SUBDIRS = instructions operands +#SUBDIRS = instructions operands + diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index b172acf..fe61125 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -754,7 +754,7 @@ char *create_vmpa_db_table(const char *base) * Remarques : - * * * ******************************************************************************/ - +#if 0 // FIXME bool load_vmpa(vmpa2t *addr, const char *base, const bound_value *values, size_t count) { char *name; /* Désignation complète */ @@ -862,7 +862,7 @@ bool store_vmpa(const vmpa2t *addr, const char *base, bound_value **values, size return true; } - +#endif /* ---------------------------------------------------------------------------------- */ diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index fe98ed4..42136e2 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -148,13 +148,13 @@ vmpa2t *string_to_vmpa_virt(const char *); /* Donne les éléments requis pour la construction d'une table. */ char *create_vmpa_db_table(const char *); - +#if 0 // FIXME /* Charge les valeurs utiles pour une localisation. */ bool load_vmpa(vmpa2t *, const char *, const bound_value *, size_t); /* Constitue les champs destinés à une insertion / modification. */ bool store_vmpa(const vmpa2t *, const char *, bound_value **, size_t *); - +#endif /* ------------------------ DEFINITION DE POSITION AVEC BITS ------------------------ */ diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 1c2d11a..a57868d 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -59,11 +59,13 @@ libcommon4_la_SOURCES = \ environment.h environment.c \ extstr.h extstr.c \ io.h io.c \ + leb128.h leb128.c \ + packed.h packed.c \ pathname.h pathname.c \ sort.h sort.c \ xdg.h xdg.c -libcommon4_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) +libcommon4_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBSSL_CFLAGS) devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) diff --git a/src/common/leb128.h b/src/common/leb128.h index ae1078a..f438068 100644 --- a/src/common/leb128.h +++ b/src/common/leb128.h @@ -29,9 +29,8 @@ #include +#include "datatypes.h" #include "packed.h" -#include "../arch/archbase.h" -#include "../arch/vmpa.h" @@ -72,4 +71,5 @@ bool unpack_uleb128(uleb128_t *, packed_buffer_t *); bool unpack_leb128(leb128_t *, packed_buffer_t *); + #endif /* _COMMON_LEB128_H */ diff --git a/tests/analysis/contents/custom.py b/tests/analysis/contents/custom.py new file mode 100644 index 0000000..2153967 --- /dev/null +++ b/tests/analysis/contents/custom.py @@ -0,0 +1,134 @@ + +from chrysacase import ChrysalideTestCase +from pychrysalide import SourceEndian +from pychrysalide.analysis import BinContent +from pychrysalide.arch import vmpa + + +class CustomContent(BinContent): + + def __init__(self, size): + super(CustomContent, self).__init__() + self._start = 10 + self._size = size * 8 + + def _describe(self, full): + return 'my_desc' + ('_full' if full else '') + + def _compute_checksum(self, checksum): + checksum.update(b'xxxxx') + + def _compute_size(self): + return int(self._size / 8) + + def _compute_start_pos(self): + return vmpa(self._start, vmpa.VmpaSpecialValue.NO_VIRTUAL) + + def _compute_end_pos(self): + return vmpa(self._start + self._size, vmpa.VmpaSpecialValue.NO_VIRTUAL) + + def _seek(self, addr, length): + addr += length + return True + + def _read_uxxx(self, addr, sizeof): + + assert(addr >= self.start_pos and addr < self.end_pos) + + val = int((addr - self.start_pos).phys / sizeof) + + addr += sizeof + + return val + + def _read_u8(self, addr): + return self._read_uxxx(addr, 1) + + def _read_u16(self, addr, endian): + return self._read_uxxx(addr, 2) + + def _read_u32(self, addr, endian): + return self._read_uxxx(addr, 4) + + def _read_u64(self, addr, endian): + return self._read_uxxx(addr, 8) + + def _read_uleb128(self, addr): + return 128 + + def _read_leb128(self, addr): + return -128 + + +class TestCustomContent(ChrysalideTestCase): + """TestCase for custom implementation of analysis.BinContent.""" + + def testBasicImplementations(self): + """Involve all implemented basic wrappers for a custom content.""" + + cnt = CustomContent(1) + + self.assertEqual(cnt._describe(False), 'my_desc') + + self.assertEqual(cnt._describe(True), 'my_desc_full') + + # $ echo -n 'xxxxx' | sha256sum + # eaf16bc07968e013f3f94ab1342472434a39fc3475f11cf341a6c3965974f8e9 - + + expected = 'eaf16bc07968e013f3f94ab1342472434a39fc3475f11cf341a6c3965974f8e9' + + self.assertEqual(cnt.checksum, expected) + + self.assertEqual(cnt.size, 1) + + addr = cnt.start_pos + offset = 13 + + cnt.seek(addr, offset) + + self.assertEqual(addr.phys, cnt.start_pos.phys + offset) + + + def testReadImplementations(self): + """Involve main implemented read wrappers for a custom content.""" + + cnt = CustomContent(8) + + def _run_check_read_implem(fn, args): + + last = None + + pos = cnt.start_pos + + while pos < cnt.end_pos: + + val = fn(pos, *args) + + if not(last is None): + self.assertEqual(last + 1, val) + else: + self.assertEqual(val, 0) + + last = val + + checks = [ + [ cnt.read_u8, [] ], + [ cnt.read_u16, [ SourceEndian.LITTLE ] ], + [ cnt.read_u32, [ SourceEndian.LITTLE ] ], + [ cnt.read_u64, [ SourceEndian.LITTLE ] ], + ] + + for f, a in checks: + _run_check_read_implem(f, a) + + + def testLEB128Implementations(self): + """Involve [U]LEB128 implemented wrappers for a custom content.""" + + cnt = CustomContent(1) + + addr = cnt.start_pos + + self.assertEqual(cnt.read_uleb128(addr), 128) + + self.assertEqual(cnt.read_leb128(addr), -128) diff --git a/tests/analysis/contents/endian.py b/tests/analysis/contents/endian.py index b7c8bec..0557174 100644 --- a/tests/analysis/contents/endian.py +++ b/tests/analysis/contents/endian.py @@ -6,8 +6,9 @@ from chrysacase import ChrysalideTestCase +from pychrysalide import SourceEndian from pychrysalide.analysis import BinContent -from pychrysalide.analysis.contents import FileContent, RestrictedContent +from pychrysalide.analysis.contents import FileContent from pychrysalide.arch import vmpa import tempfile @@ -55,36 +56,36 @@ class TestEndianness(ChrysalideTestCase): start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u16(start, BinContent.SourceEndian.LITTLE_WORD) + val = fcnt.read_u16(start, SourceEndian.LITTLE_WORD) self.assertEqual(val, 0x1516) start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u16(start, BinContent.SourceEndian.BIG_WORD) + val = fcnt.read_u16(start, SourceEndian.BIG_WORD) self.assertEqual(val, 0x1615) # 32 bits start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u32(start, BinContent.SourceEndian.LITTLE_WORD) + val = fcnt.read_u32(start, SourceEndian.LITTLE_WORD) self.assertEqual(val, 0x17181516) start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u32(start, BinContent.SourceEndian.BIG_WORD) + val = fcnt.read_u32(start, SourceEndian.BIG_WORD) self.assertEqual(val, 0x16151817) # 64 bits start = vmpa(0, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u64(start, BinContent.SourceEndian.LITTLE_WORD) + val = fcnt.read_u64(start, SourceEndian.LITTLE_WORD) self.assertEqual(val, 0x0708050603040102) start = vmpa(0, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u64(start, BinContent.SourceEndian.BIG_WORD) + val = fcnt.read_u64(start, SourceEndian.BIG_WORD) self.assertEqual(val, 0x0201040306050807) @@ -97,34 +98,34 @@ class TestEndianness(ChrysalideTestCase): start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = fcnt.read_u16(start, SourceEndian.LITTLE) self.assertEqual(val, 0x1615) start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u16(start, BinContent.SourceEndian.BIG) + val = fcnt.read_u16(start, SourceEndian.BIG) self.assertEqual(val, 0x1516) # 32 bits start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u32(start, BinContent.SourceEndian.LITTLE) + val = fcnt.read_u32(start, SourceEndian.LITTLE) self.assertEqual(val, 0x18171615) start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u32(start, BinContent.SourceEndian.BIG) + val = fcnt.read_u32(start, SourceEndian.BIG) self.assertEqual(val, 0x15161718) # 64 bits start = vmpa(0, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u64(start, BinContent.SourceEndian.LITTLE) + val = fcnt.read_u64(start, SourceEndian.LITTLE) self.assertEqual(val, 0x0807060504030201) start = vmpa(0, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = fcnt.read_u64(start, BinContent.SourceEndian.BIG) + val = fcnt.read_u64(start, SourceEndian.BIG) self.assertEqual(val, 0x0102030405060708) diff --git a/tests/analysis/contents/memory.py b/tests/analysis/contents/memory.py index f99e607..d9daad2 100644 --- a/tests/analysis/contents/memory.py +++ b/tests/analysis/contents/memory.py @@ -7,6 +7,7 @@ from chrysacase import ChrysalideTestCase +from pychrysalide import SourceEndian from pychrysalide.analysis import BinContent from pychrysalide.analysis.contents import MemoryContent from pychrysalide.arch import vmpa, mrange @@ -39,12 +40,12 @@ class TestMemoryContent(ChrysalideTestCase): start = vmpa(14, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = cnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = cnt.read_u16(start, SourceEndian.LITTLE) self.assertEqual(val, 0x1817) start = vmpa(10, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = cnt.read_u32(start, BinContent.SourceEndian.LITTLE) + val = cnt.read_u32(start, SourceEndian.LITTLE) self.assertEqual(val, 0x16150013) @@ -63,4 +64,4 @@ class TestMemoryContent(ChrysalideTestCase): with self.assertRaisesRegex(Exception, 'Invalid read access.'): start = vmpa(0, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = cnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = cnt.read_u16(start, SourceEndian.LITTLE) diff --git a/tests/analysis/contents/restricted.py b/tests/analysis/contents/restricted.py index 023e600..8c3cb50 100644 --- a/tests/analysis/contents/restricted.py +++ b/tests/analysis/contents/restricted.py @@ -7,6 +7,7 @@ from chrysacase import ChrysalideTestCase +from pychrysalide import SourceEndian from pychrysalide.analysis import BinContent from pychrysalide.analysis.contents import FileContent, RestrictedContent from pychrysalide.arch import vmpa, mrange @@ -64,10 +65,10 @@ class TestRestrictedContent(ChrysalideTestCase): val = rcnt.read_u8(start) self.assertEqual(val, 0x16) - val = rcnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u16(start, SourceEndian.LITTLE) self.assertEqual(val, 0x1817) - val = rcnt.read_u32(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u32(start, SourceEndian.LITTLE) self.assertEqual(val, 0x24232221) @@ -111,15 +112,15 @@ class TestRestrictedContent(ChrysalideTestCase): self.assertEqual(val, 0x15) start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u16(start, SourceEndian.LITTLE) self.assertEqual(val, 0x1615) start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u32(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u32(start, SourceEndian.LITTLE) self.assertEqual(val, 0x18171615) start = vmpa(12, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u64(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u64(start, SourceEndian.LITTLE) self.assertEqual(val, 0x2423222118171615) start = vmpa(23, vmpa.VmpaSpecialValue.NO_VIRTUAL) @@ -127,15 +128,15 @@ class TestRestrictedContent(ChrysalideTestCase): self.assertEqual(val, 0x28) start = vmpa(22, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u16(start, SourceEndian.LITTLE) self.assertEqual(val, 0x2827) start = vmpa(20, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u32(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u32(start, SourceEndian.LITTLE) self.assertEqual(val, 0x28272625) start = vmpa(16, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u64(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u64(start, SourceEndian.LITTLE) self.assertEqual(val, 0x2827262524232221) @@ -202,12 +203,12 @@ class TestRestrictedContent(ChrysalideTestCase): with self.assertRaisesRegex(Exception, 'Invalid read access.'): start = vmpa(11, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u16(start, SourceEndian.LITTLE) with self.assertRaisesRegex(Exception, 'Invalid read access.'): start = vmpa(23, vmpa.VmpaSpecialValue.NO_VIRTUAL) - val = rcnt.read_u16(start, BinContent.SourceEndian.LITTLE) + val = rcnt.read_u16(start, SourceEndian.LITTLE) def testDescription(self): -- cgit v0.11.2-87-g4458