?? proguard.java
字號:
referenceWarningCount > 0) && !configuration.ignoreWarnings) { System.err.println(" If you are sure the mentioned classes are not used anyway,"); System.err.println(" you could try your luck using the '-ignorewarnings' option."); throw new IOException("Please correct the above warnings first."); } // Discard unused library classes. if (configuration.verbose) { System.out.println("Removing unused library classes..."); System.out.println(" Original number of library classes: " + libraryClassPool.size()); } // Reinitialize the library class pool with only those library classes // whose hierarchies are referenced by the program classes. ClassPool newLibraryClassPool = new ClassPool(); programClassPool.classFilesAccept( new AllCpInfoVisitor( new ReferencedClassFileVisitor( new LibraryClassFileFilter( new ClassFileHierarchyTraveler(true, true, true, false, new LibraryClassFileFilter( new ClassPoolFiller(newLibraryClassPool, false))))))); libraryClassPool = newLibraryClassPool; if (configuration.verbose) { System.out.println(" Final number of library classes: " + libraryClassPool.size()); } } /** * Prints out classes and class members that are used as seeds in the * shrinking and obfuscation steps. */ private void printSeeds() throws IOException { if (configuration.verbose) { System.out.println("Printing kept classes, fields, and methods..."); } // Check if we have at least some keep commands. if (configuration.keep == null) { throw new IOException("You have to specify '-keep' options for the shrinking step."); } PrintStream ps = configuration.printSeeds.length() > 0 ? new PrintStream(new BufferedOutputStream(new FileOutputStream(configuration.printSeeds))) : System.out; // Create a visitor for printing out the seeds. Note that we're only // printing out the program elements that are preserved against shrinking. SimpleClassFilePrinter printer = new SimpleClassFilePrinter(false, ps); ClassPoolVisitor classPoolvisitor = ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep, new ProgramClassFileFilter(printer), new ProgramMemberInfoFilter(printer)); // Print out the seeds. programClassPool.accept(classPoolvisitor); libraryClassPool.accept(classPoolvisitor); if (ps != System.out) { ps.close(); } } /** * Performs the shrinking step. */ private void shrink() throws IOException { if (configuration.verbose) { System.out.println("Shrinking..."); } // Check if we have at least some keep commands. if (configuration.keep == null) { throw new IOException("You have to specify '-keep' options for the shrinking step."); } // Clean up any old visitor info. ClassFileCleaner classFileCleaner = new ClassFileCleaner(); programClassPool.classFilesAccept(classFileCleaner); libraryClassPool.classFilesAccept(classFileCleaner); // Create a visitor for marking the seeds. UsageMarker usageMarker = new UsageMarker(); ClassPoolVisitor classPoolvisitor = ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep, usageMarker, usageMarker); // Mark the seeds. programClassPool.accept(classPoolvisitor); libraryClassPool.accept(classPoolvisitor); // Mark interfaces that have to be kept. programClassPool.classFilesAccept(new InterfaceUsageMarker()); // Mark the inner class information that has to be kept. programClassPool.classFilesAccept(new InnerUsageMarker()); if (configuration.printUsage != null) { if (configuration.verbose) { System.out.println("Printing usage" + (configuration.printUsage.length() > 0 ? " to [" + configuration.printUsage + "]" : "...")); } PrintStream ps = configuration.printUsage.length() > 0 ? new PrintStream(new BufferedOutputStream(new FileOutputStream(configuration.printUsage))) : System.out; // Print out items that will be removed. programClassPool.classFilesAcceptAlphabetically(new UsagePrinter(true, ps)); if (ps != System.out) { ps.close(); } } // Discard unused program classes. if (configuration.verbose) { System.out.println("Removing unused program classes and class elements..."); System.out.println(" Original number of program classes: " + programClassPool.size()); } ClassPool newProgramClassPool = new ClassPool(); programClassPool.classFilesAccept( new UsedClassFileFilter( new MultiClassFileVisitor( new ClassFileVisitor[] { new ClassFileShrinker(1024), new ClassPoolFiller(newProgramClassPool, false) }))); programClassPool = newProgramClassPool; if (configuration.verbose) { System.out.println(" Final number of program classes: " + programClassPool.size()); } // Check if we have at least some output class files. if (programClassPool.size() == 0) { throw new IOException("The output jar is empty. Did you specify the proper '-keep' options?"); } } /** * Performs the optimization step. */ private void optimize() throws IOException { if (configuration.verbose) { System.out.println("Optimizing..."); } // Clean up any old visitor info. ClassFileCleaner classFileCleaner = new ClassFileCleaner(); programClassPool.classFilesAccept(classFileCleaner); libraryClassPool.classFilesAccept(classFileCleaner); // Check if we have at least some keep commands. if (configuration.keep == null) { throw new IOException("You have to specify '-keep' options for the optimization step."); } // Create a visitor for marking the seeds. KeepMarker keepMarker = new KeepMarker(); ClassPoolVisitor classPoolvisitor = ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep, keepMarker, keepMarker); // Mark the seeds. programClassPool.accept(classPoolvisitor); libraryClassPool.accept(classPoolvisitor); // Make class files and methods final, as far as possible. programClassPool.classFilesAccept(new ClassFileFinalizer()); // Mark all fields that are write-only. programClassPool.classFilesAccept( new AllMethodVisitor( new AllAttrInfoVisitor( new AllInstructionVisitor( new WriteOnlyFieldMarker())))); if (configuration.assumeNoSideEffects != null) { // Create a visitor for marking methods that don't have any side effects. NoSideEffectMethodMarker noSideEffectMethodMarker = new NoSideEffectMethodMarker(); ClassPoolVisitor noClassPoolvisitor = ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.assumeNoSideEffects, null, noSideEffectMethodMarker); // Mark the seeds. programClassPool.accept(noClassPoolvisitor); libraryClassPool.accept(noClassPoolvisitor); } // Mark all methods that have side effects. programClassPool.accept(new SideEffectMethodMarker()); // Mark all interfaces that have single implementations. programClassPool.classFilesAccept(new SingleImplementationMarker(configuration.allowAccessModification)); // Inline interfaces with single implementations. // First update the references to classes and class members. // Then update the class member descriptors. programClassPool.classFilesAccept(new AllMethodVisitor( new AllAttrInfoVisitor( new SingleImplementationInliner()))); programClassPool.classFilesAccept(new AllMemberInfoVisitor( new SingleImplementationInliner())); // Perform partial evaluation. programClassPool.classFilesAccept(new AllMethodVisitor( new PartialEvaluator())); // Create a branch target marker and a code attribute editor that can // be reused for all code attributes. BranchTargetFinder branchTargetFinder = new BranchTargetFinder(1024); CodeAttrInfoEditor codeAttrInfoEditor = new CodeAttrInfoEditor(1024); // Visit all code attributes. // First let the branch marker mark all branch targets. // Then perform peephole optimisations on the instructions: // - Remove push/pop instruction pairs. // - Remove load/store instruction pairs. // - Replace store/load instruction pairs by dup/store instructions. // - Replace branches to return instructions by return instructions. // - Remove nop instructions. // - Inline simple getters and setters. // Finally apply all changes to the code. programClassPool.classFilesAccept( new AllMethodVisitor( new AllAttrInfoVisitor( new MultiAttrInfoVisitor( new AttrInfoVisitor[] { branchTargetFinder, new CodeAttrInfoEditorResetter(codeAttrInfoEditor), new AllInstructionVisitor( new MultiInstructionVisitor( new InstructionVisitor[] { new PushPopRemover(branchTargetFinder, codeAttrInfoEditor), new LoadStoreRemover(branchTargetFinder, codeAttrInfoEditor), new StoreLoadReplacer(branchTargetFinder, codeAttrInfoEditor), new GotoReturnReplacer(codeAttrInfoEditor), new NopRemover(codeAttrInfoEditor), new GetterSetterInliner(codeAttrInfoEditor, configuration.allowAccessModification), })), codeAttrInfoEditor })))); } /** * Performs the obfuscation step. */ private void obfuscate() throws IOException { if (configuration.verbose) { System.out.println("Obfuscating..."); } // Check if we have at least some keep commands. if (configuration.keep == null && configuration.keepNames == null) { throw new IOException("You have to specify '-keep' options for the obfuscation step."); } // Clean up any old visitor info. ClassFileCleaner classFileCleaner = new ClassFileCleaner(); programClassPool.classFilesAccept(classFileCleaner); libraryClassPool.classFilesAccept(classFileCleaner); // Link all class members that should get the same names. programClassPool.classFilesAccept(new BottomClassFileFilter( new MemberInfoLinker())); // Create a visitor for marking the seeds. NameMarker nameMarker = new NameMarker(); ClassPoolVisitor classPoolvisitor = new MultiClassPoolVisitor(new ClassPoolVisitor[] { ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep, nameMarker, nameMarker),
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -