JarWriter { public Path rewrite(Path _todir) throws JarAnalysisException { Path dir = _todir; Matcher matcher = null; JarEntry old_entry = null, new_entry = null; try { if (dir == null) dir = java.nio.file.Files.createTempDirectory("rewritten_jar_"); this.rewrittenFile = Paths.get(dir.toString(), this.getRewriteJarFileName().toString()).toFile(); if (this.rewrittenFile.exists()) { JarWriter.log.info( "The target [" + this.rewrittenFile + "] already exists, skip rewriting"); } else { final FileOutputStream fos = new FileOutputStream(this.rewrittenFile); final JarOutputStream jos = new JarOutputStream(fos, this.createModifiedManifest()); InputStream is = null; byte[] bytes = new byte[1024]; int bytes_read = 0; final Enumeration<JarEntry> en = this.originalJar.entries(); String class_name = null; JavaId jid = null; Set<JavaId> jids = new HashSet<JavaId>(); Set<String> written_jar_entries = new HashSet<String>(); while (en.hasMoreElements()) { old_entry = en.nextElement(); is = null; if (written_jar_entries.contains(old_entry.getName())) continue; if (old_entry.getName().equals("META-INF/MANIFEST.MF")) continue; if (old_entry.getName().startsWith("META-INF/") && (old_entry.getName().toLowerCase().endsWith(".sf") || old_entry.getName().toLowerCase().endsWith(".dsa") || old_entry.getName().toLowerCase().endsWith(".rsa"))) continue; for (Map.Entry<Pattern, JarEntryWriter> e : this.callbacks.entrySet()) { matcher = e.getKey().matcher(old_entry.getName()); if (matcher.matches()) { is = e.getValue().getInputStream(e.getKey().toString(), old_entry); } } if (is == null) is = this.originalJar.getInputStream(old_entry); if (old_entry.getAttributes() != null) JarWriter.log.debug( this.toString() + ": Entry [" + old_entry.getName() + "] has specific attributes"); new_entry = new JarEntry(old_entry.getName()); jos.putNextEntry(new_entry); while ((bytes_read = is.read(bytes)) != -1) jos.write(bytes, 0, bytes_read); jos.closeEntry(); written_jar_entries.add(new_entry.getName()); } for (Map.Entry<String, Path> e : this.additionalFiles.entrySet()) { if (e.getValue().toFile().exists()) { new_entry = new JarEntry(e.getKey()); jos.putNextEntry(new_entry); is = new FileInputStream(e.getValue().toFile()); while ((bytes_read = is.read(bytes)) != -1) jos.write(bytes, 0, bytes_read); is.close(); jos.closeEntry(); } } jos.flush(); jos.close(); this.originalJar.close(); old_entry = null; JarWriter.log.info( "[" + this.originalJar.getName() + "] rewritten to [" + this.rewrittenFile + "]"); } } catch (Exception ioe) { if (old_entry != null) throw new JarAnalysisException( "Error while writing JAR entry [" + old_entry.getName() + "] to modified JAR [" + this.rewrittenFile + "]: " + ioe.getMessage(), ioe); else throw new JarAnalysisException( "Error while writing modified JAR: " + ioe.getMessage(), ioe); } return this.rewrittenFile.toPath(); } JarWriter(Path _jar); long getFileSize(); long getInstrumentedFileSize(); Manifest getOriginalManifest(); Path extract(Path _todir); synchronized String getSHA1(); void skipManifestEntry(String _entry); void addManifestEntry(String _key, String _val); boolean hasManifestEntry(String _key); boolean isRewrittenByVulas(); void setClassifier(String _string); void register(String _regex, JarEntryWriter _writer); Path getOriginalJarFileName(); Path getRewriteJarFileName(); void addFiles(String _target_dir, Set<Path> _paths, boolean _overwrite); void addFile(String _target_dir, Path _path, boolean _overwrite); boolean hasEntry(String _entry_name); File getRewrittenJarFile(); Path rewrite(Path _todir); static final void appendToClasspath(
      Set<Path> _classpath, Set<Path> _to_append, boolean _preprocess); static final Path appendToClasspath(
      Set<Path> _classpath, Path _to_append, boolean _preprocess); final SimpleDateFormat dateFormat; static final String MANIFEST_ENTRY_VULAS_MODIF; static final String MANIFEST_ENTRY_ORIG_SHA1; }
@Test public void testRewrite() { try { final JarWriter jw = new JarWriter(Paths.get("./src/test/resources/examples.jar")); jw.addManifestEntry("Test", "JUnit test entry"); jw.setClassifier(StringUtil.getRandonString(6)); jw.addFile("", Paths.get("./src/test/resources/Callgraph.class"), true); jw.addFile("WEB-INF/lib", Paths.get("./src/test/resources/examples.jar"), true); assertEquals("F22A5E25F37455867B5C2CF476BAC25189AC2B28", jw.getSHA1()); jw.register(".*.class$", this); final Path rewritten = jw.rewrite(Paths.get("./target")); assertEquals(6, this.countCallbacks); final JarWriter jw2 = new JarWriter(rewritten); assertTrue(jw2.isRewrittenByVulas()); assertEquals("F22A5E25F37455867B5C2CF476BAC25189AC2B28", jw2.getSHA1()); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } }