Introduction
In this tutorial I am going to show you how we can add a dialog box to the beginning of any app. Personally, I use this trick to help out my fellow co-workers, either giving them subtle reminders (“You have used deodorant today, right?”) or even helpful messages (“Are you sure you want to format your hard drive?”). We will be using a special technique called a code cave. I will not be going into great detail about code caves as I plan on covering them in my normal beginner’s guide to reverse engineering series, but along with the files in the downloads for this tutorial I have included a great document on code caves and how to use them.
The tools you will need for this tutorial are OllyDBG (any version), ODBGScript plugin (included in the download), “Code Cave Finder” script for Olly (also included in download), CFF Explorer (or any PE editor- you can download CFF from the tools
page), and the target file called “ColorPicker”. A computer will also come in handy.
The program I am going to use to demonstrate this technique is “Quick HTML Color Picker”, a freeware program I have had for ages. It basically lets you click any color on the screen and see what it’s RGB and hex values are (great help for web designers):
So let’s go ahead and load up the app in Olly…
The first thing we want to do is find a code cave. But first, let me give you a quick rundown…
Code Caves
Normally, a program runs through code, calling various functions, jumping to various spots, following a flow that the developer (hopefully) planned. Well, it is possible to change this flow in order to add, modify, or remove certain functionality in an existing binary. Maybe you want to add a menu item that does something when you select it, or add a button to a dialog box when clicked. Because the original intent of the program was not to do these things, the code to perform them are obviously not in the binary- we must add it. After deciding what code we wish to add to a program, the problem becomes “Where?” Where are we going to put our custom code. And the next problem is “How do we tell the program to run our code instead of the original code?”
For the first problem, the solution is a “code cave” (or sometimes “codecave”). What this means is that we are going to find some space, either within the program’s memory space itself, or in a DLL that we will link in at runtime, that we can store our custom code at. There are certain pluses and minuses to the two different ways of doing it, either within the program itself or attaching a DLL to store the code, but in this tutorial we will use the former as it is a little easier. What we are going to do is find a space in our program that has nothing in it (no code, resources, variables etc.) where we can insert some of our code. This space is usually located between sections. This is because sections are segmented by a certain amount (meaning they must be a multiple of a certain amount) and if the code doesn’t end on exactly that amount, there will be space at the end of the code before the next section starts:
In this picture you can see that the segments are each in 512kb blocks. If the data in the last segment is not exactly 512k, there will be some space before the next segment begins (purple arrows). Each of the white spaces lists how many free bytes are there, prime locations to put a code cave. You can also have caves span multiple sections so that the first performs some code then calls the second section and so on.Sometimes, binaries have very little space between segments, so we have to do something a little more involved. This may mean saving our code in a non-executable section (like a data section) and changing that section’s attributes to be able to execute code. It may also mean that we need to create a brand new section that will be tacked on to the binary. Fortunately for us, our program has lots of space at the end of it’s code section where we can put our custom code (though I will be covering some of these other challenges in other tutorials
Fortunately, there is a script that will help us find free memory in an executable section where we can put our code cave. If you do not already have ODBGScript as a plugin, get it from the files in this download and put it into the plugins folder. After you re-run Olly, you can select it and load in a script:
Now point ODBGScript to the Code Cave Finder script included in this tutorial and run it:
After it’s done it will pop up a message telling us how we can find any potential empty caves. Click OK then cancel the script as it will keep running:
So the script is telling us to look for user defined comments, so let’s do that:
And we see that the script has found a stretch of empty memory at address 42551B:
After double-clicking on that line, Olly takes us to that section and we can see that, in fact, there is a section of empty code here:
If you were to look in the Memory Window you would notice that this section of memory is in the .text section, so it is already executable
Next comes the question of how we are going to construct our dialog splash screen. Fortunately for us, this program already imports the MessageBoxA function which opens a dialog box. It would be OK if it hadn’t, but we would have had to go through the work of loading in that function from the DLL, and that’s a little more complicated (and saved for a later tutorial). Let’s do a search in our program to find the MessageBoxA function. Right-click in the disassembly window and choose “Search for” -> “All intermodular calls”. When the window first comes up it is sorted by address, so to make it a little easier to find what we’re looking for, click on the “Destination” header to sort by the function’s name:
Now, one trick in this window is that if we start typing the name of the function, Olly will start sorting the list for us. As you can see in the next picture, I typed the first four letters of MessageBoxA and the window then went right to our desired function:
So, now we know that our program calls MessageBoxA (once), probably on an about screen. Now the reason we searched for this function is because we want to find out where the Windows loader loaded in this function from the User32.dll file.Remember, when the file is first loaded, the loader checks to see which DLLs our program needs and loads them into our program’s memory space. It then iterates through the functions, looking for ones our program is going to call. When it finds the address of a particular function, it copies it into a “jump table” so that every time our program needs to call this function, it will simply call the line in the jump table that corresponds to that function. Otherwise, the loader would be required to go through every call to that function in our program and change the address to what will finally be the true address of the called function. (If you want to learn more about the jump table, please read my reverse engineering tutorials:) What we need is the address that the loader has put into the jump table for the MessageBoxA function. When we double-click on the MessageBoxA line in the intermodular calls window, we are taken to where that function is called in our program:
You can see, at address 4200D0, that our color picker program calls the MessageBoxA function inside User32.dll. Olly has kindly tried to help us by telling us it’s MessageBoxA as opposed to the actual address that MessageBoxA resides at. In order to call this function ourself from our code cave, we need to get this address. The way to do that is to click on the “CALL DWORD PTR DS:[<&USER32. MessageBoxA>]” and hit the space bar. This will bring up the assembly window (as well as the true address):
So we can see that the address we want to call is 426388. I would suggest copying and pasting this whole line (CALL DWORD PTR DS:[426388]) into a text editor for later use OK, now let’s go back to our code cave (remember, you can search for all user comments to find the empty space):
OK, now we want to start coding our own code. What this code is going to do is call a dialog box with a custom caption and text. It will have an OK button as well. Then, after the user closes the dialog, the main program will run like nothing ever happened.
For those that don’t have an API reference handy, the four parameters that are passed to MessageBoxA are 1) a handle to the owner’s window, 2) the text to display, 3) the caption (title), and 4) the style of the dialog. Of course, since we’re dealing in assembly language here, we will push the parameters in reverse order So let’s start with the first line. Click a couple lines down from the beginning of the empty section (I like to give myself a little padding for if I forget something I needed at the beginning) and hit the space bar to open the assemble window. I started on line 42551E, so you probably should as well. I then types in the first instruction, which in our case is a PUSH 0:
After you click the assemble button, the PUSH 0 instruction is added to the code, and Olly handily leaves open the window, waiting for more instructions to assemble. The second instruction we want to insert is a push of the address of the caption. We don’t know exactly where this will go, so I’m just gonna pick an address down the screen a little. You can always come back and change the address if you run out of space
I chose address 425537 as the address of the captions text.
Next, we must push the address of the text that will be displayed in the message box. I am just going to pick a number down the page a little more and choose 425557. (We have his luxury as this program happens to have a lot of free space. If we didn’t have as much, we would have to plan this better
The last parameter is another PUSH 0, as message boxes don’t need actual handles, they can just be set to zero, so add that line in next. OK, now that we have pushed our last parameter, let’s insert the actual call to MessageBoxA. Remember that line we copied earlier and saved in our text editor? That’s the one to paste back in:
And after you click assemble, you can cancel that window and we now have most of our code. The next thing we need to do is add in the strings for the caption and text. If you recall for the caption, earlier I chose address 425537 as the address to store this, so let’s add it there. Right click no this line and choose “Binary” -> “Edit”:
This will bring up our binary edit box. Now, I will type in the caption to my message box, in this case “Hey!”. Make sure you delete the initial empty character and type in the ASCII field and not the other fields. At the end, it should look like this:
Now click OK and you should notice something strange; our text is not in there? Instead there’s some crazy code that we never typed in! This is actually the binary code we typed in, but Olly is assuming for the time being that we typed in assembly opcodes instead of data so he is showing it as assembly instructions. Don’t worry, this will change shortly:
If you recall, the second paramter I pushed was the address of the actual text, and this address was 425557. Let’s do the same thing at this address (right-click -> Binary -> Edit). Type in whatever you want:
And after you click OK, you will notice that this comes up as strange code as well. Don’t worry about that yet. Soon Olly will know the difference
Now we are confronted with our second initial question, “How do we tell the program to run our code instead of the original code?” Well, there are a couple ways to do this. In this tutorial, we are going to cheat a little and change the entry point (the point in the program that will start first) from the original entry point to our new code cave. Then, at the end of our code, we are going to call the original entry point. This basically makes our code run first, and then when it’s done, it will call the regular program. First we have to find what this original entry point in the program was. To do this, double-click on the EIP register to tell Olly to jump to where we are currently paused. Since we have not run the program yet, Olly will be paused at the first line of code, which happens to be the original Entry Point for the color Picker Program:
As we can see, the OEP (original Entry Point) is 40B247. This means that had we not changed anything, this will be the first line the CPU will run when this program is executed. What we need to do is to jump to this OEP at the end of our code, so go back to our code and let’s enter a jump instruction to jump there:
Now Olly has still not figured out that our strings are strings and that our code is code, but he’s getting smarter. In this next picture, the blue section is code and the red section is our ASCII string. Notice that Olly has filled in our parameters for the MessageBoxA call by looking up our strings:
Now it is time to save our program. Highlight the entire section of the code cave where we have added code, right click and choose “Save to executable”. This will open our patched code in a new window:
Now right-click in this new window and choose “Save file”. I chose the name colorPicker2.exe:
Now as a side note, I wanted to show you what this new binary looked like with our cave in it, and I’m glad I did because there was something I forgot to go over! Load the new program (colorPicker2.exe) into olly and go to where we inserted our cave. You will see that Olly has displayed the strings correctly, but the first instruction, the one that was supposed to be PUSH 0, has been changed! This is not a mistake. If you recall, our address where our cave started was 42551E, but Olly is showing us address 42551D, so he has gotten the instruction wrong. We don’t need to worry about this except to remember that our real entry point in the cave is 42551E:
Changing the OEP
So now let’s tell the Windows loader to start at our code cave instead of the original entry point. Bring up colorPicker2 in CFF Explorer (or any PE editor). You will see that the original address of the entry point was B247, which, when added to the ImageBase, is 40b247. This was the address that we jumped to at the end of our code section!
Now, what we want to do is change this entry point to point to our code instead of the original programs starting code. Remember, our code starts at 42551E, so after subtracting the ImageBase of 400000, we get 2551E. This is our new entry point:
Now, save the changes back to the executable (in CFF Explorer, choose “Save”). Now run our new color picker:
We have done it!!! Now click OK and…
our program runs normally. Congratulations, we have added a dialog splash to a program. Now, go try to be as helpful as I am to other people, perhaps offering advice (“That outfit makes you look fat.”) or perhaps just some kind words (“You would look soooo much better if you lost 40 pounds”
-Till next time
R4ndom
June 16th, 2012 on 6:39 am
Nice tutorial ,
June 18th, 2012 on 10:38 am
Hmm….nice article – it works with me but only when I switch off my AV. Weirdo – changing the OEP seems to flag the AV. Do you have an idea why it is like that???
June 18th, 2012 on 5:06 pm
Yes, because the technique you are using is often used with viruses and your AV software is picking up on this. Unfortunately, viruses have made it a lot more difficult to just have fun with binaries
June 19th, 2012 on 7:30 am
I wonder what the AV is picking up excactly?
- changing the OEP? How does the AV know that the OEP is changed? OEP is still in the text section so all should be fine
- the jump back to old OEP?
Btw. not all AVs detect this technique
June 19th, 2012 on 4:19 pm
Well, I am not an anti-virus expert but anti-virus software vendors use heuristics (as well as signatures) to detect infection. In this case, it looks suspicious because it follows a pattern used by many virus injectors, namely, the entry point points to the end of the file, a small function is run, and then jumps to the beginning of the file. This is a red flag to some AV engines.
If you want to see how AV can get it wrong, take any crackme that you know has no infection and submit it to http://www.VirusTotal.com
. If you don’t know, VirusTotal will submit your file to 40 different AV engines and get the results. I GUARANTEE you that 99% of any non-malicious crackme will have at least 5 false positives. In fact, try taking something completely innocuous, like Windows Calculator, pack it using UPX (or some packer) and submit it to VirusTotal. You’ll get everything from Trojans to backdoors to…well, everything. AV’s are not perfect, and they must choose how to flag something.June 20th, 2012 on 7:44 am
Thanks for your comprehensive answer R4ndom. And keep up with the good work!!
July 17th, 2012 on 11:12 pm
Thank you very much
but why it doesn’t work under windows 64bit?
July 18th, 2012 on 2:38 am
It should work under Windows 64-bit, that’s what I used to make the tutorial.
July 18th, 2012 on 4:19 pm
The bytes at the address 42551D – 42551E, That should translate to push 0 and olly is interpretting it incorrectly. How do you get olly to interpret the instructions as push 0?.
July 18th, 2012 on 4:34 pm
Sorry, i was the anonymous poster that enquired about olly interpreting the bytes at 42551D incorrectly. Just wanted to note my email address incase you choose to respond to me there. I just found out about your blog today and find it very useful. Thanks for the tutorials.
August 14th, 2012 on 8:15 pm
One can read all over the tubes that .code section is read-only. Obviously is not, else code cave wouldn’t be possible. Right?
August 15th, 2012 on 4:03 pm
I’m sorry, I don’t understand your question. What are ‘tubes’?
August 15th, 2012 on 7:18 pm
Sorry for the lame wording.
The point is that many articles states that .code section is read-only. But when your are using code cave you are actually writing new code into .code section. So my assumption was that this section is not (always) read-only.
August 15th, 2012 on 7:51 pm
ooooooohhhhhhhh. I get it now. The code section is still usually read only. This is why Olly makes you re-save the changes you’ve made to a binary. It creates a new version of the file with your changes in it. If you tried to change one of these locations through code, it would not work.
August 15th, 2012 on 8:35 pm
Thanks R4ndom. That explains it all (yes, I know this is also written in the article, but I was a bit confused anyway).
Keep on writing excellent articles.
October 11th, 2012 on 3:54 am
Another good one. Finally back here and going to go through all your tuts. It would be nice if you showed how to edit the entrance pointer in the hex dump (Does OllyDBG have a PE header decoding plugin?)
October 11th, 2012 on 6:05 pm
What do you mean by that? The Entry Point?
November 22nd, 2012 on 1:38 pm
Very good tutorial. If you dont mind, i think the right title would be adding a message box to executable. The splash screen basically means an image in the jpg, png, gif or any other format. Keep up your good work.
Regards,
Kingstaa