代码如下
classTest.h
class Base1
{
public:
virtual void vb1f() {printf("Base1 vb1f");}
virtual void vf() {printf("Base1 vf");}
};
class Base2
{
public:
virtual void vb2f() {printf("Base2 vb2f");}
virtual void vf() {printf("Base2 vf");}
};
class Drive : public Base1, Base2
{
public:
virtual void vdf() {printf("Driver vdf");}
virtual void vf() {printf("Driver vf");}
void f() {printf("Driver f");}
};
classTest.cpp
#include "ClassTest.h"
#include
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_idareversecppclass_JniPerson_createClsssTest(JNIEnv *env, jobject thiz, jlong addr,
jint age) {
jlong result;
result =(jlong) new Drive();//创建了一个Drive对象
return result;
}
将生成的so 放入IDA中分析
_DWORD *Java_com_example_idareversecppclass_JniPerson_createClsssTest()
{
_DWORD *result; // r0
result = (_DWORD *)operator new(8u);
*result = &off_26840; // 虚表1
result[1] = &off_26854; //虚表2
return result;
}
off_26840 指向的地址内容
.data.rel.ro:0002683C 6C 68 02 00 DCD _ZTI5Drive ; `typeinfo for'Drive
.data.rel.ro:00026840 D5 28 01 00 off_26840 DCD _ZN5Base14vb1fEv+1 ; Base1::vb1f(void)
.data.rel.ro:00026844 E1 28 01 00 DCD _ZN5Drive2vfEv+1 ; Drive::vf(void)
.data.rel.ro:00026848 ED 28 01 00 DCD _ZN5Drive3vdfEv+1 ; Drive::vdf(void)
.data.rel.ro:0002684C FC DCB 0xFC
.data.rel.ro:0002684D FF DCB 0xFF
.data.rel.ro:0002684E FF DCB 0xFF
.data.rel.ro:0002684F FF DCB 0xFF
第一个函数是 Base1::vb1f(void)
第二个函数是 Drive::vf(void)
第三个函数是 Drive::vdf(void)
off_26854 指向的地址内容
.data.rel.ro:00026850 6C 68 02 00 DCD _ZTI5Drive ; `typeinfo for'Drive
.data.rel.ro:00026854 F9 28 01 00 off_26854 DCD _ZN5Base24vb2fEv+1; Base2::vb2f(void)
.data.rel.ro:00026858 05 29 01 00 DCD _ZThn4_N5Drive2vfEv+1 ; `non-virtual thunk to'Drive::vf(void)
第一个函数是 Base2::vb2f(void)
第二个函数是 `non-virtual thunk to’Drive::vf(void)
于是给 MyDrive建立结构体如下
struct MyDrive
{
int driveVtable1;
int driveVtable2;
};
struct DriveVtable1
{
int field_0;
int field_4;
int field_8;
};
struct DriveVtable2
{
int field_0;
int field_4;
};
修改后代码
MyDrive *Java_com_example_idareversecppclass_JniPerson_createClsssTest()
{
MyDrive *result; // r0
result = (MyDrive *)operator new(8u);
result->driveVtable1 = &stru_26840; // 虚表1
//
//
// 虚表2
result->driveVtable2 = &stru_26854;
return result;
}
代码
class Base
{
public:
virtual void vbbf() {printf("base vbbf");}
virtual void vbf() {printf("base vbf");}
};
class Base1 : virtual public Base
{
public:
virtual void vb1f() {printf("base1 vb1f");}
virtual void vf() {printf("base1 vf");}
};
class Base2 : virtual public Base
{
public:
virtual void vb2f() {printf("base2 vb2f");}
virtual void vf() {printf("base2 vf");}
};
class Drive : virtual public Base1, virtual public Base2
{
public:
virtual void vdf() {printf("drive vdf");}
virtual void vf() {printf("drive vf");}
void f() {}
};
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_idareversecppclass_JniPerson_createLxClsssTest(JNIEnv *env, jobject thiz) {
jlong result;
result =(jlong) new Drive();
return result;
}
反汇编的代码
_DWORD *Java_com_example_idareversecppclass_JniPerson_createLxClsssTest()
{
_DWORD *result; // r0
result = (_DWORD *)operator new(8u);
*result = &off_26BA0;
result[1] = &unk_26BD0;
return result;
}
off_26BA0指向的地址内容
.data.rel.ro:00026BA0 C1 2B 01 00 off_26BA0 DCD _ZN4Base4vbbfEv+1 ; Base::vbbf(void)
.data.rel.ro:00026BA4 CD 2B 01 00 DCD _ZN4Base3vbfEv+1 ; Base::vbf(void)
.data.rel.ro:00026BA8 65 2B 01 00 DCD _ZN5Base14vb1fEv+1 ; Base1::vb1f(void)
.data.rel.ro:00026BAC D9 2B 01 00 DCD _ZN7Drive112vfEv+1 ; Drive11::vf(void)
.data.rel.ro:00026BB0 E5 2B 01 00 DCD _ZN7Drive113vdfEv+1 ; Drive11::vdf(void)
第一个函数 Base::vbbf(void)
第二个函数 Base::vbf(void)
第三个函数 Base1::vb1f(void)
第四个函数 Drive11::vf(void)
第五个函数 Drive11::vdf(void)
unk_26BD0指向的地址内容
.data.rel.ro:00026BD0 00 00 00 00 dword_26BD0 DCD 0
.data.rel.ro:00026BD4 00 00 00 00 DCD 0
.data.rel.ro:00026BD8 89 2B 01 00 DCD _ZN5Base24vb2fEv+1 ; Base2::vb2f(void)
.data.rel.ro:00026BDC F1 2B 01 00 DCD _ZTv0_n28_N7Drive112vfEv+1 ; `virtual thunk to'Drive11::vf(void)
第一个函数 0
第二个函数 0
第三个函数 Base2::vb2f(void)
第四个函数 `virtual thunk to’Drive11::vf(void)