For high-level languages such as .NET or Java, it is quite trivial to reverse-engineer application binaries to recover the original source code if the application doesn’t employ any type of encryption or obfuscation. Some popular decompilers are: Dotpeek, Reflector, JustDecompile (.NET), Java Decompiler, Mocha, DJ Java Decompiler (Java). In a penetration test, program’s source code is valuable information that can be used to attack application and trusted resources. To help prevent the recovery of source code, obfuscation is often being used. Obfuscation is the intentional act of converting original source code to a form that is difficult for human to understand. The main goal of obfuscation is to provide “security through obscurity” in order to prevent attackers from:
Obfuscators (programs that help obfuscating source code), generally achieve its purposes by:
This blog post aims to provide a simple example of Java Obfuscation. Hopefully it will be helpful for programmers wanting to protect their applications.
If you just want to simply do name/data flow obfuscation for your Java program, free obfuscators such as ProGuard or yGuard will suit your needs. For stronger protection and extra capabilities such as String Encryption, Incremental Obfuscation, Stack Trace Transplantation, you may need to choose a commercial product. This article provides a great comparison among popular Java Obfuscators I am usually a proponent of open source programs; however for this tutorial I will be using Zelix KlassMaster to obfuscate a custom server/client Java program. In my opinion, it provides decent feature set for a reasonable price point. For complete feature listing visit Zelix Klassmaster
Let’s take a look at this client/server program. On the Server side, we have following classes:
Compiling server classes give us Java Archive file: Server.jar On the Client side, we have following classes:
As mentioned above, it is trivial to recover original source code with a Decompiler Program such as Java Decompiler (JD-GUI). Here is what it looks like when decompiling Client.jar with JD-GUI: 
The original source code has been recovered with great accuracy. With this information, attackers can learn the business logic of the program or import decompiled project into an IDE, modify code flow to bypass program restrictions.
The most common mistake when dealing with obfuscation is to involve it later in the game, after the implementation phase, when the binaries are made and ready for testing. In this bad example below, Client.jar is obfuscated with Zelix KlassMaster with the following settings:
After obfuscation the result binary will have the following structure:
Decompiling it will result in an empty class file as shown below:
The command to run Client program will be the same as before: java -classpath Client.jar com.client.ClientRun However it will generate exception when trying to communicate with Server Program. The reason is: Server and Client programs share some common classes: Person, SearchObject and SearchResult. When Server program attempts to read com.commons.Person object, for example, in Client program it is transformed into com.client.a, causing the Exception in the screenshot below. For both of the programs to work, Client and Server programs must be using the exact same classes, including package name.
Below is any overview of common obfuscation procedures.
If you choose to obfuscate common libraries in step 5, this is the time to fix potential compilation errors due to class/package/method renaming.
The following settings are used to obfuscate Client Program. Note that I excluded public static void main(String[] args) as it is required to run any Java application:
Specify change log location:
Save obfuscated classes into a new jar file:
Decompiling it with JD-GUI:
Review change log for the new names of entry points. Update all components that are using those entry points. Sample change log will look like: Class: public com.client.ClientRun => d Source: “ClientRun.java” Now move on to obfuscate Server program. To keep it simple, I opt to exclude servlet class name from obfuscation:
Save obfuscated classes into new jar file:
Decompiling it with JD-GUI:
Obfuscation, in general, makes reverse-engineering a time-consuming process for most attackers. Obfuscation cannot prevent other attack vectors such as bytecode manipulation or communication manipulations. To protect your application from such threats, consider implementing code signing in your application. Regarding Zelix Klassmaster itself, Security Researcher Yiannis Pavlosoglou has discovered that the its String Encryption routine is actually composing of five XOR operations, with encryption keys hard-coded in the class file. More information can be viewed here: https://www.defcon.org/images/defcon-15/dc15-presentations/dc-15-subere.pdf
In Part 2 of the series, Weylon covers how to use ForceHound to visualize Salesforce attack paths in BloodHound CE, identify transitive privilege escalation, and legacy Connected App exposures.
Discover how ForceHound automates the collection of profiles, permission sets, and connected apps to reveal the true trust boundaries of your Salesforce organization.
Discover the top critical vulnerabilities of 2026 identified by Team NetSPI and learn how proactive security measures can protect your strategic business initiatives.
© 2026 NetSPI LLC.