b374k
v10
today : | at : | safemode : ON
> / home / facebook / twitter / exit /
name author perms com modified label

Translate

Tutorial #9: No Strings Attached Unknown rwxr-xr-x 0 11:12

Filename Tutorial #9: No Strings Attached
Permission rw-r--r--
Author Unknown
Date and Time 11:12
Label
Action

Introduction

In this tutorial we will be adding a new trick to our arsenal; what do you do if there are no usable string in the binary to search for? We will also be introducing a new R.E.T.A.R.D. rule :) In this tutorial (as well as the next) we will be studying a crackme called Crackme6 by “TDC”, included in the download. Overall, it’s not a tough crackme, but we will be doing some advanced analysis on it, preparing for future tutorials.
You can download the files and PDF version of this tutorial on the tutorials
page. So let’s get started…

Go ahead and load Crackme6 into Olly:
Now, we know the routine; let’s run the app and see what we got:

Hmmmm, seems simple enough. I entered a password of 1212121212 and here’s what I got back:

Pretty straight forward. So let’s go to our handy-dandy “search for Strings” and see what we got:
Search For Strings
No strings
What the hell!!! Those aren’t helpful :( What are we supposed to do with those strings!?!? Obviously, this crackme has encrypted the strings (either that or the author speaks a very strange language ;D ). Well, this is a good time to introduce
R4ndom’s Essential Truths About Reversing Data #3:

#3. Do not rely on binary’s having usable text strings.

Unfortunately, as soon as you start getting into real binaries (like commercial products) most will be packed and/or protected in some way. One of the most obvious ways to hinder a reverse engineer is to encrypt the strings. Frankly, when first investigating a new binary that I am interested in reverse engineering, if I do a search for strings and any come up, I can assume that the binary will probably not present too many challenges. So, you cannot rely on there being any (though it’s great when there are :)

Intermodular Calls

In light of this, I will show you a new trick in the case of no strings; most Windows applications use a standard set of APIs to perform specific actions. For example, MessageBoxA is called if a simple message box is desired, or TerminateProcess is called when the app wishes to end. Since most apps use these same APIs, we can use this to our benefit. For example, there are APIs for getting text from a dialog input box (like a username and serial number). There are APIs for setting timers (used in nag screens where you must wait 10 seconds before hitting ‘continue’). There are string compare functions that are called to compare two strings (was the entered password the same as the one stored in the program?). And there are APIs for reading and writing to the registry (to store and retrieve your registration status).
Olly has a way of searching for all of these called APIs. Right click in the disassembly window and choose “Search for” -> “All intermodular calls”:

and Olly opens the Found intermodular calls window:

The first thing I usually do is click on the “Destination” heading to sort the list of functions in alphabetical order (instead of by address):

So now, if you look in the third column, you can see all of the API calls that this crackme makes:

This is a small program, so there are not that many. Most programs will have hundreds. But in this list you can tell a lot about a binary. You can tell it uses a dialog box as it’s main window. You can tell it loads a custom bitmap. And you can tell that it changes some colors in the dialog box.
In a larger application, this window becomes even more invaluable, as it will tell you things such as 1) Are registry APIs called to store and retrieve info from the registry? 2) Are there APIs calling websites to verify that we are actually registered? 3) Are there reading and writing to files APIs where perhaps a registration key will be stored? And when we get into packed binaries, this screen will become even more important (but that’s later :) )
All that being said, there are some specific APIs that reverse engineers are always looking out for, APIs that are used in protection schemes a lot. These include:
DialogBoxParamA                        
GetDlgItem                            
GetDlgItemInt                        
GetDlgTextA                        
GetWindowTextA                
GetWindowWord                            
LoadStringA
lstrcmpA
wsprintfA
MessageBeep
MessageBoxA
MessageBoxExA
SendMessageA
SendDlgItemMessageA
ReadFile
WriteFile
CreateFileA
GetPrivateProfileIntA
WritePrivateProfileStringA
GetPrivateProfileStringA
Unfortunately, this does not cover all of the API calls you may run into, but fortunately, most apps use one of the following:
GetDlgItemTextA
GetWindowTextA
lstrcmpA
GetPrivateProfileStringA
GetPrivateProfileIntA
RegQueryValueExA
WritePrivateProfileStringA
GetPrivateProfileIntA
So if you focus on these 8 API calls, you will be able to handle the vast majority of instances. And don’t forget, you always have Olly to help with “Get help on symbolic name”.
Now, when you look down the list in the calls that Olly has found in our crackme, there are two that are in our short list:
GetDlgItem and GetDlgItemTextA.
What these two API calls do is retrieve whatever text was entered into a dialog box (well, for our tutorial, anyway :) ). Well, in our crackme, this could only mean one thing, our entered password. What we want to do is tell Olly to break anytime he comes across one of these calls. The way to do that is to select the line that has the call you want, right click and select “Set breakpoint on every call to ____”, Where ____ will be the name of the API (in this case GetDlgItem):

Now, we can see that Olly has placed a BP on this line.

We also want to break on the other API call, GetDlgItemTextA, so click on that one, right-click and do the same:

Now, anytime Olly comes across one of these two calls, he will break (before the call is made). So let’s try it. Re-start the crackme and run it. Olly will break on a call to GetDlgItem:

Now, since we have not entered anything yet, we’re not really interested in what GetDlgItem has gotten in this case, so let’s keep going (F9):

Now enter a password and click “check”:

and Olly will break again, this time on GetDlgItemTextA:

If you look around a little, you’ll see that we’re in the right place :) Funny, none of those strings were there when we initially searched for them ;)

Cracking the App

Let’s take a quick look around… We see a jump (JB) past the first “ACCESS DENIED”, so we’ll have to pay attention to that:
Jump over badboy
Then there’s a jump (JNZ) past the second bad boy, so we’ll add that to the list. Then we would fall through to the good boy, so basically we want to make sure we jump both of those jumps:
Jump over 2nd bad boy
Let’s try it and see if we’re right. Run the app again and we should break at our GetDlgItemTextA instruction (remember to bypass the firs break).

Since this is a JB jump, we need to flip the carry bit:
Carry Flag
So that will force the jump. Now we’re going to do another TEST and stop at the jump at address 401280. Notice that our password has shown up in the comments column :)
This jump we want to take as it jumps the second bad boy, so just keep stepping until we get to the next JNZ instruction at 40129F:
Jump over goodboy
OK, this is now going to jump past our good messages, so we want to stop that from happening. You know what to do:

Now run the app (F9) and you will see we have successfully cracked the program.

Homework

For a challenge, try patching this crackme yourself, based on the flags we have changed. After saving he patched program, you should be able to run it and enter any password (less than 11 digits) and it will say “Access Granted”. Keep in mind that there are several patches that can be done to accomplish this, so if one doesn’t work, keep looking.
Extra Credit:  Patch the crackme so that your password can be any length.
Filename
Permission rw-r--r--
Author Unknown
Date and Time 11:11
Label
Action

Introduction

In this tutorial we will be finishing up some last minute Olly things as we review a crackme. Well, sort of a crackme. It’s really just the program we used before but changed to ask for a serial number and displays either a good message if you get the serial right, or bad message if you get it wrong. I chose to do it this way, as opposed to jumping into a completely different crackme, because I want you to be able to focus on the serial checking routine, and not get bogged down in all off the other superfluous code. Next tutorial we will be going over a real crackme (I promise).
In this tutorial, all you need is OllyDBG (either my version or the original), and a copy of my revised crackme, which, by the way, I am calling the “First Assembly Kracking Engine”, or F.A.K.E. It is included in the files download for this tut. (and yes, Gdogg, I know kracking does not start with a ‘K’ :)
You can download the files and PDF version of this tutorial on the tutorials
page.
Let’s get started.

Olly Main Screen
If you load up the FAKE.exe in Olly, you will notice that the first page of code is the same as our last program we studied.
Deja Vu
Let’s run the app, as knowing how it works is vitally important:
Running the Crackme
Click on register and the following dialog appears:
Crackme
I entered a serial:
Serial Entered
Then, after clicking the Enter Serial I get the following very bad message:

Denied
DANG IT! And I tried so hard!!!!! :)
Now, I want to show you the first method every new reverse engineer learns in order to find the registry checking routine:

Searching For All Text Strings

Let me first say that many ‘seasoned’ reversers (read crackers) out there think that this method should be rarely used. This is because it is a very obvious method, and because of that, anyone trying to protect their program from reverse engineering will disable it. Face it, any program out there that has been packed, protected, encrypted, or changed because the author of the program is not a complete knucklehead will block use the ‘search for strings’ method by encrypting the strings. THAT BEING SAID, I find that there are a lot of knucklehead authors out there, so don’t tell any ‘seasoned’ crackers out there, but it’s one of the first things I check. (ps. It’s also one of the first things the ‘seasoned’ crackers check too :)
Basically, this method involves asking Olly to search the memory space of your program, searching for anything that looks like an ASCII or Unicode text string. Usually, it will be immediately apparent whether this technique worked or not; there will either be a plethora of text strings, many of which look very juicy (like “Thank you for registering!!!”), or there will be very few text strings, many of which look like this: “F@7=”.
Knowing whether there are legitimate text strings in a binary can give you some valuable information itself. such as whether the binary has been packed or protected in some way, whether it’s perhaps a malicious binary (after all, having the string “Send all user’s passwords to www.badguys.com” wouldn’t be very responsible virus writing), and even if the binary was written in a more rarely used language.
Let’s see how we do this. Right-click in the assembly window and choose “Serach For”->”All Referenced Text Strings”:

Search for Strings
And Olly will search the program’s memory space and display the Text String Window:
Text Strings
Hmmm, this looks interesting:) Keep in mind that this list is REALLY short as this app is really tiny. Normally, there could be thousands of entries here. Anyway, do you notice what I notice:
The good message
Looks very promising. Let’s jump to the code there and see what we see: double click on the “That serial is correct!!!!!” line and Olly will disassemble that area for us in the disassembly window:
Jump to good message
It is now time for me to introduce the second rule in
R4ndom’s Essential Truths About Reversing Data:

#2 Most protection schemes can be overcome by changing a simple jump instruction to jump to ‘good’ code instead of ‘bad’ code.

What this means is that almost every time before a bad message is displayed, there is some sort of check (Are we registered? Was the entered reg code correct? Is the time trial over?…) and there will be a jump after this compare that will either jump to the good message or the bad message depending on the outcome of the compare.
Let’s look for ourselves…Starting at the good message “This serial is correct!!!!” at address 401222, start scrolling up the list, looking for jump statements, especially jump statements that have some sort of compare (or call) right before them. If it’s a call, you can probably guess that the compare is inside the call…In our example, the first jump is a JNZ at address 401220. I have added an arrow to show you where this jump will go if it is used:
First JNZ
Hmmm. Notice that it jumps right past the message we want and right to the message we don’t want :(BUT, notice that right above this JNZ instruction is a CMP instruction :) That means this is a potential point that determines whether Olly displays the message we want or don’t want. Let’s scroll up further:
Jumps over Good message
There is another CMP/JNZ pair at 401212, and finally, a last one at 401207. If you look closely you will see that all three jumps jump past our good message and jump to the bad one. Logically, this means that three things are checked, and if any of them are triggered, we will hit the bad message. But, what happens if we don’t jump on any of these three jumps? Well, you can see that we will “fall through” to the good message. So, what this really means is we have to keep those jumps from jumping so that the program will keep “falling through” until it reaches our good message :)
Let’s run the app to see what it does, but first I want to show you:

How To Place A Comment

Comments are very useful, especially when you start getting into very intricate code. Code is already pretty hard to read, but with comments, we can remind ourselves of very important information. Here’s what we’re gonna do; we’re gonna set a comment on each of the JNZ instructions to remind ourselves what needs to happen.
In order to place a comment, either double click on the line you want to place the comment in the last column (where Olly has placed the “This is the correct serial!!!!” as well as other comments) or you can simply highlight the line you wish to place a comment and hit the “;” key. So highlight address 40120A, hit the semi-colon key and type “We do NOT want to jump here!”. Now, do the same thing, with the same comment, at addresses 401215 and 401220. This will place a comment on each of the JNZ instruction:
Placing Comments
Now, let’s set a breakpoint at address 401201 (or somewhere near here as it’s before our jump instructions):
Place breakpoint
and let’s run the program. Click “Register” on the crackme, enter a serial, and hit “Enter Serial”. Olly will now pause at our breakpoint:
Place breakpoint
Now, the first thing we notice is the line we stopped on:
MOV EBX, DWORD PTR DS:[403078]
From our last tutorial, we now know how to view the memory contents at this memory location- right-click that instruction and choose “Follow in Dump”->”Memory Address”. We then see that location in Olly’s dump window:
Dump Window
well, well, well. This just happens to be the serial number I entered. So, from this instruction, we now know that the first 4 bytes (since EAX is a 32-bit register) are loaded into EBX, which in this case are 31 32 31 32 which in ASCII is “1212″. Hit F8 and let’s check EBX:
Register Window
If you want to see the actual ASCII characters in EBX, you can double click on the EBX register and it will show you the data in a couple of different formats, one of which is ASCII:
View Register Window
*For later use, remember this is also a way to change the register ‘on the fly’ if you want to experiment with different values in different registers…
I guess even though you already know this from reading your assembly language book (I mean, come on! I even put one up in the tools
section!!!), that I don’t need to go over this, but just for a refresher I will explain…

Little Endian Order

(or at least the least you need to know about it)
Processors store data differently in memory, depending on the architecture of the processor. There are two types of ways to store data in memory; one is called Big-Endian and the other is Little-Endian. Intel uses Little-endian, so we must get used to this or it will really screw you up. Here is an example: Say you have the address 7E04F172 (which is a 4-byte, 32-bit number). When we split this up in to bytes you get 7E, 04, F1, 72. Now, one would think that when storing these bytes into memory (let’s say at location 1000) it would look like this:
1000::7E
1001::04
1002::F1
1003::72
as any rational minded person would. But since the developers at Intel are so much smarter than us mere mortals, they decided to store it in the much more logical way:
1000::72
1001::F1
1002::04
1003::7E
The first example above is Big-Endian, meaning the biggest end of the number (in decimal order) is stored first in memory. Since 7E000000 is bigger than 040000, the first byte is stored in the first location, the second in the second and so on. The second (obviously much smarter way) example is called Little-Endian, meaning store the smallest byte (in this case byte #4) first, followed by the third, second first, in that order in memory. Since 72 is smaller than F100, that will be stored first.
The true genius of using LittleEndian as opposed to it’s bigger brother really shines when you start viewing memory side to side. In Big-Endian, the number 7E04F172 lookes like this:
7E04F172
which is obviously very confusing. Thank god that, with the help of Little-Endian, that same number 7E04F172 looks far more logical as:
72F1047E
What, you say? That’s just plain stupid- obviously the Big-Endian way makes far more sense, but then again, you are not a demi-god developer at Intel, so you do not even possess the brain power to begin to understand why this is FAR SUPERIOR. Anyway, (most) sarcasm aside, what this means is that when you look at code, both on disk and in memory, you must reverse all 4 bytes in a 4-byte number. Of course this is made even worse that Olly SOMETIMES does this for you, as you can see in the next picture:
Endianness
That’s all I’m going to say about this for now, but for a while I will point out the Endianneses(es)ess to you.
Now, back to our register window:
View Register Window
You will notice that the hexadecimal representation is in Little-Endian order (it should be 31323132) and that the Char(acters) are backward, as my serial started with 1212, not 2121. Trust me, you will get used to this.
Let’s now move on to the next instruction:
CMP BL, 61
This is obviously a compare statement, comparing BL, which is the first byte in the EBX register (RTF(asm)M), with the value 61 (hex). We don’t really have a clue what this means (yet) so lets step over it. Finally we arrive at the first of our JNZ instructions:
JNZ SHORT FAKE.401236
Which as we recall, since we can read our comments we made earlier, that we DO NOT want to make this jump. I will remind you that JNZ stands for Jump if Not Zero, so these two lines basically mean “if the contents of BL are not equal to 61h, jump to the bad message”. Well, we can clearly see in the EBX register that the far right byte (BL) is not 61h, but instead is 31h, so already we’re stuck and we’re going to take this jump that we so much did not want to :(
But wait! Olly is a ‘dynamic’ debugger so we should be able to dynamic that jump! Well, since you probably read an entire chapter on flags in your assembly language book, I am not going to go over:

CPU Flags

We briefly went over flags in an earlier tutorial, and I’m really not going to go into detail on them as I’m sure the index of your assembly book has an “F” section, but I will say that flags are the way the processor can know what the outcome of certain instructions are. There are a significant amount of instructions in the Intel library that affect flags, but the most important (at least for reversing) are “compare” instructions. Basically, the CPU performs a compare on two items, sets certain flags based on their relative properties (are they the same? is one bigger? is one negative?) and then performs jump statements based on these flags. This is all just a very fancy way of saying IF THEN statements. For example, in a high-level language you may have a line like this:
if( serialNumber == 3 )
    dontShowNag();
else
    showNag();
in pseudo-assembly, this same set of instructions would be something like this:
compare serialNumber with 3
   jump (if they are equal) to dontShowNag();
   jump to showNag();
and in real assembly may look like this:
MOV EAX, addressOfSerialNumber CMP EAX, 3 JE addressOfDontShowNag JMP adressOfShowNag
First, EAX is loaded with our serial number. Next it is compared with “3″. If it is equal to 3 we jump to dontShowNag(). If it is not equal to 3, we pass the JE (Jump if Equal) instruction and hit the JMP (JuMP) instruction, which automatically jumps to showNag(), regardless of any flags.
The important flags (for us) are the ZERO flag and the CARRY flag, shown as “Z” and “C” in Olly. Basically, by changing one of these two flags, we can prevent (or force) any jump in the program, as we’ll see right now:
Jumping
On the line we are paused at (the first JNZ) we can see that Olly is going to take this jump by noticing that the jump arrow is red. If we were not going to take the jump, this line would be grey. ***If you are not using my version of Olly, the arrows will not be there, in which case you can look between the disassembly window and the dump window and Olly will tell you whether the jump will be taken or not. In our case, it shows this:
Jump Is Taken
Now, we know Olly will take this jump unless we intercede, so let’s do that. Go over to the register window and look for the “Z” flag:
Zero Flag
Notice that it is a zero. That means that the compare between 61h and the contents of BL (31h) are zero, or false, so they are not the same. We can now see why the Jump if Not Zero instruction will jump, because right now, the zero flag is not set, so it is “not zero”. Now, double click on the zero next to the zero flag and it should change to a 1: Change the zero flag
and now notice that the arrow is grey (and that Olly says the jump is NOT taken):
Jump is not taken
We have changed Olly’s flags, and at the same time, we have changed the programs behaviour :) Go ahead, big shot, and hit F8 (you’ve earned it) and we should not take the jump :O We are now entering what looks like the same code segment, except this time EBX is being loaded with the second character of our serial, and it is being compared with 62h instead of 61h:
Next compare
We know that the second digit of our serial is not 62h and now we know what to do- F8 until you get to the JNZ statement, double click the zero flag, and keep going !!! You’ll pass right past the JNZ statement. We are almost there! The last section compares the third digit of our serial with 63h. The third digit of our serial is 31h, so the jump would normally be taken. Go ahead, you know what to do. We will then land on address 401222, one statement past the third jump:
Past the last jump
You’re heart should be pumping, because I think we both know what comes next. There are no more jumps between us and salvation, so either step over the next couple instructions (if you like to draw out the suspense) or just run the app (if you’re like me and can’t stand suspense) and we have reached the pearly gates:
The Pearly Gates

Homework

I know you weren’t expecting this, as this tutorial has already been so exciting, but I am going to end with two things. The first is another
R4ndom’s Essential Truths About Reversing Data:

#3 You will not learn reverse engineering by just reading tutorials. You MUST experiment on your own, and you must do a great deal of it.

and in light of this new rule, I am leaving you with some homework. You mission, should you accept it, is to find out what the serial number is. This means, what is the input that you must enter into the serial box for none of the JNZs to jump? You know you have found it when, after entering the correct serial, you do not have to adjust the app in any way, it will simply show “That Serial is Correct!!!!!!!”
 

Jayalah Indonesiaku © 2010 SouthGrinder Hacker
VB (Vio b374k) Template design by p4r46hcyb3rn3t