问题描述
在有关关闭班级帮助程序漏洞的辩论中,该漏洞允许轻松访问Delphi 10.1 Berlin中班级的私有成员(字段和方法),通常声称
In the debate about the closing of the class helper loophole that allowed easy access to private members (fields and methods) of a class in Delphi 10.1 Berlin, it is often claimed that
- 扩展的RTTI允许访问已启用(扩展的)RTTI编译的类的私有成员,
- 所有VCL / RTL / FMX类均已启用此功能
但是,如果我运行这个简单的单元(一个带有一个TListBox的简单形式,别无其他):
However, if I run this simple unit (a simple form with one TListBox, nothing else):
unit RttiAccessTest;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Rtti, Vcl.StdCtrls;
type
TForm16 = class(TForm)
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form16: TForm16;
implementation
{$R *.dfm}
function GetMethodString(const MethodName: string): string;
var
M: TRTTIMethod;
I: Integer;
begin
M := TRttiContext.Create.GetType(TCustomForm).GetMethod(MethodName);
if Assigned(M) then
Result := 'Method ' + MethodName + ': ''' + M.ToString + ';'''
else
Result := 'Method ' + MethodName + ' cannot be found';
end;
procedure TForm16.FormCreate(Sender: TObject);
begin
Listbox1.Items.Add(GetMethodString('SetWindowState'));
Listbox1.Items.Add(GetMethodString('ShowModal'));
end;
end.
列表框中的文本为:
Method SetWindowState cannot be found
Method ShowModal: 'function ShowModal: Integer;'
这意味着我无法访问 TCustomForm
的此私有方法 SetWindowState
。这是因为不是RTL / VCL / FMX中的所有类都扩展了RTTI,还是我做错了?
This means I cannot get access to this private method SetWindowState
of TCustomForm
. Is this because not all classes in the RTL/VCL/FMX have extended RTTI, or am I doing something wrong?
如果我做错了什么或忘记了什么,那该怎么办?换句话说,我该怎么做才能获得RTTI访问例如 TCustomForm
的 SetWindowState
的权限?我也无法在西雅图或更早的时间获得此访问权限。
If I am doing something wrong or forgetting something, then what? In other words, what do I have to do to get RTTI access to, say, SetWindowState
of TCustomForm
? I cannot get this access in Seattle or earlier either.
我知道如何使用该类来访问该方法帮助者仍然可以获取私有方法的地址,但这不是我的问题。 我特别询问如何使用RTTI进行操作。
I know how to get access to the method anyway, using the fact that class helpers can still get the address of private methods, but that is not my question. I am particularly asking about how to do this with RTTI.
推荐答案
为了访问对RTTI使用严格的私有/私有方法,请使用编译器指令。
In order to access strict private/private methods with RTTI, use the compiler directive {$RTTI}.
$ RTTI指令的常规语法可以分为三类部分。 $ RTTI的基本形式如下:
The general syntax of the $RTTI directive can be split into three parts. The basic form of $RTTI is as follows:
{$ RTTI INHERIT | EXPLICIT [visibility-clause]}
{$RTTI INHERIT|EXPLICIT [visibility-clause]}
visibility-clause :
方法|属性|字段(可见性表达)
METHODS|PROPERTIES|FIELDS (visibility-expression)
可见性表达:
[vcPrivate],[vcProtected],[vcPublic],[vcPublished];
[vcPrivate],[vcProtected], [vcPublic], [vcPublished];
示例:
{$RTTI EXPLICIT METHODS([vcPublic, vcProtected, vcPrivate])}
设置公共,保护和私有方法的可见性
Sets the visibility for public,protected and private methods
注意:此指令的作用域为 local 并且 RTL / VCL / FMX
关闭了这些选项,这意味着无法使用RTTI访问受保护/私有方法。
Note: The scope is local for this directive and the RTL/VCL/FMX
have these options off, which means that access to protected/private methods with RTTI are not possible.
这篇关于RTTI访问VCL的私有方法,例如TCustomForm.SetWindowState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!