0x00
这一节我们要讨论对象的继承和虚函数的汇编实现。
0x01
我们先直接看汇编代码:
#include "com_example_ndkreverse6_Lesson6.h"
#include <android/log.h>
#define LOG_TAG "lesson6"
#define ALOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
class Base {
public:
virtual void display() { //虚函数,virtual声明的函数,向上转型后的对象才能调用到子类同名的方法
ALOGD("Base:%d, BaseChar:%d", base_, baseChar_);
}
Base(int base) {
base_ = base;
baseChar_ = 8;
ALOGD("Base ...");
}
virtual ~Base() { //虚析构函数,只有声明成virtual,向上转型的对象先调用子类的析构函数,再调用父类的析构函数
ALOGD("~Base ...");
}
private:
int base_;
char baseChar_;
};
class Derived: public Base {
public:
virtual void display() { //覆盖父类的方法
ALOGD("Derived:%d, DerivedChar:%d", derived_, derivedChar_);
Base::display(); //使用父类的方法,由于是覆盖,所以同名,要用这种方式来引用
}
Derived(int derived) :
Base(derived) {
derived_ = derived;
derivedChar_ = 10;
ALOGD("Derived ...");
}
~Derived() {
ALOGD("~Derived ...");
}
private:
int derived_;
char derivedChar_;
};
JNIEXPORT void JNICALL Java_com_example_ndkreverse6_Lesson6_main
(JNIEnv * env, jobject jobject) {
Base* d = new Derived(18);
d->display();
delete d;
}
那么,运行后执行的结果如下:
D/lesson6 (28959): Base ...
D/lesson6 (28959): Derived ...
D/lesson6 (28959): Derived:18, DerivedChar:10
D/lesson6 (28959): Base:18, BaseChar:8
D/lesson6 (28959): ~Derived ...
D/lesson6 (28959): ~Base ...
下面我们使用ida来打开so,对汇编代码做出解释。该汇编代码使用的是调试状态下的汇编代码。
.text:00003088 EXPORT Java_com_example_ndkreverse6_Lesson6_main
.text:00003088 Java_com_example_ndkreverse6_Lesson6_main
.text:00003088 PUSH {R4-R6,LR}
.text:0000308A MOVS R0, #0x14 ; unsigned int R0被分配为20,表示要分配20个字节的内存单元
.text:0000308C BL _Znwj ; operator new(uint) 分配20个字节大小的内存单元
.text:00003090 LDR R3, =(_ZTV4Base_ptr - 0x3098) ;直接调用Base的构造函数
.text:00003092 MOVS R6, #0x12 ;R6被初始化为18
.text:00003094 ADD R3, PC ; _ZTV4Base_ptr
.text:00003096 LDR R3, [R3] ; `vtable for'Base 取出Base的虚表指针,指向.data.rel.ro,即0x70428960
.text:00003098 MOVS R4, R0 ;R0为刚分配的20个字节大小的内存单元的首地址,现在赋值给R4
.text:0000309A ADDS R3, #8 ;R3+8再赋值给R3,R3指向了0x70428968
.text:0000309C STR R3, [R0] ;将0x70428968赋值给刚分配的内存单元的首地址(所指向的内存单元)
.text:0000309E MOVS R3, #8 ;R3被赋值为8
.text:000030A0 LDR R5, =(aLesson6 - 0x30AA)
.text:000030A2 LDR R2, =(aBase____0 - 0x30B0)
.text:000030A4 STR R6, [R0,#