diff options
Diffstat (limited to 'plugins/elf')
-rw-r--r-- | plugins/elf/elf_def.h | 1 | ||||
-rw-r--r-- | plugins/elf/python/Makefile.am | 5 | ||||
-rw-r--r-- | plugins/elf/python/format.c | 68 | ||||
-rw-r--r-- | plugins/elf/python/program.c | 119 | ||||
-rw-r--r-- | plugins/elf/python/program.h | 41 | ||||
-rw-r--r-- | plugins/elf/python/section.c | 210 | ||||
-rw-r--r-- | plugins/elf/python/section.h | 47 | ||||
-rw-r--r-- | plugins/elf/python/translate.c | 478 | ||||
-rw-r--r-- | plugins/elf/python/translate.h | 59 |
9 files changed, 1026 insertions, 2 deletions
diff --git a/plugins/elf/elf_def.h b/plugins/elf/elf_def.h index 8c2bb45..06adff7 100644 --- a/plugins/elf/elf_def.h +++ b/plugins/elf/elf_def.h @@ -243,7 +243,6 @@ typedef union _elf_header /* Version 32 et 64 bits */ - typedef struct _elf32_phdr { uint32_t p_type; /* Type de segment */ diff --git a/plugins/elf/python/Makefile.am b/plugins/elf/python/Makefile.am index bcb739e..6080e86 100644 --- a/plugins/elf/python/Makefile.am +++ b/plugins/elf/python/Makefile.am @@ -5,7 +5,10 @@ libelfpython_la_SOURCES = \ constants.h constants.c \ dynamic.h dynamic.c \ format.h format.c \ - module.h module.c + module.h module.c \ + program.h program.c \ + section.h section.c \ + translate.h translate.c libelfpython_la_LDFLAGS = diff --git a/plugins/elf/python/format.c b/plugins/elf/python/format.c index a5e93d7..f1cf8d6 100644 --- a/plugins/elf/python/format.c +++ b/plugins/elf/python/format.c @@ -38,6 +38,9 @@ #include "constants.h" #include "dynamic.h" +#include "program.h" +#include "section.h" +#include "translate.h" #include "../format.h" @@ -45,6 +48,9 @@ /* Crée un nouvel objet Python de type 'ElfFormat'. */ static PyObject *py_elf_format_new(PyTypeObject *, PyObject *, PyObject *); +/* Fournit l'en-tête Elf correspondant au format. */ +static PyObject *py_elf_format_get_header(PyObject *, PyObject *); + /****************************************************************************** @@ -138,6 +144,33 @@ static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject /****************************************************************************** * * +* Paramètres : self = contenu binaire à manipuler. * +* args = argument non utilisé ici. * +* * +* Description : Fournit l'en-tête Elf correspondant au format. * +* * +* Retour : Structure Python créée pour l'occasion. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_elf_format_get_header(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvaille à retourner */ + GElfFormat *format; /* Version GLib du format */ + + format = G_ELF_FORMAT(pygobject_get(self)); + + result = translate_elf_header_to_python(format, g_elf_format_get_header(format)); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -151,6 +184,41 @@ static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject PyTypeObject *get_python_elf_format_type(void) { static PyMethodDef py_elf_format_methods[] = { + { + "get_header", py_elf_format_get_header, + METH_NOARGS, + "get_header($self, /)\n--\n\nGet the Elf header." + }, + { + "find_program_by_index", py_elf_format_find_program_by_index, + METH_VARARGS, + "find_program_by_index($self, index, /)\n--\n\nFind a segment using a given index." + }, + { + "find_program_by_type", py_elf_format_find_program_by_type, + METH_VARARGS, + "find_program_by_type($self, type, /)\n--\n\nFind a segment using a given type." + }, + { + "find_section_by_index", py_elf_format_find_section_by_index, + METH_VARARGS, + "find_section_by_index($self, index, /)\n--\n\nFind a section using a given index." + }, + { + "find_section_by_name", py_elf_format_find_section_by_name, + METH_VARARGS, + "find_section_by_name($self, name, /)\n--\n\nFind a section using a given name." + }, + { + "find_section_by_virtual_address", py_elf_format_find_section_by_virtual_address, + METH_VARARGS, + "find_section_by_virtual_address($self, addr, /)\n--\n\nFind a section using a given virtual address." + }, + { + "find_sections_by_type", py_elf_format_find_sections_by_type, + METH_VARARGS, + "find_sections_by_type($self, type, /)\n--\n\nFind sections using a given type." + }, { NULL } }; diff --git a/plugins/elf/python/program.c b/plugins/elf/python/program.c new file mode 100644 index 0000000..198a76b --- /dev/null +++ b/plugins/elf/python/program.c @@ -0,0 +1,119 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * program.c - prototypes pour l'équivalent Python du fichier "plugins/elf/program.c" + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "program.h" + + +#include <pygobject.h> + + +#include "translate.h" +#include "../program.h" + + + +/****************************************************************************** +* * +* Paramètres : self = format Elf à manipuler. * +* args = indice du segment visé. * +* * +* Description : Retrouve un segment par son indice. * +* * +* Retour : Elément trouvé ou rien (None). * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *py_elf_format_find_program_by_index(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvaille à retourner */ + GElfFormat *format; /* Version GLib du format */ + unsigned short int index; /* Indice du segment visé */ + int ret; /* Bilan de lecture des args. */ + elf_phdr program; /* Informations remontées */ + bool found; /* Recherches concluantes ? */ + + format = G_ELF_FORMAT(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "H", &index); + if (!ret) return NULL; + + found = find_elf_program_by_index(format, index, &program); + + if (found) + result = translate_elf_program_to_python(format, &program); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = format Elf à manipuler. * +* args = type du segment visé. * +* * +* Description : Retrouve un segment par son type. * +* * +* Retour : Elément trouvé ou rien (None). * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *py_elf_format_find_program_by_type(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvaille à retourner */ + GElfFormat *format; /* Version GLib du format */ + unsigned int type; /* Type de segment visé */ + int ret; /* Bilan de lecture des args. */ + elf_phdr program; /* Informations remontées */ + bool found; /* Recherches concluantes ? */ + + format = G_ELF_FORMAT(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "I", &type); + if (!ret) return NULL; + + found = find_elf_program_by_type(format, type, &program); + + if (found) + result = translate_elf_program_to_python(format, &program); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} diff --git a/plugins/elf/python/program.h b/plugins/elf/python/program.h new file mode 100644 index 0000000..20736c9 --- /dev/null +++ b/plugins/elf/python/program.h @@ -0,0 +1,41 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * program.h - prototypes pour l'équivalent Python du fichier "plugins/elf/program.h" + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_ELF_PYTHON_PROGRAM_H +#define _PLUGINS_ELF_PYTHON_PROGRAM_H + + +#include <Python.h> + + + +/* Retrouve un segment par son indice. */ +PyObject *py_elf_format_find_program_by_index(PyObject *, PyObject *); + +/* Retrouve un segment par son type. */ +PyObject *py_elf_format_find_program_by_type(PyObject *, PyObject *); + + + +#endif /* _PLUGINS_ELF_PYTHON_PROGRAM_H */ diff --git a/plugins/elf/python/section.c b/plugins/elf/python/section.c new file mode 100644 index 0000000..537babc --- /dev/null +++ b/plugins/elf/python/section.c @@ -0,0 +1,210 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * section.c - prototypes pour l'équivalent Python du fichier "plugins/elf/section.c" + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "section.h" + + +#include <malloc.h> +#include <pygobject.h> + + +#include "translate.h" +#include "../section.h" + + + +/****************************************************************************** +* * +* Paramètres : self = format Elf à manipuler. * +* args = indice de la section visée. * +* * +* Description : Retrouve une section par son indice. * +* * +* Retour : Elément trouvé ou rien (None). * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *py_elf_format_find_section_by_index(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvaille à retourner */ + GElfFormat *format; /* Version GLib du format */ + unsigned short int index; /* Indice de section visée */ + int ret; /* Bilan de lecture des args. */ + elf_shdr section; /* Informations remontées */ + bool found; /* Recherches concluantes ? */ + + format = G_ELF_FORMAT(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "H", &index); + if (!ret) return NULL; + + found = find_elf_section_by_index(format, index, §ion); + + if (found) + result = translate_elf_section_to_python(format, §ion); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = format Elf à manipuler. * +* args = désignation de la section visée. * +* * +* Description : Retrouve une section par son nom. * +* * +* Retour : Elément trouvé ou rien (None). * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *py_elf_format_find_section_by_name(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvaille à retourner */ + GElfFormat *format; /* Version GLib du format */ + PyObject *name; /* Etiquette à retrouver */ + int ret; /* Bilan de lecture des args. */ + elf_shdr section; /* Informations remontées */ + bool found; /* Recherches concluantes ? */ + + format = G_ELF_FORMAT(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "O!", &PyUnicode_Type, &name); + if (!ret) return NULL; + + found = find_elf_section_by_name(format, PyUnicode_DATA(name), §ion); + + if (found) + result = translate_elf_section_to_python(format, §ion); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = format Elf à manipuler. * +* args = adresse en mémoire de la section visée. * +* * +* Description : Retrouve une section par son adresse en mémoire. * +* * +* Retour : Elément trouvé ou rien (None). * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *py_elf_format_find_section_by_virtual_address(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvaille à retourner */ + GElfFormat *format; /* Version GLib du format */ + unsigned long long addr; /* Adresse en mémoire virtuelle*/ + int ret; /* Bilan de lecture des args. */ + elf_shdr section; /* Informations remontées */ + bool found; /* Recherches concluantes ? */ + + format = G_ELF_FORMAT(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "K", &addr); + if (!ret) return NULL; + + found = find_elf_section_by_virtual_address(format, addr, §ion); + + if (found) + result = translate_elf_section_to_python(format, §ion); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = format Elf à manipuler. * +* args = type des sections visées. * +* * +* Description : Retrouve des sections par leur type. * +* * +* Retour : Liste d'éléments trouvés, éventuellement vide. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *py_elf_format_find_sections_by_type(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvaille à retourner */ + GElfFormat *format; /* Version GLib du format */ + unsigned int type; /* Type de section visée */ + int ret; /* Bilan de lecture des args. */ + elf_shdr *sections; /* Liste des sections trouvées */ + size_t count; /* Taille de cette liste */ + size_t i; /* Boucle de parcours */ + PyObject *section; /* Traduction d'une section */ + + format = G_ELF_FORMAT(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "I", &type); + if (!ret) return NULL; + + find_elf_sections_by_type(format, type, §ions, &count); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + section = translate_elf_section_to_python(format, §ions[i]); + PyTuple_SetItem(result, i, section); + } + + if (sections != NULL) + free(sections); + + return result; + +} diff --git a/plugins/elf/python/section.h b/plugins/elf/python/section.h new file mode 100644 index 0000000..f5cc402 --- /dev/null +++ b/plugins/elf/python/section.h @@ -0,0 +1,47 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * section.h - prototypes pour l'équivalent Python du fichier "plugins/elf/section.h" + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_ELF_PYTHON_SECTION_H +#define _PLUGINS_ELF_PYTHON_SECTION_H + + +#include <Python.h> + + + +/* Retrouve une section par son indice. */ +PyObject *py_elf_format_find_section_by_index(PyObject *, PyObject *); + +/* Retrouve une section par son nom. */ +PyObject *py_elf_format_find_section_by_name(PyObject *, PyObject *); + +/* Retrouve une section par son adresse en mémoire. */ +PyObject *py_elf_format_find_section_by_virtual_address(PyObject *, PyObject *); + +/* Retrouve des sections par leur type. */ +PyObject *py_elf_format_find_sections_by_type(PyObject *, PyObject *); + + + +#endif /* _PLUGINS_ELF_PYTHON_SECTION_H */ diff --git a/plugins/elf/python/translate.c b/plugins/elf/python/translate.c new file mode 100644 index 0000000..2450e1a --- /dev/null +++ b/plugins/elf/python/translate.c @@ -0,0 +1,478 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * translate.c - conversion de structures ELF en objets Python + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "translate.h" + + +#include <assert.h> + + +#include <plugins/pychrysa/struct.h> + + +#include "../elf-int.h" +#include "../section.h" + + + +/****************************************************************************** +* * +* Paramètres : format = format Elf chargé sur lequel s'appuyer. * +* header = en-tête Elf à décrire en Python. * +* * +* Description : Traduit un en-tête Elf en Python. * +* * +* Retour : Structure mise en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *translate_elf_header_to_python(GElfFormat *format, const elf_header *header) +{ + PyObject *result; /* Construction à retourner */ + PyTypeObject *base; /* Modèle d'objet à créer */ + PyObject *attrib; /* Attribut à constituer */ + int ret; /* Bilan d'une mise en place */ + + base = get_python_py_struct_type(); + + result = PyObject_CallFunction((PyObject *)base, NULL); + assert(result != NULL); + + /* Signature et propriétés générales */ + + attrib = PyByteArray_FromStringAndSize((char *)ELF_HDR(format, *header, e_ident), EI_NIDENT); + + ret = PyDict_SetItemString(result, "e_ident", attrib); + if (ret != 0) goto tehtp_failed; + + /* Champs réguliers */ + +#define TRANSLATE_HEADER_FIELD(_f) \ + do \ + { \ + attrib = PyLong_FromUnsignedLongLong(ELF_HDR(format, *header, e_ ## _f)); \ + ret = PyDict_SetItemString(result, "e_" #_f, attrib); \ + if (ret != 0) goto tehtp_failed; \ + } \ + while (0); + + TRANSLATE_HEADER_FIELD(type); + TRANSLATE_HEADER_FIELD(machine); + TRANSLATE_HEADER_FIELD(version); + TRANSLATE_HEADER_FIELD(entry); + TRANSLATE_HEADER_FIELD(phoff); + TRANSLATE_HEADER_FIELD(shoff); + TRANSLATE_HEADER_FIELD(flags); + TRANSLATE_HEADER_FIELD(ehsize); + TRANSLATE_HEADER_FIELD(phentsize); + TRANSLATE_HEADER_FIELD(phnum); + TRANSLATE_HEADER_FIELD(shentsize); + TRANSLATE_HEADER_FIELD(shnum); + TRANSLATE_HEADER_FIELD(shstrndx); + + return result; + + tehtp_failed: + + Py_DECREF(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format Elf chargé sur lequel s'appuyer. * +* program = segment Elf à décrire en Python. * +* * +* Description : Traduit un segment Elf en Python. * +* * +* Retour : Structure mise en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *translate_elf_program_to_python(GElfFormat *format, const elf_phdr *program) +{ + PyObject *result; /* Construction à retourner */ + PyTypeObject *base; /* Modèle d'objet à créer */ + PyObject *attrib; /* Attribut à constituer */ + int ret; /* Bilan d'une mise en place */ + + base = get_python_py_struct_type(); + + result = PyObject_CallFunction((PyObject *)base, NULL); + assert(result != NULL); + +#define TRANSLATE_PROGRAM_FIELD(_f) \ + do \ + { \ + attrib = PyLong_FromUnsignedLongLong(ELF_PHDR(format, *program, p_ ## _f)); \ + ret = PyDict_SetItemString(result, "p_" #_f, attrib); \ + if (ret != 0) goto teptp_failed; \ + } \ + while (0); + + TRANSLATE_PROGRAM_FIELD(type); + TRANSLATE_PROGRAM_FIELD(offset); + TRANSLATE_PROGRAM_FIELD(vaddr); + TRANSLATE_PROGRAM_FIELD(paddr); + TRANSLATE_PROGRAM_FIELD(filesz); + TRANSLATE_PROGRAM_FIELD(memsz); + TRANSLATE_PROGRAM_FIELD(flags); + TRANSLATE_PROGRAM_FIELD(align); + + return result; + + teptp_failed: + + Py_DECREF(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format Elf chargé sur lequel s'appuyer. * +* section = section Elf à décrire en Python. * +* * +* Description : Traduit une section Elf en Python. * +* * +* Retour : Structure mise en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *translate_elf_section_to_python(GElfFormat *format, const elf_shdr *section) +{ + PyObject *result; /* Construction à retourner */ + PyTypeObject *base; /* Modèle d'objet à créer */ + PyObject *attrib; /* Attribut à constituer */ + int ret; /* Bilan d'une mise en place */ + elf_shdr strings; /* Section des descriptions */ + const char *name; /* Nom d'une section analysée */ + + base = get_python_py_struct_type(); + + result = PyObject_CallFunction((PyObject *)base, NULL); + assert(result != NULL); + + /* Champs réguliers */ + +#define TRANSLATE_SECTION_FIELD(_f) \ + do \ + { \ + attrib = PyLong_FromUnsignedLongLong(ELF_SHDR(format, *section, sh_ ## _f)); \ + ret = PyDict_SetItemString(result, "sh_" #_f, attrib); \ + if (ret != 0) goto testp_failed; \ + } \ + while (0); + + TRANSLATE_SECTION_FIELD(name); + TRANSLATE_SECTION_FIELD(type); + TRANSLATE_SECTION_FIELD(flags); + TRANSLATE_SECTION_FIELD(addr); + TRANSLATE_SECTION_FIELD(offset); + TRANSLATE_SECTION_FIELD(size); + TRANSLATE_SECTION_FIELD(link); + TRANSLATE_SECTION_FIELD(info); + TRANSLATE_SECTION_FIELD(addralign); + TRANSLATE_SECTION_FIELD(entsize); + + /* Liberté supplémentaire */ + + if (find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings)) + { + name = extract_name_from_elf_string_section(format, &strings, + ELF_SHDR(format, *section, sh_name)); + + if (name == NULL) + { + attrib = Py_None; + Py_INCREF(attrib); + } + + else + attrib = PyUnicode_FromString(name); + + ret = PyDict_SetItemString(result, "name", attrib); + if (ret != 0) goto testp_failed; + + } + + return result; + + testp_failed: + + Py_DECREF(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format Elf chargé sur lequel s'appuyer. * +* dyn = information du dynamisme Elf à décrire en Python. * +* * +* Description : Traduit une information du dynamisme Elf en Python. * +* * +* Retour : Structure mise en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *translate_elf_dyn_to_python(GElfFormat *format, const elf_dyn *dyn) +{ + PyObject *result; /* Construction à retourner */ + PyTypeObject *base; /* Modèle d'objet à créer */ + PyObject *attrib; /* Attribut à constituer */ + int ret; /* Bilan d'une mise en place */ + + base = get_python_py_struct_type(); + + result = PyObject_CallFunction((PyObject *)base, NULL); + assert(result != NULL); + +#define TRANSLATE_DYN_FIELD(_f) \ + do \ + { \ + attrib = PyLong_FromUnsignedLongLong(ELF_DYN(format, *dyn, d_ ## _f)); \ + ret = PyDict_SetItemString(result, "d_" #_f, attrib); \ + if (ret != 0) goto tedtp_failed; \ + } \ + while (0); + + TRANSLATE_DYN_FIELD(tag); + TRANSLATE_DYN_FIELD(un.d_val); + TRANSLATE_DYN_FIELD(un.d_ptr); + + return result; + + tedtp_failed: + + Py_DECREF(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format Elf chargé sur lequel s'appuyer. * +* symbol = symbole Elf à décrire en Python. * +* * +* Description : Traduit un symbole Elf en Python. * +* * +* Retour : Structure mise en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *translate_elf_symbol_to_python(GElfFormat *format, const elf_sym *symbol) +{ + PyObject *result; /* Construction à retourner */ + PyTypeObject *base; /* Modèle d'objet à créer */ + PyObject *attrib; /* Attribut à constituer */ + int ret; /* Bilan d'une mise en place */ + elf_shdr strings; /* Section des descriptions */ + const char *name; /* Nom d'une section analysée */ + + base = get_python_py_struct_type(); + + result = PyObject_CallFunction((PyObject *)base, NULL); + assert(result != NULL); + + /* Champs réguliers */ + +#define TRANSLATE_SYMBOL_FIELD(_f) \ + do \ + { \ + attrib = PyLong_FromUnsignedLongLong(ELF_SYM(format, *symbol, st_ ## _f)); \ + ret = PyDict_SetItemString(result, "st_" #_f, attrib); \ + if (ret != 0) goto testp_failed; \ + } \ + while (0); + + TRANSLATE_SYMBOL_FIELD(name); + TRANSLATE_SYMBOL_FIELD(value); + TRANSLATE_SYMBOL_FIELD(size); + TRANSLATE_SYMBOL_FIELD(info); + TRANSLATE_SYMBOL_FIELD(other); + TRANSLATE_SYMBOL_FIELD(shndx); + + /* Liberté supplémentaire */ + + if (find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings)) + { + name = extract_name_from_elf_string_section(format, &strings, + ELF_SYM(format, *symbol, st_name)); + + if (name == NULL) + { + attrib = Py_None; + Py_INCREF(attrib); + } + + else + attrib = PyUnicode_FromString(name); + + ret = PyDict_SetItemString(result, "name", attrib); + if (ret != 0) goto testp_failed; + + } + + return result; + + testp_failed: + + Py_DECREF(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format Elf chargé sur lequel s'appuyer. * +* rel = relocalisation Elf à décrire en Python. * +* * +* Description : Traduit une information de relocalisation Elf en Python. * +* * +* Retour : Structure mise en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *translate_elf_rel_to_python(GElfFormat *format, const elf_rel *rel) +{ + PyObject *result; /* Construction à retourner */ + PyTypeObject *base; /* Modèle d'objet à créer */ + PyObject *attrib; /* Attribut à constituer */ + int ret; /* Bilan d'une mise en place */ + + base = get_python_py_struct_type(); + + result = PyObject_CallFunction((PyObject *)base, NULL); + assert(result != NULL); + +#define TRANSLATE_REL_FIELD(_f) \ + do \ + { \ + attrib = PyLong_FromUnsignedLongLong(ELF_REL(format, *rel, r_ ## _f)); \ + ret = PyDict_SetItemString(result, "r_" #_f, attrib); \ + if (ret != 0) goto tertp_failed; \ + } \ + while (0); + + TRANSLATE_REL_FIELD(offset); + TRANSLATE_REL_FIELD(info); + + return result; + + tertp_failed: + + Py_DECREF(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format Elf chargé sur lequel s'appuyer. * +* note = note Elf à décrire en Python. * +* * +* Description : Traduit une note Elf en Python. * +* * +* Retour : Structure mise en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *translate_elf_note_to_python(GElfFormat *format, const elf_note *note) +{ + PyObject *result; /* Construction à retourner */ + PyTypeObject *base; /* Modèle d'objet à créer */ + PyObject *attrib; /* Attribut à constituer */ + int ret; /* Bilan d'une mise en place */ + + base = get_python_py_struct_type(); + + result = PyObject_CallFunction((PyObject *)base, NULL); + assert(result != NULL); + + attrib = PyLong_FromUnsignedLongLong(note->type); + + ret = PyDict_SetItemString(result, "type", attrib); + if (ret != 0) goto tentp_failed; + + if (note->name == NULL) + { + attrib = Py_None; + Py_INCREF(attrib); + } + + else + attrib = PyUnicode_FromString(note->name); + + ret = PyDict_SetItemString(result, "name", attrib); + if (ret != 0) goto tentp_failed; + + if (note->desc == NULL) + { + attrib = Py_None; + Py_INCREF(attrib); + } + + else + attrib = PyUnicode_FromString(note->desc); + + ret = PyDict_SetItemString(result, "desc", attrib); + if (ret != 0) goto tentp_failed; + + return result; + + tentp_failed: + + Py_DECREF(result); + + return NULL; + +} diff --git a/plugins/elf/python/translate.h b/plugins/elf/python/translate.h new file mode 100644 index 0000000..02ddf2d --- /dev/null +++ b/plugins/elf/python/translate.h @@ -0,0 +1,59 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * translate.h - prototypes pour la conversion de structures ELF en objets Python + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_ELF_PYTHON_TRANSLATE_H +#define _PLUGINS_ELF_PYTHON_TRANSLATE_H + + +#include <Python.h> + + +#include "../format.h" + + + +/* Traduit un en-tête Elf en Python. */ +PyObject *translate_elf_header_to_python(GElfFormat *, const elf_header *); + +/* Traduit un segment Elf en Python. */ +PyObject *translate_elf_program_to_python(GElfFormat *, const elf_phdr *); + +/* Traduit une section Elf en Python. */ +PyObject *translate_elf_section_to_python(GElfFormat *, const elf_shdr *); + +/* Traduit une information du dynamisme Elf en Python. */ +PyObject *translate_elf_dyn_to_python(GElfFormat *, const elf_dyn *); + +/* Traduit un symbole Elf en Python. */ +PyObject *translate_elf_symbol_to_python(GElfFormat *, const elf_sym *); + +/* Traduit une information de relocalisation Elf en Python. */ +PyObject *translate_elf_rel_to_python(GElfFormat *, const elf_rel *); + +/* Traduit une note Elf en Python. */ +PyObject *translate_elf_note_to_python(GElfFormat *, const elf_note *); + + + +#endif /* _PLUGINS_ELF_PYTHON_TRANSLATE_H */ |