Delphi: Prevent method names from appearing in executables - delphi

I am writing a class to handle security in my executable (checking serials, trial date check etc). After I compile the executable (even in Release build, with all debug and RTTI generation turned off), when I open it in NotePad and search the method name in the raw data, I can see all the names of the methods that assemble my class. There are no published members in any class in the code base.
This is bad for protection. Is there any way to tell Delphi not to store method names in the executable ? Why is it storing them at all if there is no RTTI needed and no COM explosion? Is there any compiler option controlling this?
It may be that ANY method of ANY class in the target executable is stored inside the executable in text form. Apparently this is caused by the extended RTTI being turned on by default for all classes in Delphi 2010.

If you are asking about the extended RTTI in Delphi 2010, it can be switched off by
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
see also docwiki.

Also strip relocations, take up the following in the project's dpr file:
{$IFDEF RELEASE}
// Leave out Relocation Table in Release version
{$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED}
{$ENDIF RELEASE}

... and don't forget to turn off "td 32 debug info" (in older versions) or debug info in the linker tab in later ones.

What you probably will see is your form definition as a resource (eg the binary represetation of the DFM files of your project).
If you don't want to show these (for the serial info screen etc) you shouldcreate these forms "in code". Eg create a TForm, place a TButton and TEdit onto it, attach the event handlers in code.
To do this in a handly way: start with a form and create the DFM. When vieing the form, choose View as text from the context menu and you will know what things you should copy into code. And make sure NOT to place any varaiablerefernces under de published (always put public/protected/private as the first line within your class definition.

Related

Delphi FMX OpenDialog is missiong OPtions list

I added a TOPenDialog component to a form and am writing the menu method to operate it. I copied code from a VCl project including the line openDialog1.Options := [ofReadOnly];.
The compiler rejects it since ofReadOnly (and other options) are not recognized. The TopenOptions type is included in VCL.Dialogs but does not seem to appear in the FMX version.
I am currently using the Delphi starter version which does not include the FMX.dialogs.pas file text so I cannot add the options into the unit. WIll including the VCL.dialogs file in the Uses section fix this? I have heard that it is not a good idea to mix VCL and FMX units together in the same program.
If you read Embarcadero's documentation, you will see that the FMX.Dialogs.TOpenDialog.Options property uses the same System.UITypes.TOpenOptions type that the VCL.Dialogs.TOpenDialog.Options property uses, so both dialogs have the same options available.
The reason your code is not compiling is because the TOpenOption enum has been declared with the {SCOPEDENUMS ON} directive enabled (see Scoped Enumerations). You need to prefix scoped enum values with their containing enum type name, eg
uses
..., System.UITypes;
OpenDialog1.Options := [TOpenOption.ofReadOnly];

Referencing a type from a package library in Delphi

I have inherited a legacy Delphi project for which I have to do a code modification. But to start with, I have problem compiling the project into a "correct" application. As I am not familiar with Delphi, I am not sure what is missing.
So far, the only changes I have done are around PATH for references and packages wherever I could find an absolute path that was different on my PC. It is compiling and running. However, one of the variable remains "incorrectly" initialized at run-time (value is nil). I am a bit surprised because I have not changed anything in the code, that is from an application otherwise running.
The type of this variable is defined in a package library (for which I have the code as well, that compiles, and that is in the list of "Packages" checked in the Project Options.
Some code sample:
Unit Unit3
interface
uses
VCLZ;
TFrmCCB = class(TForm)
vz: TVCLZ;
implementation
procedure TFrmCCB.FormCreate(Sender: TObject)
var
[...]
begin
vz.SetPath := 'C:\'; //at this point vz is nil
Do I have to add some code to get vz to not be nil, or does it look like a configuration problem with the definition not found at run time or something like that? I would seem strange that something is missing in the code though, as I have not done any change there yet and the program is otherwise running.
It sounds like vz: TVCLZ is a component on a form.
When you first open the form if you don't have the component (package) installed in the IDE it asks you if you want to remove the component (because the IDE doesn't know how to render/instantiate it at design-time). If you choose to remove it the code associated with that component remains.
So you remain with something similar to what you have. The form doesn't create the component at run-time (because it doesn't have it anymore) the vz member remains uninitialized.
So, you have to get the sources of the project with the component on the form and be careful not to delete it.
Or, you care create the instance yourself. At FormCreate just create it: vz := TVCLZ.Create(Self); before you use it. But keep in mind that all the properties set in design will be lost and you have to set them manually in code.

GExpert's Replace Components Expert doesn't replace the text in the form file (*.dfm)

I am using Delphi 2010 and GExperts stable release 1.35
I am testing the "Replace Components" expert.
I add a main form and a secondary form. Each has three TEdits on it.
I use the Replace Components Expert to replace all TEdits with TRzEdit. I Check the Replace all components on all forms of the project.
It works, it replaces them all. However, it doesn't do anything to the DFM file. How do i make it replace those instances.
If i save, compile, or rebuild, i get errors.
If i try to view the form as text after replacing, i get errors.
Can someone explain to me the steps to make this work?
Thanks
I just tried it with Delphi XE and GExperts 1.35 and it does indeed crash now even after a single "Replace Selected". (It used to work fine in the past).
It seems that using the hidden menu Project | Clear Unit Cache just after Replace Components then doing a full build before trying any Save/Compile/View As Text... fixes the problem.
I think this menu is surfaced with cnPack. I don't have it and cannot guarantee, but you can easily do it yourself by adding the following unit in one of your installed packages:
unit FGEnableHiddenMenus;
interface
procedure Register;
implementation
uses
Classes, Forms, Menus;
procedure Register;
var
Comp: TComponent;
begin
//Make a hidden menu item visible
Comp := Application.MainForm.FindComponent('ProjectClearUnitCacheItem');
if Comp is TMenuItem then
TMenuItem(Comp).Visible := True;
end;
end.
Source: Brian Long's old goodies
Update:
I had to replace a couple of TEdit by TDBEdit on our main project at work and this trick worked.
But on a new Project with 3 Forms, it failed consistently to write/commit/save the changes on the last Form (same environment).
FYI, I tried with and without DDevExtensions 2.5 and IDEFixPack 4.6.1
Update2:
Went digging in the GExperts forum as suggested by Ulrich and finally found a possible explanation. The new property Touch does not like being copied from one component to another when the source is destroyed (causing the AV).
The suggested workaround is to do a bidirectional mapping in the Expert Settings to disable the copy for this property:
You might be running into this bug while trying to copy the Touch property from the old to the new component, but it has a workaround you can fairly easily test:
http://tech.groups.yahoo.com/group/GExpertsDiscuss/message/3994
Details:
There is a limitation/bug in Delphi 2010 and XE where if you assign a
Component.Touch property from one component to another and destroy the
original component that the new component becomes corrupt (it isn't
like component/interface references, where they either auto-correct
themselves or are reference counted).
For the moment, you can assign a bi-directional replace component
property map from TPanel.Touch to TGroupBox.Touch (use the two components being replaced in your specific case) that is marked as
a disabled property map, and that will work around this problem. Our next release
will not try to assign that property any longer.
GExperts 1.36 is also now available and includes a workaround for this issue. The workaround has been in the GExperts version control system and in testing for several weeks already.

Why does MSHTML_TLB.pas produce warnings?

I am trying to get rid of lots of warnings in a project after converting it from BDS 2006 to Delphi 2009.
The project needs a type library named MSHTML_TLB. The source file mshtml_tlb.pas is an incredibly large file (about 16MB and >440.000 lines of code) which is generated when the Type Library is imported into Delphi 2009.
This file produces many warnings when building the project:
W1010 Method 'ToString' hides virtual method of base type 'TObject'
Since Delphi itself has created that file, I am wondering why these warnings come up and if I should just ignore them?
If so, is there a way to disable this kind of warning just for this file?
Delphi introduced this virtual method in TObject. Your declaration of ToString in a derived class does not use override so the ToString method of TObject is not accessible anymore. Adding override to your ToString method should solve the problem unless you declared your method differently.
Write to the beginning of the MSHTML_TLB.pas file this line (in bold):
unit MSHTML_TLB;
{$WARNINGS OFF}
and at the end:
{$WARNINGS ON}
end.
As a last resort, you can hide warnings. In Delphi 2010 this is in Project Options/Delphi Compiler/Hints and Warnings. I think this particular warning is "Redeclaration of a symbol hides a member in the base class".
Start up Delphi.
On the "Component" menu in the main toolbar select "Import ActiveX Control..."
In the list box scroll and and select "Microsoft HTML Object Library".
The "Class names" should then list "TScriptlet".
Click "Install...", then click "OK" on the "Install" form that appears and "Yes" on the confirm prompt.

Someway to override Delphi default procedures at Design Time?

Someway to override Delphi default procedures at Design Time ?
I need to override the InstanceSize at design time, I did it runtime using FastCode method:
FastcodeAddressPatch(FastcodeGetAddress(#SInstanceSize), #TWinControl.RfInstanceSize);
But, is there some way to do it at Design time ?
Tks in advice
"Design time" is really just "run time," but in the context of the IDE instead of the context of your program. Put your code in a design-time package and load it in the IDE. The IDE will call all the Register procedures in your package's units, at which time you can run whatever code you need.
Make a new package project (.dpk file).
Set project preferences so it's a design-time package.
Add a new, blank unit to it.
Add a procedure to the interface section named Register. It must have a capital R and the rest lowercase.
Implement that procedure however you want (such as by putting your call to FastcodeAddressPatch there).
Compile and install the package.
I'm a little wary about what it looks like you're trying to do in step 5, but I'll let you work that out for yourself.
If by "at design-time" you mean "change the way your components behave while in the Form Designer", that's something you really shouldn't be trying to do. The Form Designer is part of the IDE, which is all Delphi code being run in BDS.exe. If you alter TObject under the Form Designer, you alter it for the entire IDE, with potentially disastrous results.

Resources