Obfuscating NetBeans Platform Modules

DZone 's Guide to

Obfuscating NetBeans Platform Modules

· Java Zone ·
Free Resource

Keeping in mind the amount of time and effort involved in the process of software development, we often make use of one or more methods to help protect our intellectual property against reverse engineering. This article focuses on the practice of refactoring code to contain non-specific and seemingly random names, which we refer to as obfuscation. When to obfuscate and how useful obfuscation really is are topics well beyond the scope of this article. Instead, we shall focus on how to get started with obfuscation and NetBeans using the ProGuard library.

In this article we show how to create an obfuscated ZIP distribution of a NetBeans platform application by obfuscating all modules in the application. We created our example with NetBeans 6.9 Milestone 1, so, where applicable, we’ll indicate how to implement a specific step of the process with an earlier version of NetBeans.

Getting and Installing ProGuard

The ProGuard library is free and may be downloaded from the project’s SourceForge page. It is only a few megabytes in size.

ProGuard provides an ant target which provides access to the obfuscation process. To be able to load this target, the file proguard.jar (from the lib folder of the downloaded archive), needs to be in a location where ant will be able to find it. One convenient location would be /java/ant/lib (or /java2/ant/lib for versions of NetBeans earlier than 6.9). Note that if your ANT_HOME environment variable points to another folder, the proguard.jar file will need to be in the %ANT_HOME%/lib folder.

That is it – no further installation or configuration is required.

Step 1: Examine the Folder Structure

Before starting with the obfuscation, you need to familiarise yourself with the folder structure of your NetBeans application. Let’s create a new NetBeans Platform Application, and build a zip distribution of the empty application. Right click on the project in the Projects window, and choose Build ZIP distribution.

Figure 1. Suite folder structure.

Figure 1. Suite folder structure.

Figure 1 shows the folder structure of the project. In the root folder of the suite you will find the suite’s ant build script, called build.xml. You will also see a ‘dist’ folder – NetBeans automatically copies the .zip file of your application here. Note that NetBeans derives the name of the .zip file from the project property called ‘Branding Name’ in the IDE, as shown in Figure 2. The value of this project property is stored in the ant scripts as ${app.name}.

Figure 2. Suite project properties.

Figure 2. Suite project properties.

We don’t need to know more about the project structure for the goal of obfuscation. If you’d like to know more, read here about the build harness.

The next part of the puzzle is finding out where the .jar files that we want to obfuscate are located in the zip distribution. So let’s add a module with a single class called Example, and build it again. The structure of the .zip file’s contents is shown in Figure 3.

Figure 3. Folder structure with module added.

Figure 3. Folder structure with module added.

We now know that the modules in our suite are located in /suite_example1/modules. We also know that NetBeans stores the jar files that forms part of the NetBeans platform in the /platform/core, /platform/lib and /platform/modules folders. For the sake of brevity we did not expand the last two folders in the screenshot – each of them contains a fairly large number of files.

Note that the /platform folder would be called something like /platform10 in earlier versions of NetBeans.

Step 2: Add a New Target to the Build Script

Now that we know where to locate the files we need for obfuscation, we can create the ant target to trigger the obfuscation. In short, what we need to do is extract the contents of the .zip file, apply the obfuscation, and update the already existing .zip.

Add the following to the suite’s build.xml file:

<taskdef resource="proguard/ant/task.properties" classpath="proguard.jar" />
<target name="obfuscate" depends="build-zip">
  <echo message="Starting obfuscation"/>
  <unzip src="dist/${app.name}.zip" dest="dist/${app.name}"/>
  <proguard configuration="settings.pro"/>
  <copy toDir="dist/${app.name}/${app.name}/${app.name}/modules">
    <fileset dir="dist/${app.name}/${app.name}/${app.name}/processed_jars"/>
  <zip destfile="dist/${app.name}.zip" update="yes" basedir="dist/${app.name}"
  <delete dir="dist/${app.name}"/>

Note the use of the ${app.name} ant property to ensure that the file names are specified in the project’s properties. Also note that the new target depends on build-zip, which means that the project properties such as ${app.name} will be available in this target.

Only one step in the above ant script remains unexplained – why copy any files? The settings.pro file (which we shall examine in the next section) specifies that NetBeans should place all the output .jar files into the processed_jars folder. We need to copy them from there back to their proper place in the folder structure to overwrite the original files.

Step 3: Creating the Settings File

The settings used by ProGuard during obfuscation can be specified either in a settings file (the option described here), or directly in the ant target. The bare minimum to get a working build is shown below. Put this into a file called settings.pro, in the root of the suite project folder.

-injars       dist/suite_example1/suite_example1/suite_example1/modules/(*.jar;)
-outjars dist/suite_example1/suite_example1/suite_example1/processed_jars
-libraryjars /lib/rt.jar;dist/suite_example1/suite_example1/platform/(**/*.jar;)
-printmapping proguard.map

Remember to modify the reference to the platform folder for earlier versions of NetBeans.

The settings file specifies the input jars to obfuscate, output folder, and the libraries to read (but not obfuscate!). The above was used in Windows. For Linux there is just one small change – the “;” between the libraries should become “:”. The ones in the () should be left as is.

The -dontshrink setting turns off the shrinking step. Since we don’t specify any classes to keep yet, this is essential to ensure that we don’t end up with empty jar files.

Step 4: Executing the Obfuscation Target

The obfuscation will fail if there are no classes to obfuscate. That is why we created a blank class in the first step when we created the module.

To execute the new target, expand the suite’s “Important Files” node, right click on the “Build Script” and then choose Run Target | Other Targets | obfuscate from the context menu.

Besides the .zip file containing the obfuscated jars, a mapping file is also created. This file contains the name mappings that were done when renaming packages, classes and members. The contents of the file for the sample application are shown below:

za.co.kitt.example.module1.Example -> a.a.a.a.a.a:

Concluding Remarks

We have now successfully obfuscated an essentially empty module. From here onwards you may refine your obfuscation by editing the settings in the .pro file. If any specific class names need to be preserved, for example, this can be done with -keep options in the settings.pro file. See the ProGuard manual, included in the download or online, for more details about the -keep and other options.

From kitt.co.za


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}