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.
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.
Let’s run the app, as knowing how it works is vitally important:
Click on register and the following dialog appears:
I entered a serial:
Then, after clicking the Enter Serial I get the following very bad message:
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”:
And Olly will search the program’s memory space and display the Text String Window:
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:
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:
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:
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:
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:
Now, let’s set a breakpoint at address 401201 (or somewhere near here as it’s before our jump instructions):
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:
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:
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:
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:
*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:
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:
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:
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:
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:
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:
and now notice that the arrow is grey (and that Olly says the 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:
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:
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:
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!!!!!!!”
-till next time
-R4ndom
ps. If you need a hint you may click on this link .
pps. If you need additional hints, email me or leave a comment.
June 8th, 2012 on 4:12 am
I can’t find the link to download Fake.exe. Maybe I missed the link is it up?
June 8th, 2012 on 3:27 pm
Sorry, You happened to catch me between uploading the tutorial and uploading the support files. They are all up there now.
June 9th, 2012 on 3:51 pm
Great Tut, Keep it coming bro
June 10th, 2012 on 3:34 am
nice keep them coming
June 10th, 2012 on 4:40 am
I’m trying, man, I’m trying.
June 12th, 2012 on 7:17 am
Love how quick these are coming out. I’m used to gdb/Linux so it’s nice to learn a new tool. I also lol’d at you calling me out.
June 13th, 2012 on 9:38 pm
really well written, i like your tuts because they are really easy explained and straightforward. i love the simplicity.
please keep it up man!
June 21st, 2012 on 6:41 pm
I’ve always prefered Little Endian.
Just makes more sense.
Eg. take the number 10 (0x0000000A)
Say it’s stored at address 00404020, in Big Endian it’d look like
00404020: 0000000A
While in Little Endian, you’d have
00404020: 0A000000
So the first byte will actually contain something rather than 3 zero bytes, so if you know the number is currently less than 255 you could just read byte at 00404020, whereas in Big Endian you’d have to read a byte at 00404020+3.
I hope that made sense.
June 21st, 2012 on 7:57 pm
That is precisely true, and wonderful if you’re dealing with 32-bit numbers that are below 255. The trouble begins when you get above 255, say
0×12345678…
I mean this looks weird to me:
00404020: 78563412
as opposed to this:
00404020: 12345678
but it’s just my 2 cents worth
June 22nd, 2012 on 8:33 am
Well, I guess that’s just a matter of getting used to it.
Just like getting used to pushing stuff onto the stack in reversed order.
July 30th, 2012 on 2:45 pm
The homework is so easy xD
The tutorial is well explained, thank u
September 2nd, 2012 on 1:23 pm
First of all I would like to thank you for this great tutorial.
Second, I have somethings that has been bothering me lately and I just cannot get the idea of why it’s happening, but it’s not the first time:
When I loaded the program from ollydbg downloaded from their website (version 1.10, plugins are: cmdbar, bookmark, nonawrite, hidedebugger and analyze this) I get this window:
http://i48.tinypic.com/10p1x14.png
However, when I load it with your ollydbg I get the same screen as you do, why is this? I just want to know how things work instead of loading the executable on all available olly’s and praying to be lucky..
As I said not the first time happening, the first program (FirstProgram.exe) didn’t run propely in your ollydbg but worked in 1.10 ollydbg.
Thanks in advanced, please keep it up.. Maybe you should do some about gamehacking (getting structs/classes out of a game, getting a function pointer etc for MMORPG games such as Diablo) :p.
Please forgive me if my English is bad.
September 3rd, 2012 on 4:30 pm
If I understand you correctly, you are asking why the default Olly looks different from my version…This is because I have gone in and customized all of the graphics in the gui to look different. I also have additional plugins that you don’t, and my .ini file has different settings than the default Olly.
If that wasn’t your question, please fell free to ask again. You may want to ask in the forums though, as those get answered much faster than comments on the blog…
September 3rd, 2012 on 5:29 pm
Nope. I am aware of that, what I meant is my default olly breaks in different EP, and when I run the program (F9) it gets terminated and never runs. I think it’s because of the error in the bottom “Debugged program was unable to process exception”, But I have no idea as I am a beginner.
I will try the forums thing one day, thanks!
September 3rd, 2012 on 8:01 pm
Ahhhh. You need to set your exception settings like mine. Go to debugging options in Olly and select the excpetions tab, then set the following:
Check all boxes
At the bottom, select “Add range” and enter 00000000-ffffffff in the edit box that opens. This should display in the custom exception range box at the bottom/.
Now, all exceptions will be automatically passed to the target and you should be fine.
If for some reason all of these boxes ARE ALREADY checked, un-check them all and then re-start the target.
September 4th, 2012 on 9:17 am
That did not work, I played with options and figured it would. I even copied your ollydbg.ini to my olly still didn’t help, decided to just use yours. Can you explain to me or link me a tutorial regarding exceptions? I am really interested I know C++ and they are there (try, catch) but I have no idea what role do they play in reversing and how they have the ability to “break” debuggers.
Thanks!
September 4th, 2012 on 3:26 pm
I am working on a tut about exceptions, but it will still be a cpl weeks before it comes out. In the mean time, check out Lena’s tuts. She talks about them. do a search for “Index to Lena’s tutorials”
September 4th, 2012 on 4:14 pm
Alright will do once I am done with your tuts, it can wait.
Thanks!
September 3rd, 2012 on 5:33 pm
I am sorry I can not edit my previous post, thought those information would help:
When I press F9 nothing happens for like 15-25 seconds, after that I see the status of the program “Terminated” and the error in the bottom becomes “Process terminated, exit code 4000001E (1073741854.)
November 8th, 2012 on 7:16 am
I solved the first piece of homework and I couldn’t be happier. Thanks a bunch.
December 8th, 2012 on 11:22 am
Woooha!!! done.
December 8th, 2012 on 11:22 am
Woohaaa! done
December 18th, 2012 on 3:29 pm
thank you very much great tutorial but you can begin t find the correct password instead of patching
December 18th, 2012 on 3:31 pm
thank you very much great tutorial but how can we find the t correct password instead of patching
December 21st, 2012 on 12:14 am
did you figure it out? =)
December 21st, 2012 on 12:00 am
man.. this is SO excellent! ty for taking the time to offer all this!
February 21st, 2013 on 1:43 pm
thnx for t tut. homework was so easy thnx for ur great explanation. I was not fond of Assembly language before. but after your tutorial . got eager to read more.
March 13th, 2013 on 10:25 pm
Sorry if you have already answered this, but with Modnar’s problem, I was getting the same thing and thought I was loading the wrong executable. After a couple tutorials, I realized Olly was stopping early, but if I hit F9 again, it would lead me to your starting place. Also, I’m on Windows7 64 bit. Hope that helps.
BTW, these are amazing. I started with #1 yesterday and will be going through the complete series, as well as look at what else you have.
Thanks a Brazillian!!
April 26th, 2013 on 5:00 pm
Thank you for the tutorial! I almost felt like a superhero when I guessed the password on my own!
April 27th, 2013 on 9:39 pm
many thanks for your excellent tutorials and all the hard work you’ve put into them!
May 7th, 2013 on 5:29 am
Hello, great tutorials! I would like to ask why my Ollydbg doesn’t show the yellow and blue colors on Calls and Jumps? I’m also really interested in the answer of the homework.
May 7th, 2013 on 10:59 am
I unfortunately also couldn’t understand this:
[quote]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[/quote]
May 21st, 2013 on 7:17 pm
HOW CAN I MAKE THIS READ arrow ? IT DOESN’T APPEARS TO MY OLLYDBG ? THANKS IN ADVANCE
June 7th, 2013 on 2:55 pm
please , i dont’find the code ! help me !
June 7th, 2013 on 6:01 pm
FOUND !!! but is it possible to save the changes in the exe ??now the exe “jump the jumps” and we can have the access without the code after modifing the flag and so on….how can i save this to the exe ?
June 27th, 2013 on 1:19 am
Again thank you for the tutorial. I like the little homework section that has us expand on what we’ve learned in this tutorial as well as previous ones. A great example to start off for those of us who are new to this.
July 6th, 2013 on 6:47 pm
Just for the record I find all of your tutorials hilarious and well done. If you wrote a book I’d buy it in a heartbeat (unless it doesn’t have sarcasm and smiley faces then I’ll have none of it!).
August 19th, 2013 on 9:24 am
Thank you for a very well written tutorial.
Moving from a different debugger and into Olly was very challenging but you SIR made the transition enjoyable.
Thank you,
Kon
September 11th, 2013 on 10:55 am
It’s an inspiring work. I’m a man from least background of computer science and assembly language. Even though your demonstrations are really working because of it’s clarity. That’s because you’ve an overall vision to guide beginners in the world of reverse engineering. Hey one personal request: where can I get get your ollydbg.exe that shows red arrows for jumps. I desperately need it. I feel it as the most convenient way to visualize jumps. olly, the one I’m working with is from your zipped archive downloaded from tutorial 3 package. Help me..