Download presentation
Presentation is loading. Please wait.
1
Java Decompiler
2
Decompiler Go from executable bytecode to the source code
Bytecode has an M->N correspondence Partial structure destruction Executable has worse! Not all bytecode has corresponding source code
3
Class Parsing int flags = source.readUnsignedShort();
output.setFlags(flags); int this_id = source.readUnsignedShort(); String name = output.getClassName(this_id); output.setName(name); int super_id = source.readUnsignedShort(); String superName = null; if (super_id != 0) superName = output.getClassName(super_id); output.setSuperClass(superName); int count = source.readUnsignedShort(); String interfaces[] = new String[count]; for (int i=0;i<count;i++) { int id = source.readUnsignedShort(); interfaces[i] = output.getClassName(id); } output.setInterfaces(interfaces); current = ClassLevel.METADATA;
4
Signature Parsing private String FieldType() { switch (peek()) {
case 'B': case 'C': case 'D': case 'F': case 'I': case 'S': case 'Z': return BaseType(); case 'L': return ClassType(); case '[': return ArrayType(); } throw new ParseException(); private String ClassType() { StringBuilder sb = new StringBuilder(); if (next() != 'L') throw new ParseException(); while (peek() != ';') { char c = next(); sb.append(c == '/' ? '.' : c); next(); // consume ; return sb.toString();
5
Bytecode detection while (i < bytecode.length) { int index = i++;
BytecodeInstruction expr; switch(bytecode[index] & 0xff) { case 0x02: //iconst_m1 case 0x03: //iconst_0 expr = new LoadConstantInstruction(int.class, bytecode[index]-0x03); break; case 0x99: //ifeq expr = new IfInstruction("eq",index+((bytecode[i++] << 8 & 0xff) | (bytecode[i++] & 0xff)), false); case 0xb6: //invokevirtual expr = new InvokeInstruction(info, (bytecode[i++] << 8 & 0xff) | (bytecode[i++] & 0xff), false, true); default: Logger.error("Illegal opcode: "+Integer.toHexString(bytecode[index] & 0xff)); expr = null; } if (expr != null) { CodeGraph.Node node = new Node(expr); if (lastNode != null) { if (last.usesNext()) lastNode.addChild(node); lastNode = node; last = expr; map.put(index, node);
6
Runtime annotation processing
public final class OptClassLoader extends ClassLoader { public final Class<?> loadClass(String name, boolean resolve) { Annotation[] annotations = result.getAnnotations(); for (Annotation a : annotations) { Class<? extends Annotation> c = a.annotationType(); if (c.getName().equals("util.Option")) { addOption((Option)a); } else if (c.getName().equals("util.Options")) { Option[] defs = (Option[])c.getDeclaredMethod("value").invoke(a); for (Option o : defs) addOption(o); } return result; private void addOption(Option o) { String name = o.name(); Class<?> type = o.type(); String def = o.def(); OptionManager.addOption(name,type,def);
7
Sample output File: abstract class Foobar implements java.io.Serializable { public abstract <T, E extends Throwable> T foobar(T bar) throws E; } Output: /* FILE: test.java */ Foobar() { : load java.lang.Object, 0-> { } : invokenonvirtual java.lang.Object.<init>-> { } : return (none)-> { } public abstract <T extends java.lang.Object, E extends java.lang.Throwable> T foobar(T {VAR0}) throws E;
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.