Access a strict protected property of a Delphi class?
Asked Answered
N

2

17

I need to access a strict protected property, because I need to create a validation (based in the value of this property) to avoid a bug. (I don't have the source code of the third party class which has this property) only I have the definition of the class (interface) and the dcu (so I can't change the property visibility). The question is Exist a way to access a strict protected property? (I really read the Hallvard Vassbotn Blog, but I don't find anthing about this particular topic.)

Nucleotide answered 30/11, 2011 at 17:9 Comment(2)
You probably can use raw memory access to read the backing field of this property. No idea if there is a robuster solution.Acquisitive
Looks like class helpers for the win.Hairy
C
23

This class helper example compiles fine :

type
  TMyOrgClass = class
  strict private
    FMyPrivateProp: Integer;
  strict protected
    property MyProtectedProp: Integer read FMyPrivateProp;
  end;

  TMyClassHelper = class helper for TMyOrgClass
  private
    function GetMyProtectedProp: Integer;
  public
    property MyPublicProp: Integer read GetMyProtectedProp;
  end;

function TMyClassHelper.GetMyProtectedProp: Integer;
begin
  Result:= Self.FMyPrivateProp;  // Access the org class with Self
end;

Some more information about class helpers can be found here : should-class-helpers-be-used-in-developing-new-code

Update

Starting with Delphi 10.1 Berlin, accessing private or strict private members with class helpers does not work. It was considered a compiler bug and has been corrected. Accessing protected or strict protected members is still allowed with class helpers though.

In the above example access to a private member was illustrated. Below shows a working example with access to a strict protected member.

function TMyClassHelper.GetMyProtectedProp: Integer;
begin
  with Self do Result:= MyProtectedProp;  // Access strict protected property
end;
Coincidentally answered 30/11, 2011 at 17:56 Comment(5)
Does this work when class helper declared in a different unit? And the questions talks about strict protected members, properties to be precise.Bah
@DavidHeffernan, ok I revised the code to reflect the strict protected properties. And yes, it works when declared in separate units.Coincidentally
Very good. I have to confess to never having used class helpers.Bah
Starting from Delphi Berlin you can't access private and protected fields. This was a bug so dev. fixed it in Berlin. So now you can access protected methods only by inheriting the class.Knot
@alitrun, if you study the update that was made to my answer, you see that it is still possible to access protected methods using class helpers. Furthermore there is another trick that also opens up access to private/protected fields in Berlin/Tokyo. Just write this in a helper: with Self do begin { any field/ method is accessible here} end;Coincidentally
B
16

You can use a variant of the standard protected hack.

Unit 1

type
  TTest = class
  strict private
    FProp: Integer;
  strict protected
    property Prop: Integer read FProp;
  end;

Unit 2

type
  THackedTest = class(TTest)
  strict private
    function GetProp: Integer;
  public
    property Prop: Integer read GetProp;
  end;

function THackedTest.GetProp: Integer;
begin
  Result := inherited Prop;
end;

Unit 3

var
  T: TTest;

....

THackedTest(T).Prop;

Strict protected only allows you to access the member from the defining class, and subclasses. So you have to actually implement a method on the cracking class, make it public, and use that method as the route into the target strict protected member.

Bah answered 30/11, 2011 at 17:16 Comment(6)
The usual warning provisions include this one; When someone modifies the upstream class, such as when you move to a new delphi version, say, and the VCL sources change, your Cracker class gets upgraded to become (perhaps) a Crasher class.Hairy
@WarrenP No that's not the case. If the cracker is ever a crasher, then using the upstream class untainted causes the same crash,Bah
I like this solution better than the class helper solution since it doesn't have the limitations that class helpers have.Bibliography
@WarrenP: This solution is quite safe, since the inherited class shares the memory layout of the original class. THackedTest doesn't add any variables or virtual methods.Bibliography
Okay. Well, then this could be a game saver. It works in Delphi 7, too, whereas the class helper one doesn't. +1.Hairy
This is valuable for cracking Private members in D7. strict protected is a dumb addition to the language since you could always just subclass with a TSomethingAccess = class(TSomething). Protected = no protection at all.Hairy

© 2022 - 2024 — McMap. All rights reserved.