在运行时写入内存以将一个类(TMyEdit)替换为另一个(TEdit)
const
vmtNewInstance = System.vmtNewInstance;
var
AClassInstance: TClass;
OldInstance: Pointer;
function GetNewInstance: TObject;
begin
Result := AClassInstance.NewInstance;
end;
function GetVirtualMethod(AClass: TClass; const VmtOffset: Integer): Pointer;
begin
Result := PPointer(Integer(AClass) + VmtOffset)^;
end;
procedure SetVirtualMethod(AClass: TClass; const VmtOffset: Integer; const Method: Pointer);
var
WrittenBytes: DWORD;
PatchAddress: PPointer;
begin
PatchAddress := Pointer(Integer(AClass) + VmtOffset);
WriteProcessMemory(GetCurrentProcess, PatchAddress, @Method, SizeOf(Method), WrittenBytes);
end;
initialization
OldInstance := GetVirtualMethod(TMyEdit, vmtNewInstance);
AClassInstance := TMyEdit;
SetVirtualMethod(StdCtrls.TEdit, vmtNewInstance, @GetNewInstance);
finalization
SetVirtualMethod(StdCtrls.TEdit, vmtNewInstance, OldInstance);
这工作正常,但是如何编写OOP方法呢?
这是我的尝试:
type
TVirtualMethod = class
FInstance: Pointer;
FTarget: TClass;
public
constructor Create(const SourceClass, DestClass: TClass);
destructor Free;
end;
{ TVirtualMethod }
var
ASource: TClass;
function GetNewInstance: TObject;
begin
Result := ASource.NewInstance;
end;
constructor TVirtualMethod.Create(const SourceClass, DestClass: TClass);
var
WrittenBytes: DWORD;
PatchAddress: PPointer;
begin
ASource := SourceClass;
FInstance := PPointer(Integer(ASource) + vmtNewInstance)^;
FTarget := DestClass;
PatchAddress := Pointer(Integer(DestClass) + vmtNewInstance);
WriteProcessMemory(GetCurrentProcess, PatchAddress, @GetNewInstance, SizeOf(GetNewInstance), WrittenBytes);
end;
destructor TVirtualMethod.Free;
var
WrittenBytes: DWORD;
PatchAddress: PPointer;
begin
PatchAddress := Pointer(Integer(FTarget) + vmtNewInstance);
WriteProcessMemory(GetCurrentProcess, PatchAddress, @FInstance, SizeOf(FInstance), WrittenBytes);
end;
var
v1: TVirtualMethod;
initialization
v1 := TVirtualMethod.Create(TMyEdit, TEdit);
finalization
v1.Free;
它可以很好地编译,但是可以在内存中写入。
最佳答案
TVirtualMethodInterceptor功能似乎与您的某些意图重叠,并且以OOP方式实现。