网友说是 hack 手段,还没有时间深入了解,不明觉厉。
[沪]风舞轻扬(81924320) 2016-10-25 16:59:08
TGrandpaObject = classpublic procedure AVirtualMethod; virtual;end;TParentObject = class(TGrandpaObject)public procedure AVirtualMethod; override;end;TCurrentObject = class(TParentObject)public procedure AVirtualMethod; override;end;TCurrentObject的AVirtualMethod虚拟方法不希望调用父类TParentObject的AVirtualMethod方法的实现代码,而要直接继承调用祖父类TGrandpaObject的AVirtualMethod方法代码。类的继承体系中,在VMT中,子类的VMT完全包含父类的VMT,而自身的虚拟方法则是附着在VMT父类虚拟方法表的后面,也就是说子类虚拟方法和父类虚拟方法的相对偏移量是相同的,只是子类的虚拟方法有覆盖时,子类VMT中该虚拟方法的地址被覆盖啦。因此,要跳过父类的虚拟方法而直接调用祖父类的虚拟方法代码,那么只要通过VMT的虚拟方法的相对偏移量找到祖父类的虚拟方法地址,然后调用即可。procedure TCurrentObject.AVirtualMethod;begin asm MOV EDX,VMTOFFSET AVirtualMethod // 虚拟方法VMT偏移量 MOV EAX,Self // 对象实例 => EAX MOV ECX,[EAX] // 类VMT => ECX MOV ECX,[ECX].vmtParent MOV ECX,[ECX] // 父类VMT => ECX MOV ECX,[ECX].vmtParent MOV ECX,[ECX] // 祖父类VMT => ECX MOV ECX,[ECX+EDX] // 祖父类虚拟方法地址 => ECX CALL ECX // 方法调用 end;end;