Java Code Obfuscation

Download Report

Transcript Java Code Obfuscation

Java Code Obfuscation
Neerja Bhatnagar
Reverse Engineering



Figuring out source code corresponding to a
given byte code
Source code intellectual property, needs
protection
Money, intelligence, hard work, time put to
work to develop code
Problem of Reverse Engineering

Java code especially prone to reverse engineering,
because
 Java byte code well documented and well
structured (freely available in JVM specs)
 Most of the information contained in source
code also present in byte code.
 Software engineers have little control over
distribution of Java applications and their source
code because most Java applications
distributed over the Internet (easy downloads)
Code Obfuscation






Technique to discourage and deter reverse
engineering
Scrambles byte code to make it unintelligible,
difficult to understand
Alters structure and appearance of code
Attempts to make in uneconomical for an
attacker to reverse engineer code
Does not affect function of original program
Does not alter source code, alters byte code
Code Obfuscation Techniques


Low-Level
 Layout Obfuscations
 Control Obfuscations
 Data Obfuscations
High-Level or Design Obfuscations
 Class Coalescing Obfuscation
 Class Splitting Obfuscation
 Type Hiding
Design Obfuscations



Low-level obfuscation techniques not
sufficient because they do not hide
design information
Design information can facilitate an
attacker from gaining general
understanding of code and what it does
Design obfuscations aim at hiding
valuable high-level design information
Class Coalescing Obfuscation


Combines two or more classes into a single
class
If the classes to be coalesced
 have attributes with same name, these
are renamed to distinguish among them
 have non-constructor methods with same
signature, except for one non-constructor
methods, all others are renamed and
altered
Class Coalescing Obfuscation Example
public class Animal {
String name; int age;
public class A {
String name;
String model;
int age;
int age2;
public Animal() {
name = “Goofy”; age = 1;
}
public int calcAge() {
return 2004 – 1985;
}
public Animal() {
name = “Goofy”; age = 1;
}
public void comments() {
System.out.println(“Fluffy”);
}
public Car() {
name = “VW”; age = 2;
}
}
public int calcAge() {
return 2004 – 1985;
}
public class Car {
String model; int age;
public int calcAge(int make)
return 2004 – make;
}
public Car() {
name = “VW”; age = 2;
}
public int calcAge(int make)
return 2004 – make;
}
}
public void comments() {
System.out.println(“Fluffy”);
}
{
public void comments() {
System.out.println(“Smooth”);
}
{
public void commentsFromCar() {
System.out.println(“Smooth”);
}
}
Class Coalescing Obfuscation Shortcomings



Becomes very complicated when classes extend
other classes or implement interfaces because
 superclasses and interfaces need to be
coalesced too
 variable names and method signatures
cannot be altered in any way
Cannot be performed when classes extend classes
from Java standard library
 Java standard library classes need to be
coalesced too
 Makes code non-portable
Classes with native methods cannot be coalesced
because analyzing native code very difficult
Class Splitting Obfuscation




Splits a class into multiple classes
Several ways to split a class
Valid split function preserves dependencies
among class’s methods and fields
Valid split functions include


Split class A into classes A1 and A2, where A2
extends A1
Split methods defined in class A between
classes A1 and A2
Class Splitting Obfuscation Example
public class Animal
String name;
int age;
public class Dog
String name;
int age;
String sound;
{
{
public Dog() {
name = “Bruno”;
age = 5;
sound = “woof”;
}
public Animal() {
name = “Bruno”;
age = 5;
}
public void sleep() {
System.out.println(“zzz…zzz”);
}
}
public void bark() {
System.out.println(“Woof! Woof!”);
}
public void sleep() {
System.out.println(“zzz…zzz”);
}
public class Doggie extends Animal {
String sound;
public Doggie() {
super();
sound = “woof”;
}
}
public void bark() {
System.out.println(“Woof! Woof!”);
}
}
Class Splitting Obfuscation Shortcomings


Splitting a class very difficult unless initial
design faulty
May have reverse effect
 Splitting a class may improve overall
code design, and get rid of spaghetti
code!
 Might actually help the attacker, rather
than deter him
Type Hiding




Uses the concept of Java interface
Transforms a concrete class into
several interfaces
Each interface contains a random
subset of the concrete class’s methods
and fields
Obscures by declaring a concrete class
that implements those interfaces
Type Hiding Example
interface LivingCreature
public void bark();
}
public class Dog
String name;
int age;
String sound;
{
{
public Dog() {
name = “Bruno”;
age = 5;
sound = “woof”;
}
public void bark() {
System.out.println(“Woof! Woof!”);
}
interface Animal {
public void sleep();
}
public class Doggie
String name;
int age;
String sound;
public void sleep() {
System.out.println(“zzz…zzz”);
}
{
public Dog() {
name = “Bruno”;
age = 5;
sound = “woof”;
}
}
public void bark() {
System.out.println(“Woof! Woof!”);
}
public void sleep() {
System.out.println(“zzz…zzz”);
}
}
Type Hiding Shortcomings



Type hiding done the way described in
previous slide especially vulnerable to
reverse engineering
More effective when combined with
low-level obfuscation techniques
Can be made stronger when randomly
selected classes go through type
hiding, instead of all classes
Obfuscation Products




RetroGuard by Retrologic Systems
Klassmaster by Zelix
JObfuscator by Duckware
Semantic Designs
Conclusion






None of the obfuscation techniques sufficient by
themselves
A combination of these techniques might provide
strong resistance to reverse engineering
Some claim code obfuscation slows down an
application
Impact on performance depends on a particular
technique
Impact usually minimal or none at all
Decision to obfuscate or not is a trade-off between
protecting code or taking a slight performance hit