Getting mangled name from demangled name
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.
![Prasoon Saurav](https://i.stack.imgur.com/Rih5C.jpg?s=256&g=1)
Prasoon Saurav
About me Software engineer at a stealth startup. 22nd C gold badge recipient. 62nd C++ gold badge recipient. Contacts prasoonsaurav.nit @ gmail prasoonsaurav @ linkedin prasoon @ codementor
Updated on June 09, 2020Comments
-
Prasoon Saurav about 4 years
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.
-
Ben Voigt almost 12 yearsGood approach. And use
c++filt
for the other direction. -
Alba Mendez over 10 yearsIt's not always that easy. Suppose you have names like
IFS::Profiler::create(IFS::Handle hdl)
. -
18446744073709551615 about 10 yearsexactly "not that easy". Compilation fails if any mentioned data structures are not declared. Some of them are in your code, some of them come from headers.
-
einpoklum over 8 yearsCam 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?
-
jww about 8 yearsPlease forgive my ignorance... Why is it better?
-
18446744073709551615 about 8 years@jww try to get the mangled name for
abc::def::ghi()
with the original script -
Chaos_99 over 7 yearsThe 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.
-
yugr almost 6 yearsThis solution is still incomplete because you don't handle complex argument types. I think including necessary headers is unavoidable in general case.