| 1 2 3 4 5 6 7 8 9 | import com.strobel.decompiler.*; public class test { public static void main(String[] args) { PlainTextOutput output = new PlainTextOutput(); Decompiler.decompile("/path/file.class",output); System.out.print(output); } } | 
Více práce už dá, pokud chceme získat pomocí Procyon abstraktní syntaktický strom (AST). K tomuto účelu jsem si musel napsat vlastní metodu podobnou Decompiler.decompile(...) (viz zdrojáky Procyon) a výsledný AST procházet rekurzivně.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | import com.strobel.assembler.InputTypeLoader; import com.strobel.assembler.metadata.DeobfuscationUtilities; import com.strobel.assembler.metadata.IMetadataResolver; import com.strobel.assembler.metadata.ITypeLoader; import com.strobel.assembler.metadata.MetadataParser; import com.strobel.assembler.metadata.MetadataSystem; import com.strobel.assembler.metadata.TypeDefinition; import com.strobel.assembler.metadata.TypeReference; import com.strobel.core.VerifyArgument; import com.strobel.decompiler.*; import com.strobel.decompiler.languages.java.JavaFormattingOptions; import com.strobel.decompiler.languages.java.JavaLanguage; import com.strobel.decompiler.languages.java.ast.AstNode; import com.strobel.decompiler.languages.java.ast.CompilationUnit; import com.strobel.decompiler.languages.java.ast.NodeType; public class test { public static void main(String[] args) { final String internalName = "/home/greg/workspace/test-procyon/bin/test.class"; /////**** zkopirovano z metody Decompiler.decompile(...) final DecompilerSettings settings = new DecompilerSettings(); VerifyArgument.notNull(internalName, "internalName"); VerifyArgument.notNull(settings, "settings"); final ITypeLoader typeLoader = settings.getTypeLoader() != null ? settings.getTypeLoader() : new InputTypeLoader(); final MetadataSystem metadataSystem = new MetadataSystem(typeLoader); final TypeReference type; if (internalName.length() == 1) { // // Hack to get around classes whose descriptors clash with primitive types. // final MetadataParser parser = new MetadataParser(IMetadataResolver.EMPTY); final TypeReference reference = parser.parseTypeDescriptor(internalName); type = metadataSystem.resolve(reference); } else { type = metadataSystem.lookupType(internalName); } final TypeDefinition resolvedType; if (type == null || (resolvedType = type.resolve()) == null) { System.out.println("!!! ERROR: Failed to load class "+ internalName+"."); return; } DeobfuscationUtilities.processType(resolvedType); final DecompilationOptions options = new DecompilationOptions(); options.setSettings(settings); options.setFullDecompilation(true); if (settings.getFormattingOptions() == null) { settings.setFormattingOptions(JavaFormattingOptions.createDefault()); } //////******* konec casti zkopirovane z Decompiler.decompile(...) CompilationUnit cu = new CompilationUnit(); JavaLanguage jl = new JavaLanguage(); cu=jl.decompileTypeToAst(resolvedType, options); // misto decompileType dekompilujeme do AST AstNode an = null; if (cu.hasChildren()){ an = cu.getChildren().iterator().next(); }else{ System.out.println("neni dalsi"); } // pro vypis vsech urovni AST stromu bude tuto metodu potreba volat rekurzivne show_me_smtng(an,0); } /* * vypisuje a zanoruje se hloubeji do ast stromu */ private static void show_me_smtng(AstNode an, int hloubka){ while (an!=null){ final String mezera = " "; // identifikator hloubky ve strome for (int i = 0 ; i < hloubka ; i++) System.out.print(mezera); System.out.println(an.getRole()+"("+an.getNodeType()+")"+"--"+an.getRegion()); // vypis nejzajimavejsich informaci o uzlu // ignorovat vypis STATEMENT, TYPE_DECLARATION a MEMBER - zbytecne moc textu if (an.getNodeType()!=NodeType.STATEMENT && an.getNodeType()!=NodeType.TYPE_DECLARATION && an.getNodeType()!=NodeType.MEMBER){ for (int i = 0 ; i < hloubka ; i++) System.out.print(mezera); if (an.getText()!=null) System.out.println(" \""+an.getText().replaceAll("\n", "")+"\""); }else{ for (int i = 0 ; i < hloubka ; i++) System.out.print(mezera); System.out.println(" ..."); } // zanoreni hloubeji do stromu if (an.hasChildren()){ for (int i = 0 ; i < hloubka ; i++) System.out.print(mezera); System.out.println("+childs:"); // v pripade potreby omezeni hloubky stromu /*if (hloubka > 2){ an = an.getNextSibling(); System.out.println("--utnuto--"); continue; }*/ show_me_smtng(an.getFirstChild(),hloubka+1); }else{ for (int i = 0 ; i < hloubka ; i++) System.out.print(mezera); System.out.println("-nema potomky"); } System.out.println(""); an = an.getNextSibling(); // nasledujici soused } } } | 
Zdroje:
https://bitbucket.org/mstrobel/procyon/wiki/Decompiler%20API
 
Žádné komentáře:
Okomentovat