Brian Lam


Software Engineer

Crackme Solution 2 - NoREpls

For today’s crackme, we will be attempting this one by dtm of 0x00sec. We will be helping poor little edgyReggie to see how well his software holds up to reverse engineering. The link to this crackme — I mean software can be found here 😉 As I’ve done in my first crackme, I have mirrored the crackme in case the link is broken for any reason. It can be found here. Now then, let’s get started. Similar to the first crackme that I solved, I will be walking you through my thought process.

First off, let’s try to get some hints on what language this software is written in as it will provide us some hints on what functions to look at. We will load this application up in IDA, and see the Imports.

_config.yml

From this, we notice a lot of functions that resemble C functions such as CreateFileW(). And of course, IsDebuggerPresent(). It looks like “edgyReggie” was expecting us to use a debugger. Nice try! :-)

Now then, let’s try running the executable file and try registering our program without a serial number. As expected, we got a prompt indicating an invalid serial number.

_config.yml

This String will come in nifty. It is very likely that this string is stored somewhere in the program. With a little bit of browsing in the Names window (which contains constants), we find these:

_config.yml

These seem to be the Strings used in the prompt that we just saw. Let’s follow them in the disassembler view. Double clicking on aInvalidSerialN and going to the disassembler view will show you it. You will find where this String is being declared like so:

_config.yml

We will x-ref our way up to see what uses aInvalidSerialN. Pressing “X” on it will show you what references this constant.

_config.yml

As you can see, there is only one x-ref. Following it brings us here:

_config.yml

loc_4010DB is what creates the message box with the “Invalid Serial Number”. Perfect! We are about halfway there. Intuitively, you’d imagine the verification of a serial number to be something along the lines of this:

if (isValid) {
// Show MessageBox indicating that the user is registered
} else {
// Show MessageBox indicating the user entered an invalid serial number
}

We’ve already found the latter case. Let’s find the first case. Again, we will x-ref up to see what references loc_4010DB.

_config.yml

Again, there is only one match. Let’s follow it to see what is referring to it:

_config.yml

Oh boy. We’ve almost found the goldmine. :-) But let’s stay focused. Let’s look at this instruction:

.text:004010B3 jz short loc_4010DB

What this instruction indicates is jump to loc_4010DB if the register contains zero. But what register is it referring to? Let’s look back to the instruction prior to it:

.text:004010B1 test al, al

What this instruction does is it tests to see if the register AL is equal to zero. But what is moving a value into AL? Let’s check the instruction before that:

.text:004010AC call sub_401000

This is just a function call. But let’s jump into that function:

_config.yml

We’ve hit gold! The serial number is there. But wait, how does AL equal a non-zero number? I don’t see AL being populated at all.

.text:0040102B mov ecx, offset aNoreplsU89sN34 ; “NOREPLS-U89S-N34J-3IOJ-989Y”
.text:00401030 lea eax, [ebp+String]

The first instruction here pushes the address of the serial number into ECX. The second instruction here loads the address of the serial number into register EAX, and the serial number here is non-zero. EAX, AX, AH, AL are all related. They are accumulator registers. Taking a quick look at the diagram found here, we notice that EAX is a 32-bit register, and AX is a 16-bit register. AL refers to bits 0-7 (inclusive), or the 8 least significant bits. We know that the address of the string is 004109C8 which is 0000 0000 0100 0001 0000 1001 1100 1000 in binary. Taking the 8 least significant bits, we have 1100 1000, which is 200. 200 is greater than 0. So the “jz short loc_4010DB” instruction never jumps into loc_4010DB. It will then move on to the registration successful MessageBox. Now then, let’s try that serial number out and confirm if we have got it.

_config.yml

Hurray! It works. Give yourself a pat on the back and celebrate. 🙂

Written on March 3, 2019
< < Go back