问题描述
class Ex2
{
private:
int var1 = 9999;
public:
virtual int sum(int x,int y) {
return x + y;
}
virtual void virtual_func1() {
cout << "Ex2->virtual_func1" << endl;
}
virtual int funky(int a) {
return (a * var1);
}
};
class Ex3 : public Ex2
{
private:
int var1 = 7777;
public:
int subtract(int x,int y) {
return x - y;
}
virtual void virtual_func1() {
cout << "Ex3->virtual_func1" << endl;
}
int funky(int a) {
return (a * var1 + 2);
}
};
int main(int argc,char** argv,char** envp) {
Ex3* e = new Ex3();
e->virtual_func1();
e->funky(5)
delete(e);
}
这是示例代码,所以我期望的是通过vtable解析该函数,它做得很好,还可以通过ecx
传递它,以便函数可以使用int var1
变量>
然后我将代码修改为
class Ex2
{
private:
int var1 = 9999;
public:
virtual int sum(int x,int y) {
return x + y;
}
virtual void virtual_func1() {
cout << "Ex2->virtual_func1" << endl;
}
virtual int funky(int a,int b) {
return (a * b);
}
};
class Ex3 : public Ex2
{
private:
int var1 = 7777;
public:
int subtract(int x,int y) {
return x - y;
}
virtual void virtual_func1() {
cout << "Ex3->virtual_func1" << endl;
}
int funky(int a,int b) {
return (a * b + 2);
}
};
int main(int argc,char** envp) {
Ex3* e = new Ex3();
e->virtual_func1();
e->funky(8,4);
delete(e);
}
这反汇编为:
push esi
push 0Ch ; Size
call operator new(uint)
mov esi,eax
add esp,4
mov ecx,esi
mov dword ptr [esi+4],270Fh ;constructor inlined?
mov dword ptr [esi],offset const Ex3::`vftable' ;constructor inlined?
mov dword ptr [esi+8],1E61h ;constructor inlined?
call sub_401010
mov edx,[esi]
mov ecx,esi ;ecx as this
push 4 ;push as para1
push 8 ;push as para2
call dword ptr [edx+8] ;vtable call
push 0Ch
push esi ; Memory
call sub_40140B
add esp,8
xor eax,eax
pop esi
retn
所以我想知道为什么在绝对不需要访问自己的内存时他为什么添加this
?
此外,造成这种混乱的原因是
virtual void virtual_func1() {
cout << "Ex2->virtual_func1" << endl;
}
应该是vtable调用,但以某种方式直接调用
call sub_401010
vtable
.rdata:004031C0 const Ex3::`vftable' dd offset sub_401000
.rdata:004031C0 ; DATA XREF: _main+16↑o
.rdata:004031C4 dd offset sub_401010
.rdata:004031C8 dd offset sub_401030
为什么决定绕过vtable?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)