Source Code Cross Referenced for GuardDB.java in  » Development » javaguard » net » sf » javaguard » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » javaguard » net.sf.javaguard 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * JavaGuard -- an obfuscation package for Java classfiles.
003:         *
004:         * Copyright (c) 1999 Mark Welsh (markw@retrologic.com)
005:         * Copyright (c) 2002 Thorsten Heit (theit@gmx.de)
006:         *
007:         * This library is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU Lesser General Public
009:         * License as published by the Free Software Foundation; either
010:         * version 2 of the License, or (at your option) any later version.
011:         *
012:         * This library is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this library; if not, write to the Free Software
019:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
020:         *
021:         * The author may be contacted at theit@gmx.de.
022:         *
023:         *
024:         * $Id: GuardDB.java,v 1.19 2002/06/04 10:01:05 glurk Exp $
025:         */package net.sf.javaguard;
026:
027:        import java.io.*;
028:        import java.util.*;
029:        import java.util.jar.*;
030:        import java.security.DigestOutputStream;
031:        import java.security.MessageDigest;
032:        import java.security.NoSuchAlgorithmException;
033:        import net.sf.javaguard.classfile.*;
034:        import net.sf.javaguard.log.*;
035:
036:        import org.apache.oro.text.MalformedCachePatternException;
037:        import org.apache.oro.text.regex.MalformedPatternException;
038:
039:        /** Classfile database for obfuscation.
040:         *
041:         * @author <a href="mailto:theit@gmx.de">Thorsten Heit</a>
042:         * @author <a href="mailto:markw@retrologic.com">Mark Welsh</a>
043:         */
044:        public class GuardDB implements  ClassConstants {
045:            /** The file name of the manifest file. */
046:            private static final String STREAM_NAME_MANIFEST = "META-INF/MANIFEST.MF";
047:            /** Signature directory name. */
048:            private static final String SIGNATURE_PREFIX = "META-INF/";
049:            /** Signature file name extension. */
050:            private static final String SIGNATURE_EXT = ".SF";
051:
052:            /** Holds a list of input Jar files to obfuscate. */
053:            private Vector inputJars = null;
054:            /** Holds a list of input directories with files to obfuscate. The vector
055:             * must have exact the same number of elements as the {@link #inputFileFilters}
056:             * vector.
057:             */
058:            private Vector inputDirs = null;
059:            /** Holds a list of file filter expressions for the input directories. The
060:             * vector must have exact the same number of elements as the {@link #inputDirs}
061:             * vector.
062:             */
063:            private Vector inputFileFilters = null;
064:            /** Holds a list of output containers that each manage the output name of
065:             * the obfuscated Jar file and the file containers that are used as input for
066:             * the obfuscator.
067:             */
068:            private Vector outputContainers = null;
069:            /** Holds the output file. */
070:            private File outputFile;
071:            /** Holds the tree of packages, classes, methods and fields. */
072:            private ClassTree classTree = null;
073:            /** Holds script file to use for the obfuscation. */
074:            private ScriptFile scriptFile;
075:            /** Holds the package, class, method and field mapping entries from the
076:             * script file. */
077:            private Vector mappings = null;
078:
079:            /** Holds the log file to use. */
080:            private FileLogger logfile;
081:            /** Holds the system logger. */
082:            private ScreenLogger logger;
083:
084:            /** Default constructor. Builds a classfile database for obfuscation.
085:             */
086:            public GuardDB() {
087:                logfile = FileLogger.getInstance();
088:                logger = ScreenLogger.getInstance();
089:                setScriptFile(null);
090:            }
091:
092:            /** Stores the script file to use for the obfuscation.
093:             * @param scriptFile the script file to use for the obfuscation
094:             */
095:            public void setScriptFile(ScriptFile scriptFile) {
096:                this .scriptFile = scriptFile;
097:            }
098:
099:            /** Returns the script file to use for the obfuscation.
100:             * @return script file; may be null
101:             * @see #setScriptFile
102:             */
103:            private ScriptFile getScriptFile() {
104:                return scriptFile;
105:            }
106:
107:            /** Sets the list of input Jar files and directories files to obfuscate.
108:             * @param jars a vector that holds the list of input Jar files to obfuscate
109:             * @param dirs a vector that holds a list of input directories; must have the
110:             * same size number of elements as the file filter vector
111:             * @param filters a vector that holds a list of file filter expressions; must
112:             * have the same number of elements as the directories vector
113:             * @throws IllegalArgumentException if the directory and file filter vectors
114:             * don't have the same size
115:             */
116:            public void setInput(Vector jars, Vector dirs, Vector filters)
117:                    throws IllegalArgumentException {
118:                inputJars = jars;
119:                if ((null == dirs && null != filters)
120:                        || (null != dirs && null == filters)
121:                        || (null != dirs && null != filters && dirs.size() != filters
122:                                .size())) {
123:                    throw new IllegalArgumentException(
124:                            "Directory and file filter vectors must have the same size");
125:                }
126:                inputDirs = dirs;
127:                inputFileFilters = filters;
128:            }
129:
130:            /** Returns the list of input Jar files to obfuscate.
131:             * @return list of input Jar files; always a valid vector (may be empty)
132:             * @see #setInput
133:             */
134:            private Vector getInputJars() {
135:                if (null == inputJars) {
136:                    inputJars = new Vector();
137:                }
138:                return inputJars;
139:            }
140:
141:            /** Returns the list of input directories that contain files to obfuscate.
142:             * @return list of directories; always a valid vector (may be empty)
143:             * @see #setInput
144:             */
145:            private Vector getInputDirs() {
146:                if (null == inputDirs) {
147:                    inputDirs = new Vector();
148:                }
149:                return inputDirs;
150:            }
151:
152:            /** Returns the list of file filter expressions for the input directories.
153:             * @return list of file filter expressions; always a valid vector (may be
154:             * empty)
155:             * @see #setInput
156:             */
157:            private Vector getInputFileFilters() {
158:                if (null == inputFileFilters) {
159:                    inputFileFilters = new Vector();
160:                }
161:                return inputFileFilters;
162:            }
163:
164:            /** Sets the output Jar file.
165:             * @param file the output Jar file; must not be null
166:             */
167:            public void setOutputFile(File file) {
168:                outputFile = file;
169:            }
170:
171:            /** Returns the output Jar file.
172:             * @return output Jar file; may be null
173:             * @see #setOutputFile
174:             */
175:            private File getOutputFile() {
176:                return outputFile;
177:            }
178:
179:            /** Reads all class files from the Jar files and the local directories and
180:             * builds the classfile database.
181:             * @param dump true if the parsed class tree should be dumped to the console
182:             * before it is obfuscated; false else
183:             * @throws IOException if an I/O error occurs
184:             * @throws MalformedPatternException if an error occurs during the compilation
185:             * of regular expressions
186:             */
187:            public void obfuscate(boolean dump) throws IOException,
188:                    MalformedPatternException {
189:                logger.log("Building the file containers...");
190:
191:                // first create the output container
192:                OutputContainer oc = new OutputContainer(getOutputFile());
193:
194:                // add the file containers for all Jar files
195:                Vector jars = getInputJars();
196:                for (int i = 0; i < jars.size(); i++) {
197:                    FileContainer fc = new JarFileContainer(new JarFile(
198:                            (File) jars.elementAt(i)));
199:                    oc.addFileContainer(fc);
200:                }
201:
202:                // add the file containers for all local directories
203:                Vector dirs = getInputDirs();
204:                Vector fileFilters = getInputFileFilters();
205:                for (int i = 0; i < dirs.size(); i++) {
206:                    FileContainer fc = new LocalDirectoryFileContainer(
207:                            (File) dirs.elementAt(i), (String) fileFilters
208:                                    .elementAt(i));
209:                    oc.addFileContainer(fc);
210:                }
211:
212:                // walk through all file sets and remove duplicate entries
213:                Vector vec = oc.getFileContainers();
214:                for (int i = 0; i < vec.size(); i++) {
215:                    FileContainer fc = (FileContainer) vec.elementAt(i);
216:                    for (int j = i + 1; j < vec.size(); j++) {
217:                        FileContainer other = (FileContainer) vec.elementAt(j);
218:                        other.removeDuplicates(fc);
219:                    }
220:                }
221:
222:                addOutputContainer(oc);
223:                startObfuscate(getOutputContainers(), dump);
224:            }
225:
226:            /** Starts the obfuscation process for the given list of output containers.
227:             * @param vec a vector that holds output containers; may not be null
228:             * @param dump true if the parsed class tree should be dumped to the console
229:             * before it is obfuscated; false else
230:             * @throws IOException if an I/O error occurs
231:             * @throws MalformedPatternException if an error occurs during the compilation
232:             * of regular expressions
233:             */
234:            private void startObfuscate(Vector vec, boolean dump)
235:                    throws IOException, MalformedPatternException {
236:                // obfuscate each output container
237:                Iterator iter = vec.iterator();
238:                while (iter.hasNext()) {
239:                    // first build a new class tree
240:                    ClassTree classTree = new ClassTree();
241:                    ClassFile.resetDangerHeader();
242:                    parseScriptFile(classTree);
243:
244:                    OutputContainer oc = (OutputContainer) iter.next();
245:                    // add all classes from the file containers to the class tree
246:                    Vector fileContainers = oc.getFileContainers();
247:                    logger.log("Building the class tree...");
248:                    for (int j = 0; j < fileContainers.size(); j++) {
249:                        FileContainer fc = (FileContainer) fileContainers
250:                                .elementAt(j);
251:                        logger.log(Log.INFO, "Reading the contents from '"
252:                                + fc.getName() + "'");
253:                        addClasses(classTree, fc, dump);
254:                    }
255:
256:                    // write out a log header
257:                    writeLogHeader(getOutputFile().getName(), fileContainers);
258:                    // generate the mapping table for the class tree
259:                    generateMappingTable(classTree);
260:                    // log the mapping table to the log file
261:                    writeMappingTable(classTree);
262:
263:                    // create the output stream for the obfuscated Jar file
264:                    JarOutputStream jos = new JarOutputStream(
265:                            new BufferedOutputStream(new FileOutputStream(oc
266:                                    .getOutputFile())));
267:                    jos.setComment(Version.getJarComment());
268:
269:                    // obfuscate all entries in the file containers
270:                    for (int j = 0; j < fileContainers.size(); j++) {
271:                        FileContainer fc = (FileContainer) fileContainers
272:                                .elementAt(j);
273:                        obfuscateFiles(jos, classTree, fc, oc
274:                                .getManifestContainer());
275:                    }
276:
277:                    // Finally, write the new manifest file
278:                    JarEntry outEntry = new JarEntry(STREAM_NAME_MANIFEST);
279:                    jos.putNextEntry(outEntry);
280:                    DataOutputStream manifest = new DataOutputStream(
281:                            new BufferedOutputStream(jos));
282:                    oc.getManifestContainer().write(manifest);
283:                    jos.closeEntry();
284:
285:                    // finally close the output Jar file
286:                    jos.close();
287:
288:                    // finally print warnings
289:                    logfile.printMethodWarnings();
290:                    logfile.printWarnings();
291:                }
292:            }
293:
294:            /** Go through database marking certain entities for retention, while
295:             * maintaining polymorphic integrity.
296:             * @param classTree the class tree to which the script file entries are
297:             * applied
298:             * @throws MalformedPatternException if an error occurs during the compilation
299:             * of regular expressions
300:             * @throws IllegalArgumentException if a script entry contains an illegal type
301:             */
302:            public void parseScriptFile(ClassTree classTree)
303:                    throws MalformedPatternException, IllegalArgumentException {
304:                if (null != getScriptFile()) {
305:                    Iterator iterator = getScriptFile().iterator();
306:                    // Enumerate the entries in the script file
307:                    while (iterator.hasNext()) {
308:                        ScriptEntry entry = (ScriptEntry) iterator.next();
309:
310:                        switch (entry.getType()) {
311:                        case ScriptConstants.TYPE_ATTRIBUTE:
312:                        case ScriptConstants.TYPE_RENAME:
313:                        case ScriptConstants.TYPE_PRESERVE:
314:                            classTree.retainAttribute(entry);
315:                            break;
316:
317:                        case ScriptConstants.TYPE_PACKAGE:
318:                        case ScriptConstants.TYPE_PACKAGE_MAP:
319:                        case ScriptConstants.TYPE_CLASS:
320:                        case ScriptConstants.TYPE_CLASS_MAP:
321:                        case ScriptConstants.TYPE_METHOD:
322:                        case ScriptConstants.TYPE_METHOD_MAP:
323:                        case ScriptConstants.TYPE_FIELD:
324:                        case ScriptConstants.TYPE_FIELD_MAP:
325:                            addMapping(entry);
326:                            break;
327:
328:                        case ScriptConstants.TYPE_IGNORE:
329:                            classTree.addIgnoreDefaultRegex(entry.getName());
330:                            break;
331:
332:                        case ScriptConstants.TYPE_IGNORE_PACKAGE:
333:                            classTree.addIgnorePackageRegex(entry.getName());
334:                            break;
335:
336:                        case ScriptConstants.TYPE_IGNORE_CLASS:
337:                            classTree.addIgnoreClassRegex(entry.getName());
338:                            break;
339:
340:                        case ScriptConstants.TYPE_IGNORE_METHOD:
341:                            classTree.addIgnoreMethodRegex(entry);
342:                            break;
343:
344:                        case ScriptConstants.TYPE_IGNORE_FIELD:
345:                            classTree.addIgnoreFieldRegex(entry);
346:                            break;
347:
348:                        case ScriptConstants.TYPE_OBFUSCATE:
349:                            classTree.addObfuscateDefaultRegex(entry.getName());
350:                            break;
351:
352:                        case ScriptConstants.TYPE_OBFUSCATE_PACKAGE:
353:                            classTree.addObfuscatePackageRegex(entry.getName());
354:                            break;
355:
356:                        case ScriptConstants.TYPE_OBFUSCATE_CLASS:
357:                            classTree.addObfuscateClassRegex(entry.getName());
358:                            break;
359:
360:                        case ScriptConstants.TYPE_OBFUSCATE_METHOD:
361:                            classTree.addObfuscateMethodRegex(entry);
362:                            break;
363:
364:                        case ScriptConstants.TYPE_OBFUSCATE_FIELD:
365:                            classTree.addObfuscateFieldRegex(entry);
366:                            break;
367:
368:                        default:
369:                            // should never happen because we've already parsed the script
370:                            throw new IllegalArgumentException(
371:                                    "Illegal type in script file");
372:                        }
373:                    }
374:                }
375:            }
376:
377:            /** Adds the files from the given file container to the internal class
378:             * database.
379:             * @param classTree the class tree to which the available classes from the
380:             * file container may be added
381:             * @param fc the file container
382:             * @param dump true if the parsed class tree should be dumped to the console
383:             */
384:            private void addClasses(ClassTree classTree, FileContainer fc,
385:                    boolean dump) {
386:                Enumeration enumeration = fc.enumeration();
387:                while (enumeration.hasMoreElements()) {
388:                    FileEntry entry = (FileEntry) enumeration.nextElement();
389:                    // only add the next entry if it is a class file
390:                    if (entry.isClassFile()) {
391:                        DataInputStream dis = entry.getInputStream();
392:                        ClassFile cf = null;
393:                        try {
394:                            cf = ClassFile.create(classTree, dis);
395:                        } catch (IOException ioex) {
396:                            logger.println("Error: " + ioex.getMessage());
397:                            logger.printStackTrace(ioex);
398:                            logfile.println("# ERROR - corrupt class file: "
399:                                    + entry.getName());
400:                            logfile.printStackTrace(ioex);
401:                        } finally {
402:                            try {
403:                                dis.close();
404:                            } catch (IOException ioex) {
405:                                // ignored here
406:                            }
407:                        }
408:
409:                        // Check the class file for references to "dangerous" methods
410:                        cf.logDangerousMethods();
411:                        classTree.addClassFile(cf);
412:                        if (dump) {
413:                            PrintWriter pw = new PrintWriter(System.out);
414:                            cf.dump(pw);
415:                            //pw.close();
416:                        }
417:                    }
418:                }
419:            }
420:
421:            /** Generates the mapping table for the obfuscation step.
422:             * @param classTree the class tree for which the mapping table should be
423:             * generated
424:             * @throws MalformedPatternException If the compiled expression does not
425:             * conform to the grammar understood by the PatternCompiler or if some other
426:             * error in the expression is encountered.
427:             */
428:            private void generateMappingTable(ClassTree classTree)
429:                    throws MalformedPatternException {
430:                logger
431:                        .log("Generating the mapping table for the whole class tree...");
432:
433:                // before we generate obfuscated names we check which classes, fields etc.
434:                // must be obfuscated and which should be ignored.
435:                classTree.parseObfuscateAndIgnoreList();
436:
437:                // now try to retain remote classes (if specified)
438:                classTree.markRemoteClasses();
439:
440:                // retain all marked mappings
441:                classTree.retainMappings(getMappings());
442:
443:                // retain additional fields, methods and classes
444:                classTree.retainHardcodedReferences();
445:                classTree.retainSerializableElements();
446:
447:                // Traverse the class tree, generating obfuscated names within
448:                // package and class namespaces
449:                classTree.generateNames();
450:
451:                // rename classes that need special treatment
452:                classTree.retainRemoteClasses();
453:
454:                // Resolve the polymorphic dependencies of each class, generating
455:                // non-private method and field names for each namespace
456:                classTree.resolveClasses();
457:            }
458:
459:            /** Obfuscate all entries in the file container.
460:             * @param jos the Jar file output stream
461:             * @param classTree the class tree the file container belongs to
462:             * @param fileContainer the file container that holds all input files
463:             * @param manifestContainer the manifest container that manages the Manifest
464:             * file
465:             * @throws IOException if an I/O error occurs
466:             */
467:            private void obfuscateFiles(JarOutputStream jos,
468:                    ClassTree classTree, FileContainer fileContainer,
469:                    ManifestContainer manifestContainer) throws IOException {
470:                logger.log(Log.INFO,
471:                        "Obfuscating the entries in the file container: "
472:                                + fileContainer.getName());
473:
474:                // Go through the file container, remove attributes and rename the constant
475:                // pool for each class file. Other files are renamed only if the user
476:                // wishes to do so, but apart from this they are copied through unchanged.
477:                // Manifest and signature files are deleted, and a new Manifest file is
478:                // generated.
479:                Enumeration enumeration = fileContainer.enumeration();
480:                while (enumeration.hasMoreElements()) {
481:                    FileEntry entry = (FileEntry) enumeration.nextElement();
482:                    // Open the entry and prepare to process it
483:                    DataInputStream inStream = entry.getInputStream();
484:                    try {
485:                        if (entry.isClassFile()) {
486:                            // Write the obfuscated version of the class to the output Jar
487:                            ClassFile cf = ClassFile
488:                                    .create(classTree, inStream);
489:                            cf.remap(classTree);
490:                            logger.log(Log.DEBUG, "Reading:     "
491:                                    + entry.getName());
492:                            logger.log(Log.DEBUG, "  -> writing "
493:                                    + cf.getName() + CLASS_EXT);
494:                            JarEntry outEntry = new JarEntry(cf.getName()
495:                                    + CLASS_EXT);
496:                            jos.putNextEntry(outEntry);
497:
498:                            // Create an OutputStream piped through a number of digest generators for the manifest
499:                            MessageDigest shaDigest = MessageDigest
500:                                    .getInstance("SHA-1");
501:                            MessageDigest md5Digest = MessageDigest
502:                                    .getInstance("MD5");
503:                            DataOutputStream classOutputStream = new DataOutputStream(
504:                                    new DigestOutputStream(
505:                                            new BufferedOutputStream(
506:                                                    new DigestOutputStream(jos,
507:                                                            shaDigest)),
508:                                            md5Digest));
509:
510:                            // Dump the classfile, while creating the digests
511:                            cf.write(classOutputStream);
512:                            classOutputStream.flush();
513:                            jos.closeEntry();
514:
515:                            // Now update the manifest entry for the class with new name and new digests
516:                            MessageDigest[] digests = { shaDigest, md5Digest };
517:                            manifestContainer.updateManifest(entry.getName(),
518:                                    cf.getName() + CLASS_EXT, digests);
519:                        } else {
520:                            // Copy the non-class entry (resource file)
521:                            long size = entry.getSize();
522:                            if (size != -1) {
523:                                byte[] bytes = new byte[(int) size];
524:                                inStream.readFully(bytes);
525:                                String outName = classTree
526:                                        .getOutputFileName(entry.getName());
527:                                if (!entry.getName().equals(outName)) {
528:                                    logfile.log(Log.VERBOSE,
529:                                            "# renaming resource: "
530:                                                    + entry.getName() + " -> "
531:                                                    + outName);
532:                                }
533:                                logger.log(Log.DEBUG, "Reading:     "
534:                                        + entry.getName());
535:                                logger
536:                                        .log(Log.DEBUG, "  -> writing "
537:                                                + outName);
538:                                JarEntry outEntry = new JarEntry(outName);
539:                                jos.putNextEntry(outEntry);
540:
541:                                // Create an OutputStream piped through a number of digest generators for the manifest
542:                                MessageDigest shaDigest = MessageDigest
543:                                        .getInstance("SHA");
544:                                MessageDigest md5Digest = MessageDigest
545:                                        .getInstance("MD5");
546:                                DataOutputStream dataOutputStream = new DataOutputStream(
547:                                        new DigestOutputStream(
548:                                                new BufferedOutputStream(
549:                                                        new DigestOutputStream(
550:                                                                jos, shaDigest)),
551:                                                md5Digest));
552:
553:                                // Dump the data, while creating the digests
554:                                dataOutputStream.write(bytes, 0, bytes.length);
555:                                dataOutputStream.flush();
556:                                jos.closeEntry();
557:
558:                                // Now update the manifest entry for the entry with new name and new digests
559:                                MessageDigest[] digests = { shaDigest,
560:                                        md5Digest };
561:                                manifestContainer.updateManifest(entry
562:                                        .getName(), outName, digests);
563:                            }
564:                        }
565:                    } catch (NoSuchAlgorithmException nae) {
566:                        logger.println("Cannot find message digest algorithm:");
567:                        logger.println(nae.getMessage());
568:                        logger.printStackTrace(nae);
569:                        // ignore that
570:                    } finally {
571:                        if (inStream != null) {
572:                            inStream.close();
573:                        }
574:                    }
575:                }
576:            }
577:
578:            /** Writes a header out to the log file.
579:             * @param outName the name of the output Jar file
580:             * @param vec a vector containing the file containers used for the obfuscation
581:             */
582:            private void writeLogHeader(String outName, Vector vec) {
583:                logger.log(Log.INFO, "Writing log header...");
584:                logfile
585:                        .println("# If this log is to be used for incremental obfuscation / patch generation, ");
586:                logfile
587:                        .println("# add any '.class', '.method', '.field' and '.attribute' restrictions here:");
588:                logfile.println();
589:                logfile.println();
590:                logfile
591:                        .println("#-DO-NOT-EDIT-BELOW-THIS-LINE------------------DO-NOT-EDIT-BELOW-THIS-LINE--");
592:                logfile.println("#");
593:                logfile.println("# JavaGuard Bytecode Obfuscator, version "
594:                        + Version.getVersion());
595:                logfile.println("#");
596:                logfile
597:                        .println("# Logfile created on "
598:                                + new Date().toString());
599:                logfile.println("#");
600:                if (null != vec) {
601:                    for (int i = 0; i < vec.size(); i++) {
602:                        FileContainer fc = (FileContainer) vec.elementAt(i);
603:                        logfile.println("# Input taken for obfuscation: "
604:                                + fc.getName());
605:                    }
606:                }
607:                logfile.println("# Output Jar file:             " + outName);
608:                logfile.println("# JavaGuard script file used:          "
609:                        + (null != getScriptFile() ? getScriptFile().getName()
610:                                : "(none, defaults used)"));
611:                logfile.println("#");
612:                logfile.println();
613:            }
614:
615:            /** Write the obfuscation steps to the log file.
616:             * @param classTree the class tree whose mapping table should be written
617:             * @see ClassTree#dump
618:             */
619:            private void writeMappingTable(ClassTree classTree) {
620:                // Write the memory usage at this point to the log file
621:                Runtime rt = Runtime.getRuntime();
622:                rt.gc();
623:                logfile.println();
624:                logfile.println("#");
625:                logfile
626:                        .println("# Memory in use after class data structure built: "
627:                                + Long.toString(rt.totalMemory()
628:                                        - rt.freeMemory()) + " bytes");
629:                logfile
630:                        .println("# Total memory available                        : "
631:                                + Long.toString(rt.totalMemory()) + " bytes");
632:                logfile.println("#");
633:
634:                // Write the name frequency and name mapping table to the log file
635:                logfile.println();
636:                classTree.dump();
637:            }
638:
639:            /** Returns the vector that holds the package, class, method and field
640:             * mapping entries from the script file.
641:             * @return vector that contains the script file entries; always non-null
642:             */
643:            private Vector getMappings() {
644:                if (null == mappings) {
645:                    mappings = new Vector();
646:                }
647:                return mappings;
648:            }
649:
650:            /** Adds an element to the list of mapping entries.
651:             * @param entry the entry from the script file
652:             * @see #getMappings
653:             */
654:            private void addMapping(ScriptEntry entry) {
655:                getMappings().addElement(entry);
656:            }
657:
658:            /** Returns the vector that stores all output containers.
659:             * @return vector with output containers; always non-null
660:             * @see #addOutputContainer
661:             */
662:            private Vector getOutputContainers() {
663:                if (null == outputContainers) {
664:                    outputContainers = new Vector();
665:                }
666:                return outputContainers;
667:            }
668:
669:            /** Adds a new output container to the list of all available output
670:             * containers.
671:             * @param oc the output container to add
672:             * @see #getOutputContainers
673:             */
674:            private void addOutputContainer(OutputContainer oc) {
675:                getOutputContainers().addElement(oc);
676:            }
677:
678:            /** A manager class for output containers. Each output container holds a list
679:             * of file containers (that manage which input files may be put into the
680:             * output file), a manifest container (that maintains the Manifest file for
681:             * the output Jar file) and the assigned output file.
682:             */
683:            private static class OutputContainer {
684:                /** A vector that stores all assigned file containes. */
685:                private Vector fileContainers = new Vector();
686:                /** Manages the Manifest file. */
687:                private ManifestContainer manifestContainer = new ManifestContainer();
688:                /** Holds the output file. */
689:                private File outputFile;
690:
691:                /** Creates a new output container and assignes it to the given output
692:                 * Jar file.
693:                 * @param file the output Jar file
694:                 */
695:                OutputContainer(File file) {
696:                    this .outputFile = file;
697:                }
698:
699:                /** Adds a new file container to the internal list of file containers.
700:                 * @param fc the file container to add
701:                 * @see #getFileContainers
702:                 * @throws IOException if an I/O error occurs
703:                 */
704:                void addFileContainer(FileContainer fc) throws IOException {
705:                    getFileContainers().addElement(fc);
706:                    getManifestContainer().addManifest(fc.getManifest());
707:                }
708:
709:                /** Returns the vector that contains all assigned file containers.
710:                 * @return vector with file containers
711:                 * @see #addFileContainer
712:                 */
713:                Vector getFileContainers() {
714:                    return fileContainers;
715:                }
716:
717:                /** Returns the manifest container assigned to this object.
718:                 * @return manifest container
719:                 */
720:                ManifestContainer getManifestContainer() {
721:                    return manifestContainer;
722:                }
723:
724:                /** Returns the output file assigned to this object.
725:                 * @return the output file assigned to this object
726:                 */
727:                File getOutputFile() {
728:                    return outputFile;
729:                }
730:            }
731:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.