Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:


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

Поиск:
Код
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.
Автор: ___ALex___






Просмотров: 1467

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную