diff options
Diffstat (limited to 'src/binary.c')
-rw-r--r-- | src/binary.c | 596 |
1 files changed, 0 insertions, 596 deletions
diff --git a/src/binary.c b/src/binary.c deleted file mode 100644 index 85196d9..0000000 --- a/src/binary.c +++ /dev/null @@ -1,596 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * binary.c - traitement des flots de code binaire - * - * Copyright (C) 2008 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "binary.h" - - -#include <fcntl.h> -#include <malloc.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> - - -#include "analysis/line_code.h" -#include "analysis/line_comment.h" -#include "analysis/line_prologue.h" -#include "analysis/prototype.h" -#include "arch/processor.h" - - -#include "format/dbg_format.h" -#include "format/exe_format.h" - - - - -#ifndef _ -# define _(str) str -#endif - - - -extern bool find_line_info(const uint8_t *content, off_t *size); - - - - -/* Description d'un fichier binaire */ -struct _openida_binary -{ - char *filename; /* Fichier chargé en mémoire */ - - off_t bin_length; /* Taille des données brutes */ - uint8_t *bin_data; /* Données binaires brutes */ - - exe_format *format; /* Format du binaire */ - asm_processor *proc; /* Architecture du binaire */ - - GRenderingLine *lines; /* Lignes de rendu en place */ - disass_options options; /* Options de désassemblage */ - -}; - - -/* Charge en mémoire le contenu d'un fichier à partir d'XML. */ -openida_binary *load_binary_file_from_xml(xmlXPathObjectPtr); - -/* Charge en mémoire le contenu d'un fichier. */ -uint8_t *map_binary_file(const char *, off_t *); - -/* Construit la description d'introduction du désassemblage. */ -GRenderingLine *build_binary_prologue(const char *, const uint8_t *, off_t); - -/* Procède au désassemblage basique d'un contenu binaire. */ -void disassemble_openida_binary(openida_binary *); - - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier à charger. * -* * -* Description : Charge en mémoire le contenu d'un fichier. * -* * -* Retour : Adresse de la représentation ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -openida_binary *load_binary_file(const char *filename) -{ - openida_binary *result; /* Adresse à retourner */ - - result = (openida_binary *)calloc(1, sizeof(openida_binary)); - - result->filename = strdup(filename); - - result->bin_data = map_binary_file(filename, &result->bin_length); - if (result->bin_data == NULL) goto lbf_error; - - result->format = load_new_exe_format(result->bin_data, result->bin_length); - if (result->format == NULL) goto lbf_error; - - - result->proc = create_x86_processor(); - - - result->options.show_address = true; - result->options.show_code = true; - - result->options.format = result->format; - result->options.proc = result->proc; - - disassemble_openida_binary(result); - - return result; - - lbf_error: - - unload_binary_file(result); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathObj = point de lecture de tous les éléments. * -* * -* Description : Charge en mémoire le contenu d'un fichier à partir d'XML. * -* * -* Retour : Adresse de la représentation ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -openida_binary *load_binary_file_from_xml(xmlXPathObjectPtr xpathObj) -{ - openida_binary *result; /* Adresse à retourner */ - - int i; - - result = (openida_binary *)calloc(1, sizeof(openida_binary)); - - for (i = 0; i < XPATH_OBJ_NODES_COUNT(xpathObj); i++) - if (xmlStrEqual(NODE_FROM_PATH_OBJ(xpathObj, i)->name, BAD_CAST "Filename")) - result->filename = qck_get_node_text_value(NODE_FROM_PATH_OBJ(xpathObj, i)); - - - - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : binary = élément binaire à supprimer de la mémoire. * -* * -* Description : Décharge de la mémoire le contenu d'un fichier. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_binary_file(openida_binary *binary) -{ - free(binary->filename); - - free(binary); - -} - - -/****************************************************************************** -* * -* Paramètres : binary = élément binaire à consulter. * -* * -* Description : Fournit le fichier correspondant à l'élément binaire. * -* * -* Retour : Nom de fichier avec chemin absolu. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *openida_binary_get_filename(const openida_binary *binary) -{ - return binary->filename; - -} - - -/****************************************************************************** -* * -* Paramètres : binary = élément binaire à consulter. * -* * -* Description : Fournit une description humaine d'un élément binaire. * -* * -* Retour : Chaîne de caractères humainenement lisible de représentation.* -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *openida_binary_to_string(const openida_binary *binary) -{ - return binary->filename; - -} - - - - -/****************************************************************************** -* * -* Paramètres : binary = élément binaire à consulter. * -* * -* Description : Fournit les lignes de rendu issues du désassemblage. * -* * -* Retour : Lignes issues du désassemblage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GRenderingLine *get_openida_binary_lines(const openida_binary *binary) -{ - return binary->lines; - -} - - - - - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour mener les parcours. * -* base = première partie de l'expression XPath d'accès. * -* index = indice de la élément dans la liste des voisins. * -* * -* Description : Lit un élément binaire depuis un fichier XML. * -* * -* Retour : Représentation mise en place à libérer de la mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -openida_binary *read_openida_binary_from_xml(xmlXPathContextPtr xpathCtx, const char *base, unsigned int index) -{ - openida_binary *result; /* Représentation à retourner */ - size_t expr_len; /* Taille d'une expression */ - char *expr; /* Chemin XPath reconstitué */ - xmlXPathObjectPtr xpathObj; /* Cible d'une recherche */ - char *value; /* Type d'élément rencontré */ - size_t sub_expr_len; /* Taille d'une expression #2 */ - char *sub_expr; /* Chemin XPath reconstitué #2 */ - int i; /* Boucle de parcours */ - - result = NULL; - - /* S'occupe en premier lieu du niveau courant */ - - expr_len = strlen(base) + strlen("/*[position()=") + strlen("4294967295") /* UINT_MAX */ + strlen("]") + 1; - - expr = (char *)calloc(expr_len, sizeof(char)); - snprintf(expr, expr_len, "%s/*[position()=%u]", base, index); - - xpathObj = get_node_xpath_object(xpathCtx, expr); - - value = qck_get_node_prop_value(NODE_FROM_PATH_OBJ(xpathObj, 0), "type"); - - xmlXPathFreeObject(xpathObj); - - if (value == NULL) goto robfx_err1; - - /* Raffinement au second passage */ - - sub_expr_len = expr_len + strlen("/*"); - sub_expr = (char *)calloc(sub_expr_len, sizeof(char)); - snprintf(sub_expr, sub_expr_len, "%s/*", expr); - - xpathObj = get_node_xpath_object(xpathCtx, sub_expr); - - if (strcmp(value, "file") == 0) result = load_binary_file_from_xml(xpathObj); - - xmlXPathFreeObject(xpathObj); - - free(sub_expr); - - robfx_err1: - - free(expr); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : binary = élément binaire à traiter. * -* writer = rédacteur dédié à l'écriture. * -* * -* Description : Ecrit une sauvegarde du binaire dans un fichier XML. * -* * -* Retour : true si l'opération a bien tourné, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_openida_binary_to_xml(const openida_binary *binary, xmlTextWriterPtr writer) -{ - bool result; /* Bilan à faire remonter */ - - result = open_xml_element(writer, "Binary"); - - result &= write_xml_attribute(writer, "type", "file"); - - result &= write_xml_element_with_content(writer, "Filename", "%s", binary->filename); - - result &= close_xml_element(writer); - - return result; - -} - - - - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier à charger. * -* length = taille des données mises en mémoire. [OUT] * -* * -* Description : Charge en mémoire le contenu d'un fichier. * -* * -* Retour : Adresse du contenu binaire ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -uint8_t *map_binary_file(const char *filename, off_t *length) -{ - uint8_t *result; /* Données à retourner */ - int fd; /* Fichier ouvert en lecture */ - struct stat info; /* Informations sur le fichier */ - int ret; /* Bilan d'un appel */ - - fd = open(filename, 0, O_RDONLY); - if (fd == -1) - { - perror("open()"); - return NULL; - } - - ret = fstat(fd, &info); - if (ret == -1) - { - perror("fstat()"); - close(fd); - return NULL; - } - - *length = info.st_size; - - result = (uint8_t *)mmap(NULL, *length, PROT_READ, MAP_PRIVATE, fd, 0); - if (result == MAP_FAILED) - { - perror("mmap()"); - result = NULL; - } - - ret = close(fd); - if (ret == -1) - perror("close()"); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier chargé. * -* data = données en mémoire pour l'empreinte. * -* length = quantité de données à prendre en compte. * -* * -* Description : Construit la description d'introduction du désassemblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GRenderingLine *build_binary_prologue(const char *filename, const uint8_t *data, off_t length) -{ - GRenderingLine *result; /* Contenu à renvoyer */ - size_t len; /* Taille du texte */ - char *content; /* Contenu textuel d'une ligne */ - GRenderingLine *line; /* Représentation à ajouter */ - GChecksum *checksum; /* Calcul de l'empreinte */ - const gchar *hex; /* Valeur hexadécimale du SHA */ - - result = NULL;/* FIXME DL_LIST_HEAD_INIT( **/ - - line = g_prologue_line_new("Disassembly generated by OpenIDA"); - g_rendering_line_add_to_lines(&result, line); - - line = g_prologue_line_new("OpenIDA is free software - © 2008-2009 Cyrille Bagard"); - g_rendering_line_add_to_lines(&result, line); - - line = g_prologue_line_new(""); - g_rendering_line_add_to_lines(&result, line); - - /* Fichier */ - - len = strlen(_("File: ")) + strlen(filename); - content = (char *)calloc(len + 1, sizeof(char)); - - snprintf(content, len + 1, "%s%s", _("File: "), filename); - - line = g_prologue_line_new(content); - g_rendering_line_add_to_lines(&result, line); - - free(content); - - /* Checksum SHA256 */ - - checksum = g_checksum_new(G_CHECKSUM_SHA256); - - g_checksum_update(checksum, data, length); - hex = g_checksum_get_string(checksum); - - len = strlen(_("Sha256: ")) + strlen(hex); - content = (char *)calloc(len + 1, sizeof(char)); - - snprintf(content, len + 1, "%s%s", _("Sha256: "), hex); - - g_checksum_free(checksum); - - line = g_prologue_line_new(content); - g_rendering_line_add_to_lines(&result, line); - - free(content); - - line = g_prologue_line_new(""); - g_rendering_line_add_to_lines(&result, line); - - line = g_prologue_line_new(""); - g_rendering_line_add_to_lines(&result, line); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : binary = binaire dont le contenu est à analyser. * -* * -* Description : Procède au désassemblage basique d'un contenu binaire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void disassemble_openida_binary(openida_binary *binary) -{ - asm_instr *instr; - - bin_routine **routines; /* Liste des routines trouvées */ - size_t routines_count; /* Nombre de ces routines */ - - bin_part **parts; - size_t parts_count; - - - - GRenderingLine *line; - - - off_t start; - off_t pos; - off_t len; - - uint64_t base = 0; - uint64_t offset = 0; - - size_t i; - - size_t k; - - uint64_t routine_offset; /* Point de départ de routine */ - char *routine_desc; /* Prototype d'une routine */ - - - - - binary->lines = build_binary_prologue(binary->filename, binary->bin_data, binary->bin_length); - - - - - - routines = get_all_exe_routines(binary->format, &routines_count); - - - parts = get_elf_default_code_parts(binary->format, &parts_count); - qsort(parts, parts_count, sizeof(bin_part *), compare_bin_parts); - - - - - for (i = 0; i < parts_count; i++) - { - get_bin_part_values(parts[i], &pos, &len, &base); - - /* Décodage des instructions */ - - start = pos; - pos = 0; - - while (pos < len) - { - offset = base + pos; - - - instr = decode_instruction(binary->proc, &binary->bin_data[start], &pos, len, start, offset); - - - line = g_code_line_new(offset, instr, &binary->options); - g_rendering_line_add_to_lines(&binary->lines, line); - - } - - /* Ajout des prototypes de fonctions */ - - for (k = 0; k < routines_count; k++) - { - routine_offset = get_binary_routine_offset(routines[k]); - - if (!(base <= routine_offset && routine_offset < (base + len))) continue; - - routine_desc = routine_to_string(routines[k]); - - line = g_comment_line_new(routine_offset, routine_desc, &binary->options); - g_rendering_line_insert_into_lines(&binary->lines, line, true); - - free(routine_desc); - - } - - } - - - - - - - line = g_rendering_line_find_by_offset(binary->lines, get_exe_entry_point(binary->format)); - g_rendering_line_add_flag(line, RLF_ENTRY_POINT); - - - - -} |