安卓c++虚函数解密
来源:互联网 发布:类似于柏拉图软件 编辑:程序博客网 时间:2024/06/03 21:08
使用arm-none-linux-gnueabi-gcc 编译程序
下载链接: arm-2010.09-50-arm-none-linux-gnueabi
编译程序
1) sudo gedit ~/.bashrc
2) 在文件末尾添加如下的一行
export PATH=$PATH:/....../....../arm-2010.09-50/bin
3) 保存文件并退出
4) 运行命令 source ~/.bashrc
5) 用命令行验证一下是否成功: arm-none-linux-gnueabi-gcc --version。'
6) 编译: arm-none-linux-gnueabi-g++ -static hello.cpp -o hello
0x01 无继承
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
class BaseA
{
private:
int baseA_field;
public:
BaseA(int baseA_field);
~BaseA();
virtual void baseA_virtual_1()
{
printf("[-] BaseA::baseA_virtual_1()\n");
}
virtual void baseA_virtual_2()
{
printf("[-]BaseA::baseA_virtual_2()\n");
}
virtual void baseA_virtual_3()
{
printf("[-]BaseA::baseA_virtual_3()\n");
}
};
BaseA::BaseA(intbaseA_field)
{
printf("[+] BaseA constructorcalled\n");
this->baseA_field = baseA_field;
}
BaseA::~BaseA()
{
printf("[+] BaseA destructorcalled\n\n");
}
int main(int argc,char *argv[])
{
getchar();
BaseA *baseA = new BaseA(1);
baseA->baseA_virtual_2();
delete baseA;
return 0;
}
F5反编译的结果
初步分析:
(*(*v1 + 4))(v1)
v1: this指针
*v1: 虚表指针
*v1 + 4: 虚表项2指针
(*(*v1 + 4)): 虚函数2指针
(*(*v1 + 4))(v1): 虚函数2调用,只有1个this指针参数
申请对象空间
调用构造函数
C++对象的内存布局为: 虚表指针 + 成员变量
跟随虚表指针,可以看到具体的虚表项(里面是虚函数指针)
每一项占4个字节
调用虚函数
0x02单继承、无重写虚函数
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
class BaseA
{
private:
int baseA_field;
public:
BaseA(int baseA_field);
~BaseA();
virtual void baseA_virtual_1()
{
printf("[-]BaseA::baseA_virtual_1()\n");
}
virtual void baseA_virtual_2()
{
printf("[-]BaseA::baseA_virtual_2()\n");
}
virtual void baseA_virtual_3()
{
printf("[-]BaseA::baseA_virtual_3()\n");
}
};
BaseA::BaseA(intbaseA_field)
{
printf("[+] BaseA constructorcalled\n");
this->baseA_field = baseA_field;
}
BaseA::~BaseA()
{
printf("[+] BaseA destructorcalled\n\n");
}
class SubClass:public BaseA
{
private:
int subClass_field;
public:
SubClass(int subClass_field, intbaseA_field);
~SubClass();
virtual void subClass_virtula_1()
{
printf("[-] SubClass::subClass_virtula_1()\n");
}
virtual void subClass_virtula_2()
{
printf("[-]SubClass::subClass_virtula_2()\n");
}
virtual void subClass_virtula_3()
{
printf("[-]SubClass::subClass_virtula_3()\n");
}
};
SubClass::SubClass(intsubClass_field, int baseA_field) : BaseA(baseA_field)
{
printf("[+] SubClass constructorcalled\n");
this->subClass_field =subClass_field;
}
SubClass::~SubClass()
{
printf("[+] SubClass destructorcalled\n\n");
}
int main(int argc,char *argv[])
{
getchar();
SubClass *subClass = new SubClass(2,1);
subClass->subClass_virtula_3();
delete subClass;
return 0;
}
F5反汇编
申请对象空间
调用构造函数
C++对象的内存布局为: 虚表指针 + 父类成员变量 + 子类成员变量
虚表内容
子类虚函数跟在父类虚函数后面
调用虚函数subClass_virtual_3
0x03 单继承、有重写虚函数
申请对象空间
构造函数
C++对象的内存布局为: 虚表指针 + 父类成员变量 + 子类成员变量
虚表内容
父类被覆盖,一共只有5项
调用虚函数baseA_virtual_2()
0x04 多继承、无重写虚函数
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
class BaseA
{
private:
int baseA_field;
public:
BaseA(int baseA_field);
~BaseA();
virtual void virtual_1()
{
printf("[-]BaseA::virtual_1()\n");
}
virtual void virtual_2()
{
printf("[-]BaseA::virtual_2()\n");
}
virtual void baseA_virtual_3()
{
printf("[-]BaseA::baseA_virtual_3()\n");
}
};
BaseA::BaseA(int baseA_field)
{
printf("[+] BaseA constructorcalled\n");
this->baseA_field = baseA_field;
}
BaseA::~BaseA()
{
printf("[+] BaseA destructorcalled\n\n");
}
class BaseB
{
private:
int baseB_field;
public:
BaseB(int baseB_field);
~BaseB();
virtual void virtual_1()
{
printf("[-]BaseB::virtual_1()\n");
}
virtual void virtual_2()
{
printf("[-]BaseB::virtual_2()\n");
}
virtual void baseB_virtual_3()
{
printf("[-]BaseB::baseB_virtual_3()\n");
}
};
BaseB::BaseB(intbaseB_field)
{
printf("[+] BaseB constructorcalled\n");
this->baseB_field = baseB_field;
}
BaseB::~BaseB()
{
printf("[+] BaseB destructorcalled\n\n");
}
class BaseC
{
private:
int baseC_field;
public:
BaseC(int baseC_field);
~BaseC();
virtual void virtual_1()
{
printf("[-]BaseC::virtual_1()\n");
}
virtual void baseC_virtual_2()
{
printf("[-]BaseC::baseB_virtual_3()\n");
}
};
BaseC::BaseC(intbaseC_field)
{
printf("[+] BaseC constructorcalled\n");
this->baseC_field = baseC_field;
}
BaseC::~BaseC()
{
printf("[+] BaseC destructorcalled\n\n");
}
class SubClass:public BaseA, public BaseB, public BaseC
{
private:
int subClass_field;
public:
SubClass(int subClass_field, intbaseA_field, int baseB_field, int baseC_field);
~SubClass();
virtual void subClass_virtual_1()
{
printf("[-]SubClass::subClass_virtula_1()\n");
}
virtual void subClass_virtual_2()
{
printf("[-]SubClass::subClass_virtula_1()\n");
}
virtual void subClass_virtual_3()
{
printf("[-]SubClass::subClass_virtula_3()\n");
}
};
SubClass::SubClass(intsubClass_field, int baseA_field, int baseB_field, int baseC_field)
: BaseA(baseA_field),BaseB(baseB_field), BaseC(baseC_field)
{
printf("[+] SubClass constructorcalled\n");
this->subClass_field =subClass_field;
}
SubClass::~SubClass()
{
printf("[+] SubClass destructorcalled\n\n");
}
int main(int argc,char *argv[])
{
getchar();
SubClass *subClass = new SubClass(4, 3,2, 1);
subClass->BaseA::virtual_1(); //静态调用
subClass->baseB_virtual_3();
subClass->subClass_virtual_1();
delete subClass;
return 0;
}
F5反汇编
构造函数
查看虚表内容
静态调用虚函数BaseA_virtual_1
静态函数地址固定,无需通过虚表寻找。
移动指针指向虚表第三项,即BaseB::baseB_virtual_3
调用虚函数BaseB::baseB_virtual_3
调用虚函数SubClass::subClass_virtual_1
0x05 多继承、有重写虚函数
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
class BaseA
{
private:
int baseA_field;
public:
BaseA(int baseA_field);
~BaseA();
virtual void virtual_1()
{
printf("[-]BaseA::virtual_1()\n");
}
virtual void virtual_2()
{
printf("[-]BaseA::virtual_2()\n");
}
virtual void baseA_virtual_3()
{
printf("[-]BaseA::baseA_virtual_3()\n");
}
};
BaseA::BaseA(intbaseA_field)
{
printf("[+] BaseA constructorcalled\n");
this->baseA_field = baseA_field;
}
BaseA::~BaseA()
{
printf("[+] BaseA destructorcalled\n\n");
}
class BaseB
{
private:
int baseB_field;
public:
BaseB(int baseB_field);
~BaseB();
virtual void virtual_1()
{
printf("[-]BaseB::virtual_1()\n");
}
virtual void virtual_2()
{
printf("[-]BaseB::virtual_2()\n");
}
virtual void baseB_virtual_3()
{
printf("[-]BaseB::baseB_virtual_3()\n");
}
};
BaseB::BaseB(intbaseB_field)
{
printf("[+] BaseB constructorcalled\n");
this->baseB_field = baseB_field;
}
BaseB::~BaseB()
{
printf("[+] BaseB destructorcalled\n\n");
}
class BaseC
{
private:
int baseC_field;
public:
BaseC(int baseC_field);
~BaseC();
virtual void virtual_1()
{
printf("[-]BaseC::virtual_1()\n");
}
virtual void baseC_virtual_2()
{
printf("[-]BaseC::baseB_virtual_3()\n");
}
};
BaseC::BaseC(intbaseC_field)
{
printf("[+] BaseC constructorcalled\n");
this->baseC_field = baseC_field;
}
BaseC::~BaseC()
{
printf("[+] BaseC destructorcalled\n\n");
}
class SubClass:public BaseA, public BaseB, public BaseC
{
private:
int subClass_field;
public:
SubClass(int subClass_field, intbaseA_field, int baseB_field, int baseC_field);
~SubClass();
virtual void virtual_1()
{
printf("[-]SubClass::virtual_1()\n");
}
virtual void virtual_2()
{
printf("[-]SubClass::virtual_2()\n");
}
virtual void baseC_virtual_2()
{
printf("[-]SubClass::baseC_virtual_2()\n");
}
virtual void subClass_virtual_3()
{
printf("[-]SubClass::subClass_virtual_3()\n");
}
};
SubClass::SubClass(intsubClass_field, int baseA_field, int baseB_field, int baseC_field)
: BaseA(baseA_field),BaseB(baseB_field), BaseC(baseC_field)
{
printf("[+] SubClass constructorcalled\n");
this->subClass_field =subClass_field;
}
SubClass::~SubClass()
{
printf("[+] SubClass destructorcalled\n\n");
}
int main(int argc,char *argv[])
{
getchar();
SubClass *subClass = new SubClass(4, 3,2, 1);
((BaseA *)subClass)->virtual_1();
((BaseB *)subClass)->virtual_2();
((BaseC *)subClass)->virtual_1();
((BaseC*)subClass)->baseC_virtual_2();
delete subClass;
return 0;
}
F5反汇编
构造函数
C++对象内存布局:
第一继承对象(虚表指针+成员变量) 第二继承对象(虚表指针+成员变量)
第三继承对象(虚表指针+成员变量) 本身成员变量
虚表内容
调用虚函数((BaseA *)subClass)->virtual_1()
调用虚函数((BaseB *)subClass)->virtual_2();
调用虚函数((BaseC *)subClass)->virtual_1();
调用虚函数((BaseC *)subClass)->baseC_virtual_2();
0x06 总结
1). 单继承虚表结构:
1个虚表,按照父类虚函数 + 子类虚函数顺序排列
2). 多继承虚表结构:
多少个父类对应多少个虚表,子类的虚函数跟在第一个父类虚函数后面
3). 单继承虚函数调用过程:
this指针 -> 虚表指针 -> 移动虚表指针 -> 取虚函数 -> 调用虚函数(this指针)
4). 多继承虚函数调用过程:
移动this指针到父类部分 -> 父类虚表指针 -> 移动虚表指针 -> 取虚函数 -> 调用虚函数(this指针父类部分)
5). 有重写虚函数时,父类虚函数表对应函数指针被覆盖。
0x07 参考文献
从Arm汇编看Android C++虚函数实现原理
http://manyface.github.io/2016/06/21/cppVirtualMethod/
- 安卓c++虚函数解密
- 安卓AES加密解密
- 安卓DES加密解密
- 安卓RSA加密解密
- 字符串加密解密函数 (C#)
- ios 安卓 javaweb RSA加密解密
- ios 安卓 javaweb RSA加密解密
- 安卓使用加解密异常集合
- 对安卓apk进行加密解密
- C#PDU编码UCS2加密解密函数
- C#PDU编码UCS2加密解密函数
- 安卓客户端、PHP服务端AES加密解密
- 安卓NDK开发案列一:字符串的加密和解密
- 安卓AES加解密(兼容Android7.0)
- 安卓3DES加解密(kotlin)
- 解决linux c利用openssl进行3des和安卓封装的接口加密解密出的字符串不一样的问题
- 安卓开发-函数总结
- JavaScript调用安卓函数
- Retrofit(一)、Retrofit+OkHttp实现简单的Get与Post请求
- 3442: 学习小组
- const与指针、成员函数、#define
- stm32 延时 delay us ms
- C++的指针
- 安卓c++虚函数解密
- js如何获取json数组的长度
- Python核心基础:之二:基础语法
- 9、Oracle: ROWNUM用法和分页查询总结
- c++多态
- HTML发展历史
- 静态IP配置
- 理解Guice--Java依赖注入框架
- 编译错误信息收集