Hello and welcome back.
In this next challenge, we are going to take a look at another crackme.
And this crackme is 16 lowercase.
Just unzip it as usual with the unzip password, which is crackinglessons.com.
Inside this folder, you will find three files.
There will also be an additional Python script, which I'll explain later.
So the main crackme now is this one.
And this is a bit challenging because it is protected with a UPX packer.
So this is a packed file.
What it means by being packed: packed means that the whole binary is compressed and
encrypted.
So it only runs when you double-click on it.
It will then unpack itself and then only run.
So it makes it impossible to patch the file itself.
But there is a way to bypass it, which I'll show you in the coming lessons.
And the second challenge with this is that strings are not shown.
When you do a string scan, you won't find any strings at all.
So that's the other challenge.
Even after it has executed in memory and you perform a string scan, the strings are also not shown.
So first thing off is to do a scan with DIE to see what type of binary it is.
It is a 64-bit binary.
And you can see there's a packer here.
It is packed with UPX packer.
Now, normally you would think that you can use the UPX
unpacker
to unpack this.
That's true.
You might be able to do that, but sometimes there are other packers.
Like there are other packers like commercial packers, VMProtect, Enigma, and so on, where
it is not so easy to unpack.
So traditionally, you can unpack this using some software, for example UPX. You can unpack it using
UPX unpacker, and sometimes you can, sometimes it doesn't.
In this case, it might or might not work.
But we are not going to try to unpack it because there's a better way to solve this rather
than to unpack it.
And anyway, in this case, you can see that it's a modified packer.
So probably the person who wrote this crackme wants to make it difficult for you to unpack, but we
are not going to unpack it.
But I will show you the other way how to solve this without unpacking.
So now we know that it is 64-bit and it is packed.
And another way to know this is packed is to look at the entropy.
So you go here, you look at the entropy, and you will see the entropy is more than seven, which is
very high.
So the maximum entropy is eight.
If you see something so high, somewhere around seven, it means that it is packed.
That means it is compressed and encrypted.
So we open a command prompt here and run the crackme and see what it outputs.
It asks for a password.
So if you type any password, hit Enter.
It says "Incorrect. Wrong password."
So normally you search for this string "Incorrect" or this string "Enter password."
So we try to search now and see what happens.
We open the x64dbg.
And now you right-click here and try to search for current module string references.
And you find there are no strings.
Why?
Because it is packed.
That's why you don't see the strings.
Let's close this other one.
Okay, let's close this one.
As you can see, the program has unpacked itself because it managed to show the prompt.
But let's try to search and see if we can find any strings.
Search for current module string
references.
And again, you don't find this string here.
Even after you enter the wrong password, you will get this "Incorrect" string.
But this "Incorrect" string is also not found here.
So this is the challenge of this crackme.
So now I will show you how to solve this.
Now the point is that: why do we want to search a string?
Because the string allows us to set the breakpoint in the correct location.
If we don't know where to set the breakpoint, we will not be able to solve this.
So we want to set the breakpoint in the correct location.
To do that, we need to look at the strings.
Yes, but in this case there are no strings.
So we don't know where to set the breakpoint.
Okay.
How do we solve this?
Let's restart this program and I will show you a trick.
Now, before any program unpacks itself,
it needs to use some Windows API. Two of the common Windows APIs are VirtualAlloc
and VirtualProtect.
This one.
VirtualAlloc and VirtualProtect are generally used by programs which are packed.
They use these two functions, these two APIs, in order to help allocate memory so that it can unpack
itself.
So VirtualAlloc is to allocate memory for unpacking.
And VirtualProtect is to change the protection of memory to make it writable.
Sometimes we don't use VirtualAlloc.
Sometimes you use VirtualProtect.
So sometimes only VirtualProtect is found.
So to know which of these two is being used by the program that is unpacking, you can go to Symbols.
So you click on Symbols, you click on crackme, and look in the Symbol column.
And here you can see it is using this function, this API: LoadLibrary, ExitProcess, GetProcAddress,
and VirtualProtect.
So VirtualProtect is the one which is used here.
It doesn't use VirtualAlloc.
So we can set a breakpoint on VirtualProtect.
There are two ways to set a breakpoint.
The first way is: go down here, put breakpoint.
Type in "bp VirtualProtect" and then hit Enter.
Or you can come here and right-click, Toggle Breakpoint.
Once you have set a breakpoint, you can double-check on it by clicking on the Breakpoints tab.
Here you will see the breakpoint has been set.
So now when we run, we will see that this program will use VirtualProtect.
It will help it to unpack itself.
So over here, let's run and see what happens.
It hits VirtualProtect one time.
It hasn't completed unpacking.
How did we know?
Because there are no outputs here.
Run again.
It hits VirtualProtect a second time.
Again.
No output.
Run again.
It hits the third time. Again,
no output.
Run again.
Hits the fourth time. It's still not done.
Run again.
So it only hits four times.
But when you run, it shows the output.
That means after the fourth time it calls VirtualProtect, the program has completely unpacked itself
into memory.
And it is running.
So this gives us a hint where to—how to trace the location for putting a proper breakpoint.
So let's restart this and let it hit VirtualProtect four times.
So we start it.
Be sure you have a breakpoint on VirtualProtect.
Okay.
It is on.
So let it run until four times: one, two, three, four.
All right.
So now you take a look.
If I were to run again, it will show the output string.
But I don't want to run—I don't want to click Run now because it will not call VirtualProtect again.
It will—
It only calls it four times because we already did see this just now, that it only calls it four
times.
And if you run now, it will show the output string.
So we know that by this time it has fully unpacked itself.
So what we do: we go to the location where VirtualProtect was hit.
So double-click on this, or right-click and Follow in Disassembler.
Follow in -. And you can see here, VirtualProtect.
But this VirtualProtect is inside the KERNEL32.DLL. And KERNEL32,
this is a system DLL.
So we have to go back to user—user module.
The user module is the crackme module.
This one here, crackme.
So how do we go back there?
You can go back there by doing this: Run to User Code.
So just click on Execute.
That means you run to user code.
It will go back to the crackme module.
If you scroll up, you can see that this was where the user module called VirtualProtect.
And now we are here.
That means we just came back from the fourth call to VirtualProtect.
And now we are inside the main itself.
So this is where we can put our breakpoint, this location here, if we wanted to.
So if we were to graph this now, we can look down and see that this is all the main module.
We can zoom out the main module. Okay.
So this is the trick on how you can locate the original entry point for this unpacked code.
This is the original entry point. Okay.
So don't close this program.
We will stop here, but we will continue in the next video.
So leave this program running.
I'll see you then.