1. 程式人生 > >Android SO逆向-C++虛擬函式表解析

Android SO逆向-C++虛擬函式表解析

    0x00 一般繼承(無虛擬函式覆蓋)

class Base {

public:
	Base() { ALOGD("Base ..."); }
	virtual void f() { ALOGD("Base::f"); }
    void g() { ALOGD("Base::g"); }
	virtual void h() { ALOGD("Base::h"); }

	virtual ~Base() { ALOGD("~Base ...");  }

};
class Derived : public Base {

public:
	Derived() : Base()
	{ ALOGD("Derived ...");}
	virtual void f1() { ALOGD("Derived::f"); }
	virtual void g1() { ALOGD("Derived::g"); }
	virtual void h1() { ALOGD("Derived::h"); }

	virtual ~Derived()
	{ ALOGD("~Derived ...");  }
};
Base* base;
	base = new Derived();
	delete base;
    虛擬函式表如下圖:

    

    0x01 一般繼承(有虛擬函式覆蓋)

class Base {

public:
	Base() { ALOGD("Base ..."); }
	virtual void f() { ALOGD("Base::f"); }
	virtual void g() { ALOGD("Base::g"); }
	virtual void h() { ALOGD("Base::h"); }

	virtual ~Base() { ALOGD("~Base ...");  }

};
class Derived : public Base {

public:
	Derived() : Base()
	{ ALOGD("Derived ...");}
	virtual void f() { ALOGD("Derived::f"); }
	virtual void g1() { ALOGD("Derived::g"); }
	virtual void h1() { ALOGD("Derived::h"); }

	virtual ~Derived()
	{ ALOGD("~Derived ...");  }
};
Base* base;
	base = new Derived();
	delete base;
    虛擬函式表如下圖:

    

    0x02 多重繼承(無虛擬函式覆蓋)

class Base {

public:
	Base() { ALOGD("Base ..."); }
	virtual void f() { ALOGD("Base::f"); }
	virtual void g() { ALOGD("Base::g"); }
	virtual void h() { ALOGD("Base::h"); }

	virtual ~Base() { ALOGD("~Base ...");  }

};

class Base1 {

public:
	Base1() { ALOGD("Base1 ..."); }
	virtual void f() { ALOGD("Base1::f"); }
	virtual void g() { ALOGD("Base1::g"); }
	virtual void h() { ALOGD("Base1::h"); }

	virtual ~Base1() {ALOGD("~Base1 ...");}
};

class Base2 {

public:
	Base2() { ALOGD("Base2 ..."); }
	virtual void f() { ALOGD("Base2::f"); }
	virtual void g() { ALOGD("Base2::g"); }
	virtual void h() { ALOGD("Base2::h"); }

	virtual ~Base2() { ALOGD("~Base2 ..."); }

};

class Derived : public Base , public Base1 ,public Base2{

public:
	Derived() : Base()
	{ ALOGD("Derived ...");}
	virtual void f1() { ALOGD("Derived::f"); }
	virtual void g1() { ALOGD("Derived::g"); }
	virtual void h1() { ALOGD("Derived::h"); }

	virtual ~Derived()
	{ ALOGD("~Derived ...");  }
};
Base* base;
	base = new Derived();
	delete base;

    虛擬函式表如下:

.data.rel.ro:00003DD8
.data.rel.ro:00003DD8 ; Segment type: Pure data
.data.rel.ro:00003DD8                 AREA .data.rel.ro, DATA, ALIGN=3
.data.rel.ro:00003DD8                 ; ORG 0x3DD8
.data.rel.ro:00003DD8                 WEAK _ZTV4Base
.data.rel.ro:00003DD8 ; `vtable for'Base
.data.rel.ro:00003DD8 _ZTV4Base       DCB    0                ; DATA XREF: Base::~Base()+8o
.data.rel.ro:00003DD8                                         ; Derived::Derived(void)+Eo ...
.data.rel.ro:00003DD9                 DCB    0
.data.rel.ro:00003DDA                 DCB    0
.data.rel.ro:00003DDB                 DCB    0
.data.rel.ro:00003DDC                 DCB    0
.data.rel.ro:00003DDD                 DCB    0
.data.rel.ro:00003DDE                 DCB    0
.data.rel.ro:00003DDF                 DCB    0
.data.rel.ro:00003DE0                 DCD _ZN4Base1fEv+1
.data.rel.ro:00003DE4                 DCD _ZN4Base1gEv+1
.data.rel.ro:00003DE8                 DCD _ZN4Base1hEv+1
.data.rel.ro:00003DEC                 DCD _ZN4BaseD2Ev+1
.data.rel.ro:00003DF0                 DCD _ZN4BaseD0Ev+1
.data.rel.ro:00003DF4                 ALIGN 8
.data.rel.ro:00003DF8                 WEAK _ZTV5Base1
.data.rel.ro:00003DF8 ; `vtable for'Base1
.data.rel.ro:00003DF8 _ZTV5Base1      DCB    0                ; DATA XREF: Base1::~Base1()+8o
.data.rel.ro:00003DF8                                         ; Derived::Derived(void)+26o ...
.data.rel.ro:00003DF9                 DCB    0
.data.rel.ro:00003DFA                 DCB    0
.data.rel.ro:00003DFB                 DCB    0
.data.rel.ro:00003DFC                 DCB    0
.data.rel.ro:00003DFD                 DCB    0
.data.rel.ro:00003DFE                 DCB    0
.data.rel.ro:00003DFF                 DCB    0
.data.rel.ro:00003E00                 DCD _ZN5Base11fEv+1
.data.rel.ro:00003E04                 DCD _ZN5Base11gEv+1
.data.rel.ro:00003E08                 DCD _ZN5Base11hEv+1
.data.rel.ro:00003E0C                 DCD _ZN5Base1D2Ev+1
.data.rel.ro:00003E10                 DCD _ZN5Base1D0Ev+1
.data.rel.ro:00003E14                 ALIGN 8
.data.rel.ro:00003E18                 WEAK _ZTV5Base2
.data.rel.ro:00003E18 ; `vtable for'Base2
.data.rel.ro:00003E18 _ZTV5Base2      DCB    0                ; DATA XREF: Base2::~Base2()+8o
.data.rel.ro:00003E18                                         ; Derived::Derived(void)+3Co ...
.data.rel.ro:00003E19                 DCB    0
.data.rel.ro:00003E1A                 DCB    0
.data.rel.ro:00003E1B                 DCB    0
.data.rel.ro:00003E1C                 DCB    0
.data.rel.ro:00003E1D                 DCB    0
.data.rel.ro:00003E1E                 DCB    0
.data.rel.ro:00003E1F                 DCB    0
.data.rel.ro:00003E20                 DCD _ZN5Base21fEv+1
.data.rel.ro:00003E24                 DCD _ZN5Base21gEv+1
.data.rel.ro:00003E28                 DCD _ZN5Base21hEv+1
.data.rel.ro:00003E2C                 DCD _ZN5Base2D2Ev+1
.data.rel.ro:00003E30                 DCD _ZN5Base2D0Ev+1
.data.rel.ro:00003E34                 ALIGN 8
.data.rel.ro:00003E38                 WEAK _ZTV7Derived
.data.rel.ro:00003E38 ; `vtable for'Derived
.data.rel.ro:00003E38 _ZTV7Derived    DCB    0                ; DATA XREF: Derived::~Derived()+Co
.data.rel.ro:00003E38                                         ; Derived::Derived(void)+52o ...
.data.rel.ro:00003E39                 DCB    0
.data.rel.ro:00003E3A                 DCB    0
.data.rel.ro:00003E3B                 DCB    0
.data.rel.ro:00003E3C                 DCB    0
.data.rel.ro:00003E3D                 DCB    0
.data.rel.ro:00003E3E                 DCB    0
.data.rel.ro:00003E3F                 DCB    0
.data.rel.ro:00003E40                 DCD _ZN4Base1fEv+1
.data.rel.ro:00003E44                 DCD _ZN4Base1gEv+1
.data.rel.ro:00003E48                 DCD _ZN4Base1hEv+1
.data.rel.ro:00003E4C                 DCD _ZN7DerivedD2Ev+1
.data.rel.ro:00003E50                 DCD _ZN7DerivedD0Ev+1
.data.rel.ro:00003E54                 DCD _ZN7Derived2f1Ev+1
.data.rel.ro:00003E58                 DCD _ZN7Derived2g1Ev+1
.data.rel.ro:00003E5C                 DCD _ZN7Derived2h1Ev+1
.data.rel.ro:00003E60                 DCB 0xFC ; 
.data.rel.ro:00003E61                 DCB 0xFF
.data.rel.ro:00003E62                 DCB 0xFF
.data.rel.ro:00003E63                 DCB 0xFF
.data.rel.ro:00003E64                 DCB    0
.data.rel.ro:00003E65                 DCB    0
.data.rel.ro:00003E66                 DCB    0
.data.rel.ro:00003E67                 DCB    0
.data.rel.ro:00003E68                 DCD _ZN5Base11fEv+1
.data.rel.ro:00003E6C                 DCD _ZN5Base11gEv+1
.data.rel.ro:00003E70                 DCD _ZN5Base11hEv+1
.data.rel.ro:00003E74                 DCD _ZThn4_N7DerivedD1Ev+1
.data.rel.ro:00003E78                 DCD _ZThn4_N7DerivedD0Ev+1
.data.rel.ro:00003E7C                 DCB 0xF8 ; 
.data.rel.ro:00003E7D                 DCB 0xFF
.data.rel.ro:00003E7E                 DCB 0xFF
.data.rel.ro:00003E7F                 DCB 0xFF
.data.rel.ro:00003E80                 DCB    0
.data.rel.ro:00003E81                 DCB    0
.data.rel.ro:00003E82                 DCB    0
.data.rel.ro:00003E83                 DCB    0
.data.rel.ro:00003E84                 DCD _ZN5Base21fEv+1
.data.rel.ro:00003E88                 DCD _ZN5Base21gEv+1
.data.rel.ro:00003E8C                 DCD _ZN5Base21hEv+1
.data.rel.ro:00003E90                 DCD _ZThn8_N7DerivedD1Ev+1
.data.rel.ro:00003E94                 DCD _ZThn8_N7DerivedD0Ev+1
.data.rel.ro:00003E94 ; .data.rel.ro  ends

    0x03 多重繼承(有虛擬函式覆蓋)

class Base {

public:
	Base() { ALOGD("Base ..."); }
	virtual void f() { ALOGD("Base::f"); }
	virtual void g() { ALOGD("Base::g"); }
	virtual void h() { ALOGD("Base::h"); }

	virtual ~Base() { ALOGD("~Base ...");  }

};

class Base1 {

public:
	Base1() { ALOGD("Base1 ..."); }
	virtual void f() { ALOGD("Base1::f"); }
	virtual void g() { ALOGD("Base1::g"); }
	virtual void h() { ALOGD("Base1::h"); }

	virtual ~Base1() {ALOGD("~Base1 ...");}
};

class Base2 {

public:
	Base2() { ALOGD("Base2 ..."); }
	virtual void f() { ALOGD("Base2::f"); }
	virtual void g() { ALOGD("Base2::g"); }
	virtual void h() { ALOGD("Base2::h"); }

	virtual ~Base2() { ALOGD("~Base2 ..."); }

};

class Derived : public Base , public Base1 ,public Base2{

public:
	Derived() : Base()
	{ ALOGD("Derived ...");}
	virtual void f() { ALOGD("Derived::f"); }
	virtual void g1() { ALOGD("Derived::g"); }
	virtual void h1() { ALOGD("Derived::h"); }

	virtual ~Derived()
	{ ALOGD("~Derived ...");  }
};
Base* base;
	base = new Derived();
	delete base;
    虛擬函式表如下:
.data.rel.ro:00003DD8 ; Segment type: Pure data
.data.rel.ro:00003DD8                 AREA .data.rel.ro, DATA, ALIGN=3
.data.rel.ro:00003DD8                 ; ORG 0x3DD8
.data.rel.ro:00003DD8                 WEAK _ZTV4Base
.data.rel.ro:00003DD8 ; `vtable for'Base
.data.rel.ro:00003DD8 _ZTV4Base       DCB    0                ; DATA XREF: Base::~Base()+8o
.data.rel.ro:00003DD8                                         ; Derived::Derived(void)+Eo ...
.data.rel.ro:00003DD9                 DCB    0
.data.rel.ro:00003DDA                 DCB    0
.data.rel.ro:00003DDB                 DCB    0
.data.rel.ro:00003DDC                 DCB    0
.data.rel.ro:00003DDD                 DCB    0
.data.rel.ro:00003DDE                 DCB    0
.data.rel.ro:00003DDF                 DCB    0
.data.rel.ro:00003DE0                 DCD _ZN4Base1fEv+1
.data.rel.ro:00003DE4                 DCD _ZN4Base1gEv+1
.data.rel.ro:00003DE8                 DCD _ZN4Base1hEv+1
.data.rel.ro:00003DEC                 DCD _ZN4BaseD2Ev+1
.data.rel.ro:00003DF0                 DCD _ZN4BaseD0Ev+1
.data.rel.ro:00003DF4                 ALIGN 8
.data.rel.ro:00003DF8                 WEAK _ZTV5Base1
.data.rel.ro:00003DF8 ; `vtable for'Base1
.data.rel.ro:00003DF8 _ZTV5Base1      DCB    0                ; DATA XREF: Base1::~Base1()+8o
.data.rel.ro:00003DF8                                         ; Derived::Derived(void)+26o ...
.data.rel.ro:00003DF9                 DCB    0
.data.rel.ro:00003DFA                 DCB    0
.data.rel.ro:00003DFB                 DCB    0
.data.rel.ro:00003DFC                 DCB    0
.data.rel.ro:00003DFD                 DCB    0
.data.rel.ro:00003DFE                 DCB    0
.data.rel.ro:00003DFF                 DCB    0
.data.rel.ro:00003E00                 DCD _ZN5Base11fEv+1
.data.rel.ro:00003E04                 DCD _ZN5Base11gEv+1
.data.rel.ro:00003E08                 DCD _ZN5Base11hEv+1
.data.rel.ro:00003E0C                 DCD _ZN5Base1D2Ev+1
.data.rel.ro:00003E10                 DCD _ZN5Base1D0Ev+1
.data.rel.ro:00003E14                 ALIGN 8
.data.rel.ro:00003E18                 WEAK _ZTV5Base2
.data.rel.ro:00003E18 ; `vtable for'Base2
.data.rel.ro:00003E18 _ZTV5Base2      DCB    0                ; DATA XREF: Base2::~Base2()+8o
.data.rel.ro:00003E18                                         ; Derived::Derived(void)+3Co ...
.data.rel.ro:00003E19                 DCB    0
.data.rel.ro:00003E1A                 DCB    0
.data.rel.ro:00003E1B                 DCB    0
.data.rel.ro:00003E1C                 DCB    0
.data.rel.ro:00003E1D                 DCB    0
.data.rel.ro:00003E1E                 DCB    0
.data.rel.ro:00003E1F                 DCB    0
.data.rel.ro:00003E20                 DCD _ZN5Base21fEv+1
.data.rel.ro:00003E24                 DCD _ZN5Base21gEv+1
.data.rel.ro:00003E28                 DCD _ZN5Base21hEv+1
.data.rel.ro:00003E2C                 DCD _ZN5Base2D2Ev+1
.data.rel.ro:00003E30                 DCD _ZN5Base2D0Ev+1
.data.rel.ro:00003E34                 ALIGN 8
.data.rel.ro:00003E38                 WEAK _ZTV7Derived
.data.rel.ro:00003E38 ; `vtable for'Derived
.data.rel.ro:00003E38 _ZTV7Derived    DCB    0                ; DATA XREF: Derived::~Derived()+Co
.data.rel.ro:00003E38                                         ; Derived::Derived(void)+52o ...
.data.rel.ro:00003E39                 DCB    0
.data.rel.ro:00003E3A                 DCB    0
.data.rel.ro:00003E3B                 DCB    0
.data.rel.ro:00003E3C                 DCB    0
.data.rel.ro:00003E3D                 DCB    0
.data.rel.ro:00003E3E                 DCB    0
.data.rel.ro:00003E3F                 DCB    0
.data.rel.ro:00003E40                 DCD _ZN7Derived1fEv+1
.data.rel.ro:00003E44                 DCD _ZN4Base1gEv+1
.data.rel.ro:00003E48                 DCD _ZN4Base1hEv+1
.data.rel.ro:00003E4C                 DCD _ZN7DerivedD2Ev+1
.data.rel.ro:00003E50                 DCD _ZN7DerivedD0Ev+1
.data.rel.ro:00003E54                 DCD _ZN7Derived2g1Ev+1
.data.rel.ro:00003E58                 DCD _ZN7Derived2h1Ev+1
.data.rel.ro:00003E5C                 DCB 0xFC ; 
.data.rel.ro:00003E5D                 DCB 0xFF
.data.rel.ro:00003E5E                 DCB 0xFF
.data.rel.ro:00003E5F                 DCB 0xFF
.data.rel.ro:00003E60                 DCB    0
.data.rel.ro:00003E61                 DCB    0
.data.rel.ro:00003E62                 DCB    0
.data.rel.ro:00003E63                 DCB    0
.data.rel.ro:00003E64                 DCD _ZThn4_N7Derived1fEv+1
.data.rel.ro:00003E68                 DCD _ZN5Base11gEv+1
.data.rel.ro:00003E6C                 DCD _ZN5Base11hEv+1
.data.rel.ro:00003E70                 DCD _ZThn4_N7DerivedD1Ev+1
.data.rel.ro:00003E74                 DCD _ZThn4_N7DerivedD0Ev+1
.data.rel.ro:00003E78                 DCB 0xF8 ; 
.data.rel.ro:00003E79                 DCB 0xFF
.data.rel.ro:00003E7A                 DCB 0xFF
.data.rel.ro:00003E7B                 DCB 0xFF
.data.rel.ro:00003E7C                 DCB    0
.data.rel.ro:00003E7D                 DCB    0
.data.rel.ro:00003E7E                 DCB    0
.data.rel.ro:00003E7F                 DCB    0
.data.rel.ro:00003E80                 DCD _ZThn8_N7Derived1fEv+1
.data.rel.ro:00003E84                 DCD _ZN5Base21gEv+1
.data.rel.ro:00003E88                 DCD _ZN5Base21hEv+1
.data.rel.ro:00003E8C                 DCD _ZThn8_N7DerivedD1Ev+1
.data.rel.ro:00003E90                 DCD _ZThn8_N7DerivedD0Ev+1
.data.rel.ro:00003E94                 ALIGN 8
.data.rel.ro:00003E94 ; .data.rel.ro  ends
    0x04 多型的實現
class Base {

public:
	Base() { ALOGD("Base ..."); }
	virtual void f() { ALOGD("Base::f"); }
	virtual void g() { ALOGD("Base::g"); }
	virtual void h() { ALOGD("Base::h"); }

	virtual ~Base() { ALOGD("~Base ...");  }

};
class Derived : public Base {

public:
	Derived() : Base()
	{ ALOGD("Derived ...");}
	virtual void f() { ALOGD("Derived::f"); }
	virtual void g1() { ALOGD("Derived::g"); }
	virtual void h1() { ALOGD("Derived::h"); }

	virtual ~Derived()
	{ ALOGD("~Derived ...");  }
};

class Derived1 : public Base {

public:
	Derived1() : Base()
	{ ALOGD("Derived1 ...");}
	virtual void f() { ALOGD("Derived1::f"); }
	virtual void g2() { ALOGD("Derived1::g"); }
	virtual void h2() { ALOGD("Derived1::h"); }

	virtual ~Derived1()
	{ ALOGD("~Derived1 ...");  }
};
Base* base;
	if (i == 0) {
		base = new Derived();
	} else {
		base = new Derived1();
	}
	fun(base);
	delete base;
    虛擬函式表如下:
.data.rel.ro:00003E30 ; Segment type: Pure data
.data.rel.ro:00003E30                 AREA .data.rel.ro, DATA, ALIGN=3
.data.rel.ro:00003E30                 ; ORG 0x3E30
.data.rel.ro:00003E30                 WEAK _ZTV4Base
.data.rel.ro:00003E30 ; `vtable for'Base
.data.rel.ro:00003E30 _ZTV4Base       DCB    0                ; DATA XREF: Base::~Base()+8o
.data.rel.ro:00003E30                                         ; Java_com_example_ndkreverse8_Lesson8_main+8o ...
.data.rel.ro:00003E31                 DCB    0
.data.rel.ro:00003E32                 DCB    0
.data.rel.ro:00003E33                 DCB    0
.data.rel.ro:00003E34                 DCB    0
.data.rel.ro:00003E35                 DCB    0
.data.rel.ro:00003E36                 DCB    0
.data.rel.ro:00003E37                 DCB    0
.data.rel.ro:00003E38                 DCD _ZN4Base1fEv+1
.data.rel.ro:00003E3C                 DCD _ZN4Base1gEv+1
.data.rel.ro:00003E40                 DCD _ZN4Base1hEv+1
.data.rel.ro:00003E44                 DCD _ZN4BaseD2Ev+1
.data.rel.ro:00003E48                 DCD _ZN4BaseD0Ev+1
.data.rel.ro:00003E4C                 ALIGN 0x10
.data.rel.ro:00003E50                 WEAK _ZTV7Derived
.data.rel.ro:00003E50 ; `vtable for'Derived
.data.rel.ro:00003E50 _ZTV7Derived    DCB    0                ; DATA XREF: Derived::~Derived()+8o
.data.rel.ro:00003E50                                         ; Java_com_example_ndkreverse8_Lesson8_main+2Co ...
.data.rel.ro:00003E51                 DCB    0
.data.rel.ro:00003E52                 DCB    0
.data.rel.ro:00003E53                 DCB    0
.data.rel.ro:00003E54                 DCB    0
.data.rel.ro:00003E55                 DCB    0
.data.rel.ro:00003E56                 DCB    0
.data.rel.ro:00003E57                 DCB    0
.data.rel.ro:00003E58                 DCD _ZN7Derived1fEv+1
.data.rel.ro:00003E5C                 DCD _ZN4Base1gEv+1
.data.rel.ro:00003E60                 DCD _ZN4Base1hEv+1
.data.rel.ro:00003E64                 DCD _ZN7DerivedD2Ev+1
.data.rel.ro:00003E68                 DCD _ZN7DerivedD0Ev+1
.data.rel.ro:00003E6C                 DCD _ZN7Derived2g1Ev+1
.data.rel.ro:00003E70                 DCD _ZN7Derived2h1Ev+1
.data.rel.ro:00003E74                 ALIGN 8
.data.rel.ro:00003E78                 WEAK _ZTV8Derived1
.data.rel.ro:00003E78 ; `vtable for'Derived1
.data.rel.ro:00003E78 _ZTV8Derived1   DCB    0                ; DATA XREF: Derived1::~Derived1()+8o
.data.rel.ro:00003E78                                         ; Java_com_example_ndkreverse8_Lesson8_main+58o ...
.data.rel.ro:00003E79                 DCB    0
.data.rel.ro:00003E7A                 DCB    0
.data.rel.ro:00003E7B                 DCB    0
.data.rel.ro:00003E7C                 DCB    0
.data.rel.ro:00003E7D                 DCB    0
.data.rel.ro:00003E7E                 DCB    0
.data.rel.ro:00003E7F                 DCB    0
.data.rel.ro:00003E80                 DCD _ZN8Derived11fEv+1
.data.rel.ro:00003E84                 DCD _ZN4Base1gEv+1
.data.rel.ro:00003E88                 DCD _ZN4Base1hEv+1
.data.rel.ro:00003E8C                 DCD _ZN8Derived1D2Ev+1
.data.rel.ro:00003E90                 DCD _ZN8Derived1D0Ev+1
.data.rel.ro:00003E94                 DCD _ZN8Derived12g2Ev+1
.data.rel.ro:00003E98                 DCD _ZN8Derived12h2Ev+1
.data.rel.ro:00003E9C                 ALIGN 0x10
.data.rel.ro:00003E9C ; .data.rel.ro  ends
    如何使用不同的方法呢?
.text:00001234                 EXPORT Java_com_example_ndkreverse8_Lesson8_main
.text:00001234 Java_com_example_ndkreverse8_Lesson8_main
.text:00001234                 PUSH            {R3-R5,LR}
.text:00001236                 MOVS            R0, #4  ; unsigned int ;只存放一個虛表指標,只申請了4個位元組3
.text:00001238                 LDR             R5, =(_ZTV4Base_ptr - 0x123E)
.text:0000123A                 ADD             R5, PC ; _ZTV4Base_ptr
.text:0000123C                 LDR             R5, [R5] ; `vtable for'Base
.text:0000123E                 CBNZ            R2, loc_126A ;判斷R2是否為0
.text:00001240                 BLX             _Znwj   ; operator new(uint)
.text:00001244                 ADDS            R5, #8
.text:00001246                 LDR             R2, =(aBase____0 - 0x124C)
.text:00001248                 ADD             R2, PC  ; "Base ..."
.text:0000124A                 STR             R5, [R0]
.text:0000124C                 MOV             R4, R0
.text:0000124E                 LDR             R5, =(aLesson8 - 0x1256)
.text:00001250                 MOVS            R0, #3
.text:00001252                 ADD             R5, PC  ; "lesson8"
.text:00001254                 MOV             R1, R5
.text:00001256                 BLX             __android_log_print
.text:0000125A                 LDR             R3, =(_ZTV7Derived_ptr - 0x1262)
.text:0000125C                 LDR             R2, =(aDerived____0 - 0x1268)
.text:0000125E                 ADD             R3, PC ; _ZTV7Derived_ptr
.text:00001260                 LDR             R3, [R3] ; `vtable for'Derived
.text:00001262                 ADDS            R3, #8
.text:00001264                 ADD             R2, PC  ; "Derived ..."
.text:00001266                 STR             R3, [R4]
.text:00001268                 B               loc_1292
.text:0000126A ; ---------------------------------------------------------------------------
.text:0000126A
.text:0000126A loc_126A                                ; CODE XREF: Java_com_example_ndkreverse8_Lesson8_main+Aj
.text:0000126A                 BLX             _Znwj   ; operator new(uint)
.text:0000126E                 ADDS            R5, #8
.text:00001270                 LDR             R2, =(aBase____0 - 0x1276)
.text:00001272                 ADD             R2, PC  ; "Base ..."
.text:00001274                 STR             R5, [R0]
.text:00001276                 MOV             R4, R0
.text:00001278                 LDR             R5, =(aLesson8 - 0x1280)
.text:0000127A                 MOVS            R0, #3
.text:0000127C                 ADD             R5, PC  ; "lesson8"
.text:0000127E                 MOV             R1, R5
.text:00001280                 BLX             __android_log_print
.text:00001284                 LDR             R2, =(aDerived1____0 - 0x128C)
.text:00001286                 LDR             R3, =(_ZTV8Derived1_ptr - 0x128E)
.text:00001288                 ADD             R2, PC  ; "Derived1 ..."
.text:0000128A                 ADD             R3, PC ; _ZTV8Derived1_ptr
.text:0000128C                 LDR             R3, [R3] ; `vtable for'Derived1
.text:0000128E                 ADDS            R3, #8
.text:00001290                 STR             R3, [R4]
.text:00001292
.text:00001292 loc_1292                                ; CODE XREF: Java_com_example_ndkreverse8_Lesson8_main+34j
.text:00001292                 MOV             R1, R5
.text:00001294                 MOVS            R0, #3
.text:00001296                 BLX             __android_log_print
.text:0000129A                 MOV             R0, R4  ; Base *
.text:0000129C                 BL              _Z3funP4Base ; fun(Base *);R0為物件首地址,為虛表指標,指向00003E58 DCD _ZN7Derived1fEv+1或者00003E80 DCD _ZN8Derived11fEv+1
.text:000012A0                 LDR             R3, [R4]
.text:000012A2                 MOV             R0, R4
.text:000012A4                 LDR             R3, [R3,#0x10]
.text:000012A6                 BLX             R3
.text:000012A8                 POP             {R3-R5,PC}
.text:000012A8 ; End of function Java_com_example_ndkreverse8_Lesson8_main
.text:0000122A                 EXPORT _Z3funP4Base
.text:0000122A _Z3funP4Base                            ; CODE XREF: Java_com_example_ndkreverse8_Lesson8_main+68p
.text:0000122A                 PUSH            {R3,LR}
.text:0000122C                 LDR             R3, [R0]
.text:0000122E                 LDR             R3, [R3] ;執行_ZN7Derived1fEv或者_ZN8Derived11fEv
.text:00001230                 BLX             R3
.text:00001232                 POP             {R3,PC}
.text:00001232 ; End of function fun(Base *)
.text:00001232
    0x05 總結

    只有虛擬函式才會出現在虛表中,如果函式為非虛擬函式,那麼不會出現在虛表中。

    子類的虛表中會出現父類的虛方法,如果子類覆蓋父類的虛方法,那麼在子類的虛表中父類的虛方法會被改寫為子類的方法,並且子類的虛表中子類的虛方法不會再出現該方法。