Jump to content
Tuts 4 You

Keygenme 2016 - giv - VB .NET


GIV
Go to solution Solved by saneki,

Recommended Posts

Difficulty : For the algo itself i guess that 1 is more than enough. The catch is to arrive at that code.
Language : VB .NET 2010
Platform : Windows x32/x64
OS Version : XP and above
Packer / Protector : Enigma and one .NET obfuscator (i let you discover - is not hard to see what).

Description :

There are 2 goals.
1. Unpack
2. Write a valid keygen for the target.
In order to have a valid keygen you need to unpack and observe some variables and make small changes.

I assure you this challenge is 100% solvable.

Good luck!

Screenshot :

Keygenme.jpg

Keygenme 2016.rar

  • Like 2
Link to comment
Share on other sites

First of all, there's no easy way to devirtualize Eazfuscator VMed methods. So keygenning this is pretty hard task. But you can guess methods that are executing by breaking on System.Reflection.RuntimeMethodInfo.Invoke. Another way is to decrypt resource in which Eazfuscator store all VM logic. There will be visible names of methods that are executing. But in this way we will not know the order of execution. So the best way is just to use WinDbg and break on invoke.

We need to dump main assembly. Just use MegaDumper to do that.

Assembly will not start if there are no giv.txt and Ionic.Zip.dll in the same folder as keygenme. But you can launch original keygenme without that files because they are virtualized using Enigma Protector container. So let's create those two files.

In dumped assembly you can also find a timer which checks if some forbidden processes are running, such as IDA, LordPE etc. The token of the method is 0x0600001a. It is recommended to "nop" it using CFF Explorer or WinHEX.

Then we place breakpoint on method token 0x0600001b. This method is button1.Click. We also place a breakpoint on System.Reflection.RuntimeMethodInfo.Invoke. We are not going to devirtualize Eazfuscator VM so let's think what method executes firstly after you click an OK button. The first thought that comes to mind - it must be reading text from that Edit1. bBut firstly it again checks that two files (giv.txt and Ionic.Zip.dll). But if on Form.Load it checked just a presence of that files, now it also checks the contents of giv.txt. It must be base64 string of "reversing.ro" (without the quotes). In Ionic.Zip.dll can be anything. It can even not be an assembly.

So just breaking on invoke call can reveal methods that are executing. And the most important part - we can see all values in stack and registers! So finally after long "F5-button-clicking-and-checking-method-info" we break on string compare method. And now we can see correct key for our username.

My valid pair of name and key:

SHADOW
98999697102103

Also I'm attaching dumped assembly and two needed files.

 

 

Dump_.rar

  • Like 13
Link to comment
Share on other sites

Great Shadow.

The algo for key check is super simple.

But the hard part was to get the assembly working.

I think is OK.

Other solutions?

  • Like 1
Link to comment
Share on other sites

Note: This answer isn't entirely mine, I did use SHADOW_UA's dumped .exe.

Short answer: I used a custom build of eazdevirt to devirtualize all protected methods, found the important one and used it to create a keygen.

Longer answer:

I had to change a few things in eazdevirt to get it working with this file. The first thing I noticed was the VM's stream type (used to read the encrypted ManifestResource), which was different to how I'd ever seen it, setting up a byte array in the constructor and XORing against it when reading data.

After lazily adding support for the stream type, I ran into some deserialization issues. eazdevirt checks for serialization version V1 and V2 based on how the stream TypeDef looks. Because of the unexpected stream type, eazdevirt didn't properly detect V2, so I had to manually force that as well.

At this point I had 6/8 methods devirtualized, with the important method being one of the 2 that weren't. Looking at the opcodes, about 85% were recognized (mapped to a delegate method used by the VM). The delegate method that was breaking things looked almost exactly like the delegate method of Ble, so I figured it was Ble_Un. After fixing that, I had 8/8 methods devirtualized.

Checking out the fully-devirtualized assembly in dnSpy, I found this snippet (with a few things renamed):

string text = string.Empty;
int num = this.NameTextBox.Text.Length - 1;
for (int i = 0; i <= num; i++)
    text += (Strings.Asc(Conversions.ToString(i)) ^ 82).ToString();
if (Operators.CompareString(this.AnswerTextBox.Text, text.ToString(), false) == 0)
    this.Goodboy();

After that, it was just creating a simple keygen.

Giv.2016.Keygen.zip

  • Like 5
Link to comment
Share on other sites

8 hours ago, saneki said:

Note: This answer isn't entirely mine, I did use SHADOW_UA's dumped .exe.

Short answer: I used a custom build of eazdevirt to devirtualize all protected methods, found the important one and used it to create a keygen.

Longer answer:

I had to change a few things in eazdevirt to get it working with this file. The first thing I noticed was the VM's stream type (used to read the encrypted ManifestResource), which was different to how I'd ever seen it, setting up a byte array in the constructor and XORing against it when reading data.

After lazily adding support for the stream type, I ran into some deserialization issues. eazdevirt checks for serialization version V1 and V2 based on how the stream TypeDef looks. Because of the unexpected stream type, eazdevirt didn't properly detect V2, so I had to manually force that as well.

At this point I had 6/8 methods devirtualized, with the important method being one of the 2 that weren't. Looking at the opcodes, about 85% were recognized (mapped to a delegate method used by the VM). The delegate method that was breaking things looked almost exactly like the delegate method of Ble, so I figured it was Ble_Un. After fixing that, I had 8/8 methods devirtualized.

Checking out the fully-devirtualized assembly in dnSpy, I found this snippet (with a few things renamed):


string text = string.Empty;
int num = this.NameTextBox.Text.Length - 1;
for (int i = 0; i <= num; i++)
    text += (Strings.Asc(Conversions.ToString(i)) ^ 82).ToString();
if (Operators.CompareString(this.AnswerTextBox.Text, text.ToString(), false) == 0)
    this.Goodboy();

After that, it was just creating a simple keygen.

Giv.2016.Keygen.zip

Your keygen is not 100% correct.

Try to see if your keygen works for username with 1 or 2 characters.

 

In rest.

Very good work.

Bravo!

Link to comment
Share on other sites

  • Solution
2 hours ago, GIV said:

Your keygen is not 100% correct.

Try to see if your keygen works for username with 1 or 2 characters.

In rest.

Very good work.

Bravo!

Now that's just being nitpicky. :P

Attached is the fixed keygen.

Giv.2016.Keygen.zip

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...