views:

112

answers:

2
+1  Q: 

Decompile JavaEE

We have a Java EE app which vendor does not exist anymore (due to bankruptcy). Unfortunately we have to make some changes to the functionality of the app, and this means reverse engineering the JavaEE app.

We use JD-GUI to reverse-engineer about 70% of the app/classes, and then tweak them manually to build in Eclipse.

However the rests are not so easy to be built because they are produced by code-generators? What tools can I use to assist further?

Edit:

This is one example of the difficulties:

return ((SchemaTypeSystem)Class.forName(
    "org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl",
    true,
    class$schema$system$s322D2AAD7A06BA82525CDB874D86D59A$TypeSystemHolder.getClassLoader())
        .getConstructor(new Class[] { Class.class })
        .newInstance(new Object[] { TypeSystemHolder.class }));

It's hard to know what is

class$schema$system$s322D2AAD7A06BA82525CDB874D86D59A$TypeSystemHolder.getClassLoader())
+2  A: 

Give JAD (http://www.varaneckas.com/jad) a try.

The problematic code that you show is equivalent to the following:

1) Class class$schema$system$s322D2AAD7A06BA82525CDB874D86D59A$TypeSystemHolder;
2) ClassLoader loader = class$schema$system$s322D2AAD7A06BA82525CDB874D86D59A$TypeSystemHolder.getClassLoader();
3) Class type = Class.forName("org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl", true, loader);
4) Constructor ctor = type.getConstructor(Class.class);
5) Object obj = ctor.newInstance(TypeSystemHolder.class);
6) SchemaTypeSystem result = (SchemaTypeSystem) obj;
7) return result;

The part you are having trouble with is line 1, which represents a local variable or a field (possibly static). The Java compiler converts the expression 'TypeSystemHolder.class' into an invocation of getClass storing the result in a static field. This initialization happens once in each class that references 'TypeSystemHolder.class' and the compiler replaces each callsite that uses this expression with a field access.

Most decompilers fail to translate this idiom back to the original call to 'TypeSystemHolder.class' but JAD handles this quite well. Additionally, there is a plug-in that integrates JAD (and others) into Eclipse (http://jadclipse.sourceforge.net).

Unfortunately, decompilers do not handle every code sequence generated by a compiler so some manual rewriting is always required. For example, the Java compiler may generate code for one exception handling block that overlaps with code for another exception handling block. Decompilers are unable to separate this back into two catch blocks. In this case, one usually sees goto statements littered throughout the code (not valid Java) or the decompiler simply gives up on that method.

Also, you are correct that this is generated code. Specifically, it is from the XmlBeans compiler, which parses xn XML Schema and generates binding classes for Java; allowing one to serailize and deserialize XML documents conforming to that schema. If you have access to the schema it would be better to incorporate XmlBeans into your build instead of decompiling these classes.

Faron
A: 

Take a look at soot. It doesn't decompile to Java source code, but uses an intermediate layer that is compilable. While its yet another language to learn, you will get the flexibility you need.

Additionally, if you are only making small tweaks, you can just attack files individually and leave the rest intact.

Jim Rush