/* Chrysalide - Outil d'analyse de fichiers binaires * annotations.c - enregistrement des annotations liées au format MCLF * * Copyright (C) 2015-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 "annotations.h" #include #include #include #include #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)->content; /* 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, 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, 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)->content; 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, 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, 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)->content; /* flags */ instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); ADD_RAW_AS_SYM(format, symbol, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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)->content; copy_vmpa(&old, pos); init_vmpa(pos, 0x80, format->header.v1.text.start + 0x80); diff = compute_vmpa_diff(&old, pos); 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, instr, comment, _("Padding")); /* version */ instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); ADD_RAW_AS_SYM(format, symbol, 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, 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, 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, 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, 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, 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, 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, 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; }