diff options
Diffstat (limited to 'src/mangling/demangler.c')
-rw-r--r-- | src/mangling/demangler.c | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/src/mangling/demangler.c b/src/mangling/demangler.c new file mode 100644 index 0000000..f673a01 --- /dev/null +++ b/src/mangling/demangler.c @@ -0,0 +1,336 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * demangler.c - décodage des noms d'éléments + * + * Copyright (C) 2009-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 <http://www.gnu.org/licenses/>. + */ + + +#include "demangler.h" + + +#include <malloc.h> +#include <string.h> + + +//#include "itanium.h" +#include "java.h" + + + +/* Indique si une chaîne peut être traitée par le décodeur. */ +typedef bool (* can_be_demangled_fc) (const char *); + +/* Prépare de quoi effectuer un décodage. */ +typedef GDemanglingContext * (* create_context_fc) (void); + +/* Procède au décodage d'une chaîne de caractères. */ +typedef bool (* demangle_fc) (GDemanglingContext *, const char *); + + + +/* Appels liés à un décodeur */ +typedef struct _demangling_properties +{ + can_be_demangled_fc can_demangle; /* Possibilité de traitement */ + + create_context_fc create_context; /* Création de contextes */ + + demangle_fc demangle_routine; /* Décodage d'une routine */ + demangle_fc demangle_type; /* Décodage d'un type */ + +} demangling_properties; + + +/* Liste des décodeurs */ +static demangling_properties demanglers[/*DGT_COUNT*/] = { + + /* + [DGT_ITANIUM] = { + .can_demangle = (can_be_demangled_fc)can_be_itanium_demangled, + .create_context = (create_context_fc)g_itanium_dcontext_new, + .demangle_routine = (demangle_fc)demangle_itanium_routine, + .demangle_type = (demangle_fc)NULL + }, + */ + /* + [DGT_JAVA] = { + .can_demangle = (can_be_demangled_fc)NULL, + .create_context = (create_context_fc)g_java_dcontext_new, + .demangle_routine = (demangle_fc)NULL, + .demangle_type = (demangle_fc)demangle_java_type + } + */ +}; + + + +/****************************************************************************** +* * +* Paramètres : desc = chaîne de caractères à décoder. * +* * +* Description : Tente de décoder une chaîne de caractères donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinRoutine *try_to_demangle_routine(const char *desc) +{ + GBinRoutine *result; /* Construction à remonter */ + + result = g_binary_routine_new(); + g_binary_routine_set_name(result, strdup(desc)); + + return result; + + +#if 0 + GBinRoutine *result; /* Construction à remonter */ + DemanglerType i; /* Boucle de parcours */ + + static int counter = 0; + + result = NULL; + + if (strcmp(desc, "_ZN21IUDFSettingsValidator15IdNotIllegalStdEN13UDFParameters12UDF_STANDARDES1_") == 0 + || strcmp(desc, "_ZSt12partial_sortIN9__gnu_cxx17__normal_iteratorIP28CPR_MAI_ADPTY_SectorSequenceSt6vectorIS2_SaIS2_EEEEEvT_S8_S8_") == 0 + || strcmp(desc, "_ZSt22__merge_without_bufferIN9__gnu_cxx17__normal_iteratorIP15CProfStringListSt6vectorIS2_SaIS2_EEEEiEvT_S8_S8_T0_S9_") == 0 + || strcmp(desc, "_ZSt11__push_heapIN9__gnu_cxx17__normal_iteratorIP8DRIVE_IDSt6vectorIS2_SaIS2_EEEEiS2_EvT_T0_S9_T1_") == 0 // Intéressant + //|| strcmp(desc, "") == 0 + ) + goto exit; + + for (i = 0; i < DGT_COUNT; i++) + { + if (demanglers[i].can_demangle == NULL) + continue; + + if (!demanglers[i].can_demangle(desc)) + continue; + + printf("++ [%d] routine :: %s\n", ++counter, desc); + fflush(NULL); + + result = demangle_routine(i, desc); + + /* FIXME : à supprimer quand mature */ + if (result == NULL) + { + printf("++failed :: %s\n", desc); + + if (strcmp(desc, "_ZN21IUDFSettingsValidator15IdNotIllegalStdEN13UDFParameters12UDF_STANDARDES1_") != 0 + && strcmp(desc, "_ZSt12partial_sortIN9__gnu_cxx17__normal_iteratorIP28CPR_MAI_ADPTY_SectorSequenceSt6vectorIS2_SaIS2_EEEEEvT_S8_S8_") != 0 + ) + exit(-1); + + } + else printf(" -->> '%s'\n\n", g_binary_routine_get_name(result)); + + if (result != NULL) break; + + } + + exit: + + if (result == NULL) + { + result = g_binary_routine_new(); + g_binary_routine_set_name(result, strdup(desc)); + } + + return result; +#endif + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de décodeur à utiliser. * +* desc = chaîne de caractères à décoder. * +* * +* Description : Tente de décoder une chaîne de caractères donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinRoutine *demangle_routine(GType type, const char *desc) +{ + GBinRoutine *result; /* Construction à remonter */ + GDemanglingContext *context; /* Contexte pour le décodage */ + + context = g_object_new(type, NULL); + + result = g_demangling_context_get_decoded_routine(context, desc); + + g_object_unref(context); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de décodeur à utiliser. * +* desc = chaîne de caractères à décoder. * +* * +* Description : Tente de décoder une chaîne de caractères donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *demangle_type(GType type, const char *desc) +{ + GBinRoutine *result; /* Construction à remonter */ + GDemanglingContext *context; /* Contexte pour le décodage */ + + context = g_object_new(type, NULL); + + result = g_demangling_context_get_decoded_type(context, desc); + + g_object_unref(context); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède au test de décodages de chaînes de caractères. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +#if 0 +void test_itanium_demangling(void) +{ + GBinRoutine *routine; + char *human; + char stop; + +#define TEST_ITANIUM_MANGLING(name, ref) \ + do \ + { \ + printf(" >> %s\n", name); \ + routine = demangle_routine(DGT_ITANIUM, name); \ + if (routine == NULL) \ + { \ + printf("Error with %s\n", name); \ + stop = true; \ + } \ + else \ + { \ + human = g_binary_routine_to_string(routine); \ + printf(" >> %s\n", human); \ + stop = (strcmp(ref, human) != 0); \ + printf(" >> ok ? %s\n", (!stop ? "oui" : "non")); \ + if (stop) printf(" >> expected '%s'\n", ref); \ + free(human); \ + } \ + if (stop) goto end_of_test; \ + else printf("\n"); \ + } \ + while (0) + + //goto last; + + /** + * Tests de : + * http://www.codesourcery.com/public/cxx-abi/abi-examples.html#mangling + */ + + TEST_ITANIUM_MANGLING("_Z1fv", "??? f(void)"); + + TEST_ITANIUM_MANGLING("_Z1fi", "??? f(int)"); + + TEST_ITANIUM_MANGLING("_Z3foo3bar", "??? foo(bar)"); + + TEST_ITANIUM_MANGLING("_Zrm1XS_", "??? %(X, X)"); + + TEST_ITANIUM_MANGLING("_ZplR1XS0_", "??? +(X &, X &)"); + + TEST_ITANIUM_MANGLING("_ZlsRK1XS1_", "??? <<(const X &, const X &)"); + + TEST_ITANIUM_MANGLING("_Z1fIiEvi", "void f<int>(int)"); + + TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvS0_", "void first<Duo>(Duo)"); + + TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvT_", "void first<Duo>(Duo)"); + + TEST_ITANIUM_MANGLING("_Z3fooIiPFidEiEvv", "void foo<int, int (*)(double), int>(void)"); + + TEST_ITANIUM_MANGLING("_ZN6System5Sound4beepEv", "??? System::Sound::beep(void)"); + + TEST_ITANIUM_MANGLING("_Z1fI1XE vPV N1AIT_E1TE", "void f<X>(volatile A<X>::T *)"); + + //// TODO :: TEST_ITANIUM_MANGLING("_ZngILi42EE v N1A I XplT_Li2EE E 1TE", ""); + + TEST_ITANIUM_MANGLING("_Z4makeI7FactoryiE T_IT0_E v", "Factory<int> make<Factory, int>(void)"); + + TEST_ITANIUM_MANGLING("_ZlsRSoRKSs", "??? <<(std::ostream &, const std::string &)"); + + //TEST_ITANIUM_MANGLING("", ""); + + /** + * Tests de : + * http://www.codesourcery.com/public/cxx-abi/abi.html#mangling + */ + + TEST_ITANIUM_MANGLING("_ZN1N1TIiiE2mfES0_IddE", "??? N::T<int, int>::mf(N::T<double, double>)"); + + /** + * Tests de : + * (nero.so). + */ + + TEST_ITANIUM_MANGLING("_ZNSt6vectorItSaItEE6insertEN9__gnu_cxx17__normal_iteratorIPtS1_EERKt", "??? std::vector<unsigned short, std::allocator<unsigned short>>::insert(__gnu_cxx::__normal_iterator<unsigned short *, std::vector<unsigned short, std::allocator<unsigned short>>>, const unsigned short &)"); + + TEST_ITANIUM_MANGLING("_ZSt26__uninitialized_fill_n_auxIP15CProfStringListiS0_ET_S2_T0_RKT1_12__false_type", "CProfStringList *std::__uninitialized_fill_n_aux<CProfStringList *, int, CProfStringList>(CProfStringList *, int, const CProfStringList &, __false_type)"); + + // TODO TEST_ITANIUM_MANGLING("_ZN21IUDFSettingsValidator15IdNotIllegalStdEN13UDFParameters12UDF_STANDARDES1_", ""); + + TEST_ITANIUM_MANGLING("_ZNSbI26NeroMediumFeatureSpecifierSt11char_traitsIS_ESaIS_EE4_Rep10_M_destroyERKS2_", "??? std::basic_string<NeroMediumFeatureSpecifier, std::char_traits<NeroMediumFeatureSpecifier>, std::allocator<NeroMediumFeatureSpecifier>>::_Rep::_M_destroy(const std::allocator<NeroMediumFeatureSpecifier> &)"); + + last: + + /* 80 */ + TEST_ITANIUM_MANGLING("_ZNSt6vectorIlSaIlEE6insertEN9__gnu_cxx17__normal_iteratorIPlS1_EERKl", "??? std::vector<long, std::allocator<long>>::insert(__gnu_cxx::__normal_iterator<long *, std::vector<long, std::allocator<long>>>, const long &)"); + + end_of_test: + + ; + +} +#endif |