Question

How to obfuscate code quickly. I have a very small Java App and I want to deliver the obfuscated code to my client. I have heard a lot about ProGuard to obfuscate code and have downloaded it but doesn't know how to obfuscate my "abc.jar" file.

I checked out its website but it contains a lot of material to read. I don't need heavy obfuscation. I just need a obfuscate that simply changes the name of variables, methods and classes to some unreadable ones. I know ProGuard provide all of this with a ton of other functionalities too.

Q1. So could anyone tell me please some simple obfuscators or some simple steps to use proguard so that I can just input "abc.jar" and it outputs "obfuscate_abc.jar" or something simple like that.

Q2. One more thing, as my Java program uses external libraries, so should I need to obfuscate those libraries too?

Q3. Is there any Eclipse or NetBeans plugin availabe to this obfuscation?

I have also heard that we should retain the mapping table file with us so that in future we can debug or edit that obfuscated code by first de-obfuscating with the help of that mapping-table which was created at the time of obfuscation.

Q4. So, one more question is Why do we need to keep that mapping-table with us? We can simply retain a copy of un-obfuscated application so as to make changes in that (if required in future). Is there any reason to retain that mapping-table file with us?

Was it helpful?

Solution

Q1. So could anyone tell me please some simple obfuscators or some simple steps to use proguard so that I can just input "abc.jar" and it outputs "obfuscate_abc.jar" or something simple like that.

Just go for ProGuard, it's definitely a good tool (recommended in many answers here on SO like this one, this one and this one).

Q2. One more thing, as my java program uses external libraries, so should i need to obfuscate those libraries too?

No need IMHO (not even mentioning that you may not).

Q3. Is there any eclipse or netbeans plugin availabe to this obfuscation?

I'd rather suggest to use the Ant Task or the proguard-maven-plugin. See this question about the maven plugin if required.

Q4. So, one more question is Why do we need to keep that mapping-table with us. We can simply retain a copy of un-obfuscated application so as to make changes in that (if required in future). Is there any reason to retain that mapping-table file with us?

Yes, to "translate" stacktrace.

OTHER TIPS

I tried this from scratch. It should get you started. I think the key will be to understand the "keep options" in the configuration file.

Using this code:

import java.util.*;

public class Example {

    public static void main(String... args) {
        Example ex = new Example();
        ex.go();
    }

    public void go() {
        String[] strings = { "abc", "def", "ijk" };
        for (String s : strings) {
            System.out.println(s);
        }
    }

}

I created an Example.jar. I copied the proguard.jar from the ProGuard lib directory, and ran this command-line

java -jar proguard.jar @myconfig.pro

where myconfig.pro contains:

-injars Example.jar
-outjars ExampleOut.jar
-libraryjars <java.home>/lib/rt.jar

-keep public class Example {
    public static void main(java.lang.String[]);
}

This produces ExampleOut.jar which contains the same functionality and is obfuscated (verified with JAD). Note that I did not use a manifest, so to test functionality, I unjarred and tested the class. Execution entry-points within jars are left to the reader.

There are many more keep options listed in the Usage section.

You only need to obfuscate the other libraries in the case where you need to protect them against whatever you think obfuscation is doing for your code. However you should read the licences for those other libraries to see whether they restrict you from distributing modified versions.

regarding Q4: The mapping is used when users send you bug reports that contain exception stacktraces from the obfuscated code. ProGuard allows you to translate these stacktraces back to the original class names and line numbers if you have the mapping.

Just answering Q4…

There is a good reason to keep the mapping. If the client ever sends you a stacktrace, it can be very useful to know where in the code that stacktrace came from. The purpose of an obfuscator is to get rid of that information ;-) By keeping the mapping, you enable the conversion of the stacktrace into where the problem occurred in the original code.

I can answer question 4. You should retain it for debugging. Say you have a bug in function "printTheAlphabet()" on line 23, after obfuscating the stack trace might say something like "Error in j6z9r() on line 27" which makes it pretty impossible to locate the error in your source code.

How to obfuscate code quickly & dirty:

Try it: http://www.daftlogic.com/projects-online-javascript-obfuscator.htm or it: http://javascriptobfuscator.com/default.aspx or Google "javascript obfuscator online".

I know it is for Javascript, but you can get the function result using a Javascript eval for Java (have a look at: https://stackoverflow.com/a/2605051/450148)

It is not the best aprouch, but it can be useful if you are really in a hurry and you are not a paranoic about security.

EDIT: The next piece of code uses the simple ROT13 to not expose directly your password. The good thing is the "hacker" do not know which algorithm you are using (you can replace ROT13 for which algorithm you like), but it is still very easy to break it down:

static String password;

static {
    password = a("NXVNWQX5CHXRWTKGDMHD");
}

private static String a(String b) {
    String c = "eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c])}}return p}('k a(b){2 5=\\'\\';o(2 i=0;i<b.e;i++){2 c=b.g(i);2 1=b.f(i);4(c>=\\'a\\'&&c<=\\'m\\')1+=3;6 4(c>=\\'n\\'&&c<=\\'9\\')1-=3;6 4(c>=\\'7\\'&&c<=\\'h\\')1+=3;6 4(c>=\\'7\\'&&c<=\\'p\\')1-=3;2 d=8.l(1);5+=d}j 5}',26,26,'|charcode|var|13|if|sb|else|A|String|z|||||length|charCodeAt|charAt|M||return|function|fromCharCode|||for|Z'.split('|'),0,{}));";

    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("js");
    Object z = "";

    //noinspection EmptyCatchBlock
    try {
        z = engine.eval(c + " a('" + b + "');");
    } catch (ScriptException e) {}

    return z.toString();
}

I have had a quick look at yGuard before and liked the fact that you could integrate the obfuscation steps into an Ant script. This allows you to use it very easily in Eclipse etc if you want.

The documentation it comes with provide a number of ready made Ant scripts to get you started. These just need to be modified to work with your projects layout, ie setting the correct package names etc.

If your not clear on how to get Ant going in Eclipse, you pretty much just need to add a build.xml file to the project, copy the example script that comes with yGuard into it, modify the script to work with your project and run the yGuard task from the Ant view.

With regards to your mapping table question. The only reason I can think you might need something like this would be if you can't replicate a bug your obfuscated jar exhibits, from your original code. At this point you might need to work with the obfuscated version, maybe to determine if the obfuscation has caused a problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top