Получение искаженного имени из раскрученного имени

Есть ли способ вернуть искаженное имя из освобожденного имени в g++.

Например, у меня есть расколотое имя func(char*, int)что я должен сделать, чтобы получить искаженное имя, т.е. _Z4funcPci назад?

Мой вопрос специфичен для g++.

3 ответа

Вы можете просто использовать g++, чтобы скомпилировать пустую функцию с нужной вам подписью и извлечь из нее имя. Например:

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

дает вывод

_Z2f1Pci

что я думаю, что вам нужно. Убедитесь, что вы включили все соответствующие заголовочные файлы, так как они будут влиять на то, как символы будут искажены.

Основываясь на подходе Бояна Николича, вот лучший сценарий:

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.

Что еще хуже, иногда вы не можете исказить имя, потому что вы должны получить более одного результата.

См. https://reverseengineering.stackexchange.com/q/4323/4398 (в VFT есть несколько деструкторов, и все они разбиты на ClassName::~ClassName()). (То же самое относится и к конструкторам, я видел конструкторы C0 и C2.)

С другой стороны, этот ответ ссылается на Itanium ABI: https://refspecs.linuxbase.org/cxxabi-1.75.html, где указывается искажение.

Пакет itanium-abi Haskell: у меня он не работал (май 2014)

Существует пакет 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 (если я что-то не заметил). Надеюсь, это будет лучше в будущем выпуске.

Код лязг

Я не пробовал код лязга.

Другие вопросы по тегам