How to patch Delphi modules

Thursday, August 04 2005 @ 08:44 PM CEST

Patch commercial VCL modules (Delphi/Borland C++) instead of patching your built executables over and over.Lets take a dive in the Borland package libraries (BPL files)

Target: EasyMap VCL (3w.microolap.com/trials/em.zip)

Tools used:

Delphi 7 Enterprise version

Hiew 6.11 (you can use any hexeditor)

Note: A product version doesn't matter, but it's important that all
work. The second thing that you should keep in mind is what all the addresses
are represented in hexadimal system, the rest numbers are decimal.
Author : Wizard
Level : 3/10

Origin:

I have not failed.
I've just found 10,000 ways that won't work. Thomas Jefferson.

Introduction

EasyMap VCL is a Delphi/C++Builder components set for creating your own
GIS-related solutions without MapInfo, MapX, MapObjects, WinGIS and so on.

EasyMap VCL allows to add following functionalities in
Delphi/C++Builder application:

MIF/MID vector maps displaying in Longitude/Lantitude projection;

Map objects related data in grid or tabular controls displaying;

ZoomIn/ZoomOut/Pan/Selector map tools;

EasyMap Object Model allows to display on the map embedded into your
application data from most of known datasources: RDBMS, flat DBs, your
own formats etc.

Philosophical story

One day my father asked me to look at some Delphi component that was
shareware. I said that I'll take a look at it and crack it like piece of cake.
That was an arrogance from my side, because when I made an observation of the
components I concluded that a crack task won't be as simple as I thought.
The sense of the task was simple, but realization wasn't. I should patch three
files. One BPL file with two NAG screens and two DCU files with one message
inside each.

I found the places where the NAGs were. The problem was only in one thing,
how to patch these files. One might think, what so hard in that. Nothing, except
that DCU files are not just executables.
I spent a lot of hours thinking and analysing of how to do something. I didn't
find any information about BPL and DCU file structures over the net. No any
information, no tutorials or patchers. I found only one crappy tutorial and
lots of links that are just brain-picking of other sites.

During the search I understood that inet is one big scrap-heap and when
you need something you won't find it, you will only get it when you don't
need it. Well, who need information that he needed some years ago? Hah,
of course no one.
When I'm fed up with the shitty plagiarism on the net I decided to kick some
ass by myself.

What is what?

First of all, extract em.zip, than run easymapvcl_trial.exe and follow the
setup program instructions to install the components.
Now fire up Delphi. Open the demo project EasyMapDemo.dpr in it. Activate
Form1 (Shift + F12). You should see two message boxes, one after another,
which say: "Evaluation version of EasyMap VCL. For purchasing info visit...".
Each message connected to a specified component. Therefore there're two
components:

TDataBrowser class, which is in module DataBrowser.dcu

TLayersComboBox class, which is in module LayersComboBox.dcu

How do I know that? Simple, look into EasyMap directory in Delphi. It contains
three folders and six files in the its root. Go into DELPHI7 subdirectory of
EasyMap folder. In there you're gonna find forenamed DCU files. Besides the
messages say for themselves, because each message has a caption with inscription,
which tells you the name of a component. As a rule components have the same
name as modules, but without first "T" letter.Note: These modules of Delphi are always included into an exe file
during a compilation of the last one. That means those two files are always
used in run-time, because Delphi compiles them into the final executable.
I suppose DELPHI7 folder can have another name, which depends on Delphi version.

You ought to see file EasyMapD7.bpl in the same directory. This file is
used by Delphi during design-time. Lemme explain why. BPL file is the same
DLL file, but renamed. It's called by Delphi, when a programmer edits a form,
which contains such components or when he edits the components properties.
In other way there can be few BPL files. To know which of them has the message
you better use SoftIce. But there's more artless way to find out where
the NAG is. Start any string searcher (e.g. FAR or an other shell). Type
"Evaluation version" in the search string and start the search. As you can
see only three forenamed files have that stupid message.Note: In case of some smart crypted/packed modules use the
debugger to find out where a message is. But usually DCU and BPL files
are naked (ain't packed), which gives you a real power to create a crack art.

Let's find out where to dig

Now we know what files have the message inside. To be exact I'm giving the
whole list below with the explanation.

File name

Description

Comments

DataBrowser.dcu

Delphi run-time module

It has one message

LayersComboBox.dcu

Delphi run-time module

It has one message

EasyMapD7.bpl

Delphi design-time module

It has two messages

First, let's remove the NAGs from BPL file. Close Delphi if it were opened.
Open EasyMapD7.bpl with Hiew and search for the "Evaluation" string. You can do
that by pressing F7 in Hiew and type forenamed word in the search string.
I've found one at address 410D2C. Press F4 and select Hex mode (or just
press Enter key to do the same). Press Alt + F1 to switch from relative
addresses to absolute. Once you've done it you'll get 1012C instead of
memory address 410D2C.
Enter the decode mode by pressing enter or F4/Decode. Now hold on up key to
scroll up till you see this part of the code:

As you can see there're only 3 parameters which will be passed to MessageBox
function. According to help there should be another one parameter before those
three. But there's no such one, because instead of it there's a call at address
100CF.

Therefore, we can conclude that the last parameter (uType) is in stack already.
You're maybe thinking now, let's release the stack from one uType parameter by
a command e.g. pop eax and then just "nop" all the rest or jump over the
MessageBox.

Not a bad idea at all, but there's one problem here. When I did so Delphi
caused an GPF (General protection fault) and suddenly exited. When I've put a
breakpoint at address 100D4 in SoftIce and ran Delphi again I saw
strange thing. Everything was disassembled correctly in Hiew, but it was
wrongly disassembled in Delphi during design-time. That means EasyMapD7.bpl
isn't just renamed DLL or maybe I should change something else in it to make
Delphi treat the code correctly.

I've been thinking for a long time how to patch it. I tried many times to
patch it with different ways, but nothing worked out...

Breaking up the horizons

In one day I suddenly wondered about one simple thing, what if I had changed
the part of the code, which was never changed. I mean that all the jmp,
call and push commands will be replaced with different addresses
appropriate to a situation. That means, for a BPL file Delphi can change commands
in memory. E.g. if there were a command like push 410D2C, such
command might look in memory as push 470D2C or elsewise. Because it's
BPL (DLL) and who knows how Delphi treats it, what procedures/functions uses,
in what memory ranges, etc. To answer all these questions we have to know
the BPL file structure, but we don't and there's no place to get it yet.
That's why we're just wondering to patch it correctly without knowing its
structure.

Anyway the conjecture was right. When I patched forenamed push command only
the first byte was interpreted correctly, the rest din't. That was because push command (its long equivalent) consists of 5 bytes, 1st byte is mnemonics, the
rest 4 are an address, e.g. 68 2C 0D 41 00 (push 410D2C). That's why
when I patched another byte than the first I got wrong values in memory during
design-time. The same was during run-time, when I compiled an executable the
code was wrong in exe file, but only in places where I touched such commands as
push (ONLY 5 bytes long), call and jmp.

By knowing that I can conclude only one correct solution. Look at the parts of
the code again more attentively.

Now the explanation of all we did. First, we changed push 00 to jmps 1012C at address 100DA. That's because Delphi won't change push and
jmp commands, which are 2 bytes long.
Why? Because these commands save absolute values, they don't
depend upon the memory address or file size, when the last will be compiled.
Besides, the code says it pushes zero as the last parameter in stack, which is
the first parameter (hWnd) in MessageBox. Well, for you to know - zero is the
handle of the screen. It often used by such API functions as GetDC, ReleaseDC, etc.
I suppose the components use this handle to draw the message before the form
will be shown or even created. That's why you see two NAGs first and only after
that the form of an applications appears.

As you can see the jump at address 100DA jumps to the first byte of our string
that you've seen already. We're using 5 bytes of it to release the stack from values,
which will never be used by MessageBox, because the last won't be called ever too.
The last jump at address 1012F brings back the control to the program.
At this point the stack is clear from our 3 values that were saved before the
jump to our patch procedure. That's how we're preventing the NAG appearing.Note: I remind you that when we release the stack we use the back
order of the elements that were saved. The second thing, we're "popping up" three values because we have 2 of them in stack before the jump at address
100DA and one element was in stack before those 2 had been saved.

Everything should be pretty clear here, except one thing. Why do we use eax as the releasing register? That's because if you look at address 100E1 you'll
see the command xor eax,eax. This command lays right after the MessageBox call.
Which means that MessageBox function changes eax register. That's why program
makes it null after the call. And that's why we're using it as "pop-up" register
when releasing our 3 values. If we would use some other register we could *censored*
up something in stack or in program, 'cause we don't know what the program
does with what registers. That's why we should be very careful when changing
something.

If you use some other register to release the stack you better do next steps:

1. before the MessageBox call and after it write down to a paper all values
of the registers and the stack from the original (not patched) code;

2. patch the code as best as you can;

3. do the same as in the first step, but in the patched code;

4. compare all the values, which you wrote before the call and after it
in the original and the patched code. If there's full match - you did all
correctly, but if something wrong - you've made a mistake somewhere. In the last
case you have to get back to the first step.

The full patch for the first NAG as a table.

Address

Original opcode

Original mnemonics

Patched opcode

Patched mnemonics

000100DA

6A 00

push 000

EB50

jmps 00001012C

0001012C

45

inc ebp

58

pop eax

0001012D

7661

jbe 000010190

58 58

pop eax, pop eax

0001012F

6C

insb

EB B0

jmps 0000100E1

First step is done. Let's find out where the second NAG lays. To do this call
the find dialog again by pressing F7 key. Type "Evaluation" in it and start
the search once again.
You have found another and the last one (in this file) at address 1123C.
Look a bit up and you will see the same piece of code that you've seen before,
when we were patching the first NAG. Nothing different here, but the addresses.
Thus, there's no sense to give the same explanation as above. Instead of doing
that just look at the table below to check out the addresses, but the algorithm
is the same.

Address

Original opcode

Original mnemonics

Patched opcode

Patched mnemonics

000111EA

6A 00

push 000

EB 50

jmps 00001123C

0001123C

45

inc ebp

58

pop eax

0001123D

76 61

jbe 0000112A0

58 58

pop eax, pop eax

0001123F

6C

insb

EB B0

jmps 0000111F1

That's all for EasyMapD7.bpl, because if you will try to search the same string
again you won't find it. That means we've done with this file.

Keep on diggin'

I spent a lot of time on the net trying to find any information about DCU files.
I found some shitty article about how to write an emulator of Delphi IDE to
run programs without Delphi IDE. All the rest I found were the same crap, but
in different sites. I couldn't also find DCU structure description. There was
only one info that I found about it on some russian forum. There was a public
speaking of Borland. The sense of it was very simple: DCU is a private format
of Borland and won't be spreaded around the world. What an arrogance! That's
why I'm gonna tell you how to patch such files.

Open DataBrowser.dcu with Hiew and search for "Evaluation" string. I've found
it at address 348F. Switch to decode mode. Press Ctrl + F1 to change
your disassembly settings from 16 bit mode to 32. Do here the same as we do
when we were cracking the BPL file. Elevate the cursor till you see almost the
same code that we see in BPL.

Familiar code, ain't it? Sure it is! Thus, you have to patch it exactly like we
do before. Check out the table below to compare you patch.

Address

Original opcode

Original mnemonics

Patched opcode

Patched mnemonics

000343D

6A 00

push 000

EB 50

jmps 0000348F

000348F

45

inc ebp

58

pop eax

0003490

76 61

jbe 000034F3

58 58

pop eax, pop eax

0003492

6C

insb

EB B0

jmps 00003444

Try to search the string again. No such one, which means that this file is done
and we have to crack the last file.

Now open LayersComboBox.dcu in Hiew and make the same search. You should find
the string at address 2695. Scroll a little up and you will see absolutely the
same code as in the first dcu, only the addresses are different. At this point
I suppose you know what to do with it, but nevertheless compare your patch
results with mine.

Address

Original opcode

Original mnemonics

Patched opcode

Patched mnemonics

0002643

6A 00

push 000

EB 50

jmps 00002695

0002695

45

inc ebp

58

pop eax

0002696

76 61

jbe 000026F9

58 58

pop eax, pop eax

0002698

6C

insb

EB B0

jmps 0000264A

Search again the string to make sure there's no more such one. The search is
failed, which means we've cracked it. As all of three files have been cracked
this issue is over.

Living end

That's was an essay of Delphi cracking. It wasn't very hard and it wasn't too
smart, but anyway this is one of the first public steps of cracking Delphi
components and related files. I hope this steam of fresh knowledge will give
people some more imagination to create their own cracking art.

It isn't too hard when you know what to do and how, but when don't you can
waste a lot of time trying to understand how does a thing work. You may ask
questions to people, you may search info over the net, etc. But the most
important information for you is your own experience. In some cases some people
can help if you stuck somewhere, in some cases they can't. That's why first of
all, you have to dig by yourself, study yourself and public your work.

When you find a good solution of something real worthy don't put the knowledge
away from people. Don't also make brain-picking, because it won't give you more
respect. Share it with the mass, because we're all mortal. So don't take your
knowledge to tomb.