NickR
(Nicholas Ring)
18 November 2025 03:52
1
Hello,
Is it possible for a Delphi (Berlin 10.1) application to load another Delphi (Berlin 10.1) and access the RTTI information within it?
If that is not possible, could it possible be done (yeah, asking a lot here) with some hackery?
Thanks in advance,
Nick
My guess is that it is possible with a lot of work. Programs like TestComplete are able to access published properties of form components of Delphi programs under test. How you do it might take a bit of hackery as you say. In the case of Test Complete it requires some debug output from the compiler to help it.
Preparing Delphi Applications for Testing | TestComplete Documentation
My guess is this activity would be non-trivial.
Geoff
(Geoffrey Smith)
18 November 2025 10:19
3
I wrote a program that could extract the forms out of an exe file and generate a stub class for each form. It used RTTI, but the RTTI was actually from the program I was running, not the program I was extracting the forms from. One of the troubles with this method was RTTI only exists for code/components that are in the running program. To get around this, I created something like this
lObjectTypes : TList<TClass>;
lObjectTypes.Add(TForm);
lObjectTypes.Add(TFrame);
lObjectTypes.Add(TLabel);
// Standard Controls
lObjectTypes.Add(TMainMenu);
lObjectTypes.Add(TPopupMenu);
lObjectTypes.Add(TLabel);
lObjectTypes.Add(TEdit);
lObjectTypes.Add(TMemo);
lObjectTypes.Add(TButton);
lObjectTypes.Add(TCheckBox);
lObjectTypes.Add(TRadioButton);
lObjectTypes.Add(TListBox);
lObjectTypes.Add(TComboBox);
lObjectTypes.Add(TScrollBar);
lObjectTypes.Add(TGroupBox);
lObjectTypes.Add(TRadioGroup);
lObjectTypes.Add(TPanel);
lObjectTypes.Add(TActionList);
// Additional
lObjectTypes.Add(TBitBtn);
lObjectTypes.Add(TSpeedButton);
lObjectTypes.Add(TMaskEdit);
lObjectTypes.Add(TStringGrid);
lObjectTypes.Add(TDrawGrid);
lObjectTypes.Add(TImage);
lObjectTypes.Add(TShape);
lObjectTypes.Add(TBevel);
lObjectTypes.Add(TScrollBox);
lObjectTypes.Add(TCheckListBox);
lObjectTypes.Add(TSplitter);
lObjectTypes.Add(TStaticText);
lObjectTypes.Add(TControlBar);
lObjectTypes.Add(TApplicationEvents);
lObjectTypes.Add(TValueListEditor);
lObjectTypes.Add(TLabeledEdit);
lObjectTypes.Add(TColorBox);
lObjectTypes.Add(TColorListBox);
lObjectTypes.Add(TCategoryButtons);
lObjectTypes.Add(TButtonGroup);
lObjectTypes.Add(TDockTabSet);
lObjectTypes.Add(TTabSet);
lObjectTypes.Add(TChart);
lObjectTypes.Add(TActionManager);
lObjectTypes.Add(TActionMainMenuBar);
lObjectTypes.Add(TPopupActionBar);
lObjectTypes.Add(TActionToolbar);
lObjectTypes.Add(TXPColorMap);
lObjectTypes.Add(TStandardColorMap);
lObjectTypes.Add(TTwilightColorMap);
lObjectTypes.Add(TCustomizeDlg);
// Win32
lObjectTypes.Add(TTabControl);
lObjectTypes.Add(TPageControl);
lObjectTypes.Add(TImageList);
lObjectTypes.Add(TRichEdit);
lObjectTypes.Add(TTrackBar);
lObjectTypes.Add(TProgressBar);
lObjectTypes.Add(TUpDown);
lObjectTypes.Add(THotKey);
lObjectTypes.Add(TAnimate);
lObjectTypes.Add(TDateTimePicker);
lObjectTypes.Add(TMonthCalendar);
lObjectTypes.Add(TTreeView);
lObjectTypes.Add(TListView);
lObjectTypes.Add(THeaderControl);
lObjectTypes.Add(TStatusBar);
lObjectTypes.Add(TToolBar);
lObjectTypes.Add(TCoolBar);
lObjectTypes.Add(TPageScroller);
lObjectTypes.Add(TComboBoxEx);
lObjectTypes.Add(TXPManifest);
// System
lObjectTypes.Add(TTimer);
lObjectTypes.Add(TPaintBox);
lObjectTypes.Add(TMediaPlayer);
lObjectTypes.Add(TOleContainer);
lObjectTypes.Add(TDdeClientConv);
lObjectTypes.Add(TDdeClientItem);
lObjectTypes.Add(TDdeServerConv);
lObjectTypes.Add(TDdeServerItem);
// Dialogs
lObjectTypes.Add(TOpenDialog);
lObjectTypes.Add(TSaveDialog);
lObjectTypes.Add(TOpenPictureDialog);
lObjectTypes.Add(TSavePictureDialog);
lObjectTypes.Add(TOpenTextFileDialog);
lObjectTypes.Add(TSaveTextFileDialog);
lObjectTypes.Add(TFontDialog);
lObjectTypes.Add(TColorDialog);
lObjectTypes.Add(TPrintDialog);
lObjectTypes.Add(TPrinterSetupDialog);
lObjectTypes.Add(TFindDialog);
lObjectTypes.Add(TReplaceDialog);
lObjectTypes.Add(TPageSetupDialog);
// Internet
lObjectTypes.Add(TWebDispatcher);
lObjectTypes.Add(TPageProducer);
lObjectTypes.Add(TDataSetTableProducer);
lObjectTypes.Add(TDataSetPageProducer);
lObjectTypes.Add(TSQLQueryTableProducer);
lObjectTypes.Add(TXMLDocument);
lObjectTypes.Add(TWebBrowser);
// Data Controls
lObjectTypes.Add(TDBGrid);
lObjectTypes.Add(TDBNavigator);
lObjectTypes.Add(TDBText);
lObjectTypes.Add(TDBEdit);
lObjectTypes.Add(TDBMemo);
lObjectTypes.Add(TDBImage);
lObjectTypes.Add(TDBListBox);
lObjectTypes.Add(TDBComboBox);
lObjectTypes.Add(TDBCheckBox);
lObjectTypes.Add(TDBRadioGroup);
lObjectTypes.Add(TDBLookupListBox);
lObjectTypes.Add(TDBLookupComboBox);
lObjectTypes.Add(TDBRichEdit);
lObjectTypes.Add(TDBCtrlGrid);
lObjectTypes.Add(TDBChart);
// Data Access
lObjectTypes.Add(TDataSource);
lObjectTypes.Add(TXMLTransform);
lObjectTypes.Add(TXMLTransformProvider);
lObjectTypes.Add(TXMLTransformClient);
lObjectTypes.Add(TClientDataSet);
lObjectTypes.Add(TDataSetProvider);
// Indy Clients
lObjectTypes.Add(TIdTCPClient);
lObjectTypes.Add(TIdUDPClient);
lObjectTypes.Add(TIdCmdTCPClient);
lObjectTypes.Add(TIdIPMCastClient);
lObjectTypes.Add(TIdIcmpClient);
lObjectTypes.Add(TIdDayTime);
lObjectTypes.Add(TIdDayTimeUDP);
lObjectTypes.Add(TIdDICT);
lObjectTypes.Add(TIdDNSResolver);
lObjectTypes.Add(TIdEcho);
lObjectTypes.Add(TIdEchoUDP);
lObjectTypes.Add(TIdFinger);
lObjectTypes.Add(TIdFSP);
lObjectTypes.Add(TIdFTP);
lObjectTypes.Add(TIdGopher);
lObjectTypes.Add(TIdHTTP);
lObjectTypes.Add(TIdIdent);
lObjectTypes.Add(TIdIMAP4);
lObjectTypes.Add(TIdIRC);
lObjectTypes.Add(TIdLPR);
lObjectTypes.Add(TIdNNTP);
lObjectTypes.Add(TIdPOP3);
lObjectTypes.Add(TIdQOTD);
lObjectTypes.Add(TIdQOTDUDP);
lObjectTypes.Add(TIdRexec);
lObjectTypes.Add(TIdRSH);
lObjectTypes.Add(TIdSMTP);
lObjectTypes.Add(TIdSMTPRelay);
lObjectTypes.Add(TIdSNMP);
lObjectTypes.Add(TIdSNPP);
lObjectTypes.Add(TIdSNTP);
lObjectTypes.Add(TIdSysLog);
lObjectTypes.Add(TIdSystat);
lObjectTypes.Add(TIdSystatUDP);
lObjectTypes.Add(TIdTelnet);
lObjectTypes.Add(TIdTime);
lObjectTypes.Add(TIdTimeUDP);
lObjectTypes.Add(TIdTrivialFTP);
lObjectTypes.Add(TIdUnixTime);
lObjectTypes.Add(TIdUnixTimeUDP);
lObjectTypes.Add(TIdWhoIs);
// Indy Servers
lObjectTypes.Add(TIdUDPServer);
lObjectTypes.Add(TIdCmdTCPServer);
lObjectTypes.Add(TIdSimpleServer);
lObjectTypes.Add(TIdTCPServer);
lObjectTypes.Add(TIdChargenServer);
lObjectTypes.Add(TIdChargenUDPServer);
lObjectTypes.Add(TIdDayTimeServer);
lObjectTypes.Add(TIdDayTimeUDPServer);
lObjectTypes.Add(TIdDICTServer);
lObjectTypes.Add(TIdDISCARDServer);
lObjectTypes.Add(TIdDiscardUDPServer);
lObjectTypes.Add(TIdDNSServer);
lObjectTypes.Add(TIdECHOServer);
lObjectTypes.Add(TIdEchoUDPServer);
lObjectTypes.Add(TIdFingerServer);
lObjectTypes.Add(TIdFTPServer);
lObjectTypes.Add(TIdGopherServer);
lObjectTypes.Add(TIdHTTPProxyServer);
lObjectTypes.Add(TIdHTTPServer);
lObjectTypes.Add(TIdIdentServer);
lObjectTypes.Add(TIdIMAP4Server);
lObjectTypes.Add(TIdIPMCastServer);
lObjectTypes.Add(TIdIRCServer);
lObjectTypes.Add(TIdMappedFTP);
lObjectTypes.Add(TIdMappedPOP3);
lObjectTypes.Add(TIdMappedPortTCP);
lObjectTypes.Add(TIdMappedPortUDP);
lObjectTypes.Add(TIdMappedTelnet);
lObjectTypes.Add(TIdNNTPServer);
lObjectTypes.Add(TIdPOP3Server);
lObjectTypes.Add(TIdQOTDServer);
lObjectTypes.Add(TIdQotdUDPServer);
lObjectTypes.Add(TIdRexecServer);
lObjectTypes.Add(TIdRSHServer);
lObjectTypes.Add(TIdSMTPServer);
lObjectTypes.Add(TIdSocksServer);
lObjectTypes.Add(TIdSyslogServer);
lObjectTypes.Add(TIdSystatServer);
lObjectTypes.Add(TIdSystatUDPServer);
lObjectTypes.Add(TIdTelnetServer);
lObjectTypes.Add(TIdTimeServer);
lObjectTypes.Add(TIdTimeUDPServer);
lObjectTypes.Add(TIdTrivialFTPServer);
lObjectTypes.Add(TIdWhoIsServer);
// Indy I/O Handlers
lObjectTypes.Add(TIdIOHandlerStack);
lObjectTypes.Add(TIdIOHandlerStream);
lObjectTypes.Add(TIdServerIOHandlerStack);
lObjectTypes.Add(TIdServerIOHandlerSSLOpenSSL);
lObjectTypes.Add(TIdSSLIOHandlerSocketOpenSSL);
// Indy Misc
lObjectTypes.Add(TIdSocksInfo);
lObjectTypes.Add(TIdAntiFreeze);
lObjectTypes.Add(TIdSchedulerOfThreadDefault);
lObjectTypes.Add(TIdSchedulerOfThreadPool);
lObjectTypes.Add(TIdThreadComponent);
lObjectTypes.Add(TIdConnectThroughHttpProxy);
lObjectTypes.Add(TIdCompressorZlib);
lObjectTypes.Add(TIdCookieManager);
lObjectTypes.Add(TIdEncoderMIME);
lObjectTypes.Add(TIdEncoderUUE);
lObjectTypes.Add(TIdEncoderXXE);
lObjectTypes.Add(TIdEncoderQuotedPrintable);
lObjectTypes.Add(TIdDateTimeStamp);
lObjectTypes.Add(TIdDecoderMIME);
lObjectTypes.Add(TIdDecoderUUE);
lObjectTypes.Add(TIdDecoderXXE);
lObjectTypes.Add(TIdDecoderQuotedPrintable);
lObjectTypes.Add(TIdIPWatch);
lObjectTypes.Add(TIdIPAddrMon);
lObjectTypes.Add(TIdMailBox);
lObjectTypes.Add(TIdMessage);
lObjectTypes.Add(TIdMessageDecoderMIME);
lObjectTypes.Add(TIdMessageEncoderMIME);
lObjectTypes.Add(TIdMessageDecoderYenc);
lObjectTypes.Add(TIdMessageEncoderYenc);
lObjectTypes.Add(TIdNetworkCalculator);
lObjectTypes.Add(TIdSyslogMessage);
lObjectTypes.Add(TIdUserManager);
lObjectTypes.Add(TIdVCard);
// Indy SASL
lObjectTypes.Add(TIdSASLAnonymous);
lObjectTypes.Add(TIdSASLCRAMMD5);
lObjectTypes.Add(TIdSASLExternal);
lObjectTypes.Add(TIdSASLLogin);
lObjectTypes.Add(TIdSASLOTP);
lObjectTypes.Add(TIdSASLPlain);
lObjectTypes.Add(TIdSASLSKey);
lObjectTypes.Add(TIdUserPassProvider);
lObjectTypes.Add(TMainMenu);
lObjectTypes.Add(TGridPanel);
lObjectTypes.Add(TDrawGrid);
lObjectTypes.Add(TLabel);
lObjectTypes.Add(TBitBtn);
lObjectTypes.Add(TImage);
lObjectTypes.Add(TApplicationEvents);
lObjectTypes.Add(TTabSet);
lObjectTypes.Add(TFlowPanel);
lObjectTypes.Add(TProgressBar);
lObjectTypes.Add(TMonthCalendar);
lObjectTypes.Add(TAdvStringGrid);
lObjectTypes.Add(TMoneyEdit);
lObjectTypes.Add(TDirectoryListBoxEx);
lObjectTypes.Add(TFileListBoxEx);
lObjectTypes.Add(TAdvDateTimePicker);
lObjectTypes.Add(TPageControl);
lObjectTypes.Add(TAdvSmoothDatePicker);
lObjectTypes.Add(TPaintBox);
lObjectTypes.Add(TMediaPlayer);
lObjectTypes.Add(TOleContainer);
lObjectTypes.Add(TCoolBar);
// Indy
lObjectTypes.Add(TIdSSLIOHandlerSocketOpenSSL);
lObjectTypes.Add(TIdHTTPServer);
lObjectTypes.Add(TIdHTTP);
// REST Components
lObjectTypes.Add(TRESTClient);
lObjectTypes.Add(TRESTRequest);
lObjectTypes.Add(TRESTResponse);
lObjectTypes.Add(TNetHTTPClient);
lObjectTypes.Add(TSimpleAuthenticator);
lObjectTypes.Add(TOAuth2Authenticator);
lObjectTypes.Add(TOAuth1Authenticator);
// FireDac
lObjectTypes.Add(TFDConnection);
lObjectTypes.Add(TFDQuery);
lObjectTypes.Add(TFDManager);
lObjectTypes.Add(TFDMemTable);
lObjectTypes.Add(TFDMemTable);
lObjectTypes.Add(TFDStoredProc);
lObjectTypes.Add(TFDMetaInfoQuery);
lObjectTypes.Add(TFDLocalSQL);
lObjectTypes.Add(TFDPhysMySQLDriverLink);
lObjectTypes.Add(TFDPhysMSAccessDriverLink);
lObjectTypes.Add(TFDPhysMSSQLDriverLink);
// DBGo
lObjectTypes.Add(TADOConnection);
lObjectTypes.Add(TADOConnection);
lObjectTypes.Add(TADOCommand);
lObjectTypes.Add(TADODataSet);
lObjectTypes.Add(TADOTable);
lObjectTypes.Add(TADOQuery);
lObjectTypes.Add(TADOStoredProc);
lObjectTypes.Add(TADOQuery);
lObjectTypes.Add(TWebBrowser);
lObjectTypes.Add(TOpenDialog);
lObjectTypes.Add(TSaveDialog);
lObjectTypes.Add(TGauge);
lObjectTypes.Add(TAbZipKit);
lObjectTypes.Add(TJvMemoryData);
lObjectTypes.Add(TAnimate);
lObjectTypes.Add(TBluetoothLE);
lObjectTypes.Add(TBeacon);
lObjectTypes.Add(TNotificationCenter);
lObjectTypes.Add(TChart);
lObjectTypes.Add(TDBChart);
lObjectTypes.Add(TImageList);
lObjectTypes.Add(TRichEdit);
lObjectTypes.Add(TTreeView);
lObjectTypes.Add(TToolBar);
lObjectTypes.Add(TShellResources);
lObjectTypes.Add(TTaskbar);
With a big long list of components, which forced the components to be included in the exe file. This doesn’t include any of the non standard components, so you would need to add them to the list as well.
1 Like
AaronDC
(Aaron Christiansen)
18 November 2025 23:04
4
If both programs are yours, could you add an extractRTTI method in the loaded application, and call it via named pipes or similar, to request RTTI information?
That way the loaded app accesses its own properties via RTTI and the calling app can request the information it wants via the pipe or similar mechanism.
1 Like
NickR
(Nicholas Ring)
19 November 2025 01:17
5
Test Complete really pulls apart the executable to gather the data - way above what I am willing to do.
I am actually after interface definitions within the other application, so making a list is a cool idea but won’t really work.
I do like the idea of having a pipe to request the information… Will definitely thinking about this a bit more.
Geoff
(Geoffrey Smith)
19 November 2025 01:44
6
Here is a few other things I found, looking at reverse engineering existing programs.
There is also potential to use something like DelphiDetours to inject code into a running process. You would still need to get the address of the objects of interest then though.
DLL Injection with DelphiDetours