|Target:||Ratio Calculator - Performance Trends|
|Tools used:||Visual Basic 3.0 Decompiler (Full version)|
Visual Basic 3.0 Decompiler Addon
|Section:||Visual Basic reversing|
Ok we'll do this one in steps:
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]"
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."
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.
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.
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 ??!!!
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.
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:
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%
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%)
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")
l0142$ = InputBox("Enter the Working Code given by Performance Trends", "Enter Working Code")
gv04BC = Int(Val(l0142$))
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
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
gv04BA% = 1
l0146% = l0144%
gv04E4$ = "Untitled"
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 :)
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 =)
And now watch a little more up:
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:
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
l0064% = -1
If l0060% = Int(l0060% * .5#) * 2 Then
l0066% = 1
l0066% = -1
p005C = p005C + Cos(l0062% * l0060% + .1#) * l0064% * l0066%
p005C = Int(Abs(p005C * 10000))
If p005C > 315733& Then p005C = 315733&
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 :)
public class KeyGenerator extends Applet
public void init()
nameText = new TextField();
nameText.setBounds(29, 12, 192, 24);
nameText.setFont(new Font("Dialog", 1, 12));
codeText = new TextField();
codeText.setBounds(29, 48, 192, 24);
codeText.setFont(new Font("Dialog", 1, 12));
label1 = new Label("Compression Ratio - Performance Trends");
label1.setBounds(22, 84, 205, 12);
label1.setFont(new Font("Dialog", 1, 10));
label2 = new Label("Cracked by Rhytm [Dread]");
label2.setBounds(58, 96, 133, 12);
label2.setFont(new Font("Dialog", 1, 10));
SymText lSymText = new SymText();
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);
if(asciiValue == 2 * (asciiValue / 2))
sign1 = 1;
sign1 = -1;
if(i == 2 * (i / 2))
sign2 = 1;
sign2 = -1;
code += Math.cos((asciiValue * i) + 0.10000000000000001D) * sign1 * sign2;
code = Math.abs(code * 10000D);
if(code > 315733D)
code = 315733D;
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]
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.