/* Chrysalide - Outil d'analyse de fichiers binaires * decompiler.c - encadrement des phases de décompilation * * Copyright (C) 2010-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 Foobar. If not, see . */ #include "decompiler.h" #include #include #include #include #include "cmerge.h" #include "il.h" #include "reduce.h" #include "../../decomp/output.h" #include "../../decomp/expr/block.h" #include "../../decomp/lang/java.h" /* FIXME : remme ! */ #include "../../format/format.h" /* Construit la description d'introduction de la décompilation. */ static void build_decomp_prologue(GCodeBuffer *, const char *); /* S'assure de la transcription de routines en expressions. */ static void prepare_all_routines_for_decomp(const GLoadedBinary *, const char *); /****************************************************************************** * * * Paramètres : buffer = tampon de destination pour le texte. * * filename = nom du fichier ciblé à décompiler. * * * * Description : Construit la description d'introduction de la décompilation. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void build_decomp_prologue(GCodeBuffer *buffer, const char *filename) { GLangOutput *output; /* Modèle de sortie adéquat */ GBufferLine *line; /* Ligne de destination */ size_t len; /* Taille du texte */ char *content; /* Contenu textuel d'une ligne */ output = g_java_output_new(); line = g_lang_output_start_comments(output, buffer); if (line != NULL) g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Introduction */ line = g_lang_output_continue_comments(output, buffer, SL(_("Binary data decompiled by Chrysalide"))); g_buffer_line_start_merge_at(line, BLC_PHYSICAL); line = g_lang_output_continue_comments(output, buffer, SL(_("Chrysalide is free software - © 2008-2012 Cyrille Bagard"))); g_buffer_line_start_merge_at(line, BLC_PHYSICAL); line = g_lang_output_continue_comments(output, buffer, NULL, 0); g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Fichier */ if (filename == NULL) filename = _("whole binary"); len = strlen(_("File: ")) + strlen(filename) + 1; content = (char *)calloc(len, sizeof(char)); snprintf(content, len, "%s%s", _("File: "), filename); line = g_lang_output_continue_comments(output, buffer, content, len - 1); g_buffer_line_start_merge_at(line, BLC_PHYSICAL); free(content); /* Ligne de séparation */ line = g_lang_output_continue_comments(output, buffer, NULL, 0); g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Conclusion */ line = g_lang_output_end_comments(output, buffer); if (line != NULL) g_buffer_line_start_merge_at(line, BLC_PHYSICAL); g_object_unref(G_OBJECT(output)); } /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * * filename = nom du fichier source à cibler. * * * * Description : S'assure de la transcription de routines en expressions. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void prepare_all_routines_for_decomp(const GLoadedBinary *binary, const char *filename) { GExeFormat *format; /* Format du binaire fourni */ GArchProcessor *proc; /* Architecture du binaire */ GBinRoutine **routines; size_t count; size_t i; //GDecContext *context; /* Contexte pour la décompil. */ GDecInstruction *dinstrs; //GArchInstruction *instrs; /* Instructions natives */ //vmpa_t max; /* Première adresse à écarter */ format = g_loaded_binary_get_format(binary); proc = NULL;//get_arch_processor_from_format(G_EXE_FORMAT(format)); routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &count); for (i = 0; i < count; i++) { /* context = g_arch_processor_get_decomp_context(proc); g_object_set_data(G_OBJECT(context), "format", format); g_object_set_data(G_OBJECT(context), "routine", routines[i]); g_dec_context_set_max_address(context, max); */ /* instrs = g_binary_routine_get_instructions(routines[i]); max = g_binary_routine_get_address(routines[i]) + g_binary_routine_get_size(routines[i]); */ //printf("\n##### DECOMPILE '%s' #####\n", g_binary_routine_to_string(routines[i])); dinstrs = decompiled_routine_instructions(routines[i], format, proc); /* dinstrs = build_decompiled_block(instrs, g_binary_routine_get_address(routines[i]), max, VMPA_MAX, context); */ //instr = g_binary_format_decompile_routine(G_BIN_FORMAT(format), routines[i], context); //merge_lonely_conditions(dinstrs); /////reduce_used_variables(dinstrs); g_expr_block_set_border_behavior(G_EXPR_BLOCK(dinstrs), BBB_FORCE_ON); g_binary_routine_set_decomp_instructions(routines[i], dinstrs); /* if (context != NULL) g_object_unref(context); */ } g_object_unref(G_OBJECT(format)); } /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * * filename = nom du fichier source à cibler. * * * * Description : Procède à la décompilation des routines d'un fichier donné. * * * * Retour : Tampon de code mis en place. * * * * Remarques : - * * * ******************************************************************************/ GCodeBuffer *decompile_all_from_file(const GLoadedBinary *binary, const char *filename) { GCodeBuffer *result; /* Tampon constitué à renvoyer */ GExeFormat *format; /* Format du binaire fourni */ result = g_code_buffer_new(BLC_ASSEMBLY_HEAD); build_decomp_prologue(result, filename); //prepare_all_routines_for_decomp(binary, filename); format = g_loaded_binary_get_format(binary); g_binary_format_decompile(G_BIN_FORMAT(format), result, filename); g_object_unref(G_OBJECT(format)); return result; }