Delphi Reverse Engineering
DFM Files, Windows RCDATA and
Object Conversion Routines
June 1999
by +Aitor
Courtesy of Reverser's page of reverse engineering
Nice deed +Aitor! Was about time that some +HCUker would start a little sound Delphi reversing. I know that +Aitor will soon send quite a lot of additions and material (delphi related) for this and other essays, so stay tuned!
There is a crack, a crack in everything That's how the light gets in
( )Beginner ( )Intermediate (x)Advanced ( )Expert

"A little paper to teach +reversers new paths to research, and give Delphi programmers a topic to reflection"
Delphi Reverse Engineering
DFM Files, Windows RCDATA and
Object Conversion Routines
Written by +Aitor


... And then Borland created Delphi, an amazing development tool that convulsed the programming scene in the middle 90's. OOP + RAD + BP7 compiler made of Borland Delphi a very attractive option for thousands of developers around the world.

So many times we have heard things like "Delphi is like a Pascal based Visual Basic", CERTAINLY NOT!! OOP techniques applied to Delphi are the main reason to get a +100 Kb "hello world" exe file, but, taking apart all the overbloated object hierarchy, we are still able to develop full Win32 API based software, enjoying the beauty of one of the nicest languages ever, Pascal.

In a simple "Hello world" Delphi program, there are thousands of useless bytes, resources injected into the executable that program will never use, strings, cursors, etc., not to mention all the crap that VCL object hierarchy takes with it. A real programmer must know in deep the language he/she uses, now he/she most learn how his/her compiler works ... amazing situation, isn't it?

So many things hidden to our eyes ... Delphi programmers / reverse +engineers, it's time to reveal some of them ...


Delphi Reverse Engineering
DFM Files, Windows RCDATA and
Object Conversion Routines.
by +Aitor, June 1999


Anyone that has opened an executable of Delphi at some time with the Resource Workshop of Borland has met with a total absence of windows and dialog boxes, but yes with a series more or less extensive of RCDATA type resources. What is there behind all this? If you don't know it, I hope this document helps you to understand it...


Inside a Win32 executable we can store different type of resources:

RT_ACCELERATOR Accelerator table
RT_ANICURSOR Animated cursor
RT_ANIICON Animated icon
RT_BITMAP Bitmap resource
RT_CURSOR Hardware-dependent cursor resource
RT_DIALOG Dialog box
RT_FONT Font resource
RT_FONTDIR Font directory resource
RT_GROUP_CURSOR Hardware-independent cursor resource
RT_GROUP_ICON Hardware-independent icon resource
RT_ICON Hardware-dependent icon resource
RT_MENU Menu resource
RT_MESSAGETABLE Message-table entry
RT_RCDATA Application-defined resource (raw data)
RT_STRING String-table entry
RT_VERSION Version resource
We can store blocks of binary data as RCDATA resources. In this way, JPEG images, data tables, complete files or even structures of data that will be extracted by the program at runtime, can be stored into the exe file.


Delphi programs source files are usually distributed in two file types: ASCII code files (.PAS, .DPR, .INC), and resource files (.RES, .RC, .DFM, .DCR).

At design time (code time), part of the program is written in background without the programmer almost realizes. Every time the programmer changes a window's position, a button's color or assigns an event to a component, Delphi writes those modifications in a DFM file.

A DFM file is nothing more than an ASCII file encoded by Delphi. Later, during the compilation, this file is linked with the executable one in form of RCDATA resource. Starting from now, when you hear speak of the Borland/Inprise's own RCDATA format, you will know which way the wind is blowing ...


A function of the Win32 API will allow us to write a small program to do the work. Next an extract of code from our small tool:

function EnumResourceNames(
hModule: HMODULE; // EXE handle returned from LoadLibrary/Ex
lpType: PChar; // resource type (eg: RT_RCDATA)
lpEnumFunc: ENUMRESNAMEPROC; // callback function address
lParam: Integer // long integer (eg: pointer to an object)
): BOOL; stdcall;

function CB_EnumDfmNameProc(hModule: THandle; lpszType, lpszName: PChar;
lParam: Integer): Boolean; stdcall;
ms: TMemoryStream;
rs: TResourceStream;
Buffer: array of Byte;
with TResourceInfo(lParam) do
rs := TResourceStream.Create(TResourceInfo(lParam).Module,
lpszname, lpszType); // load resource in memory
ms := TMemoryStream.Create;
SetLength(Buffer, 4);
rs.Read(Buffer[0], SizeOf(Buffer)); // read the first 4 bytes
if string(Buffer) = 'TPF0' then // is it a DFM resource?
rs.Seek(0, 0);
ObjectBinaryToText(rs, ms); // decode DFM
ms.Seek(0, 0);
AddDfm(StrPas(lpszName), ms); // add it to our own list

Result := True;
end; {CB_EnumDfmNameProc}

procedure TResourceInfo.EnumDfmNames;
if FModule > 0 then // if an EXE file has been loaded
EnumResourceNames(FModule, RT_RCDATA, // go and search RCDATA resources
@CB_EnumDfmNameProc, Integer(Self));
end; {TResourceInfo.EnumDfmNames}

Uhm, apart from the Win32 API function already mentioned, here there are things that sound strange to me... what is "ObjectBinaryToText"? and that 4 bytes header? OK, everything will be explained in due course ...


As we have already mentioned before, the RCDATA format used by the DFM files is a Borland/Inprise's characteristic format. In the Delphi 4 unit "Classes" of Delphi there are 4 functions, called object conversion routines, to convert DFM binary blocks to ASCII format, and vice versa:

procedure ObjectBinaryToText(Input, Output: TStream);
procedure ObjectTextToBinary(Input, Output: TStream);
procedure ObjectResourceToText(Input, Output: TStream);
procedure ObjectTextToResource(Input, Output: TStream);
Depending on what we want to do with the concerning resource we will use some or others. In our case, for the small tool that we will write we will use both first: "ObjectBinaryToText" and "ObjectTextToBinary".

Before explaining how works our program, a question is pending, what was that 4 byte header that appeared in the code shown in the previous point? The matter is that Delphi doesn't only store automatically DFM blocks DFM as RCDATA, but rather we will also meet with resources like DVCLAL and PACKAGEINFO. To distinguish them some of other, we will read the first four bytes of the block that in all those of DFM type is always "TPF0" ($54 $50 $46 $30).


With all the above-mentioned we should already be able to write a tool that makes us life a little easier as much to crackers as to programmers.

The operation is simple:

  1. Load an executable module (EXE/DLL/BPL/DPL) in memory by means of "LoadLibrary" or "LoadLibraryEx" functions, from the Win32 API.
  2. Go through it looking for RCDATA resources by means of "EnumResourceNames", from the Win32 API.
  3. Load each DFM block found, decode it and store it in a list in memory, together with their name.
  4. In the main window of the application we will be able to visualize in text mode all the loaded DFM's of the loaded executable.
  5. Finally, we will be able to save to disk the DFM selected as an ASCII file (.RC), or as a binary block (.DAT) such which it appears linked in the executable file.
The .RC file generated is ready to be loaded from the BRW. Choose the Delphi form you're interested in, modify it and save it as ASCII .RC file. Then, load the Delphi executable with the BRW, delete the previous Delphi form and substitute it with the new (modified) one. The possibilities are enormous if you have imagination ...

Final Notes

All that you have seen here, including the little demo tool, have been written in an hot Sunday afternoon, very hot indeed ... :) It's possible that this text contains something incorrect, or that the program has shortcomings that I have not seen. If you find something wrong, don't wait more and write now, it will be of benefit to +all ...

A zip file containing binaries and full sources of the DfmExplorer tool can be downloaded here.
An spanish translation of this doc can be downloaded from">wkt homepage.

(c) 1999 Aitor, +HCU and wkt
Basque Country, May 1999

Ob Duh

Ooops! No "Ob Duh" applicable here ...

You are deep inside reverser's page of reverse engineering, choose your way out:



redhomepage red links red anonymity red+ORC redstudents' essays redacademy database redbots wars
redantismut redtools redcocktails redjavascript wars redsearch_forms redmail_reverser
redIs reverse engineering illegal?