在运行时写入内存以将一个类(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方式实现。

08-04 09:22