diff options
Diffstat (limited to 'plugins/mobicore/annotations.c')
-rw-r--r-- | plugins/mobicore/annotations.c | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/plugins/mobicore/annotations.c b/plugins/mobicore/annotations.c new file mode 100644 index 0000000..94fecaf --- /dev/null +++ b/plugins/mobicore/annotations.c @@ -0,0 +1,470 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * annotations.c - enregistrement des annotations liées au format MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "annotations.h" + + +#include <malloc.h> + + +#include <i18n.h> +#include <arch/raw.h> +#include <common/extstr.h> + + +#include "mclf-int.h" + + + +/* Place des annotations sur un descripteur de segment MCLF. */ +static bool annotate_mclf_segment_descriptor(GMCLFFormat *, const char *, vmpa2t *); + +/* Place des annotations sur le début commun du binaire MCLF. */ +static bool annotate_mclf_intro(GMCLFFormat *, vmpa2t *pos); + +/* Place des annotations sur l'en-tête v1 du binaire MCLF. */ +static bool annotate_mclf_header_v1(GMCLFFormat *, vmpa2t *pos); + +/* Place des annotations sur l'en-tête du segment de code. */ +static bool annotate_mclf_text_segment_header(GMCLFFormat *format, vmpa2t *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* prefix = désignation du segment dans son ensemble. * +* pos = tête de lecture à initialiser / faire évoluer. [OUT]* +* * +* Description : Place des annotations sur un descripteur de segment MCLF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_mclf_segment_descriptor(GMCLFFormat *format, const char *prefix, vmpa2t *pos) +{ + GBinContent *content; /* Contenu binaire à lire */ + GArchInstruction *instr; /* Instruction décodée */ + char *text; /* Texte construit par étapes */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + + content = G_BIN_FORMAT(format)->conten_; + + /* start */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + text = strdup(prefix); + text = stradd(text, _(": start address")); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + + free(text); + + /* len */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + text = strdup(prefix); + text = stradd(text, _(": length")); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + + free(text); + + return true; + +} + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = tête de lecture à initialiser / faire évoluer. [OUT]* +* * +* Description : Place des annotations sur le début commun du binaire MCLF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_mclf_intro(GMCLFFormat *format, vmpa2t *pos) +{ + GBinContent *content; /* Contenu binaire à lire */ + GArchInstruction *instr; /* Instruction décodée */ + GArchOperand *operand; /* Opérande à venir modifier */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + + content = G_BIN_FORMAT(format)->conten_; + + init_vmpa(pos, 0, format->header.v1.text.start); + + /* magic */ + + instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, pos, format->endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_CHAR); + SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR); + SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR); + SET_IMM_DISPLAY(instr, operand, 3, IOD_CHAR); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("MCLF magic number")); + + /* version */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Version")); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = tête de lecture à faire évoluer. [OUT] * +* * +* Description : Place des annotations sur l'en-tête v1 du binaire MCLF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_mclf_header_v1(GMCLFFormat *format, vmpa2t *pos) +{ + GBinContent *content; /* Contenu binaire à lire */ + GArchInstruction *instr; /* Instruction décodée */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + const char *text; /* Commentaire variable */ + + content = G_BIN_FORMAT(format)->conten_; + + /* flags */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Service flags")); + + /* mem_type */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + switch (format->header.v1.mem_type) + { + case MCLF_MEM_TYPE_INTERNAL_PREFERRED: + text = _("Memory to use: internal if available, otherwise external memory"); + break; + case MCLF_MEM_TYPE_INTERNAL: + text = _("Internal memory must be used for executing the service"); + break; + case MCLF_MEM_TYPE_EXTERNAL: + text = _("External memory must be used for executing the service"); + break; + default: + text = _("Unknown memory usage"); + break; + } + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + + /* service_type */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + switch (format->header.v1.service_type) + { + case SERVICE_TYPE_ILLEGAL: + text = _("Service type is invalid"); + break; + + case SERVICE_TYPE_DRIVER: + text = _("Service is a driver"); + break; + + case SERVICE_TYPE_SP_TRUSTLET: + text = _("Service is a Trustlet"); + break; + + case SERVICE_TYPE_SYSTEM_TRUSTLET: + text = _("Service is a system Trustlet"); + break; + } + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + + /* num_instances */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Number of instances which can be run simultaneously")); + + /* uuid */ + + instr = g_raw_instruction_new_array(content, MDS_8_BITS, 16, pos, format->endian); + + g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Loadable service unique identifier (UUID)")); + + /* driver_id */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + if (format->header.v1.service_type == SERVICE_TYPE_DRIVER) + text = _("Driver ID"); + else + text = _("Unused Driver ID"); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Number of threads")); + + /* num_threads */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Number of threads")); + + /* text.start */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual text segment: start address")); + + /* text.len */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual text segment: length")); + + /* data.start */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual data segment: start address")); + + /* data.len */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual data segment: length")); + + /* bss_len */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Length of the BSS segment in bytes")); + + /* entry */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual start address of service code")); + + + + + + /* service_version */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Version of the interface the driver exports")); + + + + + /* sip_id */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Silicon Provider ID")); + + /* sip_data */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 3, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Platform specific device identifier")); + + /* permitted_hw_cfg */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Configuration which is allowed to execute binary")); + + + return true; + +} + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = tête de lecture à initialiser / faire évoluer. [OUT]* +* * +* Description : Place des annotations sur l'en-tête du segment de code. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_mclf_text_segment_header(GMCLFFormat *format, vmpa2t *pos) +{ + GBinContent *content; /* Contenu binaire à lire */ + vmpa2t old; /* Position précédente */ + phys_t diff; /* Décallage entre positions */ + GArchInstruction *instr; /* Instruction décodée */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + + content = G_BIN_FORMAT(format)->conten_; + + copy_vmpa(&old, pos); + init_vmpa(pos, 0x80, format->header.v1.text.start + 0x80); + + diff = compute_vmpa_diff(&old, pos); + + printf("DIFF : %u\n", (unsigned int)diff); + + instr = g_raw_instruction_new_array(content, MDS_8_BITS, diff, &old, format->endian); + + g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + + ADD_RAW_AS_SYM(format, symbol, &old, instr, comment, _("Padding")); + + /* version */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Version of the TextHeader structure")); + + /* text_header_len */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Size of this structure")); + + /* required_feat */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Features that Mobicore must understand when loading")); + + /* mc_lib_entry */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Address for McLib entry")); + + /* mc_lib_data */ + + if (!annotate_mclf_segment_descriptor(format, _("Segment for McLib data"), pos)) + return false; + + //Segment for McLib data + + /* mc_lib_base */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("McLib base address")); + + /* tl_api_vers */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("TlApi version used when building trustlet")); + + /* dr_api_vers */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("DrApi version used when building trustlet")); + + /* ta_properties */ + + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + + ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Address of _TA_Properties in the TA")); + + return true; + +} + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Place des annotations sur le binaire MCLF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_mclf_binary(GMCLFFormat *format) +{ + bool result; /* Bilan à retourner */ + vmpa2t pos; /* Localisation des symboles */ + + + result = annotate_mclf_intro(format, &pos); + + result &= annotate_mclf_header_v1(format, &pos); + + result &= annotate_mclf_text_segment_header(format, &pos); + + return result; + +} |