如何获取VMT中的条目数(虚拟方法)?

时间:2017-08-20 14:57:14

标签: delphi hook virtual-method vmt

在正偏移处,VMT存储指向所有用户定义的虚拟方法的指针 我需要编写一些代码来挂钩VMT。 我这样做的方法是在祖先类中获取指向虚方法的指针 让我们说:TCustomForm.ShowModal。然后我在TCustomForm的VMT中查找偏移量。有了这个偏移量,我转到TMyForm并改变其VMT以指向我需要的功能。

我想概括一下这个方法,为了做到这一点,我想知道VMT持有的条目总数,所以我不会搜索结束。

如何获取VMT(用户可定义部分)的大小?

2 个答案:

答案 0 :(得分:0)

通过RTL源我认为这是获得计数的方法:

num_photos

如果需要,请随时纠正我。

答案 1 :(得分:0)

如果没有对VMT结构的实际了解,并且因此当VMT结构再次改变时不太容易破坏,那么这样做的方法就是使用Rtti。 TRttiInstanceType知道关联类的VmtSize

因此使用VmtSize和VMT条目为Pointer

function GetVirtualMethodCount(AClass: TClass): Integer;
var
  AContext: TRttiContext;
  AType: TRttiType;
begin
  AType := AContext.GetType(AClass);
  Result := (AType as TRttiInstanceType).VmtSize div SizeOf(Pointer);
end;

然而,这将包括从基类继承的所有条目。包括来自TObject的负偏移量。但是可以从给定的基类中减去所有条目,例如TObject。这是一个提供变量基类的方法:

function GetVirtualMethodCountMinusBase(AClass: TClass; ABaseClass: TClass): Integer;
var
  AContext: TRttiContext;
  AType, ABaseType: TRttiType;
begin
  AType := AContext.GetType(AClass);
  ABaseType := AContext.GetType(ABaseClass);
  Result := ((AType as TRttiInstanceType).VmtSize - (ABaseType as TRttiInstanceType).VmtSize) div SizeOf(Pointer);
end;

:使用 Jedi 时,JclSysUtils中有一个名为GetVirtualMethodCount的函数。虽然我不确定这是否是最新的和正确的。