Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  4 298

•  TDictionary Custom Sort  6 346

•  Fast Watermark Sources  6 136

•  3D Designer  9 070

•  Sik Screen Capture  6 457

•  Patch Maker  6 870

•  Айболит (remote control)  6 857

•  ListBox Drag & Drop  5 733

•  Доска для игры Реверси  96 623

•  Графические эффекты  7 075

•  Рисование по маске  6 377

•  Перетаскивание изображений  5 250

•  Canvas Drawing  5 620

•  Рисование Луны  5 320

•  Поворот изображения  4 869

•  Рисование стержней  3 455

•  Paint on Shape  2 713

•  Генератор кроссвордов  3 589

•  Головоломка Paletto  2 883

•  Теорема Монжа об окружностях  3 688

•  Пазл Numbrix  2 422

•  Заборы и коммивояжеры  3 105

•  Игра HIP  2 063

•  Игра Go (Го)  1 989

•  Симулятор лифта  2 350

•  Программа укладки плитки  2 051

•  Генератор лабиринта  2 510

•  Проверка числового ввода  2 195

•  HEX View  2 521

•  Физический маятник  2 137

 
скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Как редактировать таблицы виртуальных и динамических методов



Автор: ___ALex___
WEB-сайт: http://pascal.dax.ru

unit EditorVMTandDMTTables;

interface

// функция служит для выяснения существования VMT у класса
// возвращает True, если класс имеет VMT и False - если нет
function IsVMTExist(Cls: TClass): Boolean;

// процедура служит для замены адреса метода в VMT класса со смещением
// Offset(должно быть кратно 4) новым адресом, хранящимся в NewMet
// примечание: перед вызовом этой процедуры проверяйте существование
// VMT у класса функцией IsVMTExist
procedure VirtMethodReplace(Cls: TClass; Offset: LongWord; NewMet: Pointer);
  overload;

// процедура служит для замены адреса метода, хранящегося в OldMet,
// в VMT класса новым адресом, хранящимся в NewMet
// примечание: перед вызовом этой процедуры проверяйте существование
// VMT у класса функцией IsVMTExist
procedure VirtMethodReplace(Cls: TClass; OldMet, NewMet: Pointer); overload;

// функция служит для замены адреса динамического метода класса с индексом,
// хранящимся в Index, новым адресом, хранящимся в NewMet
// возвращает True, если метод с данным индексом найден и False - если нет
function DynMethodReplace(Cls: TClass; Index: Word; NewMet: Pointer): Boolean;
  overload;

// функция служит для замены адреса динамического метода класса, хранящегося
// в OldMet, новым адресом, хранящимся в NewMet
// возвращает True, если метод с данным адресом найден и False - если нет
function DynMethodReplace(Cls: TClass; OldMet, NewMet: Pointer): Boolean;
  overload;

implementation

// функция служит для получения указателя на байт, следующий за адресом
// последнего метода в VMT класса
// возвращает nil в случае, если у класса нет VMT
// функция является "внутренней" в модуле
// (используется другими подпрограммами и не объявлена в секции interface)
// , поэтому используйте её только если
// Вы полностью уверены в своих действиях(она изменяет "рабочие" регистры
// ECX и EDX)

function GetVMTEnd(Cls: TClass): Pointer;
asm
        // Вход: Cls --> EAX
        // Выход: Result --> EAX

        PUSH    EBX
        MOV     ECX, 8
        MOV     EBX, -1
        MOV     EDX, vmtSelfPtr
@@cycle:
        ADD     EDX, 4
        CMP     [EAX + EDX], EAX
        JE      @@vmt_not_found
        JB      @@continue
        CMP     [EAX + EDX], EBX
        JAE     @@continue
        MOV     EBX, [EAX + EDX]
@@continue:
        DEC     ECX
        JNZ     @@cycle
        MOV     EAX, EBX
        JMP     @@exit
@@vmt_not_found:
        XOR     EAX, EAX
@@exit:
        POP     EBX

end;

function IsVMTExist(Cls: TClass): Boolean;
asm
        // Вход: Cls --> EAX
        // Выход: Result --> AL

        CALL    GetVMTEnd
        TEST    EAX, EAX
        JZ      @@vmt_not_found
        MOV     AL, 1
@@vmt_not_found:

end;

procedure VirtMethodReplace(Cls: TClass; Offset: LongWord; NewMet: Pointer);
  overload;
asm
        // Вход: Cls --> EAX, Offset --> EDX, NewMet --> ECX

        MOV     [EAX + EDX], ECX

end;

procedure VirtMethodReplace(Cls: TClass; OldMet, NewMet: Pointer); overload;
asm
        // Вход: Cls --> EAX, OldMet --> EDX, NewMet --> ECX

        PUSH    EDI
        MOV     EDI, EAX
        PUSH    ECX
        PUSH    EDX
        PUSH    EAX
        CALL    GetVMTEnd
        POP     EDX
        SUB     EAX, EDX
        SHR     EAX, 2
        POP     EDX
        POP     ECX
        PUSH    ECX
        MOV     ECX, EAX
        MOV     EAX, EDX
        POP     EDX
        REPNE   SCASD
        JNE     @@OldMet_not_found
        MOV     [EDI - 4], EDX
@@OldMet_not_found:
        POP     EDI

end;

function DynMethodReplace(Cls: TClass; Index: Word; NewMet: Pointer): Boolean;
  overload;
asm
        // Вход: Cls --> EAX, Index --> DX, NewMet --> ECX
        // Выход: Result --> AL

        PUSH    EDI
        PUSH    ESI
        MOV     ESI, ECX
        XOR     EAX, EDX
        XOR     EDX, EAX
        XOR     EAX, EDX
        JMP     @@start
@@cycle:
        MOV     EDX, [EDX]
@@start:
        MOV     EDI, [EDX].vmtDynamicTable
        TEST    EDI, EDI
        JZ      @@get_parent_dmt
        MOVZX   ECX, WORD PTR [EDI]
        PUSH    ECX
        ADD     EDI, 2
        REPNE   SCASW
        JE      @@Index_found
        POP     ECX
@@get_parent_dmt:
        MOV     EDX, [EDX].vmtParent
        TEST    EDX, EDX
        JNZ     @@cycle
        JMP     @@Index_not_found
@@Index_found:
        POP     EAX
        SHL     EAX, 1
        SUB     EAX, ECX
        MOV     [EDI + EAX * 2 - 4], ESI
        MOV     AL, 1
        JMP     @@exit
@@Index_not_found:
        XOR     AL, AL
@@exit:
        POP     ESI
        POP     EDI

end;

function DynMethodReplace(Cls: TClass; OldMet, NewMet: Pointer): Boolean;
  overload;
asm
        // Вход: Cls --> EAX, OldMet --> EDX, NewMet --> ECX
        // Выход: Result --> AL

        PUSH    EDI
        PUSH    ESI
        MOV     ESI, ECX
        XOR     EAX, EDX
        XOR     EDX, EAX
        XOR     EAX, EDX
        JMP     @@start
@@cycle:
        MOV     EDX, [EDX]
@@start:
        MOV     EDI, [EDX].vmtDynamicTable
        TEST    EDI, EDI
        JZ      @@get_parent_dmt
        MOVZX   ECX, WORD PTR [EDI]
        LEA     EDI, EDI + 2 * ECX + 2
        REPNE   SCASD
        JE      @@OldMet_found
@@get_parent_dmt:
        MOV     EDX, [EDX].vmtParent
        TEST    EDX, EDX
        JNZ     @@cycle
        JMP     @@OldMet_not_found
@@OldMet_found:
        MOV     [EDI - 4], ESI
        MOV     AL, 1
        JMP     @@exit
@@OldMet_not_found:
        XOR     AL, AL
@@exit:
        POP     ESI
        POP     EDI

end;

end.







Copyright © 2004-2025 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте