From 0f3bbcb376ee4f76142ac4ddf729403fecac2641 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 13 Jun 2013 22:46:38 +0000
Subject: Fixed Elf format support.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@353 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                               |  32 +++++++
 configure.ac                            |   1 +
 plugins/pychrysa/format/Makefile.am     |   5 +-
 plugins/pychrysa/format/elf/Makefile.am |  17 ++++
 plugins/pychrysa/format/elf/elf.c       | 150 ++++++++++++++++++++++++++++++++
 plugins/pychrysa/format/elf/elf.h       |  39 +++++++++
 plugins/pychrysa/format/elf/module.c    |  68 +++++++++++++++
 plugins/pychrysa/format/elf/module.h    |  39 +++++++++
 plugins/pychrysa/format/module.c        |   2 +
 plugins/python/androperms/androperms.py |   6 +-
 plugins/python/androperms/panel.py      |   5 ++
 src/analysis/binaries/file.c            |  43 +++++++++
 src/analysis/binary.c                   |   3 +
 src/format/format.c                     |   2 -
 14 files changed, 407 insertions(+), 5 deletions(-)
 create mode 100644 plugins/pychrysa/format/elf/Makefile.am
 create mode 100644 plugins/pychrysa/format/elf/elf.c
 create mode 100644 plugins/pychrysa/format/elf/elf.h
 create mode 100644 plugins/pychrysa/format/elf/module.c
 create mode 100644 plugins/pychrysa/format/elf/module.h

diff --git a/ChangeLog b/ChangeLog
index 18ee7cc..12453be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+13-06-14  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Add the new Makfile from the 'plugins/pychrysa/format/elf' directory
+	to AC_CONFIG_FILES.
+
+	* plugins/pychrysa/format/elf/elf.c:
+	* plugins/pychrysa/format/elf/elf.h:
+	* plugins/pychrysa/format/elf/Makefile.am:
+	* plugins/pychrysa/format/elf/module.c:
+	* plugins/pychrysa/format/elf/module.h:
+	New entries: create basic Python Elf support.
+
+	* plugins/pychrysa/format/Makefile.am:
+	Add elf/libpychrysaformatelf.la to libpychrysaformat_la_LIBADD.
+
+	* plugins/pychrysa/format/module.c:
+	Load the elf module.
+
+	* plugins/python/androperms/androperms.py:
+	* plugins/python/androperms/panel.py:
+	Only process Dex binaries.
+
+	* src/analysis/binaries/file.c:
+	Load file content.
+
+	* src/analysis/binary.c:
+	Free data on unload.
+
+	* src/format/format.c:
+	Typo.
+
 13-06-10  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/glibext/gbuffersegment.c:
diff --git a/configure.ac b/configure.ac
index 0ada63a..cbd1d3c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -249,6 +249,7 @@ AC_CONFIG_FILES([Makefile
                  plugins/pychrysa/debug/Makefile
                  plugins/pychrysa/format/Makefile
                  plugins/pychrysa/format/dex/Makefile
+                 plugins/pychrysa/format/elf/Makefile
                  plugins/pychrysa/glibext/Makefile
                  plugins/pychrysa/gtkext/Makefile
                  plugins/pychrysa/gui/Makefile
diff --git a/plugins/pychrysa/format/Makefile.am b/plugins/pychrysa/format/Makefile.am
index 9a48749..46d4d23 100644
--- a/plugins/pychrysa/format/Makefile.am
+++ b/plugins/pychrysa/format/Makefile.am
@@ -7,7 +7,8 @@ libpychrysaformat_la_SOURCES =			\
 	module.h module.c
 
 libpychrysaformat_la_LIBADD =			\
-	dex/libpychrysaformatdex.la
+	dex/libpychrysaformatdex.la			\
+	elf/libpychrysaformatelf.la
 
 
 libpychrysaformat_la_LDFLAGS = 
@@ -20,4 +21,4 @@ AM_CPPFLAGS =
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = dex
+SUBDIRS = dex elf
diff --git a/plugins/pychrysa/format/elf/Makefile.am b/plugins/pychrysa/format/elf/Makefile.am
new file mode 100644
index 0000000..e2731cb
--- /dev/null
+++ b/plugins/pychrysa/format/elf/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES = libpychrysaformatelf.la
+
+libpychrysaformatelf_la_SOURCES =		\
+	elf.h elf.c							\
+	module.h module.c
+
+
+libpychrysaformatelf_la_LDFLAGS = 
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+	-I../../../../src
+
+AM_CPPFLAGS = 
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/pychrysa/format/elf/elf.c b/plugins/pychrysa/format/elf/elf.c
new file mode 100644
index 0000000..16baf5d
--- /dev/null
+++ b/plugins/pychrysa/format/elf/elf.c
@@ -0,0 +1,150 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * elf.c - équivalent Python du fichier "format/elf/elf.c"
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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 "elf.h"
+
+
+#include <pygobject.h>
+
+
+#include <format/elf/elf-int.h>
+
+
+#include "../../quirks.h"
+
+
+
+/* Crée un nouvel objet Python de type 'ElfFormat'. */
+static PyObject *py_elf_format_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 'ElfFormat'.             *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    const bin_t *content;                   /* Données binaires            */
+    int length;                           /* Quantité de ces données     */
+    int ret;                                /* Bilan de lecture des args.  */
+    GBinFormat *format;                     /* Version GLib du format      */
+
+    ret = PyArg_ParseTuple(args, "s#", &content, &length);
+    if (!ret) Py_RETURN_NONE;
+
+    format = g_elf_format_new(content, length);
+    if (format == NULL) Py_RETURN_NONE;
+
+    result = pygobject_new(G_OBJECT(format));
+    //g_object_unref(format);
+
+    return (PyObject *)result;
+
+}
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.format.elf.ElfFormat'. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_elf_format(PyObject *module)
+{
+    PyObject *parent_mod;                   /* Accès au module parent      */
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyMethodDef py_elf_format_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_elf_format_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_elf_format_type = {
+
+        PyObject_HEAD_INIT(NULL)
+
+        .tp_name        = "pychrysalide.format.elf.ElfFormat",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide Elf format",
+
+        .tp_methods     = py_elf_format_methods,
+        .tp_getset      = py_elf_format_getseters,
+        .tp_new         = (newfunc)py_elf_format_new
+
+    };
+
+    parent_mod = PyImport_ImportModule("pychrysalide.format");
+    if (parent_mod == NULL) return false;
+
+    py_elf_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "ExeFormat");
+    Py_DECREF(parent_mod);
+
+    if (PyType_Ready(&py_elf_format_type) < 0)
+        return false;
+
+    Py_INCREF(&py_elf_format_type);
+    ret = PyModule_AddObject(module, "ElfFormat", (PyObject *)&py_elf_format_type);
+
+    parent_mod = PyImport_ImportModule("pychrysalide.format");
+    if (parent_mod == NULL) return false;
+
+    pygobject_register_class(module, "GElfFormat", G_TYPE_ELF_FORMAT, &py_elf_format_type,
+                             Py_BuildValue("(OO)", py_elf_format_type.tp_base,
+                                           PyObject_GetAttrString(parent_mod, "BinFormat")));
+
+    Py_DECREF(parent_mod);
+
+    return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/format/elf/elf.h b/plugins/pychrysa/format/elf/elf.h
new file mode 100644
index 0000000..2b87970
--- /dev/null
+++ b/plugins/pychrysa/format/elf/elf.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * elf.h - prototypes pour l'équivalent Python du fichier "format/elf/elf.h"
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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_FORMAT_ELF_ELF_H
+#define _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Prend en charge l'objet 'pychrysalide.format.elf.ElfFormat'. */
+bool register_python_elf_format(PyObject *module);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H */
diff --git a/plugins/pychrysa/format/elf/module.c b/plugins/pychrysa/format/elf/module.c
new file mode 100644
index 0000000..ed515ea
--- /dev/null
+++ b/plugins/pychrysa/format/elf/module.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire elf en tant que module
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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 "elf.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Ajoute le module 'format.elf' au module Python.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_format_elf_module_to_python_module(PyObject *super)
+{
+    bool result;
+    PyObject *module;
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyMethodDef py_format_elf_methods[] = {
+        { NULL }
+    };
+
+    module = Py_InitModule("pychrysalide.format.elf", py_format_elf_methods);
+    if (module == NULL) return false;
+
+    Py_INCREF(module);
+    ret = PyModule_AddObject(super, "pychrysalide.format.elf", module);
+
+    result = (ret == 0);
+
+    if (ret != 0) /* ... */;
+
+    result &= register_python_elf_format(module);
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/format/elf/module.h b/plugins/pychrysa/format/elf/module.h
new file mode 100644
index 0000000..bd2a0d4
--- /dev/null
+++ b/plugins/pychrysa/format/elf/module.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire elf en tant que module
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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_FORMAT_ELF_MODULE_H
+#define _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'format.elf' au module Python. */
+bool add_format_elf_module_to_python_module(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H */
diff --git a/plugins/pychrysa/format/module.c b/plugins/pychrysa/format/module.c
index 3045dac..14bb9bd 100644
--- a/plugins/pychrysa/format/module.c
+++ b/plugins/pychrysa/format/module.c
@@ -28,6 +28,7 @@
 #include "executable.h"
 #include "format.h"
 #include "dex/module.h"
+#include "elf/module.h"
 
 
 
@@ -67,6 +68,7 @@ bool add_format_module_to_python_module(PyObject *super)
     result &= register_python_executable_format(module);
 
     result &= add_format_dex_module_to_python_module(module);
+    result &= add_format_elf_module_to_python_module(module);
 
     return result;
 
diff --git a/plugins/python/androperms/androperms.py b/plugins/python/androperms/androperms.py
index ddccb8a..f68b9a5 100644
--- a/plugins/python/androperms/androperms.py
+++ b/plugins/python/androperms/androperms.py
@@ -5,6 +5,7 @@ from manifest import AndroidManifest
 from db import PermsDataBase
 from panel import PermsPanel
 from pychrysalide import Plugin
+from pychrysalide.format.dex import DexFormat
 from xml.dom import minidom
 
 import re
@@ -31,6 +32,10 @@ class AndroPerms(Plugin):
     def execute_on_binary(self, binary, action):
         """Process once a binary is disassembled."""
 
+        fmt = binary.get_format()
+        if not isinstance(fmt, DexFormat):
+            return False
+
         zf = zipfile.ZipFile(binary.get_filename())
 
         f = zf.open('AndroidManifest.xml', 'r')
@@ -56,7 +61,6 @@ class AndroPerms(Plugin):
         db = PermsDataBase()
         db.filter_permissions(plist)
 
-        fmt = binary.get_format()
         instrs = binary.get_instructions()
         buf = binary.disassembled_buffer
 
diff --git a/plugins/python/androperms/panel.py b/plugins/python/androperms/panel.py
index b892339..8f8e925 100644
--- a/plugins/python/androperms/panel.py
+++ b/plugins/python/androperms/panel.py
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 
+from pychrysalide.format.dex import DexFormat
 from pychrysalide.gui.panels import PanelItem
 
 import gtk
@@ -88,6 +89,10 @@ class PermsPanel(PanelItem):
 
         self._store.clear()
 
+        fmt = binary.get_format()
+        if not isinstance(fmt, DexFormat):
+            return False
+
         used = self._perms[binary]
 
         for p in used:
diff --git a/src/analysis/binaries/file.c b/src/analysis/binaries/file.c
index 9c43ed5..688b65a 100644
--- a/src/analysis/binaries/file.c
+++ b/src/analysis/binaries/file.c
@@ -24,7 +24,11 @@
 #include "file.h"
 
 
+#include <fcntl.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
 
 
 #include "../binary-int.h"
@@ -156,6 +160,10 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename)
 {
     GFileBinary *result;                    /* Adresse à retourner         */
     GLoadedBinary *loaded;                  /* Version parente             */
+    int fd;                                 /* Descripteur du fichier      */
+    struct stat info;                       /* Informations sur le fichier */
+    int ret;                                /* Bilan d'un appel            */
+    void *content;                          /* Contenu brut du fichier     */
 
     result = g_object_new(G_TYPE_FILE_BINARY, NULL);
     loaded = G_LOADED_BINARY(result);
@@ -164,6 +172,41 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename)
 
     result->filename = strdup(filename);
 
+    /* Récupération des données */
+
+    fd = open(filename, O_RDONLY);
+    if (fd == -1)
+    {
+        perror("open");
+        goto lbf_error;
+    }
+
+    ret = fstat(fd, &info);
+    if (ret == -1)
+    {
+        close(fd);
+        perror("fstat");
+        goto lbf_error;
+    }
+
+    content = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (content == MAP_FAILED)
+    {
+        close(fd);
+        perror("mmap");
+        goto lbf_error;
+    }
+
+    loaded->bin_length = info.st_size;
+    loaded->bin_data = (bin_t *)malloc(info.st_size);
+
+    memcpy(loaded->bin_data, content, info.st_size);
+
+    munmap(content, info.st_size);
+    close(fd);
+
+    /* Chargement du binaire */
+
     loaded->format = G_EXE_FORMAT(load_new_format(FMT_EXEC, filename,
                                                   &loaded->bin_data, &loaded->bin_length));
 
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index e3b3e9d..05c4e99 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -151,6 +151,9 @@ static void g_loaded_binary_dispose(GLoadedBinary *binary)
     if (binary->proc != NULL)
         g_object_unref(G_OBJECT(binary->proc));
 
+    if (binary->bin_data != NULL)
+        free(binary->bin_data);
+
     /* TODO... */
 
     G_OBJECT_CLASS(g_loaded_binary_parent_class)->dispose(G_OBJECT(binary));
diff --git a/src/format/format.c b/src/format/format.c
index 846d038..d30eb66 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -531,9 +531,7 @@ GBinFormat *load_new_format(FormatType type, const char *filename, bin_t **conte
         if (_formats[i].type == type && _formats[i].match(type, *content, *length))
         {
             log_variadic_message(LMT_INFO, _("%s is matching..."), _formats[i].name);
-
             result = _formats[i].load(*content, *length);
-
         }
 
     return result;
-- 
cgit v0.11.2-87-g4458