Jump to content
Jenifer

How to calculate class size using TMemoryStream.size?

Recommended Posts

10 hours ago, Remy Lebeau said:

Enhanced RTTI provides that information.  See Working with RTTI, TRttiType.GetFields(), and TRttiField.Offset.

For example:


var
  Ctx: TRttiContext;
  Offset: Integer;
  
Offset := Ctx.GetType(TControl).GetField('FParent').Offset;

But why do you need to access the FParent and FWidth member directly?  Why can't you use the TControl's public Parent and Width properties instead?

My bad,i should have mentioned public properties(Parent,WindowProc,Width etc).

Share this post


Link to post
6 hours ago, Remy Lebeau said:

Thanks, I missed that part.  In which case, this issue just got a whole lot more dangerous.  Manipulating the RTL/VCL's data members directly, behind the RTL/VCL's back, is a HUGE risk.  Without intimate and explicit knowledge of the exact version of Delphi the other process is using, you can't hope to access its private data SAFELY, for the very reason I stated earlier - data members can and do change between versions.

I would like to mention few more info to make things clear:

  • My actual library that our application uses to capture UI properties is what, written in C language
  • It is bit legacy codebase where it uses its own structures of various Delphi UI controls like TControl,TWinControl,TPanel etc(Last updated Delphi version is of 2006)
  • Currently working on to get Delphi 10.4 support as well.
  • When I am trying to get text from control using WM_GETTEXT message, got stuck with access violation which is kind of memory allocation/offset related issue.
  • To sort that out I am trying to find offset values for members, those are of base classes(TControl,TWinControl)from Delphi.
  • There is no try to access private members of those based classes.
  • We have our own way to retrieve Delphi version, so codebase has a knowledge about version as well.

Thanks,

Jenifer

Share this post


Link to post
16 minutes ago, David Heffernan said:

Every question you've asked in this thread has been answered now. 

Hope you won't be unhappy if I ask further questions 🙂

Share this post


Link to post
9 hours ago, Jenifer said:

When I am trying to get text from control using WM_GETTEXT message, got stuck with access violation which is kind of memory allocation/offset related issue.

That has nothing to do with the framework being used by the UI control.  And certainly nothing to do with accessing offsets within that framework, unless you are trying to access the UI control's internal data members over the process boundary, which you should not be doing, especially just for using WM_GETTEXT.  There are other, safer, ways to obtain a UI control's HWND from within another process, such as via UI Automation APIs.  And once you do have a viable HWND, the only way to get an AV from using WM_GETTEXT is if you are passing in bad parameter values - either a bad buffer pointer, or an incorrect buffer length that allows a buffer overflow to happen.

9 hours ago, Jenifer said:
  • To sort that out I am trying to find offset values for members, those are of base classes(TControl,TWinControl)from Delphi.

You don't need to worry about that just to fix an AV in your own code's use of WM_GETTEXT.  Something else is going on.

9 hours ago, Jenifer said:
  • There is no try to access private members of those based classes.

But that is what you have to resort to, if you are trying to access some other process's UI control internals.  You can't access VCL objects across process boundaries.

 

Share this post


Link to post
1 hour ago, Remy Lebeau said:

That has nothing to do with the framework being used by the UI control.  And certainly nothing to do with accessing offsets within that framework, unless you are trying to access the UI control's internal data members over the process boundary, which you should not be doing, especially just for using WM_GETTEXT.  There are other, safer, ways to obtain a UI control's HWND from within another process, such as via UI Automation APIs.  And once you do have a viable HWND, the only way to get an AV from using WM_GETTEXT is if you are passing in bad parameter values - either a bad buffer pointer, or an incorrect buffer length that allows a buffer overflow to happen.

You don't need to worry about that just to fix an AV in your own code's use of WM_GETTEXT.  Something else is going on.

But that is what you have to resort to, if you are trying to access some other process's UI control internals.  You can't access VCL objects across process boundaries.

 

Able to fix the issue, thanks everyone!!

 

Below code helped me to get offsets of all the properties including private members:

begin
  rttiType:= Ctx.GetType(TypeInfo(TWinControl));
  sFields := rttiType.Name + ' {';
  fields := rttiType.GetFields;
  for i := low(fields) to high(fields) do
        begin
       Offset:=fields.Offset];
        end;;
end;

 

Had to adjust offsets of our own structure members to match with the actual ones.

 

Thanks,

Jenifer

Share this post


Link to post
23 hours ago, Jenifer said:

Below code helped me to get offsets of all the properties including private members:

Note that this approach will only work if your app is compiled with the same compiler and RTL/VCL version as the target app, since you are reading the RTTI of your app, not the RTTI of the target app.

Edited by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×