15 June 2005

How Private are Private Fields?

Read from an interesting article. Yeah, how private are private fields? The example codes that were shown from that article were still "nice" in such a way that it has to explicitly name the private field to be screwfully modified.

Here's a more wicked way of doing it, what we'll do is to enumerate all fields then modify them all hihihihi. Note: BOYS AND GIRLS, DO NOT TRY THIS AT HOME.

Listing 1: NoMatterHowPrivate.java



package org.hacks.wicked;

/**
* @author Jared Odulio
*
*/
public class NoMatterHowPrivate {

private String yourName;
private String yourSecret;

private static NoMatterHowPrivate instance;


/**
* @return Returns the yourName.
*/
public String getYourName() {
return yourName;
}
/**
* @param yourName The yourName to set.
*/
public void setYourName(String yourName) {
this.yourName = yourName;
}
/**
* @return Returns the yourSecret.
*/
public String getYourSecret() {
return yourSecret;
}
/**
* @param yourSecret The yourSecret to set.
*/
public void setYourSecret(String yourSecret) {
this.yourSecret = yourSecret;
}
/**
* @return Returns the instance.
*/
public static NoMatterHowPrivate getInstance() {
if (instance == null){
instance = new NoMatterHowPrivate();
}
return instance;
}
}




The code above is your typical "HighLander" class. You know what's a "Highlander" class? "There can only be one..." says Duncan McLaud(?). Right, it's a singleton. And that class has a client call SissyClient.

Listing 2: SissyClient.java



package org.hacks.wicked;

/**
* @author Jared Odulio
*
*/
public class SissyClient {

private NoMatterHowPrivate nmhp;

public void setSomeStuff(){
nmhp = NoMatterHowPrivate.getInstance();
nmhp.setYourName("Sissy");
nmhp.setYourSecret("Sly");
}

public void getSomeStuff(){

nmhp = NoMatterHowPrivate.getInstance();
System.out.println("I am " + nmhp.getYourName());
System.out.println("I am " + nmhp.getYourSecret());

}
}




SissyClient is your clueless class who thinks she's doing everything fine. :))


And here's our badass Reflections-loving class. It's called WickedHacker.

Listing 3: WickedHacker.java



package org.hacks.wicked;

import java.lang.reflect.Field;

/**
* @author Jared Odulio
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class WickedHacker {

private NoMatterHowPrivate toScrew;

public void screwSomeStuff(){

String[] stuffs = new String[2];
toScrew = NoMatterHowPrivate.getInstance();
Object tmp = (Object)toScrew;
Field[] fields = toScrew.getClass().getDeclaredFields();
int fldCount = fields.length;
for (int ctr = 0;ctr < fldCount; ctr++){
Class clazz = fields[ctr].getType();
if (!clazz.getName().equals(toScrew.getClass().getName())){
fields[ctr].setAccessible(true);
try {
fields[ctr].set(tmp, "Screwed");

} catch (IllegalArgumentException e) {

e.printStackTrace();
} catch (IllegalAccessException e) {

e.printStackTrace();
}
}

}

}

}




This class is ruthless except for the static fields. It takes on almost anything especially the privates.

We can run this by using this main class.

Listing 4: Runner.java



package org.hacks.wicked;

/**
* @author Jared Odulio
*
*/
public class Runner {

public static void main(String[] args) {
SissyClient client = new SissyClient();
client.setSomeStuff();
new WickedHacker().screwSomeStuff();
client.getSomeStuff();
}
}




Output will be:


I am Screwed
I am Screwed


You can try this with your existing code and have some fun. Now, run to your productions servers!

3 comments:

Luke said...

Java Lang = obj oriented
Static mod = !obj oriented
VM, Reflection = very useful but screws OO encapsulation

Only if your JVM's policy along with an organization IT sec policy is lenient.

Don't be tempted by the powers of the dark side.

nox said...

wicked!

how do we create a *real* private field in java then?

cheers!

Luke said...

err... junk java, use cobol???

convert your java binaries to native or use a stronger .java.policy