In this tutorial we will discuss working with binaries written in Delphi. Delphi binaries are quite different then binaries written in other languages. You can generally tell a Delphi program by the numerous calls (far more than a typical program) as well as some other techniques we will be discussing.
Included in the tutorial download are the two crackme’s, the Delphi Decompiler (DeDe), and ExeInfoPE, available on the tutorials
You will also need Resource Hacker (and OllyDBG) available on the tools
Most program construction in Delphi is by using forms, which are basically just windows or dialog boxes. You design them using a graphic utility to ‘paint’ the form, meaning to add buttons, edit boxes etc wherever you would like them. Really, the only thing you need to do after that is let the Delphi compiler know which actions you would like to handle and what you would like to do should that action happen. For example, when a button is clicked, you may want to open a file dialog box. In this case you would let the Delphi compiler know that the button should be associated with your code that you provide, and this code simply opens the file dialog.
These forms, along with everything associated with them (strings, sizes, colors) are stored in resources, in theory like a normal C++ application, but implemented far differently. One interesting thing is that Delphi associates all of these resources by name, meaning that the name you called the specific resource is the name that will be hard-coded into the executable, and the name that the executable will use to ‘look up’ resources. This is both good and bad. Good in that you can easily find these names that are associated with resources. Bad in that they are all stored in one area and are not logically int3erwoven into the code, so finding the code that goes along with a resource (say, a button click) is a lot tougher.
Much of the programming is done for you, other than, say, C++. There is a tremendous amount done ‘behind the scenes’ in a Delphi program. This is one reason the code looks different than what you may expect.
The first target
One of the first questions you may have is, “How do I know that I’m dealing with a Delphi program?” After a lot more experience, they stand out like a sore thumb, but until then, we are going to use a tool that will help. Go ahead and run ExeInfoPE. This program is generally used to discover what packer has been used on a packed binary (and we will use it a great deal when we get to packing). But, lucky for us, if the program is not packed it also tells us what language the program was written in. When you first run ExeInfoPE you will see the startup screen:
Go ahead and load our first target, DelphiCrackme.exe into ExeInfoPE and you will see the various fields populated (you can just drag the crackme icon and drop it into the ExeInfoPE window):
Here we can see that ExeInfoPE has found that this binary was compiled in Delphi. Under that you cannot also see that it is not packed. Also, just as a quick aside, as soon as you load the binary into Olly you will see that you’re dealing with something different:
You can tell it doesn’t look like the typical apps we’ve been dealing with.
Looking at Delphi resources
One of the most important differences, at least to a reverse engineer, of a Delphi program is the resources. Loading up the DelphiCrackme into Resource Hacker, you should notice a new folder that is not typically not there called RCDATA. Opening this folder shows us the resource sections associated with this binary:
*** If you do not have Resource Hacker you can download it from the tools page ***
Generally, the most important sub-folder (resource sections) are the TFORM sections. These are the windows/dialog boxes in the Delphi program. In this particular crackme, we can see that there is one form, TFORM1. Clicking on the little flower inside TFORM1 opens the main data area for this section in Resource Hacker (as you can see above). This data tells you everything about the form; the size, the colors, the placement on the screen, the title (caption), any fields or buttons it has in it- everything.
Usually, the first place I look is the ‘Caption’ as this tells you what will be in the title bar in the window. In this case it’s “Delphi – MsgBoxes”. The importance of this field is, in an app that has many forms called TFORM1, TFORM2, TFORM3… it is difficult to know which form is associated with which window. Looking at the captions can help distinguish this. For example, the caption may say “Register” letting us know it’s the registration screen, or “About” for the about screen.
Finally, of importance to us is the button objects at the bottom. The reason these are important is because we generally want to trap the program after a button has been hit, say, after hitting OK on the registration screen after entering our username and serial. The important thing about the buttons is the button name for the method when the button is clicked. In this case it’s “Button1Click”. As I said earlier, Delphi programs connect everything with ASCII names, so when the app wishes to run the code associated with clicking this button, it will look up the name “Button1Clicked” to find the method.
From viewing this file in a resource viewer, we have gathered that there is one form (window) with one button. The caption of he window is “Delphi – MsgBoxes” and the callback function that handles the click of the button is called “Button1Click”.
Now let’s move on to using one of the most important tools in dealing with Delphi programs…
Delphi Decompiler loads a Delphi program and breaks it down for you, showing all the forms data we’ve seen, but also where all the methods are called, the address of all the methods, and the method names. It also shows a complete decompilation of the binary if we wish, along with capabilities to modify it. Let’s go ahead and run DeDe. After a really kick-ass splash screen (if you’re 9) we see the main window:
First, we need to load our program in so DeDe can decompile it. You can either select the open folder icon or just drag our DelphiCrackme into the DeDe window and choose ‘Yes’ to allow DeDe to begin processing the binary. At this point, DeDe pops up a message box asking if the target has loaded:
at the same time, it runs the target as we can see the target’s main window appear:
Sometimes, if there is a nag or splash that pops up at he beginning of running the target, you will want to proceed to the main part of the program before telling DeDe to process the app. In this case, the target is already fully loaded, so you can click the OK button and allow DeDe to proceed. deDe will then close the target and ask if you want to perform more robust processing on the app:
I usually choose no here, as clicking yes has never given me any more info that I need. DeDe will then finish processing the target and the main window will be populated:
DeDe defaults to showing us the class info, as we can see by the “Classes Info” tab being depressed. You can scroll through the list if you like, but what we want is the “Forms” tab:
Here, we can see the info we saw in Resource Hacker; the attributes for the form. The reason I show you this is so that in the future you can bypass the Resource Hacker step and just look at it in DeDe. Now click on the “Procedures” tab. This is the most important tab in DeDe:
Here, DeDe shows us the method callback names and addresses for the TForm1 form. Since this is a very simple program, there is only one button, and therefore, only one callback. BUT, the nice thing is we now know the address of this callback- 457F0C. Remember that address! Now let’s load the crackme into Olly and see what we can do…
Finding the patch
If you do a search for strings you will see that you are our of luck:
Searching for intermodular calls also is a dead giveaway for a Delphi program:
You will notice that Delphi makes A LOT of calls.
Normally, at this point, we would try to run the app and pause it on the bad boy message, but you will find that this won’t work in this case because when you return, you will be about 15 layers down in calls, and finding the actual code that handles the processing of the message box is almost impossible.
BUT, if we recall from DeDe, we know the address that is called when the button is clicked. It’s 457F0C. So let’s go check that address out in Olly:
Ahhhhh. That looks much better Let’s place a BP at the beginning of this (457F0C) and run the app:
*** Olly may give you a warning that you are setting a BP in a data section. Just ignore it. ***
Notice it says we are unregistered. Also, notice the name in the title. “Delphi – MsgBoxes”. And there is one button. All this should look familiar. Go ahead and press the button and Olly will break at our BP:
Now it is just a matter of stepping the code and leading Olly the right way to display the good boy instead of the bad boy. I don’t need to tell you how to do this. (If I do, please go back and re-read the tutorials in this series.)
The second target
In my quest to find targets that will not hurt anyone, the second app we will be looking at is freeware, though it does have a nag that is displayed until you register the app. Registration is free. It was the least downloaded app in the “tools” category on Cnet, with 4 downloads in the last year. It is a program called Exif2htm. I have no idea what an exif file is, but apparently you can convert them into html files using this program.
When we load the app into ExeInfoPE we see that it is in fact a Delphi program and not packed:
Running the app, we can see the nag popup:
Anyway, we can see it is UNREGISTERED at the top. Clicking “About” gives us the about screen:
and clicking “Register” on the bottom gives us the registration screen:
Entering false data gives us an unfortunate message:
Let’s load the app into DeDe and see what we can see. Make sure you click past the nag before hitting OK for DeDe to proceed:
Clicking on Forms gives us the forms window. Clicking on TForm1, we can see that this is probably the main window:
We can also see a caption for Files, and if we look down farther, there are more for “save”, “print” and “editor”. Clicking on TForm2 is far more interesting, though:
So the caption is ‘Register’, we can see the labels for the edit boxes are ‘Name’ and ‘Code’, and we can see two buttons at the bottom, ‘OK’, and ‘Cancel’. Let’s click on the “Procedures” tab and see what we’ve got:
Clicking on Unit2 – TForm2 we can see that there is one method, “BitBtn1Click”, which we saw in the forms window corresponds with the “OK” button on the bottom of the registration window. We can also see that DeDe shows the RVA of the address for this method. Something tells me that is going to be very helpful here. Let’s write down that address and load up the app in Olly.
Finding the patch
This does not look like a very friendly binary in Olly:
Let’s go to our saved address and see what we have (I placed a BP on it to remember it):
Toward the end we can see the message that comes up telling us to restart he app to see if our registration code worked. This is a technique used quite often, and it does provide a small challenge to us. The problem is we don’t know if we typed in the right code until we restart, and the area that checks if it was right could be anywhere in the program. We also can’t force our code to be right as we don’t know where the instructions are that check if it’s correct or not! But using a little common sense, you will see that it’s no that much harder to get past a protection like this.
The hint comes from the fact that, after you enter your code, the app must store it somewhere (or at least store SOMETHING somewhere) so that when it restarts it can look and see if we stored the correct code in or not. It could either store our entered name and code, or it could store a flag that we are registered, or any of a number of other things. The point is, though, it must store something.
There are only a couple places a program can store data from run to run of the app. Almost always it’s the registry or an ini file. So what we have to do is find out where this data is stored so that when we run the app again we can find where this data is processed and checked for if we’re registered or not.
We have our BP set, so let’s run the app in Olly. Click on Register, enter some fake data, and click OK. Olly should break at our BP:
Now let’s look at the code where Olly broke. At first is a bunch of pushes that set up a bunch of variables on the stack. We then push some varibles onto the stack and make a call at 4A0095. If you step over the code (stopping at address 4A009A, you will see something interesting in the info window:
It appears it is doing something with our username. 99.99999999999999999% of the time this will be a check to make sure we actually entered something into the edit text field in the registration window (usually returning a length). The fact that EAX equals 6 on return helps support this hypothesis, though we don’t know for sure. There is a check if EAX equals zero right after this and a jump. I’m sure you can guess what that’s for. Slowly stepping over the next couple instructions, we then see our code pop up in the window as well:
What do you want to bet that this is doing the same thing on our code? EAX again is compared with zero (it is 8 this time, which just happens to be the length of my code ) and jumps if it is zero. Next we pass a couple more calls, each of which loads our name and code as arguments again. You can step over this code until we get to the big red flag at address 4A0101:
This looks very important. It is a data file that looks like it is going to create. Stepping over the next two lines brings us to address 4A010B:
What appears to be a file path is displayed in the info window. It points to the location I am currently running the app from (my desktop). In this file path is the name of the dat file it looks like it’s going to create. Stepping a couple more times until you step over the call at 4A0112, you may notice a little something pop up on your desktop:
Hmmm. That wasn’t there before. My file has a Notepad++ icon because that’s what I’ve associated .dat files with- yours may look different. Let’s open this file and have a look (you can open it in any text editor):
Well, I think we found out where our info will be stored We know that the app creates a file called reginfo.dat in the same folder as the app is stored, and in this file is saved our entered name and code. Now that we know how the program is going to check for if we are registered or not, we can use this to find the code. Go in to Olly and do a search for strings and search for “reginfo.dat”. Mine came up with two instances, the second of which was the area we were just looking at where the reginfo file was created. The first looks very interesting though:
I placed a BP on the reference to reginfo and double clicked to see what the code looks like:
Scrolling up, we can see that there are no conditional jumps, though below our BP we see several. Go ahead and close the app (clicking run in Olly and clicking OK in the registry window and closing the app through the app- not through Olly. We want to make sure all of the code that stores the registered info get’s done). Now, right when we re-start the app we break at our new BP:
Now lets single step to see what’s going on…At the first conditional jump at address 49AC26 we do not jump. This could be OK or it could be a potential place we want to patch, we don’t know yet, so let’s keep stepping. The next set of instructions loads our username and code from the data file and performs some calls with it. This is looking much more likely. When we get to the next conditional jump, we see that we are indeed going to jump:
Stepping in we can see where we jump to:
This is not looking good. Continuing to step, we will eventually run the “Shareware” code, so we know we have gone too far. Let’s re-start the app and see what happens if we don’t make that last jump.
*** You may wonder why I didn’t try patching the conditional jump at address 49AC26. The answer is, I did, and we still got he bad boy message ***
Step until you get to the second conditional jump at address 49AC58:
Now, let’s tell Olly not to jump by changing he zero flag and keep stepping through code. We will eventually come to the last conditional jump at address 49AC78:
Looking down where this jump jumps to we can see that it is the same destination as the previous jump. If you want, you can step through it, though you will see that it is the same outcome, setting our app as shareware. This tells us that this is a second check on our name/code pair. Let’s keep Olly from jumping by setting the zero flag again and keep going:
Now if you keep stepping, you will notice that nothing noticeable happens, so go ahead and run the app. You will notice that our nag does not show and that the main window pops up. Also you will notice that there is no UNREGISTERED text anymore:
We have now forced the app to use whatever name and code have been entered! We have cracked the app
-Till next time