Android SO逆向-C++虛擬函式表解析
阿新 • • 發佈:2019-02-19
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 總結只有虛擬函式才會出現在虛表中,如果函式為非虛擬函式,那麼不會出現在虛表中。
子類的虛表中會出現父類的虛方法,如果子類覆蓋父類的虛方法,那麼在子類的虛表中父類的虛方法會被改寫為子類的方法,並且子類的虛表中子類的虛方法不會再出現該方法。