/* OpenIDA - Outil d'analyse de fichiers binaires
* decompiler.c - encadrement des phases de décompilation
*
* Copyright (C) 2010-2012 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 .
*/
#include "decompiler.h"
#include
#include
#include
#include
#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_ADDRESS);
/* Introduction */
line = g_lang_output_continue_comments(output, buffer,
SL(_("Binary data decompiled by Chrysalide")));
g_buffer_line_start_merge_at(line, BLC_ADDRESS);
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_ADDRESS);
line = g_lang_output_continue_comments(output, buffer, NULL, 0);
g_buffer_line_start_merge_at(line, BLC_ADDRESS);
/* 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_ADDRESS);
free(content);
/* Ligne de séparation */
line = g_lang_output_continue_comments(output, buffer, NULL, 0);
g_buffer_line_start_merge_at(line, BLC_ADDRESS);
/* Conclusion */
line = g_lang_output_end_comments(output, buffer);
if (line != NULL) g_buffer_line_start_merge_at(line, BLC_ADDRESS);
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 = 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);
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);
*/
}
}
/******************************************************************************
* *
* 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);
return result;
}