52

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.

Mat
  • 202,337
  • 40
  • 393
  • 406
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 3
    @H2CO3: Great link, but is there any way to know if it's up-to-date and authoritative? The domain name seems to be to a website at the University of Winnipeg. – j_random_hacker Sep 13 '12 at 05:53
  • @j_random_hacker American technical universities have the good habit of not putting junk on their official website(s). –  Sep 13 '12 at 05:55
  • @H2CO3: On the contents page that page links to: "This document was generated on 27 August 1999". Also, Winnipeg is in Canada if I recall :-P – j_random_hacker Sep 13 '12 at 05:57
  • 1
    @j_random_hacker correct. I shoulda said 'american'. Well, let's try to find a newer version then. –  Sep 13 '12 at 05:58
  • @j_random_hacker also, this [related SO Q/A](http://stackoverflow.com/questions/3262585/c-get-the-mangled-names-of-a-function-method) points to the same site :) –  Sep 13 '12 at 05:59
  • @H2CO3: True. I've now gone and rained on that answer's parade too. :-/ – j_random_hacker Sep 13 '12 at 06:07
  • See also answers in [compiler construction - What is Linux utility to mangle a C++ symbol name? - Stack Overflow](https://stackoverflow.com/questions/11335624/what-is-linux-utility-to-mangle-a-c-symbol-name?noredirect=1&lq=1) ■ Reverse question: [c++ - Function to mangle/demangle functions - Stack Overflow](https://stackoverflow.com/questions/4939636/function-to-mangle-demangle-functions) – user202729 Dec 07 '21 at 06:13

3 Answers3

43

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.

Bojan Nikolic
  • 1,296
  • 12
  • 8
13

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.

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127
  • Cam you explain how your script takes in the second parameter (constr/destr)? I can' really see it in the code (I only see $1). Also, what are C0, C1 and C2 ctors/dtors? – einpoklum Jan 21 '16 at 14:41
  • Please forgive my ignorance... Why is it better? – jww Jun 17 '16 at 07:49
  • @jww try to get the mangled name for `abc::def::ghi()` with the original script – 18446744073709551615 Jun 17 '16 at 08:07
  • The script does only work with arguments of built-in types. Once you have custom types, you'll need to include the declarations in the header files in the temporary C++ code. – Chaos_99 Feb 09 '17 at 10:38
  • 1
    This solution is still incomplete because you don't handle complex argument types. I think including necessary headers is unavoidable in general case. – yugr Sep 14 '18 at 08:45
4

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.

Community
  • 1
  • 1
18446744073709551615
  • 16,368
  • 4
  • 94
  • 127