From 3a2dcf9f1e6718b0a45feed8eefadb71be66f4ac Mon Sep 17 00:00:00 2001 From: Cyrille Bagard 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 + + * 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 * 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 +#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 #include #include +#include + + +#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 /* 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