Target: | Ratio Calculator - Performance Trends |
Difficulty: | Easy/Medium |
Tools used: | Visual Basic 3.0 Decompiler (Full version) Visual Basic 3.0 Decompiler Addon SoftICE 3.2x Visual Basic |
Date: | 12-02-'99 |
Section: | Visual Basic reversing |
Ok we'll do this one in steps:
Step1
Fire up the program, it tells you to enter an name longer then 8 chars and gives you a code when you entered it. Write them down. Mines was "Rhytm [Dread]"
Step2
The Program wants to know if you've got a code for the program. Choose Yes and enter a lame code. Mines was "444555666". You get the message "This working code does not match the required pattern. Try again the next time you start the program."
Step3
Start over again enter your code. Start SoftICE and do a "bpx hmemcpy" return to the program and press the ok-button. You're back in SoftICE now.
Step4
If you haven't read Razzia's essay on VB programs close this file and start reading the essay first. Use the same technics on this program.
Start tracing through the code. Do a bpx on the places where the code gets stored. After a hour or so you'll get lost in the runtime library.
Step5
Well why don't we search for the pre-made comparestring by Razzia.
First start over again do a bpx hmemcpy press F11 and keep stepping through the code (F10) till you're in the VB Runtime.
Do a s 0 l ffff 8B,CA,F3,A6,74,01,9f,92,8D,5E,08,E8,0E,06 (Don't you know what this mean ??? Then I'll have to refer to Step4 again :)
You'll get one hit (There's only one place in the runtime where strings get compared). Put a bpx on the memoryaddress you found and press F5,
"This working code does not match the required pattern. Try again the next time you start the program."
Damned !!! Why doesn't it work ??!!!
Step6
Lets start all over again with new coffee and new toolz, this time we'll use the VB 3.0 Decompiler.
Start your Decompiler (Dodi's is the best) and decompile the cr.exe
You'll get 3 modules and some other VB-Files.
Step7
Open the bas-files and search for the text "This working code does not match the required pattern. Try again the next time you start the program." or if you're lazy "working code" will do the job too.
You'll find this:
-----------------------Start Code-----------------------
gv04CC$ = l011E$ + "this feature" + l0120$
gv04D0$ = l011E$ + "many features" + l0120$
If l0126% = 0 Then
l0128% = FreeFile
Open App.Path + "\CRCNFG.PTI" For Input As l0128%
Line Input #l0128%, gv047C$
Input #l0128%, gv0490
If Not EOF(l0128%) Then Input #l0128%, gv04BC
If Not EOF(l0128%) Then Input #l0128%, gv04D4%
Close #l0128%
Call sub00D0(gv047C$)
If gv047C$ <> "SIMONSONVI" Then
l0128% = FreeFile
Open App.Path + "\CRTEXT\OUTHELP.TXT" For Input As l0128%
For l0134% = 0 To 14
If Not EOF(l0128%) Then
Line Input #l0128%, gv04A4$(l0134%)
End If
Next l0134%
Close #l0128%
Call sub008A(l013C)
If Abs(gv04BC - l013C) > 3 Then
gv04BA% = 0
Select Case MsgBox(gv04D0$ + Chr$(13) + Chr$(13) + "Do you have a Working Code given to you by Performance Trends?", 4 Or 32 Or 256, "Demo Version")
Case 6
l0142$ = InputBox("Enter the Working Code given by Performance Trends", "Enter Working Code")
gv04BC = Int(Val(l0142$))
Call sub008A(l013C)
If Abs(gv04BC - l013C) > 3 Then
MsgBox "This working code does not match the required pattern. Try again the next time you start the program."
gv04BC = 0
gv04BA% = 0
Else
MsgBox "This Working Code will be saved to disk and will enable you to use all features in this program." + Chr$(13) + Chr$(13) + "Be sure to write down this Working Code and your Registered Name and Registered Code # (displayed in the 'About' screen available from the Main Menu) and keep them in a safe place. Should you need to reinstall this program, these 3 pieces of information will activate all features in this program."
gv04BA% = 1
End If
Case 7
End Select
Else
gv04BA% = 1
End If
End If
l0146% = l0144%
gv04E4$ = "Untitled"
End If
------------------------End Code------------------------
Step8
Wel that's a lot of code take a good look :)
Do you see the name SIMONSONVI ??
If the name you entered isn't SIMONSONVI it'll keep running else it'll do nothing. So the name SIMONSONVI is probably used by programmers to test their algoRhytm. Well if they're so lazy to do this then reversing this program can't be that hard :)
Step9
Do you see this line ??
"If Abs(gv04BC - l013C) > 3 Then"
So if the difference between the badguy and the goodguy after getting rid of the "-" is larger then 3 then you've fucked up =)
Step10
And now watch a little more up:
"Call sub008A(l013C)"
This babe'll probably calculate the goodcode.
Start searching through your VB files again and you'll find sub008A in Module1.
Here's the code:
-----------------------Start Code-----------------------
Sub sub008A (p005C As Variant)
Dim l0060 As Integer
Dim l0062 As Integer
Dim l0064 As Integer
Dim l0066 As Integer
p005C = 0
For l0060% = 1 To Len(gv047C$)
l0062% = Asc(Mid$(gv047C$, l0060%, 1))
If l0062% = Int(l0062% * .5#) * 2 Then
l0064% = 1
Else
l0064% = -1
End If
If l0060% = Int(l0060% * .5#) * 2 Then
l0066% = 1
Else
l0066% = -1
End If
p005C = p005C + Cos(l0062% * l0060% + .1#) * l0064% * l0066%
Next l0060%
p005C = Int(Abs(p005C * 10000))
If p005C > 315733& Then p005C = 315733&
End Sub
------------------------End Code------------------------
Step11
Tadaaaaa !!!
So for every character: Take the ascii-value. Take the Position of the character. It checks if the ascii-value is odd or e and if the position is odd or e. This way the two flags get set (1 or -1).
And the returnvalue is the old returnvalue and the cosinus(ascii-value * position) * flag1 * flag2.
This'll loop for every character.
When finished it multiplies the returnvalue with 10000 and removes the "-" if necesary.
And if the value is larger then 315733 then it is 315733
ok, well lets make a keygen for ths one,
here's the source written in Java :)
-----------------------Start Code-----------------------
import java.applet.Applet;
import java.awt.*;
import java.awt.event.TextEvent;
public class KeyGenerator extends Applet
{
public void init()
{
setLayout(null);
setSize(250, 120);
setBackground(new Color(0x586c88));
nameText = new TextField();
nameText.setBounds(29, 12, 192, 24);
nameText.setFont(new Font("Dialog", 1, 12));
nameText.setBackground(new Color(0xffffff));
add(nameText);
codeText = new TextField();
codeText.setEditable(false);
codeText.setBounds(29, 48, 192, 24);
codeText.setFont(new Font("Dialog", 1, 12));
codeText.setBackground(new Color(0xffffff));
add(codeText);
label1 = new Label("Compression Ratio - Performance Trends");
label1.setBounds(22, 84, 205, 12);
label1.setFont(new Font("Dialog", 1, 10));
add(label1);
label2 = new Label("Cracked by Rhytm [Dread]");
label2.setBounds(58, 96, 133, 12);
label2.setFont(new Font("Dialog", 1, 10));
add(label2);
SymText lSymText = new SymText();
nameText.addTextListener(lSymText);
}
void nameText_TextValueChanged(TextEvent event)
{
String name = nameText.getText();
double code = 0.0D;
if(name.length() > 7)
{
for(int i = 1; i < name.length() + 1; i++)
{
int asciiValue = name.charAt(i - 1);
int sign1;
if(asciiValue == 2 * (asciiValue / 2))
sign1 = 1;
else
sign1 = -1;
int sign2;
if(i == 2 * (i / 2))
sign2 = 1;
else
sign2 = -1;
code += Math.cos((asciiValue * i) + 0.10000000000000001D) * sign1 * sign2;
}
code = Math.abs(code * 10000D);
if(code > 315733D)
code = 315733D;
codeText.setText(String.valueOf((int)code));
}
}
public KeyGenerator()
{
}
TextField nameText;
TextField codeText;
Label label1;
Label label2;
}
------------------------End Code------------------------
Ok fire up the program enter the yes button enter your name
Enter your calculated code and it's registered.
For the lazy people:
Name: Rhytm [Dread]
Code: 8973
Conclusion
So what was different in this program.
We now know why the breakpoint on the comparestring was useless.
The strings don't get compared.
The program checks if the difference between the codes is larger then 3 :)
Well that was all folks, sorry for my bad English.
And sorry for the messy way of writing this tutor.
I'll write a better one later.
Questions, Comments and Money can be send to:
Rhytm@Newmail.net or ICQ me at 16549991
DREAD is NOT responsible for any abuse of the information we provide. Members of DREAD don't crack to get programs registered. As a matter of fact, we don't crack at all, since we are reverse engineers. Our only objective is to further our knowledge. If you want to use a program you reversed, you have to buy it!
This essay is © copyright 1999 by Rhytm.