Getting mangled name from demangled name

Is there any way to get back the mangled name from demangled name in g++.

For example , I have the demangled name func(char*, int), what should I do to get the mangled name i.e _Z4funcPci back?

My question is g++ specific.


Solution 1:

You can simply use g++ to compile an empty function with the signature you require and extract the name from that. For example:

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

gives output

_Z2f1Pci

which is I think what you require. Make sure that you include any relevant header files as they will affect the way the symbols are mangled.

Solution 2:

Based on the Bojan Nikolic's approach, here's a better 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/:$//'

Use:

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

But as to constructors and destructors, remember that there are C0 C1 C2 and D0 D1 D2 ones.

Solution 3:

What's worst, sometimes you cannot mangle a name because you must get more than one result.

See https://reverseengineering.stackexchange.com/q/4323/4398 (there are multiple destructors in VFT, and all of them are demangled as ClassName::~ClassName()). (The same applies to constructors, I have seen C0 and C2 constructors.)

On the other hand, that answer references the Itanium ABI: https://refspecs.linuxbase.org/cxxabi-1.75.html#mangling-type where mangling is specified.

The itanium-abi Haskell package: it did not work for me (May 2014)

There is a Haskell package http://hackage.haskell.org/package/itanium-abi that promises both demangling and mangling, but I could run only the demangling:

Installation on Ubuntu Precise:

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

Then you run ghci and after import ABI.Itanium and import Data.Either you get:

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

There is mangleName, but it takes a DecodedName which is a data structure rather than a string, and that data structure is produced only by demangleName (unless I overlooked something). Hopefully, this will get better in some future release.

The clang code

I did not try the clang code.