在D:\android-ndk-r19c-windows-x86_64\android-ndk-r19c\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin\aarch64-linux-android-c++filt.exe
有一个c++filt
的程序。Linux中也有。
使用方法
c++filt TheManglingName
例如c++filt _ZNKSt9type_info4nameEv
就能还原符号
RTTI
RTTI的实现依赖于编译时使用的STL,libc++
,liggnustl
与libstlport
的RTTI实现可能是不同的。
我们使用默认选项编译(此处使用的应该是llvm-libc++)
clang++ app9.cpp -o app9 -fPIE -pie -std=c++11
然后我们使用nm
查看与c++类型相关的__cxxabiv1
命名空间,(也可以type_info
)
nm app9 | grep cxxabiv1
得到结果
U _ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3
U _ZTVN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3
U _ZTVN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3
U _ZTVN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3
我们使用c++filt
还原四个导出符号
ubuntu# c++filt _ZTVN10__cxxabiv117__class_type_infoE
vtable for __cxxabiv1::__class_type_info
ubuntu# c++filt _ZTVN10__cxxabiv119__pointer_type_infoE
vtable for __cxxabiv1::__pointer_type_info
ubuntu# c++filt _ZTVN10__cxxabiv120__si_class_type_infoE
vtable for __cxxabiv1::__si_class_type_info
ubuntu# c++filt _ZTVN10__cxxabiv121__vmi_class_type_infoE
vtable for __cxxabiv1::__vmi_class_type_info
从名称上可以看出,这是四个类的vtable
虚表信息。对于启用了RTTI的类来说,所有的基础类(没有父类的类)都继承于_class_type_info
,所有的基础类指针都继承自__pointer_type_info
,所有的单一继承类都继承自__si_class_type_info
,所有的多继承类都继承自__vmi_class_type_info
。
正因为所有启用了RTTI
的类都继承自它们,静态分析工具只要检索对它们的交叉引用,就可以定位所有的类。
一个类的typeinfo
结构体,起始地址保存的是类的虚表的地址,第二个成员中存放的是当前类的类名的指针。如果当前类是单一继承的,在第三个成员存放的是父类的typeinfo
指针;如果当前类是双重继承或多重继承,在接下来的成员中会分别存放一些用于标志成员和父类的typeinfo
指针。
配合frida进行demangle
# Extract exports & demangle it
import frida
import cxxfilt
session = frida.attach("PwnAdventure3-Linux-Shipping")
script = session.create_script("""
var exports = Module.enumerateExportsSync("libGameLogic.so");
for (i = 0; i < exports.length; i++) {
send(exports[i].name);
}
""");
def on_message(message, data):
print message["payload"] + " - " + cxxfilt.demangle(message["payload"])
script.on('message', on_message)
script.load()
Comments | NOTHING