From 18648e4e8763a3bc005d6fae51eae3d1528d7d29 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 11 Sep 2015 20:40:24 +0000 Subject: Created an interface from the original GBinContent object. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@576 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 107 ++++ configure.ac | 2 + plugins/mobicore/mclf-int.c | 2 +- plugins/mobicore/mclf.c | 2 +- plugins/pychrysa/analysis/Makefile.am | 4 +- plugins/pychrysa/analysis/content.c | 297 ++++++++++ plugins/pychrysa/analysis/content.h | 42 ++ plugins/pychrysa/analysis/contents/Makefile.am | 14 + plugins/pychrysa/analysis/contents/file.c | 199 +++++++ plugins/pychrysa/analysis/contents/file.h | 42 ++ plugins/pychrysa/analysis/contents/module.c | 92 +++ plugins/pychrysa/analysis/contents/module.h | 39 ++ plugins/pychrysa/analysis/module.c | 4 + plugins/pychrysa/core/formats.c | 190 ++++++ plugins/pychrysa/core/formats.h | 42 ++ plugins/pychrysa/format/dex/dex.c | 2 +- plugins/pychrysa/format/elf/elf.c | 2 +- plugins/pychrysa/glibext/Makefile.am | 1 - plugins/pychrysa/glibext/bincontent.c | 303 ---------- plugins/pychrysa/glibext/bincontent.h | 42 -- plugins/pychrysa/glibext/module.c | 2 - plugins/ropgadgets/select.c | 3 +- src/analysis/Makefile.am | 5 +- src/analysis/binaries/file.c | 4 +- src/analysis/content-int.h | 86 +++ src/analysis/content.c | 282 +++++++++ src/analysis/content.h | 91 +++ src/analysis/contents/Makefile.am | 16 + src/analysis/contents/file.c | 603 +++++++++++++++++++ src/analysis/contents/file.h | 58 ++ src/arch/arm/v7/processor.c | 31 +- src/arch/dalvik/operand.c | 4 +- src/arch/dalvik/operands/pool.c | 2 +- src/arch/dalvik/operands/register.c | 4 +- src/arch/dalvik/operands/target.c | 2 +- src/arch/immediate.c | 12 +- src/arch/immediate.h | 3 +- src/arch/instruction.h | 2 +- src/arch/processor-int.h | 2 +- src/arch/processor.c | 7 +- src/common/endianness.c | 6 +- src/common/endianness.h | 8 +- src/debug/jdwp/misc/header.c | 6 +- src/debug/jdwp/misc/id.c | 2 +- src/debug/jdwp/misc/location.c | 2 +- src/format/dex/dex-int.c | 4 +- src/format/dex/dex.c | 2 +- src/format/elf/elf-int.c | 2 +- src/format/elf/elf.c | 2 +- src/format/elf/strings.c | 2 +- src/format/format.h | 2 +- src/format/java/java.c | 2 +- src/format/pe/pe-int.c | 8 +- src/glibext/Makefile.am | 1 - src/glibext/gbincontent.c | 782 ------------------------- src/glibext/gbincontent.h | 103 ---- src/glibext/gbufferline.h | 2 +- src/gui/panels/strings.c | 2 +- src/plugins/plugin-int.h | 2 +- 59 files changed, 2275 insertions(+), 1312 deletions(-) create mode 100644 plugins/pychrysa/analysis/content.c create mode 100644 plugins/pychrysa/analysis/content.h create mode 100644 plugins/pychrysa/analysis/contents/Makefile.am create mode 100644 plugins/pychrysa/analysis/contents/file.c create mode 100644 plugins/pychrysa/analysis/contents/file.h create mode 100644 plugins/pychrysa/analysis/contents/module.c create mode 100644 plugins/pychrysa/analysis/contents/module.h create mode 100644 plugins/pychrysa/core/formats.c create mode 100644 plugins/pychrysa/core/formats.h delete mode 100644 plugins/pychrysa/glibext/bincontent.c delete mode 100644 plugins/pychrysa/glibext/bincontent.h create mode 100644 src/analysis/content-int.h create mode 100644 src/analysis/content.c create mode 100644 src/analysis/content.h create mode 100755 src/analysis/contents/Makefile.am create mode 100644 src/analysis/contents/file.c create mode 100644 src/analysis/contents/file.h delete mode 100644 src/glibext/gbincontent.c delete mode 100644 src/glibext/gbincontent.h diff --git a/ChangeLog b/ChangeLog index 62d4587..166ef5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,110 @@ +15-09-11 Cyrille Bagard + + * configure.ac: + Add the new Makefiles from the 'plugins/pychrysa/analysis/contents' + and 'src/analysis/contents' directories. + + * plugins/mobicore/mclf.c: + * plugins/mobicore/mclf-int.c: + Update code. + + * plugins/pychrysa/analysis/content.c: + * plugins/pychrysa/analysis/content.h: + Moved entries. Create an interface from the original BinContent object. + + * plugins/pychrysa/analysis/contents/file.c: + * plugins/pychrysa/analysis/contents/file.h: + * plugins/pychrysa/analysis/contents/Makefile.am: + * plugins/pychrysa/analysis/contents/module.c: + * plugins/pychrysa/analysis/contents/module.h: + New entries: load a file content with Python. + + * plugins/pychrysa/analysis/Makefile.am: + Add the 'content.[ch]' files to libpychrysaanalysis_la_SOURCES and + 'contents/libpychrysaanalysiscontents.la' to libpychrysaanalysis_la_LIBADD. + + * plugins/pychrysa/analysis/module.c: + Update code. + + * plugins/pychrysa/core/formats.c: + * plugins/pychrysa/core/formats.h: + New entries: provide some definitions for information. + + * plugins/pychrysa/format/dex/dex.c: + * plugins/pychrysa/format/elf/elf.c: + Update code. + + * plugins/pychrysa/glibext/bincontent.c: + * plugins/pychrysa/glibext/bincontent.h: + Moved entries. + + * plugins/pychrysa/glibext/Makefile.am: + Remove the 'bincontent.[ch]' files from libpychrysaglibext_la_SOURCES. + + * plugins/pychrysa/glibext/module.c: + * plugins/ropgadgets/select.c: + * src/analysis/binaries/file.c: + Update code. + + * src/analysis/content.c: + * src/analysis/content.h: + * src/analysis/content-int.h: + New entries: create an interface from the original GBinContent object. + + * src/analysis/contents/file.c: + * src/analysis/contents/file.h: + Moved entries: define file contents from the original GBinContent object. + + * src/analysis/contents/Makefile.am: + New entry: handle content definitions. + + * src/analysis/Makefile.am: + Add the 'content*[ch]' files to libanalysis_la_SOURCES and + 'contents/libanalysiscontents.la' to libanalysis_la_LIBADD. + + * src/arch/arm/v7/processor.c: + * src/arch/dalvik/operand.c: + * src/arch/dalvik/operands/pool.c: + * src/arch/dalvik/operands/register.c: + * src/arch/dalvik/operands/target.c: + * src/arch/immediate.c: + * src/arch/immediate.h: + * src/arch/instruction.h: + * src/arch/processor.c: + * src/arch/processor-int.h: + Update code. + + * src/common/endianness.c: + * src/common/endianness.h: + Clean the prototypes for reading 4 or 8 bits: no need for endianness here! + + * src/debug/jdwp/misc/header.c: + * src/debug/jdwp/misc/id.c: + * src/debug/jdwp/misc/location.c: + * src/format/dex/dex.c: + * src/format/dex/dex-int.c: + * src/format/elf/elf.c: + * src/format/elf/elf-int.c: + * src/format/elf/strings.c: + * src/format/format.h: + * src/format/java/java.c: + * src/format/pe/pe-int.c: + Update code. + + * src/glibext/gbincontent.c: + * src/glibext/gbincontent.h: + Moved entries. + + * src/glibext/gbufferline.h: + Update code. + + * src/glibext/Makefile.am: + Remove the 'gbincontent.[ch]' files from libglibext_la_SOURCES. + + * src/gui/panels/strings.c: + * src/plugins/plugin-int.h: + Update code. + 15-09-02 Cyrille Bagard * src/gtkext/easygtk.c: diff --git a/configure.ac b/configure.ac index d447047..77b76a7 100644 --- a/configure.ac +++ b/configure.ac @@ -269,6 +269,7 @@ AC_CONFIG_FILES([Makefile plugins/pychrysa/analysis/Makefile plugins/pychrysa/analysis/binaries/Makefile plugins/pychrysa/analysis/blocks/Makefile + plugins/pychrysa/analysis/contents/Makefile plugins/pychrysa/analysis/db/Makefile plugins/pychrysa/analysis/db/items/Makefile plugins/pychrysa/arch/Makefile @@ -297,6 +298,7 @@ AC_CONFIG_FILES([Makefile src/analysis/Makefile src/analysis/binaries/Makefile src/analysis/blocks/Makefile + src/analysis/contents/Makefile src/analysis/db/Makefile src/analysis/db/items/Makefile src/analysis/db/misc/Makefile diff --git a/plugins/mobicore/mclf-int.c b/plugins/mobicore/mclf-int.c index cb4dbb3..a4dd3b7 100644 --- a/plugins/mobicore/mclf-int.c +++ b/plugins/mobicore/mclf-int.c @@ -62,7 +62,7 @@ bool read_mclf_header(GMCLFFormat *format, mclf_header_t *header, SourceEndian e printf("Mem type : 0x%08x\n", header->v1.mem_type); result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.num_instances); - result &= g_binary_content_get_raw(content, &pos, 16, (bin_t *)&header->v1.uuid); + result &= g_binary_content_read_raw(content, &pos, 16, (bin_t *)&header->v1.uuid); result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.driver_id); result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.num_threads); diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c index 829a488..99ff7ed 100644 --- a/plugins/mobicore/mclf.c +++ b/plugins/mobicore/mclf.c @@ -74,7 +74,7 @@ const char *mclf_is_matching(GBinContent *content, GExeFormat *parent) init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - status = g_binary_content_get_raw(content, &addr, 4, (bin_t *)magic); + status = g_binary_content_read_raw(content, &addr, 4, (bin_t *)magic); status &= (memcmp(magic, MC_SERVICE_HEADER_MAGIC_STR, 4) == 0); diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am index 8b0609d..c014dfd 100644 --- a/plugins/pychrysa/analysis/Makefile.am +++ b/plugins/pychrysa/analysis/Makefile.am @@ -4,12 +4,14 @@ noinst_LTLIBRARIES = libpychrysaanalysis.la libpychrysaanalysis_la_SOURCES = \ binary.h binary.c \ block.h block.c \ + content.h content.c \ module.h module.c \ routine.h routine.c libpychrysaanalysis_la_LIBADD = \ binaries/libpychrysaanalysisbinaries.la \ blocks/libpychrysaanalysisblocks.la \ + contents/libpychrysaanalysiscontents.la \ db/libpychrysaanalysisdb.la libpychrysaanalysis_la_LDFLAGS = @@ -20,4 +22,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = binaries blocks db +SUBDIRS = binaries blocks contents db diff --git a/plugins/pychrysa/analysis/content.c b/plugins/pychrysa/analysis/content.c new file mode 100644 index 0000000..a37aa44 --- /dev/null +++ b/plugins/pychrysa/analysis/content.c @@ -0,0 +1,297 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content.c - prototypes pour l'équivalent Python du fichier "analysis/content.c" + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 "content.h" + + +#include + + +#include + + + +/* Fournit une empreinte unique (SHA256) pour les données. */ +static PyObject *py_binary_content_get_checksum(PyObject *, PyObject *); + +/* Détermine le nombre d'octets lisibles. */ +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 *); + + + +/****************************************************************************** +* * +* Paramètres : self = contenu binaire à manipuler. * +* args = non utilisé ici. * +* * +* Description : Fournit une empreinte unique (SHA256) pour les données. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_content_get_checksum(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GBinContent *content; /* Version GLib du format */ + const gchar *checksum; /* Empreinte fournie */ + + content = G_BIN_CONTENT(pygobject_get(self)); + + //checksum = g_binary_content_get_cheksum(content); + + printf("YEAH\n"); + fflush(NULL); + + result = PyUnicode_FromString("checksum"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = contenu binaire à manipuler. * +* args = non utilisé ici. * +* * +* Description : Détermine le nombre d'octets lisibles. * +* * +* Retour : Quantité représentée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_content_compute_size(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GBinContent *content; /* Version GLib du format */ + phys_t size; /* Quantité d'octets dispos. */ + + content = G_BIN_CONTENT(pygobject_get(self)); + + size = g_binary_content_compute_size(content); + + result = PyLong_FromUnsignedLongLong(size); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = contenu binaire à manipuler. * +* args = non utilisé ici. * +* * +* Description : Lit un nombre non signé sur un octet. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_content_read_u8(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 */ + uint8_t val; /* Valeur lue à faire suivre */ + bool status; /* Bilan de l'opération */ + + content = G_BIN_CONTENT(pygobject_get(self)); + + //printf("Passage\n"); + + 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) /* ... */; + + 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);; + //Py_INCREF(result); + + return result; + +} + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + + +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 } +}; + +static PyGetSetDef py_binary_content_getseters[] = { + { NULL } +}; + +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 + +}; + + + +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." + }, + { "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 } + }; + + static PyGetSetDef py_binary_content_getseters[] = { + { NULL } + }; + + static 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 + + }; +#endif + return &py_binary_content_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.glibext.BinContent'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_binary_content(PyObject *module) +{ + PyTypeObject *py_binary_content_type; /* Type Python 'BinContent' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_binary_content_type = get_python_binary_content_type(); + + //py_binary_content_type->tp_base = &PyGObject_Type; + //py_binary_content_type->tp_basicsize = py_binary_content_type->tp_base->tp_basicsize; + + //py_binary_content_type->tp_base = &PyObject_Type; + //py_binary_content_type->tp_basicsize = py_binary_content_type->tp_base->tp_basicsize; + + /* + if (PyType_Ready(py_binary_content_type) != 0) + return false; + */ + + /* + Py_INCREF(py_binary_content_type); + ret = PyModule_AddObject(module, "BinContent", (PyObject *)py_binary_content_type); + if (ret != 0) return false; + */ + + dict = PyModule_GetDict(module); + pyg_register_interface(dict, "BinContent", G_TYPE_BIN_CONTENT, py_binary_content_type); + + return true; + +} diff --git a/plugins/pychrysa/analysis/content.h b/plugins/pychrysa/analysis/content.h new file mode 100644 index 0000000..230bfe1 --- /dev/null +++ b/plugins/pychrysa/analysis/content.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content.h - prototypes pour l'équivalent Python du fichier "analysis/content.h" + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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_PYCHRYSA_ANALYSIS_CONTENT_H +#define _PLUGINS_PYCHRYSA_ANALYSIS_CONTENT_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_binary_content_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.BinContent'. */ +bool register_python_binary_content(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSA_ANALYSIS_CONTENT_H */ diff --git a/plugins/pychrysa/analysis/contents/Makefile.am b/plugins/pychrysa/analysis/contents/Makefile.am new file mode 100644 index 0000000..ff835e3 --- /dev/null +++ b/plugins/pychrysa/analysis/contents/Makefile.am @@ -0,0 +1,14 @@ + +noinst_LTLIBRARIES = libpychrysaanalysiscontents.la + +libpychrysaanalysiscontents_la_SOURCES = \ + file.h file.c \ + module.h module.c + +libpychrysaanalysiscontents_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I../../../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/pychrysa/analysis/contents/file.c b/plugins/pychrysa/analysis/contents/file.c new file mode 100644 index 0000000..b145662 --- /dev/null +++ b/plugins/pychrysa/analysis/contents/file.c @@ -0,0 +1,199 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * file.c - prototypes pour l'équivalent Python du fichier "analysis/contents/file.c" + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 "file.h" + + +#include + + +#include + + + +/* Crée un nouvel objet Python de type 'BinContent'. */ +static PyObject *py_file_content_new(PyTypeObject *, PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'BinContent'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_file_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + const char *filename; /* Nom du fichier à charger */ + int ret; /* Bilan de lecture des args. */ + GBinContent *content; /* Version GLib du contenu */ + + ret = PyArg_ParseTuple(args, "s", &filename); + if (!ret) Py_RETURN_NONE; + + content = g_file_content_new(filename); + + result = pygobject_new(G_OBJECT(content)); + g_object_unref(content); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + + + +PyMethodDef py_file_content_methods[] = { + { NULL } +}; + +PyGetSetDef py_file_content_getseters[] = { + { NULL } +}; + +PyTypeObject py_file_content_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.contents.FileContent", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide binary file content", + + /* + .tp_methods = py_file_content_methods, + .tp_getset = py_file_content_getseters, + .tp_new = (newfunc)py_file_content_new + */ + +}; + + + +PyTypeObject *get_python_file_content_type(void) +{ +#if 0 + static PyMethodDef py_file_content_methods[] = { + { NULL } + }; + + static PyGetSetDef py_file_content_getseters[] = { + { NULL } + }; + + static PyTypeObject py_file_content_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.contents.FileContent", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 1 << 9, + + .tp_doc = "PyChrysalide binary file content", + + /* + .tp_methods = py_file_content_methods, + .tp_getset = py_file_content_getseters, + .tp_new = (newfunc)py_file_content_new + */ + + }; +#endif + return &py_file_content_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.glibext.BinContent'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +#include "../content.h" +bool register_python_file_content(PyObject *module) +{ + PyTypeObject *py_file_content_type; /* Type Python 'BinContent' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_file_content_type = get_python_file_content_type(); + + //py_file_content_type->tp_base = &PyGObject_Type; + //py_file_content_type->tp_basicsize = py_file_content_type->tp_base->tp_basicsize; + + /* + if (PyType_Ready(py_file_content_type) != 0) + return false; + */ + + /* + Py_INCREF(py_file_content_type); + ret = PyModule_AddObject(module, "FileContent", (PyObject *)py_file_content_type); + if (ret != 0) return false; + */ + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "FileContent", G_TYPE_FILE_CONTENT, py_file_content_type, + Py_BuildValue("(O)", &PyGObject_Type/*py_file_content_type->tp_base*/, + get_python_binary_content_type())); + + /* + if (PyType_Ready(py_file_content_type) != 0) + return false; + */ + + + return true; + +} diff --git a/plugins/pychrysa/analysis/contents/file.h b/plugins/pychrysa/analysis/contents/file.h new file mode 100644 index 0000000..a9edcef --- /dev/null +++ b/plugins/pychrysa/analysis/contents/file.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * file.h - prototypes pour l'équivalent Python du fichier "analysis/contents/file.h" + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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_PYCHRYSA_ANALYSIS_CONTENTS_FILE_H +#define _PLUGINS_PYCHRYSA_ANALYSIS_CONTENTS_FILE_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_file_content_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.BinContent'. */ +bool register_python_file_content(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSA_ANALYSIS_CONTENTS_FILE_H */ diff --git a/plugins/pychrysa/analysis/contents/module.c b/plugins/pychrysa/analysis/contents/module.c new file mode 100644 index 0000000..f97ba27 --- /dev/null +++ b/plugins/pychrysa/analysis/contents/module.c @@ -0,0 +1,92 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire contents en tant que module + * + * Copyright (C) 2013 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 "module.h" + + +#include + + +#include "file.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'contents' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#include "../content.h" +bool add_analysis_contents_module_to_python_module(PyObject *super) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Sous-module mis en place */ + int ret; /* Bilan d'un appel */ + + static PyModuleDef py_chrysalide_contents_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.analysis.contents", + .m_doc = "Python module for Chrysalide.analysis.contents", + + .m_size = -1, + + }; + + result = false; + + module = PyModule_Create(&py_chrysalide_contents_module); + if (module == NULL) return false; + + ret = PyState_AddModule(super, &py_chrysalide_contents_module); + if (ret != 0) goto loading_failed; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.contents"); + if (ret != 0) goto loading_failed; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "contents", module); + if (ret != 0) goto loading_failed; + + result = true; + + result &= register_python_binary_content(module); + + + result &= register_python_file_content(module); + + loading_failed: + + assert(result); + + return result; + +} diff --git a/plugins/pychrysa/analysis/contents/module.h b/plugins/pychrysa/analysis/contents/module.h new file mode 100644 index 0000000..35ff722 --- /dev/null +++ b/plugins/pychrysa/analysis/contents/module.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire contents en tant que module + * + * Copyright (C) 2013 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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_PYOIDA_ANALYSIS_CONTENTS_MODULE_H +#define _PLUGINS_PYOIDA_ANALYSIS_CONTENTS_MODULE_H + + +#include +#include + + + +/* Ajoute le module 'contents' au module Python. */ +bool add_analysis_contents_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYOIDA_ANALYSIS_CONTENTS_MODULE_H */ diff --git a/plugins/pychrysa/analysis/module.c b/plugins/pychrysa/analysis/module.c index d45a3f1..2520d42 100644 --- a/plugins/pychrysa/analysis/module.c +++ b/plugins/pychrysa/analysis/module.c @@ -30,9 +30,11 @@ #include "binary.h" #include "block.h" +#include "content.h" #include "routine.h" #include "binaries/module.h" #include "blocks/module.h" +#include "contents/module.h" #include "db/module.h" @@ -85,10 +87,12 @@ bool add_analysis_module_to_python_module(PyObject *super) result &= register_python_loaded_binary(module); result &= register_python_instr_block(module); + //result &= register_python_binary_content(module); result &= register_python_binary_routine(module); result &= add_analysis_binaries_module_to_python_module(module); result &= add_analysis_blocks_module_to_python_module(module); + result &= add_analysis_contents_module_to_python_module(module); result &= add_analysis_db_module_to_python_module(module); loading_failed: diff --git a/plugins/pychrysa/core/formats.c b/plugins/pychrysa/core/formats.c new file mode 100644 index 0000000..5c10ba8 --- /dev/null +++ b/plugins/pychrysa/core/formats.c @@ -0,0 +1,190 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * formats.c - équivalent Python du fichier "core/formats.c" + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 "formats.h" + + +#include + + +#include + + +#include "../helpers.h" + + + +/* Fournit le nom humain du format binaire visé. */ +static PyObject *py_formats_get_binary_format_name(PyObject *, PyObject *); + +/* Définit les constantes pour les paramètres. */ +static bool py_formats_define_constants(PyTypeObject *); + + + +/****************************************************************************** +* * +* Paramètres : self = NULL car méthode statique. * +* args = non utilisé ici. * +* * +* Description : Fournit le nom humain du format binaire visé. * +* * +* Retour : Désignation humaine trouvée ou None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_formats_get_binary_format_name(PyObject *self, PyObject *args) +{ + PyObject *result; /* Désignation à retourner */ + const char *key; /* Nom court du format */ + int ret; /* Bilan de lecture des args. */ + const char *name; /* Désignation humaine */ + + ret = PyArg_ParseTuple(args, "s", &key); + if (!ret) return NULL; + + name = get_binary_format_name(key); + + if (name != NULL) + result = PyUnicode_FromString(name); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_formats_type(void) +{ + static PyMethodDef py_formats_methods[] = { + + { "get_binary_format_name", py_formats_get_binary_format_name, + METH_VARARGS | METH_STATIC, + "get_binary_format_name(key, /)\n--\n\nGive access to the main configuration of Chrysalide." + }, + { NULL } + + }; + + static PyTypeObject py_formats_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.core.formats", + .tp_basicsize = sizeof(PyObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "Python object for parameters", + + .tp_methods = py_formats_methods + + }; + + return &py_formats_type; + +} + + +/****************************************************************************** +* * +* Paramètres : obj_type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes pour les paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_formats_define_constants(PyTypeObject *obj_type) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= PyDict_AddIntMacro(obj_type, FMS_MATCHED); + result &= PyDict_AddIntMacro(obj_type, FMS_FORWARDED); + result &= PyDict_AddIntMacro(obj_type, FMS_UNKNOWN); + + result &= PyDict_AddIntMacro(obj_type, FMS_COUNT); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.core.formats'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_formats(PyObject *module) +{ + PyTypeObject *py_formats_type; /* Type Python pour 'formats' */ + int ret; /* Bilan d'un appel */ + + py_formats_type = get_python_formats_type(); + + py_formats_type->tp_new = PyType_GenericNew; + + if (PyType_Ready(py_formats_type) != 0) + return false; + + if (!py_formats_define_constants(py_formats_type)) + return false; + + Py_INCREF(py_formats_type); + ret = PyModule_AddObject(module, "formats", (PyObject *)py_formats_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/core/formats.h b/plugins/pychrysa/core/formats.h new file mode 100644 index 0000000..f4fe2db --- /dev/null +++ b/plugins/pychrysa/core/formats.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * formats.h - prototypes pour l'équivalent Python du fichier "core/formats.h" + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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_CORE_FORMATS_H +#define _PLUGINS_PYCHRYSALIDE_CORE_FORMATS_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_formats_type(void); + +/* Prend en charge l'objet 'pychrysalide.core.formats'. */ +bool register_python_formats(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_CORE_FORMATS_H */ diff --git a/plugins/pychrysa/format/dex/dex.c b/plugins/pychrysa/format/dex/dex.c index a11af52..08c48f0 100644 --- a/plugins/pychrysa/format/dex/dex.c +++ b/plugins/pychrysa/format/dex/dex.c @@ -33,7 +33,7 @@ #include "../executable.h" -#include "../../glibext/bincontent.h" +#include "../../analysis/content.h" diff --git a/plugins/pychrysa/format/elf/elf.c b/plugins/pychrysa/format/elf/elf.c index a292c91..07e5130 100644 --- a/plugins/pychrysa/format/elf/elf.c +++ b/plugins/pychrysa/format/elf/elf.c @@ -32,7 +32,7 @@ #include "../executable.h" -#include "../../glibext/bincontent.h" +#include "../../analysis/content.h" diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am index 0a61da2..74def8a 100644 --- a/plugins/pychrysa/glibext/Makefile.am +++ b/plugins/pychrysa/glibext/Makefile.am @@ -2,7 +2,6 @@ noinst_LTLIBRARIES = libpychrysaglibext.la libpychrysaglibext_la_SOURCES = \ - bincontent.h bincontent.c \ bufferline.h bufferline.c \ codebuffer.h codebuffer.c \ configuration.h configuration.c \ diff --git a/plugins/pychrysa/glibext/bincontent.c b/plugins/pychrysa/glibext/bincontent.c deleted file mode 100644 index 085c9af..0000000 --- a/plugins/pychrysa/glibext/bincontent.c +++ /dev/null @@ -1,303 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * bincontent.c - prototypes pour l'équivalent Python du fichier "glibext/gbincontent.c" - * - * Copyright (C) 2015 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 "bincontent.h" - - -#include - - -#include - - -#include "../arch/vmpa.h" - - -/* Crée un nouvel objet Python de type 'BinContent'. */ -static PyObject *py_binary_content_new(PyTypeObject *, PyObject *, PyObject *); - -/* Fournit une empreinte unique (SHA256) pour les données. */ -static PyObject *py_binary_content_get_checksum(PyObject *, PyObject *); - -/* Détermine le nombre d'octets lisibles. */ -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 *); - - - - - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'BinContent'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_binary_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - const char *filename; /* Nom du fichier à charger */ - int ret; /* Bilan de lecture des args. */ - GBinContent *content; /* Version GLib du contenu */ - - ret = PyArg_ParseTuple(args, "s", &filename); - if (!ret) Py_RETURN_NONE; - - content = g_binary_content_new_from_file(filename); - - result = pygobject_new(G_OBJECT(content)); - g_object_unref(content); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = contenu binaire à manipuler. * -* args = non utilisé ici. * -* * -* Description : Fournit une empreinte unique (SHA256) pour les données. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_binary_content_get_checksum(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - GBinContent *content; /* Version GLib du format */ - const gchar *checksum; /* Empreinte fournie */ - - content = G_BIN_CONTENT(pygobject_get(self)); - - checksum = g_binary_content_get_cheksum(content); - - result = PyUnicode_FromString(checksum); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = contenu binaire à manipuler. * -* args = non utilisé ici. * -* * -* Description : Détermine le nombre d'octets lisibles. * -* * -* Retour : Quantité représentée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_binary_content_compute_size(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - GBinContent *content; /* Version GLib du format */ - phys_t size; /* Quantité d'octets dispos. */ - - content = G_BIN_CONTENT(pygobject_get(self)); - - size = g_binary_content_compute_size(content); - - result = PyLong_FromUnsignedLongLong(size); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = contenu binaire à manipuler. * -* args = non utilisé ici. * -* * -* Description : Lit un nombre non signé sur un octet. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_binary_content_read_u8(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 */ - uint8_t val; /* Valeur lue à faire suivre */ - bool status; /* Bilan de l'opération */ - - content = G_BIN_CONTENT(pygobject_get(self)); - - //printf("Passage\n"); - - 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) /* ... */; - - 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);; - //Py_INCREF(result); - - return result; - -} - - - - - - - - -/****************************************************************************** -* * -* 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) -{ - static PyMethodDef py_binary_content_methods[] = { - { "get_cheksum", py_binary_content_get_checksum, - METH_NOARGS, - "get_cheksum($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 } - }; - - static PyGetSetDef py_binary_content_getseters[] = { - { NULL } - }; - - static PyTypeObject py_binary_content_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.glibext.BinContent", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = "PyChrysalide binary content", - - .tp_methods = py_binary_content_methods, - .tp_getset = py_binary_content_getseters, - .tp_new = (newfunc)py_binary_content_new - - }; - - return &py_binary_content_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.glibext.BinContent'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_binary_content(PyObject *module) -{ - PyTypeObject *py_binary_content_type; /* Type Python 'BinContent' */ - int ret; /* Bilan d'un appel */ - PyObject *dict; /* Dictionnaire du module */ - - py_binary_content_type = get_python_binary_content_type(); - - py_binary_content_type->tp_base = &PyGObject_Type; - py_binary_content_type->tp_basicsize = py_binary_content_type->tp_base->tp_basicsize; - - if (PyType_Ready(py_binary_content_type) != 0) - return false; - - Py_INCREF(py_binary_content_type); - ret = PyModule_AddObject(module, "BinContent", (PyObject *)py_binary_content_type); - if (ret != 0) return false; - - dict = PyModule_GetDict(module); - pygobject_register_class(dict, "BinContent", G_TYPE_BIN_CONTENT, py_binary_content_type, - Py_BuildValue("(O)", py_binary_content_type->tp_base)); - - return true; - -} diff --git a/plugins/pychrysa/glibext/bincontent.h b/plugins/pychrysa/glibext/bincontent.h deleted file mode 100644 index b6ae9a5..0000000 --- a/plugins/pychrysa/glibext/bincontent.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * bincontent.h - prototypes pour l'équivalent Python du fichier "glibext/gbincontent.h" - * - * Copyright (C) 2015 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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_PYCHRYSA_GLIBEXT_BINCONTENT_H -#define _PLUGINS_PYCHRYSA_GLIBEXT_BINCONTENT_H - - -#include -#include - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_binary_content_type(void); - -/* Prend en charge l'objet 'pychrysalide.glibext.BinContent'. */ -bool register_python_binary_content(PyObject *); - - - -#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_BINCONTENT_H */ diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c index 0cb96a7..b34b91e 100644 --- a/plugins/pychrysa/glibext/module.c +++ b/plugins/pychrysa/glibext/module.c @@ -28,7 +28,6 @@ #include -#include "bincontent.h" #include "bufferline.h" #include "codebuffer.h" #include "configuration.h" @@ -81,7 +80,6 @@ bool add_glibext_module_to_python_module(PyObject *super) result = true; - result &= register_python_binary_content(module); result &= register_python_buffer_line(module); result &= register_python_code_buffer(module); result &= register_python_config_param(module); diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c index 514b6ca..53995e5 100644 --- a/plugins/ropgadgets/select.c +++ b/plugins/ropgadgets/select.c @@ -36,6 +36,7 @@ #include +#include #include #include #include @@ -1326,7 +1327,7 @@ static GBinFormat *load_external_format_for_rop_gadgets(GObject *ref) /* Récupération du contenu binaire */ - content = g_binary_content_new_from_file(filename); + content = g_file_content_new(filename); if (content == NULL) { push_status_printing_of_rop_search_step(ref, "loading", _("unable to get the binary content"), false); diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index 26f9df6..f3f6e92 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -5,6 +5,8 @@ libanalysis_la_SOURCES = \ binary.h binary.c \ block-int.h \ block.h block.c \ + content-int.h \ + content.h content.c \ project.h project.c \ roptions.h roptions.c \ routine.h routine.c \ @@ -15,6 +17,7 @@ libanalysis_la_SOURCES = \ libanalysis_la_LIBADD = \ binaries/libanalysisbinaries.la \ blocks/libanalysisblocks.la \ + contents/libanalysiscontents.la \ db/libanalysisdb.la \ decomp/libanalysisdecomp.la \ disass/libanalysisdisass.la \ @@ -27,4 +30,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = binaries blocks db decomp disass types +SUBDIRS = binaries blocks contents db decomp disass types diff --git a/src/analysis/binaries/file.c b/src/analysis/binaries/file.c index 75f2c18..32cd41f 100644 --- a/src/analysis/binaries/file.c +++ b/src/analysis/binaries/file.c @@ -28,10 +28,10 @@ #include "../binary-int.h" +#include "../../analysis/contents/file.h" #include "../../common/extstr.h" #include "../../core/formats.h" #include "../../core/processors.h" -#include "../../glibext/gbincontent.h" #include "../../gui/panels/log.h" @@ -170,7 +170,7 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename) result->filename = strdup(filename); - content = g_binary_content_new_from_file(filename); + content = g_file_content_new(filename); if (content == NULL) goto lbf_error; target = find_matching_format(content, NULL); diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h new file mode 100644 index 0000000..7734916 --- /dev/null +++ b/src/analysis/content-int.h @@ -0,0 +1,86 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content-int.h - définitions internes propres aux contenus binaires + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_CONTENT_INT_H +#define _ANALYSIS_CONTENT_INT_H + + +#include "content.h" + + + +/* Fournit une empreinte unique (SHA256) pour les données. */ +typedef const gchar * (* get_checksum_fc) (GBinContent *); + +/* Détermine le nombre d'octets lisibles. */ +typedef phys_t (* compute_size_fc) (const GBinContent *); + +/* Donne accès à une portion des données représentées. */ +typedef const bin_t * (* get_raw_access_fc) (const GBinContent *, vmpa2t *, phys_t); + +/* Fournit une portion des données représentées. */ +typedef bool (* read_raw_fc) (const GBinContent *, vmpa2t *, phys_t, bin_t *); + +/* Lit un nombre non signé sur quatre bits. */ +typedef bool (* read_u4_fc) (const GBinContent *, vmpa2t *, bool *, uint8_t *); + +/* Lit un nombre non signé sur un octet. */ +typedef bool (* read_u8_fc) (const GBinContent *, vmpa2t *, uint8_t *); + +/* Lit un nombre non signé sur deux octets. */ +typedef bool (* read_u16_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint16_t *); + +/* Lit un nombre non signé sur quatre octets. */ +typedef bool (* read_u32_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint32_t *); + +/* Lit un nombre non signé sur huit octets. */ +typedef bool (* read_u64_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint64_t *); + + +/* Accès à un contenu binaire quelconque (interface) */ +struct _GBinContentIface +{ + GTypeInterface base_iface; /* A laisser en premier */ + + get_checksum_fc get_checksum; /* Calcul de l'empreinte */ + + compute_size_fc compute_size; /* Calcul de la taille totale */ + + get_raw_access_fc get_raw_access; /* Accès brut à une position */ + + read_raw_fc read_raw; /* Lecture brute */ + read_u4_fc read_u4; /* Lecture de 4 bits */ + read_u8_fc read_u8; /* Lecture de 8 bits */ + read_u16_fc read_u16; /* Lecture de 16 bits */ + read_u32_fc read_u32; /* Lecture de 32 bits */ + read_u64_fc read_u64; /* Lecture de 64 bits */ + +}; + + +/* Redéfinition */ +typedef GBinContentIface GBinContentInterface; + + + +#endif /* _ANALYSIS_CONTENT_INT_H */ diff --git a/src/analysis/content.c b/src/analysis/content.c new file mode 100644 index 0000000..5a4c899 --- /dev/null +++ b/src/analysis/content.c @@ -0,0 +1,282 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content.c - lecture de données binaires quelconques + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#include "content.h" + + +#include "content-int.h" + + + +/* Procède à l'initialisation de l'interface de rassemblement. */ +static void g_binary_content_default_init(GBinContentInterface *); + + + +/* Détermine le type d'une interface pour la lecture de binaire. */ +G_DEFINE_INTERFACE(GBinContent, g_binary_content, G_TYPE_OBJECT) + + +/****************************************************************************** +* * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de rassemblement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_content_default_init(GBinContentInterface *iface) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Fournit une empreinte unique (SHA256) pour les données. * +* * +* Retour : Chaîne représentant l'empreinte du contenu binaire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const gchar *g_binary_content_get_cheksum(GBinContent *content) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->get_checksum(content); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Détermine le nombre d'octets lisibles. * +* * +* Retour : Quantité représentée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +phys_t g_binary_content_compute_size(const GBinContent *content) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->compute_size(content); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* length = quantité d'octets à lire. * +* * +* Description : Donne accès à une portion des données représentées. * +* * +* Retour : Pointeur vers les données à lire ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t *addr, phys_t length) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->get_raw_access(content, addr, length); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* length = quantité d'octets à lire. * +* out = réceptacle disponible pour ces données. [OUT] * +* * +* Description : Fournit une portion des données représentées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_raw(content, addr, length, out); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* low = position éventuelle des 4 bits visés. [OUT] * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur quatre bits. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, uint8_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u4(content, addr, low, val); + +} + + + +/****************************************************************************** +* * +* 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 : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u8(content, addr, val); + +} + + +/****************************************************************************** +* * +* 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 : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u16(content, addr, endian, val); + +} + + +/****************************************************************************** +* * +* 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. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u32(content, addr, endian, val); + +} + + +/****************************************************************************** +* * +* 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. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u64(content, addr, endian, val); + +} diff --git a/src/analysis/content.h b/src/analysis/content.h new file mode 100644 index 0000000..d422dc6 --- /dev/null +++ b/src/analysis/content.h @@ -0,0 +1,91 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content.h - prototypes pour la lecture de données binaires quelconques + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_CONTENT_H +#define _ANALYSIS_CONTENT_H + + +#include +#include + + +#include "../arch/vmpa.h" +#include "../common/endianness.h" + + + +#define G_TYPE_BIN_CONTENT (g_binary_content_get_type()) +#define G_BIN_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_CONTENT, GBinContent)) +#define G_BIN_CONTENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_BIN_CONTENT, GBinContentIface)) +#define GTK_IS_BIN_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_CONTENT)) +#define GTK_IS_BIN_CONTENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_BIN_CONTENT)) +#define G_BIN_CONTENT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_BIN_CONTENT, GBinContentIface)) + + +/* Accès à un contenu binaire quelconque (coquille vide) */ +typedef struct _GBinContent GBinContent; + +/* Accès à un contenu binaire quelconque (interface) */ +typedef struct _GBinContentIface GBinContentIface; + + +/* Détermine le type d'une interface pour la lecture de binaire. */ +GType g_binary_content_get_type(void) G_GNUC_CONST; + +/* Fournit une empreinte unique (SHA256) pour les données. */ +const gchar *g_binary_content_get_cheksum(GBinContent *); + +/* Détermine le nombre d'octets lisibles. */ +phys_t g_binary_content_compute_size(const GBinContent *); + +/* Donne accès à une portion des données représentées. */ +const bin_t *g_binary_content_get_raw_access(const GBinContent *, vmpa2t *, phys_t); + +/* Fournit une portion des données représentées. */ +bool g_binary_content_read_raw(const GBinContent *, vmpa2t *, phys_t, bin_t *); + +/* Lit un nombre non signé sur quatre bits. */ +bool g_binary_content_read_u4(const GBinContent *, vmpa2t *, bool *, uint8_t *); + +/* Lit un nombre non signé sur un octet. */ +bool g_binary_content_read_u8(const GBinContent *, vmpa2t *, uint8_t *); + +/* Lit un nombre non signé sur deux octets. */ +bool g_binary_content_read_u16(const GBinContent *, vmpa2t *, SourceEndian, uint16_t *); + +/* Lit un nombre non signé sur quatre octets. */ +bool g_binary_content_read_u32(const GBinContent *, vmpa2t *, SourceEndian, uint32_t *); + +/* Lit un nombre non signé sur huit octets. */ +bool g_binary_content_read_u64(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *); + + +#define g_binary_content_read_s4(c, a, l, v) g_binary_content_read_u4(c, a, l, (uint8_t *)v) +#define g_binary_content_read_s8(c, a, v) g_binary_content_read_u8(c, a, (uint8_t *)v) +#define g_binary_content_read_s16(c, a, e, v) g_binary_content_read_u16(c, a, e, (uint16_t *)v) +#define g_binary_content_read_s32(c, a, e, v) g_binary_content_read_u32(c, a, e, (uint32_t *)v) +#define g_binary_content_read_s64(c, a, e, v) g_binary_content_read_u64(c, a, e, (uint64_t *)v) + + + +#endif /* _ANALYSIS_CONTENT_H */ diff --git a/src/analysis/contents/Makefile.am b/src/analysis/contents/Makefile.am new file mode 100755 index 0000000..e2eec74 --- /dev/null +++ b/src/analysis/contents/Makefile.am @@ -0,0 +1,16 @@ + +noinst_LTLIBRARIES = libanalysiscontents.la + +libanalysiscontents_la_SOURCES = \ + file.h file.c + +libanalysiscontents_la_LIBADD = + +libanalysiscontents_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c new file mode 100644 index 0000000..eb0d488 --- /dev/null +++ b/src/analysis/contents/file.c @@ -0,0 +1,603 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * file.c - chargement de données binaires à partir d'un fichier + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#include "file.h" + + +#include +#include +#include +#include +#include +#include + + +#include "../content-int.h" + + + +/* Contenu de données binaires issues d'un fichier (instance) */ +struct _GFileContent +{ + GObject parent; /* A laisser en premier */ + + bin_t *data; /* Contenu binaire représenté */ + mrange_t range; /* Couverture du binaire */ + + GChecksum *checksum; /* Calcul de l'empreinte */ + bool cs_computed; /* Calcul effectué ? */ + +}; + +/* Contenu de données binaires issues d'un fichier (classe) */ +struct _GFileContentClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des contenus de données binaires. */ +static void g_file_content_class_init(GFileContentClass *); + +/* Initialise une instance de contenu de données binaires. */ +static void g_file_content_init(GFileContent *); + +/* Procède à l'initialisation de l'interface de lecture. */ +static void g_file_content_interface_init(GBinContentInterface *); + +/* Supprime toutes les références externes. */ +static void g_file_content_dispose(GFileContent *); + +/* Procède à la libération totale de la mémoire. */ +static void g_file_content_finalize(GFileContent *); + +/* Fournit une empreinte unique (SHA256) pour les données. */ +static const gchar *g_file_content_get_checksum(GFileContent *); + +/* Détermine le nombre d'octets lisibles. */ +static phys_t g_file_content_compute_size(const GFileContent *); + +/* Donne accès à une portion des données représentées. */ +static const bin_t *g_file_content_get_raw_access(const GFileContent *, vmpa2t *, phys_t); + +/* Fournit une portion des données représentées. */ +static bool g_file_content_read_raw(const GFileContent *, vmpa2t *, phys_t, bin_t *); + +/* Lit un nombre non signé sur quatre bits. */ +static bool g_file_content_read_u4(const GFileContent *, vmpa2t *, bool *, uint8_t *); + +/* Lit un nombre non signé sur un octet. */ +static bool g_file_content_read_u8(const GFileContent *, vmpa2t *, uint8_t *); + +/* Lit un nombre non signé sur deux octets. */ +static bool g_file_content_read_u16(const GFileContent *, vmpa2t *, SourceEndian, uint16_t *); + +/* Lit un nombre non signé sur quatre octets. */ +static bool g_file_content_read_u32(const GFileContent *, vmpa2t *, SourceEndian, uint32_t *); + +/* Lit un nombre non signé sur huit octets. */ +static bool g_file_content_read_u64(const GFileContent *, vmpa2t *, SourceEndian, uint64_t *); + + + +/* Indique le type défini par la GLib pour les contenus de données. */ +G_DEFINE_TYPE_WITH_CODE(GFileContent, g_file_content, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_BIN_CONTENT, g_file_content_interface_init)) + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des contenus de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_class_init(GFileContentClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_file_content_dispose; + object->finalize = (GObjectFinalizeFunc)g_file_content_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance à initialiser. * +* * +* Description : Initialise une instance de contenu de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_init(GFileContent *content) +{ + content->checksum = g_checksum_new(G_CHECKSUM_SHA256); + assert(content->checksum != NULL); + + content->cs_computed = false; + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de lecture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_interface_init(GBinContentInterface *iface) +{ + iface->get_checksum = (get_checksum_fc)g_file_content_get_checksum; + + iface->compute_size = (compute_size_fc)g_file_content_compute_size; + + iface->get_raw_access = (get_raw_access_fc)g_file_content_get_raw_access; + + iface->read_raw = (read_raw_fc)g_file_content_read_raw; + iface->read_u4 = (read_u4_fc)g_file_content_read_u4; + iface->read_u8 = (read_u8_fc)g_file_content_read_u8; + iface->read_u16 = (read_u16_fc)g_file_content_read_u16; + iface->read_u32 = (read_u32_fc)g_file_content_read_u32; + iface->read_u64 = (read_u64_fc)g_file_content_read_u64; + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_dispose(GFileContent *content) +{ + g_checksum_free(content->checksum); + + G_OBJECT_CLASS(g_file_content_parent_class)->dispose(G_OBJECT(content)); + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_finalize(GFileContent *content) +{ + if (content->data != NULL) + free(content->data); + + G_OBJECT_CLASS(g_file_content_parent_class)->finalize(G_OBJECT(content)); + +} + + +/****************************************************************************** +* * +* Paramètres : filename = chemin d'accès au fichier à charger. * +* * +* Description : Charge en mémoire le contenu d'un fichier donné. * +* * +* Retour : Représentation de contenu à manipuler ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinContent *g_file_content_new(const char *filename) +{ + GFileContent *result; /* Structure à retourner */ + int fd; /* Descripteur du fichier */ + struct stat info; /* Informations sur le fichier */ + int ret; /* Bilan d'un appel */ + void *content; /* Contenu brut du fichier */ + vmpa2t base; /* Localisation des données */ + + /* Récupération des données */ + + fd = open(filename, O_RDONLY); + if (fd == -1) + { + perror("open"); + goto gbcnff_error; + } + + ret = fstat(fd, &info); + if (ret == -1) + { + close(fd); + perror("fstat"); + goto gbcnff_error; + } + + content = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (content == MAP_FAILED) + { + close(fd); + perror("mmap"); + goto gbcnff_error; + } + + /* Constitution du contenu officiel */ + + result = g_object_new(G_TYPE_FILE_CONTENT, NULL); + + result->data = (bin_t *)malloc(info.st_size); + memcpy(result->data, content, info.st_size); + + munmap(content, info.st_size); + close(fd); + + init_vmpa(&base, 0, VMPA_NO_VIRTUAL); + init_mrange(&result->range, &base, info.st_size); + + return G_BIN_CONTENT(result); + + gbcnff_error: + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Fournit une empreinte unique (SHA256) pour les données. * +* * +* Retour : Chaîne représentant l'empreinte du contenu binaire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const gchar *g_file_content_get_checksum(GFileContent *content) +{ + if (!content->cs_computed) + { + g_checksum_reset(content->checksum); + + g_checksum_update(content->checksum, content->data, get_mrange_length(&content->range)); + + content->cs_computed = true; + + } + + return g_checksum_get_string(content->checksum); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Détermine le nombre d'octets lisibles. * +* * +* Retour : Quantité représentée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static phys_t g_file_content_compute_size(const GFileContent *content) +{ + phys_t result; /* Quantité trouvée à retourner*/ + + result = get_mrange_length(&content->range); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* length = quantité d'octets à lire. * +* * +* Description : Donne accès à une portion des données représentées. * +* * +* Retour : Pointeur vers les données à lire ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const bin_t *g_file_content_get_raw_access(const GFileContent *content, vmpa2t *addr, phys_t length) +{ + phys_t offset; /* Emplacement de départ */ + + offset = get_phy_addr(addr); + + if (offset == VMPA_NO_PHYSICAL) + return NULL; + + if ((offset + length) >= get_mrange_length(&content->range)) + return NULL; + + advance_vmpa(addr, length); + + return &content->data[offset]; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* length = quantité d'octets à lire. * +* out = réceptacle disponible pour ces données. [OUT] * +* * +* Description : Fournit une portion des données représentées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_raw(const GFileContent *content, vmpa2t *addr, phys_t length, bin_t *out) +{ + bool result; /* Bilan à remonter */ + const bin_t *data; /* Pointeur vers données utiles*/ + + data = g_file_content_get_raw_access(content, addr, length); + + if (data != NULL) + { + result = true; + memcpy(out, data, length); + } + else + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* low = position éventuelle des 4 bits visés. [OUT] * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur quatre bits. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u4(const GFileContent *content, vmpa2t *addr, bool *low, uint8_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u4(val, content->data, &pos, length, low); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + 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 g_file_content_read_u8(const GFileContent *content, vmpa2t *addr, uint8_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u8(val, content->data, &pos, length); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + 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 g_file_content_read_u16(const GFileContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u16(val, content->data, &pos, length, endian); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + 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 quatre octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u32(const GFileContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u32(val, content->data, &pos, length, endian); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + 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 huit octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u64(const GFileContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u64(val, content->data, &pos, length, endian); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + return result; + +} diff --git a/src/analysis/contents/file.h b/src/analysis/contents/file.h new file mode 100644 index 0000000..2e3cfef --- /dev/null +++ b/src/analysis/contents/file.h @@ -0,0 +1,58 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * file.h - prototypes pour le chargement de données binaires à partir d'un fichier + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_CONTENTS_FILE_H +#define _ANALYSIS_CONTENTS_FILE_H + + +#include + + +#include "../content.h" + + + +#define G_TYPE_FILE_CONTENT (g_file_content_get_type()) +#define G_FILE_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_FILE_CONTENT, GFileContent)) +#define G_IS_FILE_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_FILE_CONTENT)) +#define G_FILE_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_FILE_CONTENT, GFileContentClass)) +#define G_IS_FILE_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_FILE_CONTENT)) +#define G_FILE_CONTENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_FILE_CONTENT, GFileContentClass)) + + +/* Contenu de données binaires issues d'un fichier (instance) */ +typedef struct _GFileContent GFileContent; + +/* Contenu de données binaires issues d'un fichier (classe) */ +typedef struct _GFileContentClass GFileContentClass; + + +/* Indique le type défini par la GLib pour les contenus de données. */ +GType g_file_content_get_type(void); + +/* Charge en mémoire le contenu d'un fichier donné. */ +GBinContent *g_file_content_new(const char *); + + + +#endif /* _ANALYSIS_CONTENTS_FILE_H */ diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c index 9117861..7a1dd5a 100644 --- a/src/arch/arm/v7/processor.c +++ b/src/arch/arm/v7/processor.c @@ -68,7 +68,7 @@ static void g_armv7_processor_finalize(GArmV7Processor *); static GArmV7Context *g_armv7_processor_get_context(const GArmV7Processor *); /* Décode une instruction dans un flux de données. */ -static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *, GArmV7Context *, const bin_t *, vmpa2t *, phys_t); +static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *, GArmV7Context *, const GBinContent *, vmpa2t *); @@ -218,11 +218,10 @@ static GArmV7Context *g_armv7_processor_get_context(const GArmV7Processor *proc) /****************************************************************************** * * -* Paramètres : proc = architecture visée par la procédure. * -* ctx = contexte lié à l'exécution du processeur. * -* data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* end = limite des données à analyser. * +* Paramètres : proc = architecture visée par la procédure. * +* ctx = contexte lié à l'exécution du processeur. * +* content = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * * * * Description : Désassemble une instruction dans un flux de données. * * * @@ -232,26 +231,23 @@ static GArmV7Context *g_armv7_processor_get_context(const GArmV7Processor *proc) * * ******************************************************************************/ -static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *proc, GArmV7Context *ctx, const bin_t *data, vmpa2t *pos, phys_t end) +static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *proc, GArmV7Context *ctx, const GBinContent *content, vmpa2t *pos) { GArchInstruction *result; /* Instruction à renvoyer */ - phys_t start; /* Point de départ de lecture */ - phys_t diff; /* Avancée dans la lecture */ + SourceEndian endian; /* Boutisme des données lues */ uint16_t raw16; /* Donnée 16 bits à analyser */ uint32_t raw32; /* Donnée 32 bits à analyser */ ArmV7InstrSet iset; /* Type de jeu d'instructions */ - iset = g_armv7_context_find_encoding(ctx, get_virt_addr(pos)); - - start = get_phy_addr(pos); + endian = G_ARCH_PROCESSOR(proc)->endianness; - diff = 4; + iset = g_armv7_context_find_encoding(ctx, get_virt_addr(pos)); switch (iset) { case AV7IS_ARM: - if (!read_u32(&raw32, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness)) + if (!g_binary_content_read_u32(content, pos, endian, &raw32)) return NULL; result = process_armv7_arm_instruction_set_encoding(raw32); @@ -260,7 +256,7 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr case AV7IS_THUMB: - if (!read_u16(&raw16, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness)) + if (!g_binary_content_read_u16(content, pos, endian, &raw16)) return NULL; switch (raw16 >> 11) @@ -271,7 +267,7 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr raw32 = raw16 << 16; - if (!read_u16(&raw16, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness)) + if (!g_binary_content_read_u16(content, pos, endian, &raw16)) return NULL; raw32 |= raw16; @@ -280,7 +276,6 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr break; default: - diff = 2; result = process_armv7_thumb_16_instruction_set_encoding(raw16); break; @@ -294,8 +289,6 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr } - if (result != NULL) - advance_vmpa(pos, diff); /* else result = g_raw_instruction_new_array_old(data, MDS_32_BITS, 1, pos, end, diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c index fca7956..838d953 100644 --- a/src/arch/dalvik/operand.c +++ b/src/arch/dalvik/operand.c @@ -398,7 +398,7 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, const GDexFormat opa = g_dalvik_register_operand_new(data, pos, end, low, MDS_4_BITS, endian); - if (!read_u4(&b, data, pos, end, low, endian)) + if (!read_u4(&b, data, pos, end, low)) goto err_va; @@ -492,7 +492,7 @@ static bool dalvik_read_variatic_operands(GArchInstruction *instr, const GDexFor uint16_t c; /* Indice de registre */ GArchOperand *op; /* Opérande unique décodé */ - if (!read_u8(&a, data, pos, end, endian)) + if (!read_u8(&a, data, pos, end)) return false; if (!read_u16(&b, data, pos, end, endian)) diff --git a/src/arch/dalvik/operands/pool.c b/src/arch/dalvik/operands/pool.c index a1fde2e..3537cd6 100644 --- a/src/arch/dalvik/operands/pool.c +++ b/src/arch/dalvik/operands/pool.c @@ -191,7 +191,7 @@ GArchOperand *g_dalvik_pool_operand_new(const GDexFormat *format, DalvikPoolType switch (size) { case MDS_8_BITS: - test = read_u8(&index8, data, pos, end, endian); + test = read_u8(&index8, data, pos, end); break; case MDS_16_BITS: test = read_u16(&index16, data, pos, end, endian); diff --git a/src/arch/dalvik/operands/register.c b/src/arch/dalvik/operands/register.c index 2ae9224..1b789f2 100644 --- a/src/arch/dalvik/operands/register.c +++ b/src/arch/dalvik/operands/register.c @@ -184,10 +184,10 @@ GArchOperand *g_dalvik_register_operand_new(const bin_t *data, off_t *pos, off_t switch (size) { case MDS_4_BITS: - test = read_u4(&index8, data, pos, end, low, endian); + test = read_u4(&index8, data, pos, end, low); break; case MDS_8_BITS: - test = read_u8(&index8, data, pos, end, endian); + test = read_u8(&index8, data, pos, end); break; case MDS_16_BITS: test = read_u16(&index16, data, pos, end, endian); diff --git a/src/arch/dalvik/operands/target.c b/src/arch/dalvik/operands/target.c index 147aaae..690858b 100644 --- a/src/arch/dalvik/operands/target.c +++ b/src/arch/dalvik/operands/target.c @@ -181,7 +181,7 @@ GArchOperand *g_dalvik_target_operand_new(const bin_t *data, off_t *pos, off_t e switch (size) { case MDS_8_BITS_SIGNED: - read_s8(&val8, data, pos, end, endian); + read_s8(&val8, data, pos, end); address = base + val8 * sizeof(uint16_t); break; case MDS_16_BITS_SIGNED: diff --git a/src/arch/immediate.c b/src/arch/immediate.c index c21239e..3720bff 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -235,13 +235,13 @@ GArchOperand *_g_imm_operand_new_from_data_old(MemoryDataSize size, const bin_t switch (size) { case MDS_4_BITS_UNSIGNED: - if (!read_u4(&uval8, data, &pos, end, low, endian)) + if (!read_u4(&uval8, data, &pos, end, low)) goto gionfd_error; result->raw = uval8; break; case MDS_8_BITS_UNSIGNED: - if (!read_u8(&uval8, data, &pos, end, endian)) + if (!read_u8(&uval8, data, &pos, end)) goto gionfd_error; result->raw = uval8; break; @@ -265,13 +265,13 @@ GArchOperand *_g_imm_operand_new_from_data_old(MemoryDataSize size, const bin_t break; case MDS_4_BITS_SIGNED: - if (!read_s4(&sval8, data, &pos, end, low, endian)) + if (!read_s4(&sval8, data, &pos, end, low)) goto gionfd_error; result->raw = sval8; break; case MDS_8_BITS_SIGNED: - if (!read_s8(&sval8, data, &pos, end, endian)) + if (!read_s8(&sval8, data, &pos, end)) goto gionfd_error; result->raw = sval8; break; @@ -348,7 +348,7 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten switch (size) { case MDS_4_BITS_UNSIGNED: - if (!g_binary_content_read_u4(content, addr, low, endian, &uval8)) + if (!g_binary_content_read_u4(content, addr, low, &uval8)) goto gionfd_error; result->raw = uval8; break; @@ -378,7 +378,7 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten break; case MDS_4_BITS_SIGNED: - if (!g_binary_content_read_s4(content, addr, low, endian, &sval8)) + if (!g_binary_content_read_s4(content, addr, low, &sval8)) goto gionfd_error; result->raw = sval8; break; diff --git a/src/arch/immediate.h b/src/arch/immediate.h index 2393b49..1a587ad 100644 --- a/src/arch/immediate.h +++ b/src/arch/immediate.h @@ -32,8 +32,7 @@ #include "archbase.h" #include "operand.h" -#include "../common/endianness.h" -#include "../glibext/gbincontent.h" +#include "../analysis/content.h" diff --git a/src/arch/instruction.h b/src/arch/instruction.h index b3a272f..baeee2e 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -32,10 +32,10 @@ #include "immediate.h" #include "register.h" #include "vmpa.h" +#include "../analysis/content.h" #include "../analysis/type.h" #include "../decomp/context.h" #include "../decomp/instruction.h" -#include "../glibext/gbincontent.h" //#include "../format/executable.h" //#include "../format/format.h" diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index d387bde..f4562f6 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -58,7 +58,7 @@ typedef GDecContext * (* get_decomp_context_fc) (const GArchProcessor *); typedef GArchInstruction * (* decode_instruction_fc) (const GArchProcessor *, GProcContext *, const bin_t *, off_t *, off_t, vmpa_t, GBinFormat *); /* Désassemble une instruction dans un flux de données. */ -typedef GArchInstruction * (* disass_instr_fc) (const GArchProcessor *, GProcContext *, const bin_t *, vmpa2t *, phys_t); +typedef GArchInstruction * (* disass_instr_fc) (const GArchProcessor *, GProcContext *, const GBinContent *, vmpa2t *); /* Définition générique d'un processeur d'architecture (instance) */ diff --git a/src/arch/processor.c b/src/arch/processor.c index 95176e9..7e2ecec 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -286,15 +286,10 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc { GArchInstruction *result; /* Instruction à renvoyer */ vmpa2t back; /* Position sauvegardée */ - /* FIXME */ - const bin_t *_bin_data; - off_t _bin_length; copy_vmpa(&back, pos); - _bin_data = g_binary_content_get(content, &_bin_length); - - result = G_ARCH_PROCESSOR_GET_CLASS(proc)->disassemble(proc, ctx, _bin_data, pos, _bin_length); + result = G_ARCH_PROCESSOR_GET_CLASS(proc)->disassemble(proc, ctx, content, pos); if (result == NULL) copy_vmpa(pos, &back); diff --git a/src/common/endianness.c b/src/common/endianness.c index 5e48b02..7dc5bc2 100755 --- a/src/common/endianness.c +++ b/src/common/endianness.c @@ -36,7 +36,6 @@ * pos = position courante dans ce flux. [OUT] * * end = limite des données à analyser. * * low = position éventuelle des 4 bits visés. [OUT] * -* endian = ordre des bits dans la source. * * * * Description : Lit un nombre non signé sur 4 bits. * * * @@ -46,7 +45,7 @@ * * ******************************************************************************/ -bool read_u4(uint8_t *target, const bin_t *data, off_t *pos, off_t end, bool *low, SourceEndian endian) +bool read_u4(uint8_t *target, const bin_t *data, off_t *pos, off_t end, bool *low) { if (*pos < 0) return false; if ((end - *pos) < 1) return false; @@ -74,7 +73,6 @@ bool read_u4(uint8_t *target, const bin_t *data, off_t *pos, off_t end, bool *lo * data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * end = limite des données à analyser. * -* endian = ordre des bits dans la source. * * * * Description : Lit un nombre non signé sur un octet. * * * @@ -84,7 +82,7 @@ bool read_u4(uint8_t *target, const bin_t *data, off_t *pos, off_t end, bool *lo * * ******************************************************************************/ -bool read_u8(uint8_t *target, const bin_t *data, off_t *pos, off_t end, SourceEndian endian) +bool read_u8(uint8_t *target, const bin_t *data, off_t *pos, off_t end) { if (*pos < 0) return false; if ((end - *pos) < 1) return false; diff --git a/src/common/endianness.h b/src/common/endianness.h index c573366..2764f66 100755 --- a/src/common/endianness.h +++ b/src/common/endianness.h @@ -43,10 +43,10 @@ typedef enum _SourceEndian /* Lit un nombre non signé sur 4 bits. */ -bool read_u4(uint8_t *, const bin_t *, off_t *, off_t, bool *, SourceEndian); +bool read_u4(uint8_t *, const bin_t *, off_t *, off_t, bool *); /* Lit un nombre non signé sur un octet. */ -bool read_u8(uint8_t *, const bin_t *, off_t *, off_t, SourceEndian); +bool read_u8(uint8_t *, const bin_t *, off_t *, off_t); /* Lit un nombre non signé sur deux octets. */ bool read_u16(uint16_t *, const bin_t *, off_t *, off_t, SourceEndian); @@ -58,8 +58,8 @@ bool read_u32(uint32_t *, const bin_t *, off_t *, off_t, SourceEndian); bool read_u64(uint64_t *, const bin_t *, off_t *, off_t, SourceEndian); -#define read_s4(target, data, pos, len, low, endian) read_u4((uint8_t *)target, data, pos, len, low, endian) -#define read_s8(target, data, pos, len, endian) read_u8((uint8_t *)target, data, pos, len, endian) +#define read_s4(target, data, pos, len, low) read_u4((uint8_t *)target, data, pos, len, low) +#define read_s8(target, data, pos, len) read_u8((uint8_t *)target, data, pos, len) #define read_s16(target, data, pos, len, endian) read_u16((uint16_t *)target, data, pos, len, endian) #define read_s32(target, data, pos, len, endian) read_u32((uint32_t *)target, data, pos, len, endian) #define read_s64(target, data, pos, len, endian) read_u64((uint64_t *)target, data, pos, len, endian) diff --git a/src/debug/jdwp/misc/header.c b/src/debug/jdwp/misc/header.c index 6a6ed69..6525580 100644 --- a/src/debug/jdwp/misc/header.c +++ b/src/debug/jdwp/misc/header.c @@ -170,7 +170,7 @@ bool get_jdwp_header(const bin_t *blob, jdwp_header *header) if (!read_u32(&header->id, blob, &pos, len, SRE_BIG)) return false; - if (!read_u8(&header->flags, blob, &pos, len, SRE_BIG)) + if (!read_u8(&header->flags, blob, &pos, len)) return false; /* Réponse ? */ @@ -183,10 +183,10 @@ bool get_jdwp_header(const bin_t *blob, jdwp_header *header) /* Requête ! */ else { - if (!read_u8(&header->set, blob, &pos, len, SRE_BIG)) + if (!read_u8(&header->set, blob, &pos, len)) return false; - if (!read_u8(&header->command, blob, &pos, len, SRE_BIG)) + if (!read_u8(&header->command, blob, &pos, len)) return false; } diff --git a/src/debug/jdwp/misc/id.c b/src/debug/jdwp/misc/id.c index 84d1c93..5e2ba3d 100644 --- a/src/debug/jdwp/misc/id.c +++ b/src/debug/jdwp/misc/id.c @@ -114,7 +114,7 @@ bool _get_jdwp_dynsized_id(const bin_t *blob, off_t *pos, off_t len, uint32_t si switch (size) { case 1: - if (!read_u8(&id8, blob, pos, len, SRE_BIG)) + if (!read_u8(&id8, blob, pos, len)) return false; *id = (jdwp_dynsized_id)id8; break; diff --git a/src/debug/jdwp/misc/location.c b/src/debug/jdwp/misc/location.c index d4357dd..66f009f 100644 --- a/src/debug/jdwp/misc/location.c +++ b/src/debug/jdwp/misc/location.c @@ -47,7 +47,7 @@ bool get_jdwp_location(const bin_t *blob, off_t *pos, off_t len, const jdwp_cmd_vm_id_sizes_reply *sizes, jdwp_location *loc) { - if (!read_u8(&loc->tag, blob, pos, len, SRE_BIG)) + if (!read_u8(&loc->tag, blob, pos, len)) return false; if (!get_jdwp_class_id(blob, pos, len, sizes, &loc->class_id)) diff --git a/src/format/dex/dex-int.c b/src/format/dex/dex-int.c index 914f491..5ce0675 100644 --- a/src/format/dex/dex-int.c +++ b/src/format/dex/dex-int.c @@ -64,12 +64,12 @@ bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header) length = 0; //G_BIN_FORMAT(format)->length; for (i = 0; i < DEX_FILE_MAGIC_LEN && result; i++) - result = read_u8(&header->magic[i], content, pos, length, SRE_LITTLE); + result = read_u8(&header->magic[i], content, pos, length); result &= read_u32(&header->checksum, content, pos, length, SRE_LITTLE); for (i = 0; i < 20 && result; i++) - result = read_u8(&header->signature[i], content, pos, length, SRE_LITTLE); + result = read_u8(&header->signature[i], content, pos, length); result &= read_u32(&header->file_size, content, pos, length, SRE_LITTLE); result &= read_u32(&header->header_size, content, pos, length, SRE_LITTLE); diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c index eb78f79..0015357 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -85,7 +85,7 @@ bool dex_is_matching(GBinContent *content) init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - result = g_binary_content_get_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic); + result = g_binary_content_read_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic); result &= (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c index 3e70932..2d6da8b 100644 --- a/src/format/elf/elf-int.c +++ b/src/format/elf/elf-int.c @@ -53,7 +53,7 @@ bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, Sourc init_vmpa(&pos, 0, VMPA_NO_VIRTUAL); - result = g_binary_content_get_raw(content, &pos, EI_NIDENT, (bin_t *)header->hdr32.e_ident); + result = g_binary_content_read_raw(content, &pos, EI_NIDENT, (bin_t *)header->hdr32.e_ident); /* Détermination de l'espace d'adressage */ if (result) diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 7f3af9f..5c81b2f 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -102,7 +102,7 @@ const char *elf_is_matching(GBinContent *content, GExeFormat *parent) init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - status = g_binary_content_get_raw(content, &addr, 4, (bin_t *)magic); + status = g_binary_content_read_raw(content, &addr, 4, (bin_t *)magic); status &= (memcmp(magic, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c index 4d8a32e..948f384 100644 --- a/src/format/elf/strings.c +++ b/src/format/elf/strings.c @@ -173,7 +173,7 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t init_vmpa(&pos, start, address); - if (!g_binary_content_get_raw(content, &pos, size, (bin_t *)data)) + if (!g_binary_content_read_raw(content, &pos, size, (bin_t *)data)) goto pesd_error; /* Boucle de parcours */ diff --git a/src/format/format.h b/src/format/format.h index 9fe23f4..8c06522 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -31,9 +31,9 @@ #include "symbol.h" +#include "../analysis/content.h" #include "../analysis/routine.h" #include "../arch/context.h" -#include "../glibext/gbincontent.h" diff --git a/src/format/java/java.c b/src/format/java/java.c index 4929b52..39403c4 100755 --- a/src/format/java/java.c +++ b/src/format/java/java.c @@ -76,7 +76,7 @@ bool java_is_matching(GBinContent *content) init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - result = g_binary_content_get_raw(content, &addr, 4, (bin_t *)magic); + result = g_binary_content_read_raw(content, &addr, 4, (bin_t *)magic); result &= (memcmp(magic, "\xca\xfe\xba\xbe", 4) == 0); diff --git a/src/format/pe/pe-int.c b/src/format/pe/pe-int.c index bcffe62..e73b720 100644 --- a/src/format/pe/pe-int.c +++ b/src/format/pe/pe-int.c @@ -148,8 +148,8 @@ bool read_pe_optional_header(const GPeFormat *format, off_t *pos, image_optional length = 0; //G_BIN_FORMAT(format)->length; result = read_u16(&header->magic, content, pos, length, SRE_LITTLE); - result &= read_u8(&header->major_linker_version, content, pos, length, SRE_LITTLE); - result &= read_u8(&header->minor_linker_version, content, pos, length, SRE_LITTLE); + result &= read_u8(&header->major_linker_version, content, pos, length); + result &= read_u8(&header->minor_linker_version, content, pos, length); result &= read_u32(&header->size_of_code, content, pos, length, SRE_LITTLE); result &= read_u32(&header->size_of_initialized_data, content, pos, length, SRE_LITTLE); result &= read_u32(&header->size_of_uninitialized_data, content, pos, length, SRE_LITTLE); @@ -249,7 +249,7 @@ bool read_pe_image_section_header(const GPeFormat *format, off_t *pos, image_sec result = true; for (i = 0; i < IMAGE_SIZEOF_SHORT_NAME && result; i++) - result = read_u8((uint8_t *)§ion->name[i], content, pos, length, SRE_LITTLE); + result = read_u8((uint8_t *)§ion->name[i], content, pos, length); result &= read_u32(§ion->misc.physical_address, content, pos, length, SRE_LITTLE); @@ -342,7 +342,7 @@ bool read_pe_image_import_by_name(const GPeFormat *format, off_t *pos, image_imp for (i = 0; result; i++) { - result = read_u8((uint8_t *)&import->name[i], content, &new_pos, length, SRE_LITTLE); + result = read_u8((uint8_t *)&import->name[i], content, &new_pos, length); if (import->name[i] == '\0') break; diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 0d4b57c..192587d 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -8,7 +8,6 @@ libglibext_la_SOURCES = \ configuration.h configuration.c \ delayed-int.h \ delayed.h delayed.c \ - gbincontent.h gbincontent.c \ gbinportion.h gbinportion.c \ gbufferline.h gbufferline.c \ gbuffersegment.h gbuffersegment.c \ diff --git a/src/glibext/gbincontent.c b/src/glibext/gbincontent.c deleted file mode 100644 index 0230e70..0000000 --- a/src/glibext/gbincontent.c +++ /dev/null @@ -1,782 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gbincontent.c - prototypes pour le chargement de données binaires en mémoire - * - * Copyright (C) 2015 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 Foobar. If not, see . - */ - - -#include "gbincontent.h" - - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "../common/endianness.h" - - - -/* Aire de contenu binaire */ -typedef struct _binary_part -{ - bin_t *data; /* Contenu binaire représenté */ - mrange_t range; /* Couverture du binaire */ - -} binary_part; - - -/* Content de données binaires quelconques (instance) */ -struct _GBinContent -{ - GObject parent; /* A laisser en premier */ - - binary_part *parts; /* Parties prises en compte */ - size_t count; /* Nombre de ces parties */ - - GChecksum *checksum; /* Calcul de l'empreinte */ - bool cs_computed; /* Calcul effectué ? */ - -}; - -/* Content de données binaires quelconques (classe) */ -struct _GBinContentClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des contenus de données binaires. */ -static void g_binary_content_class_init(GBinContentClass *); - -/* Initialise une instance de contenu de données binaires. */ -static void g_binary_content_init(GBinContent *); - -/* Supprime toutes les références externes. */ -static void g_binary_content_dispose(GBinContent *); - -/* Procède à la libération totale de la mémoire. */ -static void g_binary_content_finalize(GBinContent *); - -/* Retrouve la zone adaptée pour une localisation de données. */ -static const binary_part *g_binary_content_find_part(const GBinContent *, const vmpa2t *, phys_t *); - - - -/* Indique le type défini par la GLib pour les contenus de données. */ -G_DEFINE_TYPE(GBinContent, g_binary_content, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des contenus de données binaires. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_content_class_init(GBinContentClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_content_dispose; - object->finalize = (GObjectFinalizeFunc)g_binary_content_finalize; - - -} - - -/****************************************************************************** -* * -* Paramètres : content = instance à initialiser. * -* * -* Description : Initialise une instance de contenu de données binaires. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_content_init(GBinContent *content) -{ - content->checksum = g_checksum_new(G_CHECKSUM_SHA256); - assert(content->checksum != NULL); - - content->cs_computed = false; - -} - - -/****************************************************************************** -* * -* Paramètres : content = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_content_dispose(GBinContent *content) -{ - g_checksum_free(content->checksum); - - G_OBJECT_CLASS(g_binary_content_parent_class)->dispose(G_OBJECT(content)); - -} - - -/****************************************************************************** -* * -* Paramètres : content = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_content_finalize(GBinContent *content) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < content->count; i++) - free(content->parts[i].data); - - if (content->parts != NULL) - free(content->parts); - - G_OBJECT_CLASS(g_binary_content_parent_class)->finalize(G_OBJECT(content)); - -} - - -/****************************************************************************** -* * -* Paramètres : filename = chemin d'accès au fichier à charger. * -* * -* Description : Charge en mémoire le contenu d'un fichier donné. * -* * -* Retour : Représentation de contenu à manipuler ou NULL en cas d'échec.* -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinContent *g_binary_content_new_from_file(const char *filename) -{ - GBinContent *result; /* Structure à retourner */ - int fd; /* Descripteur du fichier */ - struct stat info; /* Informations sur le fichier */ - int ret; /* Bilan d'un appel */ - void *content; /* Contenu brut du fichier */ - vmpa2t base; /* Localisation des données */ - - /* Récupération des données */ - - fd = open(filename, O_RDONLY); - if (fd == -1) - { - perror("open"); - goto gbcnff_error; - } - - ret = fstat(fd, &info); - if (ret == -1) - { - close(fd); - perror("fstat"); - goto gbcnff_error; - } - - content = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (content == MAP_FAILED) - { - close(fd); - perror("mmap"); - goto gbcnff_error; - } - - /* Constitution du contenu officiel */ - - result = g_object_new(G_TYPE_BIN_CONTENT, NULL); - - result->parts = (binary_part *)calloc(1, sizeof(binary_part)); - result->count = 1; - - result->parts[0].data = (bin_t *)malloc(info.st_size); - memcpy(result->parts[0].data, content, info.st_size); - - munmap(content, info.st_size); - close(fd); - - init_vmpa(&base, 0, VMPA_NO_VIRTUAL); - init_mrange(&result->parts[0].range, &base, info.st_size); - - return result; - - gbcnff_error: - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* * -* Description : Fournit une empreinte unique (SHA256) pour les données. * -* * -* Retour : Chaîne représentant l'empreinte du contenu binaire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const gchar *g_binary_content_get_cheksum(GBinContent *content) -{ - size_t i; /* Boucle de parcours */ - binary_part *part; /* Bloc parcouru pour analyse */ - - if (!content->cs_computed) - { - g_checksum_reset(content->checksum); - - for (i = 0; i < content->count; i++) - { - part = &content->parts[i]; - g_checksum_update(content->checksum, part->data, get_mrange_length(&part->range)); - } - - content->cs_computed = true; - - } - - return g_checksum_get_string(content->checksum); - -} - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* * -* Description : Détermine le nombre d'octets lisibles. * -* * -* Retour : Quantité représentée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -phys_t g_binary_content_compute_size(const GBinContent *content) -{ - phys_t result; /* Quantité trouvée à retourner*/ - size_t i; /* Boucle de parcours */ - - result = 0; - - for (i = 0; i < content->count; i++) - result = get_mrange_length(&content->parts[i].range); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture globale demandée. * -* start = position de la tête de lecture dans la zone. [OUT] * -* * -* Description : Retrouve la zone adaptée pour une localisation de données. * -* * -* Retour : Partie trouvée ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const binary_part *g_binary_content_find_part(const GBinContent *content, const vmpa2t *addr, phys_t *start) -{ - const binary_part *result; /* Trouvaille à retourner */ - size_t i; /* Boucle de parcours */ - binary_part *part; /* Zone mémoire manipulée */ - - result = NULL; - - for (i = 0; i < content->count && result == NULL; i++) - { - part = &content->parts[i]; - - if (mrange_contains_addr(&part->range, addr)) - result = part; - - } - - if (result != NULL) - *start = compute_vmpa_diff(get_mrange_addr(&result->range), addr); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* length = quantité d'octets à lire. * -* * -* Description : Donne accès à une portion des données représentées. * -* * -* Retour : Pointeur vers les données à lire ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t *addr, phys_t length) -{ - phys_t offset; /* Emplacement de départ */ - - /* FIXME */ - - offset = get_phy_addr(addr); - - if ((offset + length) >= get_mrange_length(&content->parts[0].range)) - return NULL; - - advance_vmpa(addr, length); - - return &content->parts[0].data[offset]; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* length = quantité d'octets à lire. * -* out = réceptacle disponible pour ces données. [OUT] * -* * -* Description : Fournit une portion des données représentées. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_get_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out) -{ - bool result; /* Bilan à remonter */ - const bin_t *data; /* Pointeur vers données utiles*/ - - data = g_binary_content_get_raw_access(content, addr, length); - - if (data != NULL) - { - result = true; - memcpy(out, data, length); - } - else - result = false; - - return result; - -} - - - - - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* low = position éventuelle des 4 bits visés. [OUT] * -* endian = ordre des bits dans la source. * -* val = lieu d'enregistrement de la lecture. [OUT] * -* * -* Description : Lit un nombre non signé sur quatre bits. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian, uint8_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 1) return false; - - data = part->data; - - if (*low) - { - *val = data[start] & 0x0f; - *low = false; - } - else - { - *val = (data[start] & 0xf0) >> 4; - *low = true; - advance_vmpa(addr, 4); - } - - return true; - -} - - - -/****************************************************************************** -* * -* 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 : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 1) return false; - - data = part->data; - - *val = data[start]; - - advance_vmpa(addr, 1); - - return true; - -} - - -/****************************************************************************** -* * -* 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 : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 2) return false; - - data = part->data; - - switch (endian) - { - case SRE_LITTLE: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start] | (uint16_t)data[start + 1] << 8; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start + 1] | (uint16_t)data[start] << 8; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - case SRE_MIDDLE: - assert(false); /* TODO */ - break; - - case SRE_BIG: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start + 1] | (uint16_t)data[start] << 8; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start] | (uint16_t)data[start + 1] << 8; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - - } - - advance_vmpa(addr, 2); - - return true; - -} - - -/****************************************************************************** -* * -* 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. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 4) return false; - - data = part->data; - - switch (endian) - { - case SRE_LITTLE: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start] | (uint32_t)data[start + 1] << 8; - *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start + 3] | (uint32_t)data[start + 2] << 8; - *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - case SRE_MIDDLE: - assert(false); /* TODO */ - break; - - case SRE_BIG: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start + 3] | (uint32_t)data[start + 2] << 8; - *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start] | (uint32_t)data[start + 1] << 8; - *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - - } - - advance_vmpa(addr, 4); - - return true; - -} - - -/****************************************************************************** -* * -* 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. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 8) return false; - - data = part->data; - - switch (endian) - { - case SRE_LITTLE: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8; - *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24; - *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40; - *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8; - *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24; - *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40; - *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - case SRE_MIDDLE: - assert(false); /* TODO */ - break; - - case SRE_BIG: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8; - *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24; - *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40; - *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8; - *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24; - *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40; - *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - - } - - advance_vmpa(addr, 8); - - return true; - -} - - - - -const bin_t *g_binary_content_get(GBinContent *content, off_t *length) -{ - *length = content->parts[0].range.length; - - return content->parts[0].data; - -} - - diff --git a/src/glibext/gbincontent.h b/src/glibext/gbincontent.h deleted file mode 100644 index b1e9ec1..0000000 --- a/src/glibext/gbincontent.h +++ /dev/null @@ -1,103 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gbincontent.h - prototypes pour le chargement de données binaires en mémoire - * - * Copyright (C) 2015 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 Foobar. If not, see . - */ - - -#ifndef _GLIBEXT_GBINCONTENT_H -#define _GLIBEXT_GBINCONTENT_H - - -#include - - -#include "../arch/archbase.h" -#include "../arch/vmpa.h" -#include "../common/endianness.h" - - - -#define G_TYPE_BIN_CONTENT (g_binary_content_get_type()) -#define G_BIN_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_CONTENT, GBinContent)) -#define G_IS_BIN_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_CONTENT)) -#define G_BIN_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_CONTENT, GBinContentClass)) -#define G_IS_BIN_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_CONTENT)) -#define G_BIN_CONTENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_CONTENT, GBinContentClass)) - - -/* Content de données binaires quelconques (instance) */ -typedef struct _GBinContent GBinContent; - -/* Content de données binaires quelconques (classe) */ -typedef struct _GBinContentClass GBinContentClass; - - - -/* Indique le type défini par la GLib pour les contenus de données. */ -GType g_binary_content_get_type(void); - -/* Charge en mémoire le contenu d'un fichier donné. */ -GBinContent *g_binary_content_new_from_file(const char *); - -/* Fournit une empreinte unique (SHA256) pour les données. */ -const gchar *g_binary_content_get_cheksum(GBinContent *); - -/* Détermine le nombre d'octets lisibles. */ -phys_t g_binary_content_compute_size(const GBinContent *); - -/* Donne accès à une portion des données représentées. */ -const bin_t *g_binary_content_get_raw_access(const GBinContent *, vmpa2t *, phys_t); - -/* Fournit une portion des données représentées. */ -bool g_binary_content_get_raw(const GBinContent *, vmpa2t *, phys_t, bin_t *); - - - -/* Lit un nombre non signé sur quatre bits. */ -bool g_binary_content_read_u4(const GBinContent *, vmpa2t *, bool *, SourceEndian, uint8_t *); - -/* Lit un nombre non signé sur un octet. */ -bool g_binary_content_read_u8(const GBinContent *, vmpa2t *, uint8_t *); - -/* Lit un nombre non signé sur deux octets. */ -bool g_binary_content_read_u16(const GBinContent *, vmpa2t *, SourceEndian, uint16_t *); - -/* Lit un nombre non signé sur quatre octets. */ -bool g_binary_content_read_u32(const GBinContent *, vmpa2t *, SourceEndian, uint32_t *); - -/* Lit un nombre non signé sur huit octets. */ -bool g_binary_content_read_u64(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *); - - -#define g_binary_content_read_s4(c, a, l, e, v) g_binary_content_read_u4(c, a, l, e, (uint8_t *)v) -#define g_binary_content_read_s8(c, a, v) g_binary_content_read_u8(c, a, (uint8_t *)v) -#define g_binary_content_read_s16(c, a, e, v) g_binary_content_read_u16(c, a, e, (uint16_t *)v) -#define g_binary_content_read_s32(c, a, e, v) g_binary_content_read_u32(c, a, e, (uint32_t *)v) -#define g_binary_content_read_s64(c, a, e, v) g_binary_content_read_u64(c, a, e, (uint64_t *)v) - - - -const bin_t *g_binary_content_get(GBinContent *content, off_t *length); - - - - - -#endif /* _GLIBEXT_GBINCONTENT_H */ diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index e9e6fae..0da5ffd 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -29,8 +29,8 @@ #include -#include "gbincontent.h" #include "gbuffersegment.h" +#include "../analysis/content.h" #include "../arch/archbase.h" #include "../arch/vmpa.h" diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index 4d7d077..ff6bf05 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -517,7 +517,7 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin copy_vmpa(&pos, addr); - if (!g_binary_content_get_raw(content, &pos, get_mrange_length(range), (uint8_t *)text)) + if (!g_binary_content_read_raw(content, &pos, get_mrange_length(range), (uint8_t *)text)) { free(text); continue; diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h index f136d3f..acaf735 100644 --- a/src/plugins/plugin-int.h +++ b/src/plugins/plugin-int.h @@ -31,7 +31,7 @@ #include "plugin.h" #include "plugin-def.h" -#include "../glibext/gbincontent.h" +#include "../analysis/content.h" #include "../gui/panels/log.h" -- cgit v0.11.2-87-g4458