Android SO逆向-对象的继承和虚函数

    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 ...


    0x02

    下面我们使用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,#
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值