Skip to content

Instantly share code, notes, and snippets.

@extremecoders-re
Created February 23, 2016 18:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save extremecoders-re/a8d90cea12a7e6ff4d12 to your computer and use it in GitHub Desktop.
Save extremecoders-re/a8d90cea12a7e6ff4d12 to your computer and use it in GitHub Desktop.

Solving ResolveMe TWO crackme by deurus

Author: extremecoders
Date: 23-February-2016

The crackme requires microsoft java virtual machine to run and is coded in Visual J++. Now, J++ and Java are very similar with the former being developed by microsoft. Hence we can safely assume, that the crackme was coded in Java.

Preliminary Analysis

Running the crackme, presents us with the screen below.

![Main screen](http://s12.postimg.org/xzinqn2pp/image.png)

Initially the "Register" button is disabled, and the "Enable Me" button is greyed out. We need to select a particular combination of radio buttons and checkboxes, which would enable the "Enable Me" button, clicking which would enable the "Register" button too.

Extracting the class file

Now, I said before that the J++ is very similar to java, hence there must be a class file somewhere. Peering into the resources of the executable leads us to

![Resource](http://s30.postimg.org/si3bv76b5/image.png)

There is a binary resource where we can locate the magic value 0xCAFEBABE, which incidentally is the signature for java class files. Hence the class file is embedded within the executable as a resource. We can now extract the resource from the executable, delete the unneeded part before the signature, and try decompiling it.

Decompiling the class file

Decompiling the resultant class at http://www.javadecompilers.com/ gives us the following code listing

import com.ms.wfc.app.Application;
import com.ms.wfc.app.Timer;
import com.ms.wfc.core.Container;
import com.ms.wfc.core.Event;
import com.ms.wfc.core.EventHandler;
import com.ms.wfc.core.IContainer;
import com.ms.wfc.ui.Button;
import com.ms.wfc.ui.CheckBox;
import com.ms.wfc.ui.Control;
import com.ms.wfc.ui.Edit;
import com.ms.wfc.ui.Font;
import com.ms.wfc.ui.Form;
import com.ms.wfc.ui.GroupBox;
import com.ms.wfc.ui.Label;
import com.ms.wfc.ui.MessageBox;
import com.ms.wfc.ui.Point;
import com.ms.wfc.ui.RadioButton;

public class Form1
extends Form {
    Container components = new Container();
    Edit edit1 = new Edit();
    Button Check = new Button();
    Edit edit2 = new Edit();
    GroupBox gb2 = new GroupBox();
    GroupBox gb1 = new GroupBox();
    Label label1 = new Label();
    Label label2 = new Label();
    Timer timer1 = new Timer((IContainer)this.components);
    Button tranka = new Button();
    RadioButton z = new RadioButton();
    RadioButton y = new RadioButton();
    RadioButton x = new RadioButton();
    RadioButton w = new RadioButton();
    CheckBox w1 = new CheckBox();
    CheckBox x2 = new CheckBox();
    CheckBox y3 = new CheckBox();
    CheckBox z4 = new CheckBox();

    public Form1() {
        this.initForm();
        this.timer1.setEnabled(true);
        this.timer1.start();
    }

    private void initForm() {
        this.setText("ResolveMe TWO - by deurus");
        this.setAutoScaleBaseSize(new Point(5, 13));
        this.setBorderStyle(5);
        this.setClientSize(new Point(331, 256));
        this.setStartPosition(1);
        this.addOnClick(new EventHandler((Object)this, "Form1_click"));
        this.edit1.setLocation(new Point(72, 24));
        this.edit1.setSize(new Point(224, 20));
        this.edit1.setTabIndex(0);
        this.edit1.setText("");
        this.edit1.setMaxLength(35);
        this.Check.setLocation(new Point(72, 72));
        this.Check.setSize(new Point(224, 32));
        this.Check.setTabIndex(2);
        this.Check.setText("Register");
        this.Check.addOnClick(new EventHandler((Object)this, "button1_click"));
        this.edit2.setLocation(new Point(72, 48));
        this.edit2.setSize(new Point(224, 20));
        this.edit2.setTabIndex(1);
        this.edit2.setText("");
        this.gb2.setEnabled(false);
        this.gb2.setLocation(new Point(8, 128));
        this.gb2.setSize(new Point(312, 112));
        this.gb2.setTabIndex(1);
        this.gb2.setTabStop(false);
        this.gb2.setText("Register Me!");
        this.gb1.setLocation(new Point(8, 8));
        this.gb1.setSize(new Point(312, 112));
        this.gb1.setTabIndex(0);
        this.gb1.setTabStop(false);
        this.gb1.setText("Enable Me!");
        this.label1.setEnabled(false);
        this.label1.setFont(new Font("Microsoft Sans Serif", 12.0f));
        this.label1.setLocation(new Point(16, 24));
        this.label1.setSize(new Point(48, 16));
        this.label1.setTabIndex(4);
        this.label1.setTabStop(false);
        this.label1.setText("Name");
        this.label2.setEnabled(false);
        this.label2.setFont(new Font("Microsoft Sans Serif", 12.0f));
        this.label2.setLocation(new Point(16, 48));
        this.label2.setSize(new Point(48, 16));
        this.label2.setTabIndex(3);
        this.label2.setTabStop(false);
        this.label2.setText("Pass");
        this.timer1.setInterval(300);
        this.timer1.setEnabled(true);
        this.timer1.addOnTimer(new EventHandler((Object)this, "timer1_timer"));
        this.tranka.setEnabled(false);
        this.tranka.setLocation(new Point(112, 64));
        this.tranka.setSize(new Point(88, 32));
        this.tranka.setTabIndex(0);
        this.tranka.setText("Enable Me");
        this.tranka.addOnClick(new EventHandler((Object)this, "tranka_click"));
        this.z.setLocation(new Point(112, 16));
        this.z.setSize(new Point(16, 24));
        this.z.setTabIndex(4);
        this.z.setText("");
        this.y.setLocation(new Point(136, 16));
        this.y.setSize(new Point(16, 24));
        this.y.setTabIndex(3);
        this.y.setText("");
        this.x.setLocation(new Point(160, 16));
        this.x.setSize(new Point(16, 24));
        this.x.setTabIndex(2);
        this.x.setText("");
        this.w.setLocation(new Point(184, 16));
        this.w.setSize(new Point(16, 24));
        this.w.setTabIndex(1);
        this.w.setText("");
        this.w1.setLocation(new Point(112, 40));
        this.w1.setSize(new Point(16, 16));
        this.w1.setTabIndex(8);
        this.w1.setText("");
        this.x2.setLocation(new Point(136, 40));
        this.x2.setSize(new Point(16, 16));
        this.x2.setTabIndex(7);
        this.x2.setText("");
        this.y3.setLocation(new Point(160, 40));
        this.y3.setSize(new Point(16, 16));
        this.y3.setTabIndex(6);
        this.y3.setText("");
        this.z4.setLocation(new Point(184, 40));
        this.z4.setSize(new Point(16, 16));
        this.z4.setTabIndex(5);
        this.z4.setText("");
        this.setNewControls(new Control[]{this.gb2, this.gb1});
        this.gb2.setNewControls(new Control[]{this.label2, this.label1, this.edit2, this.edit1, this.Check});
        this.gb1.setNewControls(new Control[]{this.z4, this.y3, this.x2, this.w1, this.w, this.x, this.y, this.z, this.tranka});
    }

    public static void main(String[] arrstring) {
        Application.run((Form)new Form1());
    }

    private void button1_click(Object object, Event event) {
        int n = 0;
        int n2 = 0;
        int n3 = 0;
        String string = System.getProperty("user.name");
        String string2 = this.edit1.getText();
        n3 = string2.length();
        if (n3 == 0) {
            MessageBox.show((String)"Enter Name", (String)"Advice");
            return;
        }
        int n4 = 0;
        while (n4 < n3) {
            n2 += string2.charAt(n);
            ++n4;
        }
        n3 = n3 * n2 + 54385 + 13 + 3039;
        String string3 = String.valueOf(n3);
        int n5 = n3 % 9 * n3 / 9;
        string3 = string3 + "-" + string + "-" + String.valueOf(n5);
        String string4 = this.edit2.getText();
        if (string4.equals(string3)) {
            MessageBox.show((String)"Now make a keygen and send the tuto to crackmes.de", (String)"Good Job!");
            return;
        }
        MessageBox.show((String)"Try again", (String)"Error");
    }

    public void dispose() {
        super.dispose();
        this.components.dispose();
    }

    private void Form1_click(Object object, Event event) {
    }

    private void timer1_timer(Object object, Event event) {
        if (this.w1.getChecked() & this.y3.getChecked() & this.y.getChecked() & !this.x2.getChecked() & !this.z4.getChecked()) {
            this.tranka.setEnabled(true);
            this.gb1.setText("Enable Me! - Good Job :-)");
            return;
        }
        this.tranka.setEnabled(false);
        this.gb1.setText("Enable Me!");
    }

    private void tranka_click(Object object, Event event) {
        this.gb2.setEnabled(true);
    }
}

Enabling the button

Analyzing the function timer1_timer we can see that the button "Enable Me" is enabled only when checkboxes w1 , y3 & radiobutton y are checked. As there is no logical relation between the names of the controls and their respective positions in the form, we must use their position of creation (in the function initForm) to identify the names.

The radio buttons have names of Z, Y, X and W. The checkboxes have names of W1, X2, Y3, Z4 from left to right.

To proceed Y, W1, and Y3 must be checked as per the following images.

![layout](http://s30.postimg.org/9xaiadvhp/layout.png)
![enter image description here](http://s23.postimg.org/iccgjnip7/enabled.png)

Keygenning and Solving

Developing a keygen is even simpler. We can directly rip out the code from the function button1_click. This is possible since the crackme itself generates valid keys and checks if our entered key matches its generated one. For a change, I have developed the keygen in python. Here is the code:

import getpass
userName = getpass.getuser() # Get the current user name
name = raw_input('Enter your name: ')

sumOfChars = ord(name[0]) * len(name) # BUG, BUG!!!
calc = len(name) * sumOfChars + 54385 + 13 + 3039
serial = ''
serial += str(calc) + '-' + userName + '-' + str(calc % 9 * calc / 9)

print '------------------------------------'
print 'Name:', name
print 'Pass:', serial
print '------------------------------------'

Possible Bug ?

In the decompiled code, we can see the following loop

int n4 = 0;
while (n4 < n3) 
{
    n2 += string2.charAt(n);
    ++n4;
}

The above snippet calculates the product of the first character and the length of the name. I believe that the crackme author made a mistake and instead may have wanted to calculate the sum of all characters in the name and should be like below.

int n4 = 0;
while (n4 < n3) 
{
    n2 += string2.charAt(n4);
    ++n4;
}

Regardless, the developed keygen works as per the algorithm. Note that the variable sumOfChars is not actually the sum of the characters as explained above.

![enter image description here](http://s29.postimg.org/ond98lqlz/final.png)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment