How to obfuscate Java code quickly? - java

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?

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.

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.

-injars Decryption.jar (input .jar file that you want to obfuscate)
-outjars DecryptionOut.jar (output .jar file that you get after obfuscate)
-libraryjars '<java.home>\lib\rt.jar'
#-dontwarn javax.crypto.** only if it gives any warnings in import
-dontshrink
-keep class Decryption{ *; }
Try to copy these rules in your myconfig.pro rules and then save it and run the command java -jar proguard.jar #myconfig.pro on cmd
Download proguard.jar from https://sourceforge.net/projects/proguard/

Related

Reverse Engineering of an APK

For my master thesis I'm studying and improving the security of an application. The code is obfuscated and my goal now is to see how easily I can exploit the application. However, I'm having some problems; I think I may have found a piece of code that, when removed, will allow me to override some fundamental step of the application logic. As such, I want to recompile the single class that contains that piece of code and replace the one on the application with this new version. I used dex2jar to obtain a jar with all the classes and have already obtained the .java file with the class I want to alter. My exact problem is how I can recompile the file. I already downloaded the Android API jars and I'm using javac with the classpath pointing to the jar having the remaining classes of the application and to the Android API, but I still can't compile as javac complains about some Android literals being ambiguous. Can you please help? Thanks!

library for Java/Groovy code analysis

I have a project that should analyze Java and Groovy code and build a special script from the source code.
Googling code analysis libraries didn't really result in anything useful for me.
But someone gave me a link to the Spoon project to analyze Java code.
Right now, the only parts that I need from Spoon are to give a set of .java files and it will return me the source code in a big data structure provided by Spoon.
So far the code that I use:
private CtPackage analyzeSourceCode()
{
Launcher spoon = new Launcher();
this.javaFiles.forEach(spoon::addInputResource);
spoon.buildModel();
return spoon.getFactory().Package().getRootPackage();
}
After which, I build up whatever I need from the packages returned.
(Note that I also require the actual executions, not only the data structures and members of the source code.)
But this only works for .java files and not for .groovy files... which brings me back to the point where I need a library to analyze Groovy code.
This one also doesn't allow me to use Java and Groovy together, so I need something else anyway.
Can anyone tell me what I am doing wrong in my google searches or provide me with links to a library that can analyze Java and Groovy code?

Compile-time define in java [duplicate]

When I used to write libraries in C/C++ I got into the habit of having a method to return the compile date/time. This was always a compiled into the library so would differentiate builds of the library. I got this by returning a #define in the code:
C++:
#ifdef _BuildDateTime_
char* SomeClass::getBuildDateTime() {
return _BuildDateTime_;
}
#else
char* SomeClass::getBuildDateTime() {
return "Undefined";
}
#endif
Then on the compile I had a '-D_BuildDateTime_=Date' in the build script.
Is there any way to achieve this or similar in Java without needing to remember to edit any files manually or distributing any seperate files.
One suggestion I got from a co-worker was to get the ant file to create a file on the classpath and to package that into the JAR and have it read by the method.
Something like (assuming the file created was called 'DateTime.dat'):
// I know Exceptions and proper open/closing
// of the file are not done. This is just
// to explain the point!
String getBuildDateTime() {
return new BufferedReader(getClass()
.getResourceAsStream("DateTime.dat")).readLine();
}
To my mind that's a hack and could be circumvented/broken by someone having a similarly named file outside the JAR, but on the classpath.
Anyway, my question is whether there is any way to inject a constant into a class at compile time
EDIT
The reason I consider using an externally generated file in the JAR a hack is because this is) a library and will be embedded in client apps. These client apps may define their own classloaders meaning I can't rely on the standard JVM class loading rules.
My personal preference would be to go with using the date from the JAR file as suggested by serg10.
I would favour the standards based approach. Put your version information (along with other useful publisher stuff such as build number, subversion revision number, author, company details, etc) in the jar's Manifest File.
This is a well documented and understood Java specification. Strong tool support exists for creating manifest files (a core Ant task for example, or the maven jar plugin). These can help with setting some of the attributes automatically - I have maven configured to put the jar's maven version number, Subversion revision and timestamp into the manifest for me at build time.
You can read the contents of the manifest at runtime with standard java api calls - something like:
import java.util.jar.*;
...
JarFile myJar = new JarFile("nameOfJar.jar"); // various constructors available
Manifest manifest = myJar.getManifest();
Map<String,Attributes> manifestContents = manifest.getAttributes();
To me, that feels like a more Java standard approach, so will probably prove more easy for subsequent code maintainers to follow.
I remember seeing something similar in an open source project:
class Version... {
public static String tstamp() {
return "#BUILDTIME#";
}
}
in a template file. With Ant's filtering copy you can give this macro a value:
<copy src="templatefile" dst="Version.java" filtering="true">
<filter token="BUILDTIME" value="${build.tstamp}" />
</copy>
use this to create a Version.java source file in your build process, before the compilation step.
AFAIK there is not a way to do this with javac. This can easily be done with Ant -- I would create a first class object called BuildTimestamp.java and generate that file at compile time via an Ant target.
Here's an Ant type that will be helpful.
Unless you want to run your Java source through a C/C++ Preprocessor (which is a BIG NO-NO), use the jar method. There are other ways to get the correct resources out of a jar to make sure someone didn't put a duplicate resource on the classpath. You could also consider using the Jar manifest for this. My project does exactly what you're trying to do (with build dates, revisions, author, etc) using the manifest.
You'll want to use this:
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");
This will get you ALL of the manifests on the classpath. You can figure out which jar they can from by parsing the URL.
Personally I'd go for a separate properties file in your jar that you'd load at runtime... The classloader has a defined order for searching for files - I can't remember how it works exactly off hand, but I don't think another file with the same name somewhere on the classpath would be likely to cause issues.
But another way you could do it would be to use Ant to copy your .java files into a different directory before compiling them, filtering in String constants as appropriate. You could use something like:
public String getBuildDateTime() {
return "#BUILD_DATE_TIME#";
}
and write a filter in your Ant file to replace that with a build property.
Perhaps a more Java-style way of indicating your library's version would be to add a version number to the JAR's manifest, as described in the manifest documentation.
One suggestion I got from a co-worker
was to get the ant file to create a
file on the classpath and to package
that into the JAR and have it read by
the method. ... To my mind that's a
hack and could be circumvented/broken
by someone having a similarly named
file outside the JAR, but on the
classpath.
I'm not sure that getting Ant to generate a file is a terribly egregious hack, if it's a hack at all. Why not generate a properties file and use java.util.Properties to handle it?

Netbeans Obfuscation

I'm very new to obfuscation and don't have a lot of experience with ant. Come someone provide me a way to obfuscate a regular Java application with ProGuard (or any other open source obfuscator). Currently I'm using NetBeans 6.5.1, and only see the obfuscation ability if I create a JAVA ME, and not a Java Application like I have. I've looked at http://wiki.netbeans.org/DevFaqModuleObfuscation, but don't understand what they're saying.
Thanks for any input.
The FAQ you point to is for obfuscating NetBeans modules. This is quite a complicated use case, so I will assume that it is not the regular application you are interested in.
Very briefly: the obfuscation process changes the names of classes, methods and fields to make it more difficult to reverse engineer your application.
This causes some issues:
the JVM requires your application to have a public static void main( String args[] ) in a public class, so you must tell proguard not to change this name
if you are using any sort of introspection, you have to protect the relevant names from being changed
other cases, as explained in the manual
Additionally, proguard strips out unused code. If you have any classes that are used but not referenced directly, you have to -keep them as well.
The proguard documentation includes an example of how to obfuscate a simple application. Here is the example explained (with some less confusing names):
-injars application.jar # obfuscate all the classes in the named jars
-outjars obfuscated.jar # save all the obfuscated classes to the named jar
-libraryjars <java.home>/lib/rt.jar # these are all the libraries that the application uses
-printmapping obfuscation.map # save a file linking the original names to the obfuscated ones
# this helps understanding stack traces from the obfuscated application
# we need to keep our main class and the application entry point
-keep public class com.mycompany.Application {
public static void main(java.lang.String[]);
}
Unless you specify -dontshrink, proguard will remove any code not kept or not referenced from any kept code. So in the above configuration, any code not referenced (indirectly) by the main method will be removed.
Proguard includes an Ant task that can be used to integrate with the NetBeans workflow. I would suggest experimenting manually first though, without Ant, as that takes one of the complicating factors out of the process. Build your application jar with NetBeans and then try to obfuscate with the above configuration (fleshed out if necessary). Make sure to test the obfuscated application, as innumerable things can go awry. Once you have a working proguard configuration, try adding an Ant task to your build file to automate the obfuscation process within NetBeans.
Another solution than -dontskipnonpubliclibraryclasses is to use the same JDK for running proguard as you used for compiling the code in the JAR file.
For example, instead of
java -jar ../proguard3.8/lib/proguard.jar
use
/usr/local/jdk1.5.0/bin/java -jar ../proguard3.8/lib/proguard.jar
Jacob

Is there any way to define a constant value to Java at compile time

When I used to write libraries in C/C++ I got into the habit of having a method to return the compile date/time. This was always a compiled into the library so would differentiate builds of the library. I got this by returning a #define in the code:
C++:
#ifdef _BuildDateTime_
char* SomeClass::getBuildDateTime() {
return _BuildDateTime_;
}
#else
char* SomeClass::getBuildDateTime() {
return "Undefined";
}
#endif
Then on the compile I had a '-D_BuildDateTime_=Date' in the build script.
Is there any way to achieve this or similar in Java without needing to remember to edit any files manually or distributing any seperate files.
One suggestion I got from a co-worker was to get the ant file to create a file on the classpath and to package that into the JAR and have it read by the method.
Something like (assuming the file created was called 'DateTime.dat'):
// I know Exceptions and proper open/closing
// of the file are not done. This is just
// to explain the point!
String getBuildDateTime() {
return new BufferedReader(getClass()
.getResourceAsStream("DateTime.dat")).readLine();
}
To my mind that's a hack and could be circumvented/broken by someone having a similarly named file outside the JAR, but on the classpath.
Anyway, my question is whether there is any way to inject a constant into a class at compile time
EDIT
The reason I consider using an externally generated file in the JAR a hack is because this is) a library and will be embedded in client apps. These client apps may define their own classloaders meaning I can't rely on the standard JVM class loading rules.
My personal preference would be to go with using the date from the JAR file as suggested by serg10.
I would favour the standards based approach. Put your version information (along with other useful publisher stuff such as build number, subversion revision number, author, company details, etc) in the jar's Manifest File.
This is a well documented and understood Java specification. Strong tool support exists for creating manifest files (a core Ant task for example, or the maven jar plugin). These can help with setting some of the attributes automatically - I have maven configured to put the jar's maven version number, Subversion revision and timestamp into the manifest for me at build time.
You can read the contents of the manifest at runtime with standard java api calls - something like:
import java.util.jar.*;
...
JarFile myJar = new JarFile("nameOfJar.jar"); // various constructors available
Manifest manifest = myJar.getManifest();
Map<String,Attributes> manifestContents = manifest.getAttributes();
To me, that feels like a more Java standard approach, so will probably prove more easy for subsequent code maintainers to follow.
I remember seeing something similar in an open source project:
class Version... {
public static String tstamp() {
return "#BUILDTIME#";
}
}
in a template file. With Ant's filtering copy you can give this macro a value:
<copy src="templatefile" dst="Version.java" filtering="true">
<filter token="BUILDTIME" value="${build.tstamp}" />
</copy>
use this to create a Version.java source file in your build process, before the compilation step.
AFAIK there is not a way to do this with javac. This can easily be done with Ant -- I would create a first class object called BuildTimestamp.java and generate that file at compile time via an Ant target.
Here's an Ant type that will be helpful.
Unless you want to run your Java source through a C/C++ Preprocessor (which is a BIG NO-NO), use the jar method. There are other ways to get the correct resources out of a jar to make sure someone didn't put a duplicate resource on the classpath. You could also consider using the Jar manifest for this. My project does exactly what you're trying to do (with build dates, revisions, author, etc) using the manifest.
You'll want to use this:
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");
This will get you ALL of the manifests on the classpath. You can figure out which jar they can from by parsing the URL.
Personally I'd go for a separate properties file in your jar that you'd load at runtime... The classloader has a defined order for searching for files - I can't remember how it works exactly off hand, but I don't think another file with the same name somewhere on the classpath would be likely to cause issues.
But another way you could do it would be to use Ant to copy your .java files into a different directory before compiling them, filtering in String constants as appropriate. You could use something like:
public String getBuildDateTime() {
return "#BUILD_DATE_TIME#";
}
and write a filter in your Ant file to replace that with a build property.
Perhaps a more Java-style way of indicating your library's version would be to add a version number to the JAR's manifest, as described in the manifest documentation.
One suggestion I got from a co-worker
was to get the ant file to create a
file on the classpath and to package
that into the JAR and have it read by
the method. ... To my mind that's a
hack and could be circumvented/broken
by someone having a similarly named
file outside the JAR, but on the
classpath.
I'm not sure that getting Ant to generate a file is a terribly egregious hack, if it's a hack at all. Why not generate a properties file and use java.util.Properties to handle it?

Categories