The dictionary meaning of obfuscation is to make something unclear or unintelligible. In programming, obfuscator is used to protect source code from hackers. In this section, we will learn what is code obfuscation, the working of obfuscators, obfuscation tools, its uses. Also, we will learn how to obfuscate a Java application.
The word obfuscation is widely used in the computer science field. In the programming context, the meaning of obfuscation is to make the code unclear by doing some modifications in the executable code but the code remains fully functional. The purpose of using obfuscation is that the code is no longer useful to hackers.
Note that the obfuscation process may modify the method instructions or metadata but does not alter the output of the application or program. The main objective of code obfuscation is to make reverse engineering difficult. The tools that we used in this process are called code obfuscators.
In programming, almost all code can be reverse engineering with enough time and effort. There are a number of decompiles freely available for diffident platforms such as Java, Android, .NET, iOS, etc. that can be used to reverse-engineering source code from an executable or library with no time and effort. Hence, the code is easily understandable to hackers.
To overcome the problem, we use code obfuscator. These are the tools that protect code from hackers without changing its functionality.
Working of Obfuscator
The working of obfuscation includes various techniques that provide layered security against reverse engineering. These techniques are as follows:
It is the basic obfuscation that is used by many obfuscators. It alters the name of the methods and variables. By changing the name of the method and variables it is harder to understand code. Note that it does not alter the program execution. Renaming can use alphabets, numbers, unprintable characters, etc. For example, consider the following code snippet:
In code, all the strings can be read clearly even after performing the renaming obfuscation. String usually includes messages (such as error messages) that are visible to the user. It hides the string in executable and restores the original string if needed. For example, consider the following figure:
Control Flow Obfuscation
It creates conditional branching and iterative constructs. It generates a valid executable logic. But yield non-deterministic semantic results when decompiled. It makes code difficult that cannot be easily comprehended by hackers. Note that the technique may reduce the runtime performance of a method.
Instruction Pattern Transformation
In this technique, the instructions created by the compiler are converted into others. Usually, these are the legal machine language instructions that cannot be mapped to high-level languages.
Dummy Code Insertion
It inserts the dummy code into the executable but does not affect the logic of the application. It breaks the decompiles. By inserting dimming code, it is harder to analyze reverse-engineered code.
Unused Code and Meta Data Removal
Removing debug information, non-essential metadata, and used code from applications make them smaller and reduces the information available to an attacker. It boosts the performance of the application.
It combines multiple input executables/libraries into one or more than one output binaries. It makes applications smaller, especially when used with renaming and pruning. Hence, it reduces the information available to hackers.
Opaque Predicate Insertion
It adds the conditional branches that always evaluate to known results. These are the results that cannot be guess or determined easily by performing static analysis. It provides potentially incorrect code that never executes. The only motive is to make confuse hackers who are trying to understand original source code.
An obfuscator can constrain application self-assurance into the code to confirm that the application has not been altered at all. In the case of altering is recognized, it can close down, as far as possible the usefulness, invoke irregular crashes (to disguise the justification the crashes), or play out some other custom activity.
An obfuscator can layer in application self-security by infusing code to diagnose if our production application is executing inside a debugger. In the event that a debugger is utilized, it can ruin delicate information (shielding it from theft), summon random collides (to disguise that the crash was the aftereffect of an investigate check), or play out some other custom activity.
Why should we use an obfuscator?
In Java, applications can be easily reverse-engineered by using Java decompilers. Java decompileers expose the source code to avoid the same we use obfuscator. By using the obfuscator, we can protect our source code from hackers. It is the best solution to provide security to the source code. For different platforms, there are different obfuscators. There are many Java obfuscator tools that are freely available.
Java Obfuscate Tools
There is a number of obfuscation tools are available for Java. Here, we have listed some popular and widely used obfuscators.
Let's use the obfuscation tool to obfuscate the bytecode or Java class file.
Before moving to the obfuscation of code, we will understand how to reverse engineer Java bytecode using the Java decompilers.
Obfuscate Java Application Using ProGuard
ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It optimizes bytecode and renames the classes, files, methods, and variables using the short meaningless name. In addition, it also optimizes the code and detects unused classes, methods, attributes, and unused instructions. It is also suitable for Android and Kotlin.
In order to use ProGuard tool, first, we need to download it. After that, follow the steps.
Step 1: Download the proguard-ant-7.2.0-beta1.jar file.
Step 2: Create a configuration file that contains all the information about the application. In our case, we have created democofig.pro file.
-injars: Specify the path of .jar files (compiled Java application).
-outjars: It is a jar file that is created by the ProGuard, after obfuscation. It contains all the jumbled, obscure naming convention of the methods and variables in the class file.
-printmapping: The file contains all the mapping information for our reference.
-keep: In this file, we specify the class files and methods that we do not want to obfuscate. For example, com.javatpoint.DemoClass contains the entry point for the application with the main class that will not get obfuscated in the following example.
Now, we will execute the ProGuard application by using the following commands.
After executing the ProGuard, it creates the following two files:
Let's see the demo files.
The file shows the original name of the Java source objects and the corresponding new obfuscated name. For example, consider the following:
Demo.java (before obfuscation)
We get the following Java source code that was decompiled from the class file after obfuscation.
We observe that the statement HashSet<String> obj=new HashSet(list); got transformed into the statement A<m> o=new A(list); Therefore, no one can guess from the above code what the actual application has.