From 3a2dcf9f1e6718b0a45feed8eefadb71be66f4ac Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 16 Oct 2015 19:20:29 +0000
Subject: Extended the Python bindings in order to load and read contents.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@597 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                                 |   8 ++
 plugins/pychrysa/analysis/binary.c        |   5 +-
 plugins/pychrysa/analysis/content.c       | 220 +++++++++++++++++++++++-------
 plugins/pychrysa/analysis/contents/file.c |   3 +-
 plugins/pychrysa/arch/vmpa.c              |  10 ++
 5 files changed, 192 insertions(+), 54 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f5894ff..e2b786f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+15-10-16  Cyrille Bagard <nocbos@gmail.com>
+
+	* plugins/pychrysa/analysis/binary.c:
+	* plugins/pychrysa/analysis/content.c:
+	* plugins/pychrysa/analysis/contents/file.c:
+	* plugins/pychrysa/arch/vmpa.c:
+	Extend the Python bindings in order to load and read contents.
+
 15-10-15  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/area.c:
diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c
index 31fbfc2..9e45e27 100644
--- a/plugins/pychrysa/analysis/binary.c
+++ b/plugins/pychrysa/analysis/binary.c
@@ -31,6 +31,7 @@
 #include <analysis/binary.h>
 
 
+#include "content.h"
 #include "../helpers.h"
 
 
@@ -292,7 +293,7 @@ PyTypeObject *get_python_loaded_binary_type(void)
 
         .tp_name        = "pychrysalide.analysis.LoadedBinary",
 
-        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 
         .tp_doc         = "PyChrysalide loaded binary",
 
@@ -330,7 +331,7 @@ bool register_python_loaded_binary(PyObject *module)
     py_loaded_binary_type->tp_base = &PyGObject_Type;
     py_loaded_binary_type->tp_basicsize = py_loaded_binary_type->tp_base->tp_basicsize;
 
-    APPLY_ABSTRACT_FLAG(py_loaded_binary_type);
+    //APPLY_ABSTRACT_FLAG(py_loaded_binary_type);
 
     if (PyType_Ready(py_loaded_binary_type) != 0)
         return false;
diff --git a/plugins/pychrysa/analysis/content.c b/plugins/pychrysa/analysis/content.c
index a37aa44..bd25589 100644
--- a/plugins/pychrysa/analysis/content.c
+++ b/plugins/pychrysa/analysis/content.c
@@ -25,10 +25,15 @@
 #include "content.h"
 
 
+#include <assert.h>
 #include <pygobject.h>
 
 
 #include <analysis/content.h>
+#include <common/endianness.h>
+
+
+#include "../arch/vmpa.h"
 
 
 
@@ -41,6 +46,16 @@ static PyObject *py_binary_content_compute_size(PyObject *, PyObject *);
 /* Lit un nombre non signé sur un octet. */
 static PyObject *py_binary_content_read_u8(PyObject *, PyObject *);
 
+/* Lit un nombre non signé sur deux octets. */
+static PyObject *py_binary_content_read_u16(PyObject *, PyObject *);
+
+/* Lit un nombre non signé sur quatre octets. */
+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 *);
+
+
 
 
 /******************************************************************************
@@ -130,99 +145,202 @@ static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
     bool status;                            /* Bilan de l'opération        */
 
     content = G_BIN_CONTENT(pygobject_get(self));
-
-    //printf("Passage\n");
+    assert(content != NULL);
 
     ret = PyArg_ParseTuple(args, "O", &addr_obj);
-
-    //printf("ret == %d\n", ret);
-
     if (!ret) return NULL;
 
     addr = get_internal_vmpa(addr_obj);
-    if (addr == NULL) /* ... */;
+    assert(addr != NULL);
 
     status = g_binary_content_read_u8(content, addr, &val);
     if (!status) return NULL;
 
-    //printf("val :: 0x%02hhx\n", val);
+    result = PyBytes_FromStringAndSize((char *)&val, 1);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = non utilisé ici.                                      *
+*                                                                             *
+*  Description : Lit un nombre non signé sur deux octets.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+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     */
+    unsigned long endianness;               /* Boutisme de la lecture      */
+    vmpa2t *addr;                           /* Position interne associée   */
+    uint16_t val;                           /* Valeur lue à faire suivre   */
+    bool status;                            /* Bilan de l'opération        */
+
+    content = G_BIN_CONTENT(pygobject_get(self));
+    assert(content != NULL);
+
+    ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+    if (!ret) return NULL;
+
+    addr = get_internal_vmpa(addr_obj);
+    assert(addr != NULL);
+
+    status = g_binary_content_read_u16(content, addr, endianness, &val);
+    if (!status) return NULL;
 
-    result = PyBytes_FromStringAndSize((char *)&val, 1);;
-    //Py_INCREF(result);
+    result = PyBytes_FromStringAndSize((char *)&val, 2);
 
     return result;
 
 }
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = non utilisé ici.                                      *
+*                                                                             *
+*  Description : Lit un nombre non signé sur quatre octets.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
+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     */
+    unsigned long endianness;               /* Boutisme de la lecture      */
+    vmpa2t *addr;                           /* Position interne associée   */
+    uint32_t val;                           /* Valeur lue à faire suivre   */
+    bool status;                            /* Bilan de l'opération        */
+
+    content = G_BIN_CONTENT(pygobject_get(self));
+    assert(content != NULL);
+
+    ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+    if (!ret) return NULL;
+
+    addr = get_internal_vmpa(addr_obj);
+    assert(addr != NULL);
+
+    status = g_binary_content_read_u32(content, addr, endianness, &val);
+    if (!status) return NULL;
+
+    result = PyBytes_FromStringAndSize((char *)&val, 4);
+
+    return result;
 
+}
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : -                                                            *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = non utilisé ici.                                      *
 *                                                                             *
-*  Description : Fournit un accès à une définition de type à diffuser.        *
+*  Description : Lit un nombre non signé sur huit octets.                     *
 *                                                                             *
-*  Retour      : Définition d'objet pour Python.                              *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
+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     */
+    unsigned long endianness;               /* Boutisme de la lecture      */
+    vmpa2t *addr;                           /* Position interne associée   */
+    uint64_t val;                           /* Valeur lue à faire suivre   */
+    bool status;                            /* Bilan de l'opération        */
+
+    content = G_BIN_CONTENT(pygobject_get(self));
+    assert(content != NULL);
+
+    ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+    if (!ret) return NULL;
+
+    addr = get_internal_vmpa(addr_obj);
+    assert(addr != NULL);
 
-static PyMethodDef py_binary_content_methods[] = {
-    { "get_checksum", py_binary_content_get_checksum,
-      METH_NOARGS,
-      "get_checksum($self, /)\n--\n\nCompute a SHA256 hash as chechsum of handled data."
-    },
-    { "compute_size", py_binary_content_compute_size,
-      METH_NOARGS,
-      "compute_size($self, /)\n--\n\nCompute the quantity of readable bytes."
-    },
-    { "read_u8", py_binary_content_read_u8,
-      METH_VARARGS,
-      "read_u8($self, addr, /)\n--\n\nRead an unsigned byte from a given position."
-    },
-    { NULL }
-};
+    status = g_binary_content_read_u64(content, addr, endianness, &val);
+    if (!status) return NULL;
+
+    result = PyBytes_FromStringAndSize((char *)&val, 8);
 
-static PyGetSetDef py_binary_content_getseters[] = {
-    { NULL }
-};
+    return result;
 
-PyTypeObject py_binary_content_type = {
+}
 
-    PyVarObject_HEAD_INIT(NULL, 0)
 
-    .tp_name        = "pychrysalide.analysis.contents.BinContent",
-    .tp_basicsize   = sizeof(PyObject),
 
-    .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 
-    .tp_doc         = "PyChrysalide binary content",
 
-    .tp_methods     = py_binary_content_methods,
-    //.tp_getset      = py_binary_content_getseters
 
-};
 
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
 PyTypeObject *get_python_binary_content_type(void)
 {
-#if 0
     static PyMethodDef py_binary_content_methods[] = {
-        { "get_checksum", py_binary_content_get_checksum,
-          METH_NOARGS,
-          "get_checksum($self, /)\n--\n\nCompute a SHA256 hash as chechsum of handled data."
+        {
+            "get_checksum", py_binary_content_get_checksum,
+            METH_NOARGS,
+            "get_checksum($self, /)\n--\n\nCompute a SHA256 hash as chechsum of handled data."
+        },
+        {
+            "compute_size", py_binary_content_compute_size,
+            METH_NOARGS,
+            "compute_size($self, /)\n--\n\nCompute the quantity of readable bytes."
         },
-        { "compute_size", py_binary_content_compute_size,
-          METH_NOARGS,
-          "compute_size($self, /)\n--\n\nCompute the quantity of readable bytes."
+        {
+            "read_u8", py_binary_content_read_u8,
+            METH_VARARGS,
+            "read_u8($self, addr, /)\n--\n\nRead an unsigned byte 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."
         },
         { NULL }
     };
@@ -243,10 +361,10 @@ PyTypeObject *get_python_binary_content_type(void)
         .tp_doc         = "PyChrysalide binary content",
 
         .tp_methods     = py_binary_content_methods,
-        //.tp_getset      = py_binary_content_getseters
+        .tp_getset      = py_binary_content_getseters
 
     };
-#endif
+
     return &py_binary_content_type;
 
 }
diff --git a/plugins/pychrysa/analysis/contents/file.c b/plugins/pychrysa/analysis/contents/file.c
index b145662..d356197 100644
--- a/plugins/pychrysa/analysis/contents/file.c
+++ b/plugins/pychrysa/analysis/contents/file.c
@@ -109,6 +109,7 @@ PyTypeObject py_file_content_type = {
       .tp_getset      = py_file_content_getseters,
       .tp_new         = (newfunc)py_file_content_new
     */
+    .tp_new         = (newfunc)py_file_content_new
 
 };
 
@@ -160,7 +161,7 @@ PyTypeObject *get_python_file_content_type(void)
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-#include "../content.h"
+#include "../content.h"//////////////////////////////////////////
 bool register_python_file_content(PyObject *module)
 {
     PyTypeObject *py_file_content_type;   /* Type Python 'BinContent'    */
diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c
index 350f61b..65e0387 100644
--- a/plugins/pychrysa/arch/vmpa.c
+++ b/plugins/pychrysa/arch/vmpa.c
@@ -34,6 +34,11 @@
 
 
 
+#include <common/endianness.h>  /* TODO : à bouger vers base ? */
+
+
+
+
 /* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */
 
 
@@ -526,6 +531,11 @@ static bool py_vmpa_define_constants(PyTypeObject *obj_type)
     result &= PyDict_AddIntMacro(obj_type, VMPA_NO_PHYSICAL);
     result &= PyDict_AddIntMacro(obj_type, VMPA_NO_VIRTUAL);
 
+    /* TODO : à bouger vers base ? */
+    result &= PyDict_AddIntMacro(obj_type, SRE_LITTLE);
+    result &= PyDict_AddIntMacro(obj_type, SRE_MIDDLE);
+    result &= PyDict_AddIntMacro(obj_type, SRE_BIG);
+
     return result;
 
 }
-- 
cgit v0.11.2-87-g4458