web-dev-qa-db-ja.com

デマングルされた名前からマングルされた名前を取得する

G ++でデマングルされた名前からマングルされた名前を取得する方法はありますか。

たとえば、私はデマングルされた名前func(char*, int)を持っています。マングルされた名前、つまり_Z4funcPci戻る?

私の質問はg ++固有です。

47
Prasoon Saurav

G ++を使用して、必要な署名で空の関数をコンパイルし、そこから名前を抽出できます。例えば:

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

出力を与える

_Z2f1Pci

それはあなたが必要とするものだと思います。シンボルのマングル方法に影響するため、関連するヘッダーファイルを必ず含めてください。

41
Bojan Nikolic

Bojan Nikolicのアプローチに基づいて、より良いスクリプトを次に示します。

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/:$//'

使用する:

$ ./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

ただし、コンストラクタとデストラクタについては、C0 C1 C2とD0 D1 D2があることに注意してください。

13

最悪なのは、cannot複数の結果を取得する必要があるため、名前を変更できない場合があることです。

https://reverseengineering.stackexchange.com/q/4323/4398 を参照してください(VFTには複数のデストラクタがあり、それらはすべてClassName::~ClassName()としてデマングルされます)。 (コンストラクターにも同じことが当てはまります。C0およびC2コンストラクターを見てきました。)

一方、その答えはItanium ABIを参照しています。 https://refspecs.linuxbase.org/cxxabi-1.75.html#mangling-type ここで、マングリングが指定されています。

itanium-abi Haskellパッケージ:私にとってはうまくいきませんでした(2014年5月)

Haskellパッケージがあります http://hackage.haskell.org/package/itanium-abi デマングルとマングリングの両方を約束しますが、デマングルのみを実行できます:

Ubuntu Preciseへのインストール:

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

次に、ghciを実行し、import ABI.Itaniumおよびimport Data.Eitherの後に以下を取得します。

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

mangleNameがありますが、それは文字列ではなくデータ構造であるDecodedNameを取り、そのデータ構造はdemangleNameによってのみ生成されます(何かを見落としていなければ)。うまくいけば、これは将来のリリースで改善されるでしょう。

clangコード

clangコード を試しませんでした。