web-dev-qa-db-fra.com

Obtenir un nom mutilé à partir d'un nom démangé

Existe-t-il un moyen de récupérer le nom mutilé à partir du nom démangé dans g ++.

Par exemple, j'ai le nom démangé func(char*, int), que dois-je faire pour obtenir le nom mutilé, c'est-à-dire _Z4funcPci arrière?

Ma question est spécifique à g ++.

48
Prasoon Saurav

Vous pouvez simplement utiliser g ++ pour compiler une fonction vide avec la signature dont vous avez besoin et en extraire le nom. Par exemple:

echo "int f1(char *, int) {} " | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'

donne une sortie

_Z2f1Pci

ce qui est, je pense, ce dont vous avez besoin. Assurez-vous d'inclure tous les fichiers d'en-tête pertinents car ils affecteront la façon dont les symboles sont modifiés.

41
Bojan Nikolic

Basé sur l'approche de Bojan Nikolic, voici un meilleur script:

mangle.bash:

IFS='::' read -a array <<< "$1"

indexes=("${!array[@]}")

prefix=""
middle=""
suffix=""
rettype=""
if [ -z "$2" ]; then
    rettype="void"
fi


for index in "${indexes[@]}"
do
    #echo "$index ${array[index]}"
    if [ $index == ${indexes[-1]} ]; then
    #echo "last"
    middle="$rettype ${array[index]};"
    Elif [ -n "${array[index]}" ]; then
    #echo "not empty"
    prefix="${prefix}struct ${array[index]}{"
    suffix="${suffix}};"
    fi
done

#echo "$prefix$middle$suffix $rettype $1{}"
echo "$prefix$middle$suffix $rettype $1{}" | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'

Utilisation:

$ ./mangle.bash "abc::def::ghi()"
_ZN3abc3def3ghiEv
$ ./mangle.bash "abc::def::ghi(int i, char c)"
_ZN3abc3def3ghiEic
$ ./mangle.bash "abc::def::def(int i, char c)" constr
_ZN3abc3defC2Eic
$ ./mangle.bash "abc::def::~def()" destr
_ZN3abc3defD2Ev

Mais en ce qui concerne les constructeurs et les destructeurs, rappelez-vous qu'il y en a C0 C1 C2 et D0 D1 D2.

13

Le pire, parfois vous ne peut pas modifiez un nom car vous devez obtenir plus d'un résultat.

Voir https://reverseengineering.stackexchange.com/q/4323/4398 (il existe plusieurs destructeurs dans VFT, et tous sont démêlés sous la forme ClassName::~ClassName()). (La même chose s'applique aux constructeurs, j'ai vu des constructeurs C0 et C2.)

D'autre part, cette réponse fait référence à l'Itanium ABI: https://refspecs.linuxbase.org/cxxabi-1.75.html#mangling-type où mangling est spécifié.

Le package itanium-abi Haskell: il n'a pas fonctionné pour moi (mai 2014)

Il y a un paquet Haskell http://hackage.haskell.org/package/itanium-abi qui promet à la fois le démêlage et la mutilation, mais je ne pouvais exécuter que le démêlage:

Installation sur Ubuntu Precise:

Sudo aptitude install ghc
Sudo aptitude install cabal-install
cabal update
cabal install itanium-abi

Ensuite, vous exécutez ghci et après import ABI.Itanium et import Data.Either vous obtenez:

Prelude ABI.Itanium Data.Either> cxxNameToText $ head (rights [ demangleName "_ZTI13QSystemLocale" ])
"typeinfo for QSystemLocale"

Il y a mangleName, mais il faut un DecodedName qui est une structure de données plutôt qu'une chaîne, et cette structure de données n'est produite que par demangleName (sauf si j'ai oublié quelque chose). Espérons que cela s'améliorera dans certaines versions futures.

Le code de clang

Je n'ai pas essayé le code clang .

3