pondělí 10. listopadu 2014

Vytvoření AST pomocí Procyon z .jar souboru

Program pro vytvoření AST pomocí Procyonu z .jar souboru může vypadat následovně:

Potřebné knihovny:

1
2
3
4
5
6
7
8
9
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.*;
import com.strobel.assembler.*;
import com.strobel.assembler.metadata.*;
import com.strobel.core.*;
import com.strobel.decompiler.*;
import com.strobel.decompiler.languages.java.*;
import com.strobel.decompiler.languages.java.ast.*;

Funkce pro rekurzivní zanořování v AST stromě a výpis informací o tokenech:
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
private static void show_me_smtng(AstNode an, int hloubka){
 
 while (an!=null){
  final String mezera = "  ";
     

  for (int i = 0 ; i < hloubka ; i++) System.out.print(mezera);
  System.out.println(an.getRole()+"("+an.getNodeType()+")"+"--"+an.getRegion());
     
     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(" ...");
     }
     
     if (an.hasChildren()){
   for (int i = 0 ; i < hloubka ; i++) System.out.print(mezera);
      System.out.println("+childs:");
      /*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();
    }
}

Upravená metoda decompile třídy Decompiler. Tedy metoda, která zajistí vytvoření AST:
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
public static void decompile(String internalName, PlainTextOutput output, DecompilerSettings settings) {
 
 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());
 }
 
 CompilationUnit cu = new CompilationUnit();
 JavaLanguage jl = new JavaLanguage();
 cu=jl.decompileTypeToAst(resolvedType, options);
 
 
 AstNode an = null;
 if (cu.hasChildren()){
  an = cu.getChildren().iterator().next(); 
 }else{
  System.out.println("neni dalsi");
 }
 
 show_me_smtng(an,0);
}


A na závěr všehospouštěč main:
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
public static void main(String[] args) { 
  
 final String jarName = "/home/greg/Plocha/starship.jar";
 try {
  JarFile jarFile = new JarFile(jarName);
  JarTypeLoader jarFileloader = new JarTypeLoader(jarFile);
  PlainTextOutput output;
  
  DecompilerSettings settings = new DecompilerSettings();
  settings.setShowSyntheticMembers(false);
  settings.setTypeLoader(new CompositeTypeLoader(new ITypeLoader[] { jarFileloader, new InputTypeLoader() }));
  
  Enumeration<JarEntry> entries = jarFile.entries();

  while (entries.hasMoreElements()){
   JarEntry entry = entries.nextElement();
   System.out.println(entry.getName());
   if (entry.getName().endsWith(".class")){
    output = new PlainTextOutput();
    String name = StringUtilities.removeRight(entry.getName(), ".class");
    decompile(name, output, settings);
    System.out.print(output);
   }
  }
  
 } catch (IOException e) {
  e.printStackTrace();
 }
 
    
}


Žádné komentáře:

Okomentovat