WriteProcessMemory in OOP approach



运行时在内存中写入用另一个(TEdit)代替一个类(TMyEdit)

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);

这工作得很好,但如何编写面向对象的方法?下面是我的尝试:

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的特性似乎与你的一些意图重叠,并以面向对象的方式完成。

最新更新