Где я могу найти информацию о структуре Delphi VMT? - PullRequest
12 голосов
/ 17 апреля 2009

Файл System.pas содержит достаточное количество информации о жестко закодированных смещениях VMT, но, похоже, фактически не говорит о структуре самого VMT. Что я действительно хотел бы знать, так это то, есть ли способ узнать размер VMT во время выполнения или, другими словами, сколько виртуальных методов существует для данного класса?

Ответы [ 5 ]

13 голосов
/ 17 апреля 2009

Какую структуру VMT вы хотите знать? Вы также знаете, что это внутренняя деталь реализации, которая может быть изменена (и изменилась с течением времени).

Чтобы ответить на ваш конкретный вопрос, вот простой способ узнать количество виртуальных методов для данного класса:

function GetVirtualMethodCount(AClass: TClass): Integer;
begin
  Result := (PInteger(Integer(AClass) + vmtClassName)^ - 
    (Integer(AClass) + vmtParent) - SizeOf(Pointer)) div SizeOf(Pointer);
end;

Это работает, потому что я знаю, что строка, представляющая имя класса, помещается сразу после всех векторов виртуальных методов в VMT.

Я также знаю, что существует 11 виртуальных методов (для D2009, 9 для D2007 и ранее) на всех объектах TO, которые отрицательно смещены от самого указателя VMT.

Вот причина ссылки на vmtParent.

Наконец, используя ссылку на класс TClass, вы можете передать любой производный класс TObject в эту функцию и получить количество виртуальных методов.

9 голосов
/ 17 апреля 2009

Я был почти уверен, что у Халварда было что-то на ВМТ. Конечно же, у него есть Hack # 8: явные вызовы VMT , которые ссылаются на Рэя Лишнера Секреты Delphi 2 и Delphi в двух словах .

Вот его взломанная версия VMT

type
  PClass = ^TClass;
  PSafeCallException = function  (Self: TObject; ExceptObject:
    TObject; ExceptAddr: Pointer): HResult;
  PAfterConstruction = procedure (Self: TObject);
  PBeforeDestruction = procedure (Self: TObject);
  PDispatch          = procedure (Self: TObject; var Message);
  PDefaultHandler    = procedure (Self: TObject; var Message);
  PNewInstance       = function  (Self: TClass) : TObject;
  PFreeInstance      = procedure (Self: TObject);
  PDestroy           = procedure (Self: TObject; OuterMost: ShortInt);
  PVmt = ^TVmt;
  TVmt = packed record
    SelfPtr           : TClass;
    IntfTable         : Pointer;
    AutoTable         : Pointer;
    InitTable         : Pointer;
    TypeInfo          : Pointer;
    FieldTable        : Pointer;
    MethodTable       : Pointer;
    DynamicTable      : Pointer;
    ClassName         : PShortString;
    InstanceSize      : PLongint;
    Parent            : PClass;
    SafeCallException : PSafeCallException;
    AfterConstruction : PAfterConstruction;
    BeforeDestruction : PBeforeDestruction;
    Dispatch          : PDispatch;
    DefaultHandler    : PDefaultHandler;
    NewInstance       : PNewInstance;
    FreeInstance      : PFreeInstance;
    Destroy           : PDestroy;
   {UserDefinedVirtuals: array[0..999] of procedure;}
  end;

Вам нужно будет прочитать его статью, чтобы узнать больше о взломе.

2 голосов
/ 17 апреля 2009

Я подключу свой собственный сайт для этого:

Что такое таблица виртуальных методов?

Это точно с Delphi 2005, я думаю.

VMT не имеет никакого значения, указывающего количество указателей виртуальных методов, которые он содержит. Только компилятору нужно знать эту информацию, поэтому нет причин записывать ее для использования во время выполнения.

2 голосов
/ 17 апреля 2009

Googling :-P для "delphi vmt" дает this . Может быть, это дает вам начало.

0 голосов
/ 17 апреля 2009

я помню, что была некоторая информация о delphi vmt в книге "delphi in a Nutshell". Вы можете начать с delphi в двух словах, глава 2 или this

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...