C++ Internals: VC RTTI - 基本数据结构
来源:互联网 发布:澳门打车软件 编辑:程序博客网 时间:2024/05/21 14:01
返回目录
网上资料比较少,ms还是有研究的价值 ^_^
相关资源:
Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI
Reversing C++
C++的RTTI一旦遇上了多重和虚继承,简直就是噩梦 -.-
这里介绍一下VC中用来表示RTTI的内部数据结构(具体可以参考《Reversing C++》里的描述)。利用下面的程序可以察看多态类的RTTI信息,我们可以借此熟悉一下RTTI到底长什么样子 :-)
#include <windows.h>
#include <iostream>
using namespace std;
#include <typeinfo>
using std::type_info;
typedef type_info TypeDescriptor;
struct PMD
{
ptrdiff_t mdisp; //vftable offset
ptrdiff_t pdisp; //vbtable offset
ptrdiff_t vdisp; //vftable offset (for virtual base class)
void Output();
};
struct _s_RTTICompleteObjectLocator;
struct _s_RTTIClassHierarchyDescriptor;
struct _s_RTTIBaseClassDescriptor;
struct _s_RTTICompleteObjectLocator
{
DWORD signature;
DWORD offset; //vftable offset to this
DWORD cdOffset;
TypeDescriptor *pTypeDescriptor;
_s_RTTIClassHierarchyDescriptor *pClassHierarchyDescriptor;
void Output(size_t tabs);
};
struct _s_RTTIClassHierarchyDescriptor
{
DWORD signature;
DWORD attributes; //bit 0 multiple inheritance, bit 1 virtual inheritance
size_t numBaseClasses; //at least 1 (all base classes, including itself)
_s_RTTIBaseClassDescriptor **pBaseClassArray;
void Output(size_t tabs);
};
struct _s_RTTIBaseClassDescriptor
{
TypeDescriptor *pTypeDescriptor;
size_t numBaseClasses; //direct base classes
PMD pmd; //Len=0xC
DWORD attributes;
_s_RTTIClassHierarchyDescriptor *pClassHierarchyDescriptor; //of this base class
void Output(size_t tabs);
};
void PMD::Output()
{
cout<<'('<<mdisp<<','<<pdisp<<','<<vdisp<<')';
}
void OutputTab(size_t tabs) {for(size_t i=0;i<tabs;++i) cout<<'/t';}
void _s_RTTICompleteObjectLocator::Output(size_t tabs)
{
OutputTab(tabs);
cout<<"CompleteObjectLocator:"<<endl;
OutputTab(tabs);
cout<<"signature:"<<signature<<endl;
OutputTab(tabs);
cout<<"offset:"<<offset<<endl;
OutputTab(tabs);
cout<<"cdOffset:"<<cdOffset<<endl;
OutputTab(tabs);
cout<<"pTypeDescriptor:"<<pTypeDescriptor->name()<<endl;
OutputTab(tabs);
cout<<"pClassHierarchyDescriptor:"<<endl;
pClassHierarchyDescriptor->Output(tabs+1);
cout<<endl;
cout<<endl;
}
void _s_RTTIClassHierarchyDescriptor::Output(size_t tabs)
{
OutputTab(tabs);
cout<<"signature:"<<signature<<endl;
OutputTab(tabs);
cout<<"attributes:"<<attributes<<endl;
for (size_t i=0;i<numBaseClasses;++i) {
OutputTab(tabs);
cout<<"base class "<<i+1<<":"<<endl;
pBaseClassArray[i]->Output(tabs+1);
}
}
void _s_RTTIBaseClassDescriptor::Output(size_t tabs)
{
OutputTab(tabs);
cout<<"pTypeDescriptor:"<<pTypeDescriptor->name()<<endl;
OutputTab(tabs);
cout<<"numBaseClasses:"<<numBaseClasses<<endl;
OutputTab(tabs);
cout<<"pmd:";
pmd.Output();
cout<<endl;
OutputTab(tabs);
cout<<"attributes:"<<attributes<<endl;
}
template<typename R> //only ptrdiff_t and size_t allowed
R ReadData(size_t ptr)
{
return *((const R *)ptr);
}
template<typename R,typename T>
R ReadData(const T *ptr)
{
return ReadData<R>((size_t)ptr);
}
//We assume the vftable is at offset 0
//If it is not the case, we assume the vbtable should be at offset 0, and with its first entry equal to 0 (point to itself).
//Then its second entry should contain the offset of vftable
template<typename T>
_s_RTTICompleteObjectLocator *GetCompleteObjectLocator(const T *ptr) //not have vbtable
{
ptrdiff_t offset=0;
if (ReadData<ptrdiff_t>(ReadData<size_t>(ptr))==0) offset=ReadData<ptrdiff_t>(ReadData<size_t>(ptr)+4);
return (_s_RTTICompleteObjectLocator *)(ReadData<size_t>(ReadData<size_t>((size_t)ptr+offset)-4));
}
#pragma warning(disable:4584)
class A1
{
public:
virtual ~A1() {}
private:
int data;
};
class A2
{
public:
virtual ~A2() {}
private:
int data;
};
class B1:virtual public A1,virtual public A2
{
public:
virtual ~B1() {}
virtual void FunB1() {}
private:
int data;
};
class B2:public A1,public A2
{
public:
virtual ~B2() {}
virtual void FunB2() {}
private:
int data;
};
class C:public B1,virtual public B2
{
public:
virtual ~C() {}
virtual void FunC() {}
private:
int data;
};
class D:public A1,virtual public A2
{
public:
virtual ~D() {}
virtual void FunD() {}
private:
int data;
};
class E:public C,public D
{
public:
virtual ~E() {}
virtual void FunE() {}
private:
int data;
};
#include <cstddef>
template<size_t N>
class Evil1:public Evil1<N-1>,public Evil1<N-2>
{
public:
virtual ~Evil1() {}
};
template<size_t N>
class Evil2:virtual public Evil2<N-1>,public Evil2<N-2>
{
public:
virtual ~Evil2() {}
};
template<size_t N>
class Evil3:public Evil3<N-1>,virtual public Evil3<N-2>
{
public:
virtual ~Evil3() {}
};
template<size_t N>
class Evil4:virtual public Evil4<N-1>,virtual public Evil4<N-2>
{
public:
virtual ~Evil4() {}
};
template<> class Evil1<0> {public: virtual ~Evil1() {}};
template<> class Evil1<1> {public: virtual ~Evil1() {}};
template<> class Evil2<0> {public: virtual ~Evil2() {}};
template<> class Evil2<1> {public: virtual ~Evil2() {}};
template<> class Evil3<0> {public: virtual ~Evil3() {}};
template<> class Evil3<1> {public: virtual ~Evil3() {}};
template<> class Evil4<0> {public: virtual ~Evil4() {}};
template<> class Evil4<1> {public: virtual ~Evil4() {}};
int main()
{
_s_RTTICompleteObjectLocator *pCompleteObjectLocator;
A1 a1;
A2 a2;
B1 b1;
B2 b2;
C c;
D d;
E e;
pCompleteObjectLocator=GetCompleteObjectLocator(&a1);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&b1);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&b2);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&c);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&d);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
Evil1<5> e1;
Evil2<5> e2;
Evil3<5> e3;
Evil4<5> e4;
pCompleteObjectLocator=GetCompleteObjectLocator(&e1);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e2);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e3);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e4);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
}
网上资料比较少,ms还是有研究的价值 ^_^
相关资源:
Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI
Reversing C++
C++的RTTI一旦遇上了多重和虚继承,简直就是噩梦 -.-
这里介绍一下VC中用来表示RTTI的内部数据结构(具体可以参考《Reversing C++》里的描述)。利用下面的程序可以察看多态类的RTTI信息,我们可以借此熟悉一下RTTI到底长什么样子 :-)
#include <windows.h>
#include <iostream>
using namespace std;
#include <typeinfo>
using std::type_info;
typedef type_info TypeDescriptor;
struct PMD
{
ptrdiff_t mdisp; //vftable offset
ptrdiff_t pdisp; //vbtable offset
ptrdiff_t vdisp; //vftable offset (for virtual base class)
void Output();
};
struct _s_RTTICompleteObjectLocator;
struct _s_RTTIClassHierarchyDescriptor;
struct _s_RTTIBaseClassDescriptor;
struct _s_RTTICompleteObjectLocator
{
DWORD signature;
DWORD offset; //vftable offset to this
DWORD cdOffset;
TypeDescriptor *pTypeDescriptor;
_s_RTTIClassHierarchyDescriptor *pClassHierarchyDescriptor;
void Output(size_t tabs);
};
struct _s_RTTIClassHierarchyDescriptor
{
DWORD signature;
DWORD attributes; //bit 0 multiple inheritance, bit 1 virtual inheritance
size_t numBaseClasses; //at least 1 (all base classes, including itself)
_s_RTTIBaseClassDescriptor **pBaseClassArray;
void Output(size_t tabs);
};
struct _s_RTTIBaseClassDescriptor
{
TypeDescriptor *pTypeDescriptor;
size_t numBaseClasses; //direct base classes
PMD pmd; //Len=0xC
DWORD attributes;
_s_RTTIClassHierarchyDescriptor *pClassHierarchyDescriptor; //of this base class
void Output(size_t tabs);
};
void PMD::Output()
{
cout<<'('<<mdisp<<','<<pdisp<<','<<vdisp<<')';
}
void OutputTab(size_t tabs) {for(size_t i=0;i<tabs;++i) cout<<'/t';}
void _s_RTTICompleteObjectLocator::Output(size_t tabs)
{
OutputTab(tabs);
cout<<"CompleteObjectLocator:"<<endl;
OutputTab(tabs);
cout<<"signature:"<<signature<<endl;
OutputTab(tabs);
cout<<"offset:"<<offset<<endl;
OutputTab(tabs);
cout<<"cdOffset:"<<cdOffset<<endl;
OutputTab(tabs);
cout<<"pTypeDescriptor:"<<pTypeDescriptor->name()<<endl;
OutputTab(tabs);
cout<<"pClassHierarchyDescriptor:"<<endl;
pClassHierarchyDescriptor->Output(tabs+1);
cout<<endl;
cout<<endl;
}
void _s_RTTIClassHierarchyDescriptor::Output(size_t tabs)
{
OutputTab(tabs);
cout<<"signature:"<<signature<<endl;
OutputTab(tabs);
cout<<"attributes:"<<attributes<<endl;
for (size_t i=0;i<numBaseClasses;++i) {
OutputTab(tabs);
cout<<"base class "<<i+1<<":"<<endl;
pBaseClassArray[i]->Output(tabs+1);
}
}
void _s_RTTIBaseClassDescriptor::Output(size_t tabs)
{
OutputTab(tabs);
cout<<"pTypeDescriptor:"<<pTypeDescriptor->name()<<endl;
OutputTab(tabs);
cout<<"numBaseClasses:"<<numBaseClasses<<endl;
OutputTab(tabs);
cout<<"pmd:";
pmd.Output();
cout<<endl;
OutputTab(tabs);
cout<<"attributes:"<<attributes<<endl;
}
template<typename R> //only ptrdiff_t and size_t allowed
R ReadData(size_t ptr)
{
return *((const R *)ptr);
}
template<typename R,typename T>
R ReadData(const T *ptr)
{
return ReadData<R>((size_t)ptr);
}
//We assume the vftable is at offset 0
//If it is not the case, we assume the vbtable should be at offset 0, and with its first entry equal to 0 (point to itself).
//Then its second entry should contain the offset of vftable
template<typename T>
_s_RTTICompleteObjectLocator *GetCompleteObjectLocator(const T *ptr) //not have vbtable
{
ptrdiff_t offset=0;
if (ReadData<ptrdiff_t>(ReadData<size_t>(ptr))==0) offset=ReadData<ptrdiff_t>(ReadData<size_t>(ptr)+4);
return (_s_RTTICompleteObjectLocator *)(ReadData<size_t>(ReadData<size_t>((size_t)ptr+offset)-4));
}
#pragma warning(disable:4584)
class A1
{
public:
virtual ~A1() {}
private:
int data;
};
class A2
{
public:
virtual ~A2() {}
private:
int data;
};
class B1:virtual public A1,virtual public A2
{
public:
virtual ~B1() {}
virtual void FunB1() {}
private:
int data;
};
class B2:public A1,public A2
{
public:
virtual ~B2() {}
virtual void FunB2() {}
private:
int data;
};
class C:public B1,virtual public B2
{
public:
virtual ~C() {}
virtual void FunC() {}
private:
int data;
};
class D:public A1,virtual public A2
{
public:
virtual ~D() {}
virtual void FunD() {}
private:
int data;
};
class E:public C,public D
{
public:
virtual ~E() {}
virtual void FunE() {}
private:
int data;
};
#include <cstddef>
template<size_t N>
class Evil1:public Evil1<N-1>,public Evil1<N-2>
{
public:
virtual ~Evil1() {}
};
template<size_t N>
class Evil2:virtual public Evil2<N-1>,public Evil2<N-2>
{
public:
virtual ~Evil2() {}
};
template<size_t N>
class Evil3:public Evil3<N-1>,virtual public Evil3<N-2>
{
public:
virtual ~Evil3() {}
};
template<size_t N>
class Evil4:virtual public Evil4<N-1>,virtual public Evil4<N-2>
{
public:
virtual ~Evil4() {}
};
template<> class Evil1<0> {public: virtual ~Evil1() {}};
template<> class Evil1<1> {public: virtual ~Evil1() {}};
template<> class Evil2<0> {public: virtual ~Evil2() {}};
template<> class Evil2<1> {public: virtual ~Evil2() {}};
template<> class Evil3<0> {public: virtual ~Evil3() {}};
template<> class Evil3<1> {public: virtual ~Evil3() {}};
template<> class Evil4<0> {public: virtual ~Evil4() {}};
template<> class Evil4<1> {public: virtual ~Evil4() {}};
int main()
{
_s_RTTICompleteObjectLocator *pCompleteObjectLocator;
A1 a1;
A2 a2;
B1 b1;
B2 b2;
C c;
D d;
E e;
pCompleteObjectLocator=GetCompleteObjectLocator(&a1);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&b1);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&b2);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&c);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&d);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
Evil1<5> e1;
Evil2<5> e2;
Evil3<5> e3;
Evil4<5> e4;
pCompleteObjectLocator=GetCompleteObjectLocator(&e1);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e2);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e3);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
pCompleteObjectLocator=GetCompleteObjectLocator(&e4);
if (pCompleteObjectLocator) pCompleteObjectLocator->Output(0);
}
- C++ Internals: VC RTTI - 基本数据结构
- C++ Internals: VC RTTI - 基本数据结构
- C++ Internals: VC RTTI - typeid
- C++ Internals: VC RTTI - typeid
- C++ Internals: VC RTTI - dynamic_cast (1)
- C++ Internals: VC RTTI - dynamic_cast (2)
- C++ Internals: VC RTTI - dynamic_cast (1)
- C++ Internals: VC RTTI - dynamic_cast (2)
- VC 之余RTTI
- VC++启动RTTI
- 【C/C++】RTTI
- 计算机算法(c++) 基本数据结构
- ?[C++_10]RTTI
- <C++> RTTI机制
- C++RTTI小总结
- C++RTTI强制转型
- .NET(C#) Internals: 鲜为人知的??
- .NET(C#) Internals: 鲜为人知的??
- 归档命令介绍.
- 如何写makefile
- 利用rpm安装实用程序安装rpm包
- linux常用命令
- 这两天的问题
- C++ Internals: VC RTTI - 基本数据结构
- Endnote 教程 http://lib.ict.ac.cn/EndNote/endnote%E6%95%99%E7%A8%8B.pdf
- 使用DEM生成3D模型(补完)
- 如何将JAVA生成可执行文件?http://www.nou.com.cn/cms/cxsj/5642/page.action
- Symbian游戏编程入门 (四)图形显示 ------很棒的文章
- Hibernate错误日志
- eHR实施 如何让计划跟着变化“变脸”?
- OA呼唤行业标准 产业链亟待整合
- 学会甘当配角 IT部门该退台时要退台