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

LU RD
  • 34,438
  • 5
  • 88
  • 296
Salvador
  • 16,132
  • 33
  • 143
  • 245

2 Answers2

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;
LU RD
  • 34,438
  • 5
  • 88
  • 296
  • Does this work when class helper declared in a different unit? And the questions talks about strict protected members, properties to be precise. – David Heffernan Nov 30 '11 at 18:15
  • @DavidHeffernan, ok I revised the code to reflect the strict protected properties. And yes, it works when declared in separate units. – LU RD Nov 30 '11 at 18:29
  • Very good. I have to confess to never having used class helpers. – David Heffernan Nov 30 '11 at 18:33
  • 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. – alitrun Jun 04 '17 at 19:01
  • 2
    @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;` – LU RD Jun 04 '17 at 19:21
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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 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. – Warren P Nov 30 '11 at 19:18
  • @WarrenP No that's not the case. If the cracker is ever a crasher, then using the upstream class untainted causes the same crash, – David Heffernan Nov 30 '11 at 19:19
  • 1
    I like this solution better than the class helper solution since it doesn't have the limitations that class helpers have. – Jens Mühlenhoff Nov 30 '11 at 19:55
  • 2
    @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. – Jens Mühlenhoff Nov 30 '11 at 19:57
  • Okay. Well, then this could be a game saver. It works in Delphi 7, too, whereas the class helper one doesn't. +1. – Warren P Nov 30 '11 at 21:39
  • 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. – Warren P Dec 01 '11 at 01:34