About this tutorial:
Tutorial:Keygenning a Java-coded program:SplitMail 1.0

Target:SplitMail 1.0(http://www.bcsupernet.com/users/zewsoft/)

Tools:Java Development Kit 1.3, Java Runtime Environment 1.3, Jad 1.5.7

Date:6 December 2000

Descriptions&Comments:Welcome again to the interesting subject of java cracking. Unfortunately this essay is not (totally)intended to teach useful things to crackers as I believe we will learn nothing from decompilation, still I promise that you will learn at least a few things here which are closely related to Java programming language. Instead, though you may not believe, my real purpose of writing this essay is to show you the ease of cracking/keygenning/breaking in to our target which is vulnerable to decompilation. Imagine a strong warrior standing in the center of the battle ground, with no shields and whatever means of protections, and at the same time surrounded by thousands of enemies, that is what Java is like now. Hopefully, with this essay, both the users(I'm one of them!) and developer of Java programming language know the importance of protection against decompilation and start to either use some obfuscators or improve Java language and its compiler(Sun Microsystems, hear me?) to defend itself from decompilation. Eventually, once Java is protected against decompilation or there are efforts to accomplish that, crackers will get the challenge they have been asking for in cracking Java-code programs...

Protections:Java, name/serial

Disclaimer:This file is used for educational purposes only. Any misuse of the information presented here is not my responsibility.

Copyright information:This tutorial is copyright © ManKind

Starting words:
Hello,welcome to my tutorial. I am ManKind, a newbie in cracking who want to share my cracking skills with other newbies. Contact me at mankind001@bigfoot.com


The process:
(For you to follow this essay, I have to assume that you have all the tools I specified above and they are all well configured. You can refer to my previous 2 tutorials for more information like how to configure them, especially the JDK)
First of all, extract everything from the package of SplitMail which you have downloaded into a folder of your choice. Look at the files and their extensions. "Hell, this is no Java program. There is a .exe file, a .jar file and ...", you complained. First of all, this is a Java-coded program, I am 100% sure of that, and the .exe file is provided for lazy Windows users to easily start SplitMail. You mention the .jar file? Good, because this is where we are going to start working on. Let me give you the definition of .jar file first(taken from Chapter 36-JAR Basics of the Java 1.1 Unleashed book published by Sams):

What Are JAR Files?
In versions of the JDK before version 1.1, if an applet was made up of several different class files or had resources such as GIFs or audio files, you had to download each resource individually. In addition to forcing the user of the applet to wait while the applet's pieces downloaded, this arrangement put an extra load on the HTTP server. To address this problem, Sun introduced JAR files. Based on the widely used ZIP file format developed by PKWare, a JAR file allows multiple resources (Java class files, graphics files, and others) to be bundled into a single, compressed archive file. In addition to making the server's job easier, applets and resources download quicker when they are compressed. A new package, java.util.zip, contains classes to manipulate JAR files (as well as normal ZIP files). You can simply store files in a JAR file, or you can compress them before storing to save space.

JAR files include a manifest file in the archive. This manifest (named META-INF/MANIFEST.MF) gives message digests of the component files in the archive. Additionally, digital signatures of component files can be included in the META-INF directory of the archive. Code signed by a trusted entity can be granted extra privileges (such as writing files). Code signing and related issues are covered in detail in Chapter 37.

This solved all our curiosity, as it says JAR file is used to bundle all the resources needed by a Java program into a single, compressed archive file just like ZIP files. We will have to extract it(just as we do with ZIP files) to get its .class file before we can decompile that and keygen it. To waste no time load up the MS-DOS Prompt(for Windows platform, for others go to your command-line prompt), type the following command(remember that casing is significant issue for Java):

X:\PutInAppropriateDiskDriveAndDirectoryHere>jar xvf SplitMail.jar

jar will report to you how many files have been extracted, their names, their sizes and other informations which are not important to use. You can delete all the other files, we only need SplitMail.class because the keygenneration routine and all other important codes is in there(note that this time I tell you so, the next time when you work on your own, you must investigate first). Now you have to get Jad ready, put the jad.exe in the same directory as the SplitMail.class file. Do the following command at the command-line to decompile the .class file into its original source file(it is wonderful that Java decompilers can work this well):

X:\PutInAppropriateDiskDriveAndDirectoryHere>jad SplitMail.class

If there is no error(there shouldn't be), a .jad file which is about 85 kb will be generated(wow, lots of codes. see how lame a programming language which can be decompiled?). That is the source code of the SplitMail program and if I am a bad guy(which I am not), I would not have continued trying to keygen the program, instead I will go and distribute and abuse the source code. However I will not do that, as I know how important source code is to a programmer especially of a big, commercial program(and I take this special chance to remind all my readers once again, please do not abuse the source code, we are only interested in the protection part and remember to delete everything from your computer once we are done). Try to run(either by running the .exe file or run it according to its documentation) the SplitMail program, wow at very starting of the program a nag has been displayed, close it, go to the Register tab, try to register with fake informations, remember the error message that is displayed after that and exit it. Open the SplitMail.jad file with any text editor. Hmm, we have difficulty finding the part we are interested in in this 85 kb file(which tells us how difficult and time consuming for the programmer to code this, so once again, do not abuse the source code!). Never mind. Search for "The registration number is invald." and you will reach here(my comment is preceeded by <-- ):


JOptionPane joptionpane = new JOptionPane(jpanel);
        int i = JOptionPane.showOptionDialog(component, jpanel, "", -1, 0, null, aobj, aobj[0]);
        if(i == 0)
        {
            RegName = jtextfield.getText(); <-- get Your Name
            RegNum = jtextfield1.getText(); <-- get Registration Code
            if(RegName.trim().length() == 0) <-- check the length of trimmed Your Name
                ErMessage(component, "You did not enter a name..."); <-- bad_boy msg if the length = 0
            else
            if(RegNum.trim().length() == 0) <-- check the length of trimmed Registration Code
                ErMessage(component, "You did not enter a registration code"); <-- bad_boy msg if the length = 0
            else
            if(authenticate(jtextfield.getText(), jtextfield1.getText())) <-- call a verification function/procedure/method
            {
                SvCfg(); <-- start doing this if the above returns true
                Reg = true;
                ErMessage(component, "SplitMail is Registered\nThank you for purchasing SplitMail");
            } else <-- if false, do the following
            {
                ErMessage(component, "The Registration number is invald."); <-- bad_boy msg
            }
        }

The above code is not very interesting as it only passed the Your Name and Registration Code text fields data to another function/procedure/method called authenticate(very suitable name, hehe :D ) which happen to be of boolean type(return value is either true or false) and then reacts according to the returned value. Again, utilise the search function of your text editor and search for the text "authenticate" without quotes and you shall be able to get here:


    public static boolean authenticate(String s, String s1) <-- string s and s1 is the argument/parameter it takes from the above code which happens to be Your Name and Registration Code's text fields' data
    {
        boolean flag = false; <-- initialize the boolean flag to false first
        byte abyte0[] = new byte[14]; <-- declare a new variable of array of bytes type
        String s2 = new String(); <-- declare a new string
        String s3 = new String(""); <-- refer to above
        byte byte1 = 12; <-- initialize the value 12 to byte1
        s2 = s; <-- s2 = s = Your Name
        if(s2.length() > 13) <-- if length of s2 more than 13
            s2 = s2.substring(0, 13); <-- take only 13 bytes starting from position 0
        abyte0 = s.getBytes(); <-- get bytes of s to abyte0
        for(int j = 0; j < s2.length(); j++) <-- loop for as many times as length of name
        {
            byte byte0 = abyte0[j]; <-- get current byte of name to byte0
            byte0 += 12; <-- byte0 = byte0 + 12
            abyte0[j] = byte0; <-- update current position of abyte0 with the value of current byte + 12
            s3 = s3 + Byte.toString(abyte0[j]); <-- build a new string out of the updated value
        }

        int i = 0; <-- initialize i to 0
        if(s3.length() > 10) <-- if the new string's length is more than 10
            s3 = s3.substring(s3.length() - 10, s3.length()); <-- get s3.length() bytes from s3 starting from position s3.length() - 10
        if(s3.length() < 10) <-- if the new string's length is less than 10
            while(s3.length() < 10) <-- loop as long as s3.length() is still less than 10
            {
                s3 = s3 + s3.substring(i, s3.length()); <-- append s3.length() bytes from s3 to new s3 starting from position i
                i++; <-- increment i
            }
        if(s3.trim().equals(RegNum.trim())) <-- if trimmed s3 and RegNum equal
            flag = true; <-- set boolean flag to true
        else <-- if not equal
            flag = false; <-- set boolean flag to false
        return flag; <-- return the boolean flag to where this function/procedure/method is called
    }

So, here's the main keygenneration routine. I have commented the codes according to my understanding and a little investigation(please do not condemn me if there is anything that I have explained wrongly, kindly send me an email and I will correct it). To me, the keygenneration routine looks simple, however, I think I still need to explain a few things. First, don't worry about the Byte keyword, it is just the same as ascii value of a character in the name(at least in this calculation), length keyword and trim are self-explainory, Byte.toString() is similar to Str() in Visual Basic except that it needs a byte for input anf finally the substring keyword. After some examining, I found that to use the substring function/procedure/method, it takes the following structure(pay attention to the words in the brackets):

s3 = s3 + s3.substring(starting_position, length)

What it does is actually extract length characters from a string starting from starting_position. Now let me summarize the whole keygenneration routine:

-trim the name(discard space in between chars of name)
-calculation only based on the first 13 chars of name
-loop for as many times as the length of name and in each loop ascii of current char is added with 12 and the total addition is converted back to its equivalent char before appended to a new string
-if the length of serial is > 10, extract as many characters as length of serial from serial starting from position length of serial - 10 to build a new serial
-if the length of serial is < 10, loop for as long as length of serial is < 10 to extract as many characters as length of serial from serial starting from current position of serial as pointed by i(according to how many times the loop has run)

Well, those are all, simple, isn't it? A keygen can easily be build from scratch according to the keygenneration routine. Below is the source of an example keygen in Java with some codes (willingly be)ripped from the original source code of the program which you can compile and run with the following command(assuming you are using Java Development Kit):

X:\PutInAppropriateDiskDriveAndDirectoryHere>javac KeyGen.java

X:\PutInAppropriateDiskDriveAndDirectoryHere>java KeyGen

// Compile with this command -> javac KeyGen.java
// Run with this command -> java KeyGen
// no comment this time, sorry.

import java.io.*;
public class KeyGen {
  public static void main(String args[]) {
    System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=") ;
    System.out.println("+                                 +") ;
    System.out.println("|  Java KeyGen for SplitMail 1.0  |") ;
    System.out.println("|      by ManKind on 4 Dec 2K     |") ;
    System.out.println("+                                 +") ;
    System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=") ;
    System.out.print("Your Name: ") ;
    String s = new String();    
    char c;    
    try { 
      Reader in = new InputStreamReader(System.in);
      while ((c = (char)in.read()) != '\n') {
        s = s + c;
      }
    }
    catch (Exception e) {      
      System.out.println("Error: " + e.toString()); 
      System.exit(0) ;   
    }
        byte abyte0[] = new byte[14];
        String s2 = new String();
        String s3 = new String("");
        byte byte1 = 12;
        s = s.trim();
        s2 = s;
        if(s2.length() > 0) { 
            if(s2.length() > 13)
                s2 = s2.substring(0, 13);
            abyte0 = s.getBytes();
            for(int j = 0; j < s2.length(); j++)
            {
                byte byte0 = abyte0[j];
                byte0 += 12;
                abyte0[j] = byte0;
                s3 = s3 + Byte.toString(abyte0[j]);
            }
            int i = 0;
            if(s3.length() > 10)
                s3 = s3.substring(s3.length() - 10, s3.length());
            if(s3.length() < 10)
                while(s3.length() < 10) 
                {
                    s3 = s3 + s3.substring(i, s3.length());
                    i++;
                }

            System.out.println("Registration Code: " + s3) ;
            System.exit(0) ;
        }
        else
        {
            System.out.println("You did not enter a name. Please try again.") ;
            System.exit(0) ;
        }
  }
}

I am not good in coding, so if you can optimize the above code, then by all means do it! Oh, by the way, after registering, the registration information is stored in a file named SMail.cfg in the same directory as the executable is in(either .jar or the extracted .class file). We have once again come to the end of a tutorial, I am sorry if you don't find the things you want here as after writing I realized that there is more to be learnt here about Java than cracking but one nice thing in here is that it is fun and interesting cracking this way(at least for me :D). Now you see how easy it is for us to crack/keygen/break in to a program that can be decompiled just because it is coded in a certain language? I am not trying to condemn Java over here, I love it very much and I can never deny that it is a very, very powerful programming language. However as you can see, protection against decompilation is really vital and that (well, partly)made me wrote this essay. If you are a Java user and/or developer or probably will be one in the future, consider applying protection against decompilers either by using obfuscators widely available now or even better yet, urge Sun Microsystems to improve Java and its compiler so that Java-coded programs cannot be decompiled...(FINAL NOTE:DON'T FORGET TO DELETE THE SOURCE CODE AFTER YOU ARE DONE WITH CRACKING IT)

Extra notes:
Recently, I have read a few comments by tutorials' readers concerning the quality of cracking tutorials available. Quite a few of them said that there are some tutorials that are useless as they teach nothing and are just a scratch work by the author and I am greatly disturbed by those statements. I am not sure if my essays fall into that kind of category of useless essays but the truth is that I have tried my best to make every of my essays(at least those of my latest ones) resourceful and not just any essays that teach nothing. So, I will like to call out to all my essays' readers(if there are any, hehe :D ) to send me suggestions, comments, opinions and feedbacks so that I know whether my essay and writing style is acceptable to you(that means, you can understand what I try to present, learn something and not bored by my texts) or do they need some change. I am open to positive remarks, I will like to receive critics and is willing to change and improve if my essays and writing style are really that bad rather than continue writing USELESS essays. Thanks(and hope that I am not one of the authors who write useless essays :D )...

Well, whether or not we crack this program is not important at all here. I just want you to understand the approaches I have taken and the reasons for doing so and to learn from the methods I have shown you. However you must be clever enough to take other approaches and methods(based on your logics) when dealing with other targets. Ability to do so will make you a great cracker as tutorials I believe are not used to teach you how to crack only a specific target, they show you the methods, approaches and logics available while cracking and expect you to apply them on other targets with your own intelligence...


Ending:
Thanks and greetz to:
+ORC, +HCU, Sandman, HarvestR, tKC, ytc_, Punisher, Kwai_Lo, TORN@DO, CrackZ, cLUSTER, LaZaRuS, mISTER fANATIC, yes123, WhizKiD, Volatility, ACiD BuRN, Eternal Bliss, R!SC, Kwazy Webbit, +Mammon, MisterE, Shadow, Falcon, ^tCM^, WaJ, egis, Borna Janes, CyberBlade, Sheep140/Reclaim, josephCo, Kathras, +tsehp, Predator, tscube, AB4DS(Death), douby, Steinowitz, Lord Soth, seifer666, Latigo, Dawai, Lucifer48, NoodleSpa, Mercution, NeuRaL_NoiSE, Fravia+, [dshadow], yAtEs, Duelist, Alpine, hutch, flag eRRatum, Nitrus, LiQUiD8, +Frog's Print, Muad`Dib, Acid_Cool_178, Iczelion, Razzia, wOODY^dRN, Warezpup, Bomber Monkey, XMen, llama and other crackers, individuals and organisations who have helped me, either directly or indirectly.

Service for Mankind
ManKind
mankind001@bigfoot.com