summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-11-25 07:18:21 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-11-25 07:18:21 (GMT)
commit472d566943f527e18eb95f31dbe70c50043396aa (patch)
treeafb1a2d32a4f40e3a356e3f81eab98a627e816a0 /plugins/pychrysalide
parent643ad3b7981e4da54c1748e72b525a1f477ea155 (diff)
Updated the Python bindings documentation for binary contents.
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r--plugins/pychrysalide/analysis/Makefile.am1
-rw-r--r--plugins/pychrysalide/analysis/constants.c72
-rw-r--r--plugins/pychrysalide/analysis/constants.h38
-rw-r--r--plugins/pychrysalide/analysis/content.c255
4 files changed, 254 insertions, 112 deletions
diff --git a/plugins/pychrysalide/analysis/Makefile.am b/plugins/pychrysalide/analysis/Makefile.am
index 65f2150..bb7bec6 100644
--- a/plugins/pychrysalide/analysis/Makefile.am
+++ b/plugins/pychrysalide/analysis/Makefile.am
@@ -5,6 +5,7 @@ libpychrysaanalysis_la_SOURCES = \
binary.h binary.c \
block.h block.c \
cattribs.h cattribs.c \
+ constants.h constants.c \
content.h content.c \
loaded.h loaded.c \
loading.h loading.c \
diff --git a/plugins/pychrysalide/analysis/constants.c b/plugins/pychrysalide/analysis/constants.c
new file mode 100644
index 0000000..de7e522
--- /dev/null
+++ b/plugins/pychrysalide/analysis/constants.c
@@ -0,0 +1,72 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes liées aux analyses
+ *
+ * Copyright (C) 2018 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 <common/endianness.h>
+
+
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives au contenus binaires. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_analysis_content_constants(PyTypeObject *type)
+{
+ 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(type, false, "SourceEndian", values,
+ "Endianness of handled data.");
+
+ exit:
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/constants.h b/plugins/pychrysalide/analysis/constants.h
new file mode 100644
index 0000000..c4da054
--- /dev/null
+++ b/plugins/pychrysalide/analysis/constants.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes liées aux analyses
+ *
+ * Copyright (C) 2019 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_ANALYSIS_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+/* Définit les constantes relatives aux contenus binaires. */
+bool define_analysis_content_constants(PyTypeObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/analysis/content.c b/plugins/pychrysalide/analysis/content.c
index 5f8694a..93292fb 100644
--- a/plugins/pychrysalide/analysis/content.c
+++ b/plugins/pychrysalide/analysis/content.c
@@ -37,12 +37,23 @@
#include "cattribs.h"
+#include "constants.h"
#include "../access.h"
#include "../helpers.h"
#include "../arch/vmpa.h"
+#define BINARY_CONTENT_DOC \
+ "The BinContent is an interface which handles access to a given" \
+ " binary content." \
+ "\n" \
+ "All of its implementations are located in the" \
+ " pychrysalide.analysis.contents module. The main implemantation" \
+ " is the pychrysalide.analysis.contents.FileContent class."
+
+
+
/* Fournit le nom associé au contenu binaire. */
static PyObject *py_binary_content_describe(PyObject *, PyObject *);
@@ -71,16 +82,16 @@ static PyObject *py_binary_content_get_attributes(PyObject *, void *);
static PyObject *py_binary_content_get_checksum(PyObject *, void *);
/* Détermine le nombre d'octets lisibles. */
-static PyObject *py_binary_content_compute_size(PyObject *, void *);
+static PyObject *py_binary_content_get_size(PyObject *, void *);
/* Détermine la position initiale d'un contenu. */
-static PyObject *py_binary_content_compute_start_pos(PyObject *, void *);
+static PyObject *py_binary_content_get_start_pos(PyObject *, void *);
/* Détermine la position finale d'un contenu. */
-static PyObject *py_binary_content_compute_end_pos(PyObject *, void *);
+static PyObject *py_binary_content_get_end_pos(PyObject *, void *);
/* Renvoie tout le contenu binaire d'un coup. */
-static PyObject *py_binary_content_get_all_bytes(PyObject *, void *);
+static PyObject *py_binary_content_get_data(PyObject *, void *);
@@ -100,17 +111,25 @@ static PyObject *py_binary_content_get_all_bytes(PyObject *, void *);
static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- GBinContent *content; /* Version GLib du format */
int full; /* Description complète ? */
int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Version GLib du format */
const char *desc; /* Description obtenue */
- content = G_BIN_CONTENT(pygobject_get(self));
- assert(content != NULL);
+#define BINARY_CONTENT_DESCRIBE_METHOD PYTHON_METHOD_DEF \
+( \
+ describe, "$self, /, full=False", \
+ METH_VARARGS, py_binary_content, \
+ "Get a (full ?) description of the binary content." \
+)
- ret = PyArg_ParseTuple(args, "p", &full);
+ full = 0;
+
+ ret = PyArg_ParseTuple(args, "|p", &full);
if (!ret) return NULL;
+ content = G_BIN_CONTENT(pygobject_get(self));
+
desc = g_binary_content_describe(content, full);
result = PyUnicode_FromString(desc);
@@ -136,23 +155,25 @@ static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
static PyObject *py_binary_content_read_raw(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- GBinContent *content; /* Version GLib du format */
- PyObject *addr_obj; /* Objet pour une position */
- vmpa2t *addr; /* Position interne associée */
+ 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 */
const bin_t *val; /* Valeur lue à faire suivre */
- content = G_BIN_CONTENT(pygobject_get(self));
- assert(content != NULL);
+#define BINARY_CONTENT_READ_RAW_METHOD PYTHON_METHOD_DEF \
+( \
+ read_raw, "$self, addr, length, /", \
+ METH_VARARGS, py_binary_content, \
+ "Read bytes from a given position." \
+)
- ret = PyArg_ParseTuple(args, "OK", &addr_obj, &length);
+ ret = PyArg_ParseTuple(args, "O&K", convert_any_to_vmpa, &addr, &length);
if (!ret) return NULL;
- addr = get_internal_vmpa(addr_obj);
- assert(addr != NULL);
+ content = G_BIN_CONTENT(pygobject_get(self));
- val = g_binary_content_get_raw_access(content, addr, length);
+ val = g_binary_content_get_raw_access(content, &addr, length);
if (val == NULL)
{
PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -182,23 +203,25 @@ static PyObject *py_binary_content_read_raw(PyObject *self, PyObject *args)
static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- GBinContent *content; /* Version GLib du format */
+ vmpa2t addr; /* Position interne associée */
int ret; /* Bilan de lecture des args. */
- PyObject *addr_obj; /* Objet pour une position */
- vmpa2t *addr; /* Position interne associée */
+ GBinContent *content; /* Version GLib du format */
uint8_t val; /* Valeur lue à faire suivre */
bool status; /* Bilan de l'opération */
- content = G_BIN_CONTENT(pygobject_get(self));
- assert(content != NULL);
+#define BINARY_CONTENT_READ_U8_METHOD PYTHON_METHOD_DEF \
+( \
+ read_u8, "$self, addr, /", \
+ METH_VARARGS, py_binary_content, \
+ "Read an unsigned byte from a given position." \
+)
- ret = PyArg_ParseTuple(args, "O", &addr_obj);
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
if (!ret) return NULL;
- addr = get_internal_vmpa(addr_obj);
- assert(addr != NULL);
+ content = G_BIN_CONTENT(pygobject_get(self));
- status = g_binary_content_read_u8(content, addr, &val);
+ status = g_binary_content_read_u8(content, &addr, &val);
if (!status)
{
PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -228,24 +251,29 @@ static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
static PyObject *py_binary_content_read_u16(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- GBinContent *content; /* Version GLib du format */
- int ret; /* Bilan de lecture des args. */
- PyObject *addr_obj; /* Objet pour une position */
+ vmpa2t addr; /* Position interne associée */
unsigned long endianness; /* Boutisme de la lecture */
- vmpa2t *addr; /* Position interne associée */
+ int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Version GLib du format */
uint16_t val; /* Valeur lue à faire suivre */
bool status; /* Bilan de l'opération */
- content = G_BIN_CONTENT(pygobject_get(self));
- assert(content != NULL);
+#define BINARY_CONTENT_READ_U16_METHOD PYTHON_METHOD_DEF \
+( \
+ read_u16, "$self, addr, endian, /", \
+ METH_VARARGS, py_binary_content, \
+ "Read two unsigned bytes from a given position." \
+ "\n" \
+ "The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values." \
+)
- ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+ ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
if (!ret) return NULL;
- addr = get_internal_vmpa(addr_obj);
- assert(addr != NULL);
+ content = G_BIN_CONTENT(pygobject_get(self));
- status = g_binary_content_read_u16(content, addr, endianness, &val);
+ status = g_binary_content_read_u16(content, &addr, endianness, &val);
if (!status)
{
PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -275,24 +303,29 @@ static PyObject *py_binary_content_read_u16(PyObject *self, PyObject *args)
static PyObject *py_binary_content_read_u32(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- GBinContent *content; /* Version GLib du format */
- int ret; /* Bilan de lecture des args. */
- PyObject *addr_obj; /* Objet pour une position */
+ vmpa2t addr; /* Position interne associée */
unsigned long endianness; /* Boutisme de la lecture */
- vmpa2t *addr; /* Position interne associée */
+ int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Version GLib du format */
uint32_t val; /* Valeur lue à faire suivre */
bool status; /* Bilan de l'opération */
- content = G_BIN_CONTENT(pygobject_get(self));
- assert(content != NULL);
+#define BINARY_CONTENT_READ_U32_METHOD PYTHON_METHOD_DEF \
+( \
+ read_u32, "$self, addr, endian, /", \
+ METH_VARARGS, py_binary_content, \
+ "Read four unsigned bytes from a given position." \
+ "\n" \
+ "The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values." \
+)
- ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+ ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
if (!ret) return NULL;
- addr = get_internal_vmpa(addr_obj);
- assert(addr != NULL);
+ content = G_BIN_CONTENT(pygobject_get(self));
- status = g_binary_content_read_u32(content, addr, endianness, &val);
+ status = g_binary_content_read_u32(content, &addr, endianness, &val);
if (!status)
{
PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -321,24 +354,29 @@ static PyObject *py_binary_content_read_u32(PyObject *self, PyObject *args)
static PyObject *py_binary_content_read_u64(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- GBinContent *content; /* Version GLib du format */
- int ret; /* Bilan de lecture des args. */
- PyObject *addr_obj; /* Objet pour une position */
+ vmpa2t addr; /* Position interne associée */
unsigned long endianness; /* Boutisme de la lecture */
- vmpa2t *addr; /* Position interne associée */
+ int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Version GLib du format */
uint64_t val; /* Valeur lue à faire suivre */
bool status; /* Bilan de l'opération */
- content = G_BIN_CONTENT(pygobject_get(self));
- assert(content != NULL);
+#define BINARY_CONTENT_READ_U64_METHOD PYTHON_METHOD_DEF \
+( \
+ read_u64, "$self, addr, endian, /", \
+ METH_VARARGS, py_binary_content, \
+ "Read eight unsigned bytes from a given position." \
+ "\n" \
+ "The endianness of the data can be provided using" \
+ " pychrysalide.analysis.BinContent.SourceEndian values." \
+)
- ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+ ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
if (!ret) return NULL;
- addr = get_internal_vmpa(addr_obj);
- assert(addr != NULL);
+ content = G_BIN_CONTENT(pygobject_get(self));
- status = g_binary_content_read_u64(content, addr, endianness, &val);
+ status = g_binary_content_read_u64(content, &addr, endianness, &val);
if (!status)
{
PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -445,6 +483,12 @@ static PyObject *py_binary_content_get_checksum(PyObject *self, void *closure)
GBinContent *content; /* Version GLib du format */
const gchar *checksum; /* Empreinte fournie */
+#define BINARY_CONTENT_CHECKSUM_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ checksum, py_binary_content, \
+ "Compute a SHA256 hash as chechsum of handled data." \
+)
+
content = G_BIN_CONTENT(pygobject_get(self));
checksum = g_binary_content_get_checksum(content);
@@ -469,12 +513,18 @@ static PyObject *py_binary_content_get_checksum(PyObject *self, void *closure)
* *
******************************************************************************/
-static PyObject *py_binary_content_compute_size(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_size(PyObject *self, void *closure)
{
PyObject *result; /* Instance à retourner */
GBinContent *content; /* Version GLib du format */
phys_t size; /* Quantité d'octets dispos. */
+#define BINARY_CONTENT_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ size, py_binary_content, \
+ "Compute the quantity of readable bytes." \
+)
+
content = G_BIN_CONTENT(pygobject_get(self));
size = g_binary_content_compute_size(content);
@@ -499,12 +549,18 @@ static PyObject *py_binary_content_compute_size(PyObject *self, void *closure)
* *
******************************************************************************/
-static PyObject *py_binary_content_compute_start_pos(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_start_pos(PyObject *self, void *closure)
{
PyObject *result; /* Instance à retourner */
GBinContent *content; /* Version GLib du format */
vmpa2t pos; /* Position à transmettre */
+#define BINARY_CONTENT_START_POS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ start_pos, py_binary_content, \
+ "Provide the starting position of the binary content." \
+)
+
content = G_BIN_CONTENT(pygobject_get(self));
g_binary_content_compute_start_pos(content, &pos);
@@ -529,12 +585,18 @@ static PyObject *py_binary_content_compute_start_pos(PyObject *self, void *closu
* *
******************************************************************************/
-static PyObject *py_binary_content_compute_end_pos(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_end_pos(PyObject *self, void *closure)
{
PyObject *result; /* Instance à retourner */
GBinContent *content; /* Version GLib du format */
vmpa2t pos; /* Position à transmettre */
+#define BINARY_CONTENT_END_POS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ end_pos, py_binary_content, \
+ "Provide the ending position of the binary content." \
+)
+
content = G_BIN_CONTENT(pygobject_get(self));
g_binary_content_compute_end_pos(content, &pos);
@@ -559,7 +621,7 @@ static PyObject *py_binary_content_compute_end_pos(PyObject *self, void *closure
* *
******************************************************************************/
-static PyObject *py_binary_content_get_all_bytes(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_data(PyObject *self, void *closure)
{
PyObject *result; /* Contenu à retourner */
GBinContent *content; /* Version GLib du format */
@@ -567,8 +629,13 @@ static PyObject *py_binary_content_get_all_bytes(PyObject *self, void *closure)
phys_t length; /* Nombre d'octets disponibles */
const bin_t *val; /* Valeur lue à faire suivre */
+#define BINARY_CONTENT_DATA_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ data, py_binary_content, \
+ "Provide all the content bytes at once." \
+)
+
content = G_BIN_CONTENT(pygobject_get(self));
- assert(content != NULL);
init_vmpa(&start, 0, VMPA_NO_VIRTUAL);
@@ -599,61 +666,22 @@ static PyObject *py_binary_content_get_all_bytes(PyObject *self, void *closure)
PyTypeObject *get_python_binary_content_type(void)
{
static PyMethodDef py_binary_content_methods[] = {
- {
- "describe", py_binary_content_describe,
- METH_VARARGS,
- "describe($self, full, /)\n--\n\nGet a (full ?) description of the binary content."
- },
- {
- "read_raw", py_binary_content_read_raw,
- METH_VARARGS,
- "read_raw($self, addr, length, /)\n--\n\nRead bytes from a given position."
- },
- {
- "read_u8", py_binary_content_read_u8,
- METH_VARARGS,
- "read_u8($self, addr, /)\n--\n\nRead an unsigned byte from a given position."
- },
- {
- "read_u16", py_binary_content_read_u16,
- METH_VARARGS,
- "read_u16($self, addr, endianness, /)\n--\n\nRead two unsigned bytes from a given position."
- },
- {
- "read_u32", py_binary_content_read_u32,
- METH_VARARGS,
- "read_u32($self, addr, endianness, /)\n--\n\nRead four unsigned bytes from a given position."
- },
- {
- "read_u64", py_binary_content_read_u64,
- METH_VARARGS,
- "read_u64($self, addr, endianness, /)\n--\n\nRead eight unsigned bytes from a given position."
- },
+ BINARY_CONTENT_DESCRIBE_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,
{ NULL }
};
static PyGetSetDef py_binary_content_getseters[] = {
BINARY_CONTENT_ATTRIBUTES_ATTRIB,
- {
- "checksum", py_binary_content_get_checksum, NULL,
- "Compute a SHA256 hash as chechsum of handled data.", NULL
- },
- {
- "size", py_binary_content_compute_size, NULL,
- "Compute the quantity of readable bytes.", NULL
- },
- {
- "start_pos", py_binary_content_compute_start_pos, NULL,
- "Provide the starting position of the binary content.", NULL
- },
- {
- "end_pos", py_binary_content_compute_end_pos, NULL,
- "Provide the ending position of the binary content.", NULL
- },
- {
- "data", py_binary_content_get_all_bytes, NULL,
- "Provide all the content bytes at once.", NULL
- },
+ BINARY_CONTENT_CHECKSUM_ATTRIB,
+ BINARY_CONTENT_SIZE_ATTRIB,
+ BINARY_CONTENT_START_POS_ATTRIB,
+ BINARY_CONTENT_END_POS_ATTRIB,
+ BINARY_CONTENT_DATA_ATTRIB,
{ NULL }
};
@@ -666,7 +694,7 @@ PyTypeObject *get_python_binary_content_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide binary content",
+ .tp_doc = BINARY_CONTENT_DOC,
.tp_methods = py_binary_content_methods,
.tp_getset = py_binary_content_getseters
@@ -707,6 +735,9 @@ bool ensure_python_binary_content_is_registered(void)
if (!register_interface_for_pygobject(dict, G_TYPE_BIN_CONTENT, type))
return false;
+ if (!define_analysis_content_constants(type))
+ return false;
+
}
return true;