首先我们新建一个类叫Person
class Person {
public:
Person() {
age = 31;
time = 1234567890123
name = "fly";
printf("Person:Person() called\n");
};
virtual ~Person() {
printf("Person:~Person() called\n");
}
virtual int getAge() {
return age;
}
virtual void setAge(int age_) {
age = age_;
}
void init() {
name = "test";
namestd = "teststd";
}
public:
int age;
long time ;
char * name;
};
c++ 反汇编原理
一个c++类包含多个方法和字段 用结构体表示
如:
struct xxx
{
void* ptr1;
void* ptr2;
var_tyoe1 var1;
}
c++类的构造与使用在编译完成后遵循一下规则
1 由new完成类大小字节的内存空间
2 执行当前类的初始化
3如果当前的类父类 则在父类中出初始基类的vtable 和成员变量
4 如果父类还有其他的父类 则执行上面的步骤
5 所有都初始化完成后 在后最底层那个父类初始化当前类的vtable与成员变量
6 初始化完成过后,通过访问vtable中的指针调用当前的类的虚方法
同步c++ 的类
没有同步之前
该类的大致信息如上
1 在类初始化的地方点进去查看vtable成员指针
Person *v1; // ST04_4
v1 = (Person *)this;
Person::Person((Person *)this);
LODWORD(v1->vtable) = off_1148 #双击进入vtabble 表位置 由于我已经改过名字了 所以off_1148对应就是上图vtbp_Person的位置
//如果没有被隐藏符号化 看到的就是这个类的 成员了
.data.rel.ro:0004CEA8 stu_vtable DCD _ZN7StudentD2Ev ; Student::~Student()
.data.rel.ro:0004CEAC DCD _ZN7StudentD0Ev ; Student::~Student()
.data.rel.ro:0004CEB0 DCD _ZN7Student6getAgeEv ; Student::getAge(void)
.data.rel.ro:0004CEB4 DCD _ZN6Person6setAgeEi ; Person::setAge(int)
.data.rel.ro:0004CEB8 WEAK _ZTV6Person //弱应用
2 添加结构体详细信息
函数包含 构造函数 析构函数 和 getAge ,setAge 4个函数 跟开始写的类源码 能一一对应了
成员包含 初始化 包含3 个
因此我们 开始构建结构体
在ida 结构体 tab 页 按下insert
输入新建的名字 Person
2.1将鼠标放在 ends这一行,单击快捷键D即可添加结构体成员,成员的命名默认是以field_x表示的,x代表了该成员在结构体
备注:一般类结构体 第一个是vtable 指针集合 以后是成员
2.2 把鼠标放在结构体刚刚创建的成员所在的行,按D,就可以切换不同的字节大小
默认情况下可供选择的就只有db,dw,dd(1,2,4字节大小)
如果想添加型的类型,可以在option-->setup data types(快捷键Alt+D),进行设置 选项-》设置数据类型
通过以上操作我们构建的结构体如下
vtable 表如下
3 新建了结构体就可以在原来不被认识的类的地方 《右键-> 转换为结构体* convert to stuct*》 在结构体列表选择刚刚创建的结构体就ok了
如果转化正确应该效果如下图
没有同步结构体之前
同步之后 一下结构清晰了很多
练习demo 链接:https://pan.baidu.com/s/1Z6dTTldRWH-nYlrGdWR1ig
提取码:po0j