List of usage examples for org.apache.commons.compress.archivers.zip ZipArchiveEntry getMethod
public int getMethod()
From source file:cz.muni.fi.xklinec.zipstream.App.java
/** * Entry point. /* ww w .j a va 2 s.c o m*/ * * @param args * @throws FileNotFoundException * @throws IOException * @throws NoSuchFieldException * @throws ClassNotFoundException * @throws NoSuchMethodException */ public static void main(String[] args) throws FileNotFoundException, IOException, NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InterruptedException { OutputStream fos = null; InputStream fis = null; if ((args.length != 0 && args.length != 2)) { System.err.println(String.format("Usage: app.jar source.apk dest.apk")); return; } else if (args.length == 2) { System.err.println( String.format("Will use file [%s] as input file and [%s] as output file", args[0], args[1])); fis = new FileInputStream(args[0]); fos = new FileOutputStream(args[1]); } else if (args.length == 0) { System.err.println(String.format("Will use file [STDIN] as input file and [STDOUT] as output file")); fis = System.in; fos = System.out; } final Deflater def = new Deflater(9, true); ZipArchiveInputStream zip = new ZipArchiveInputStream(fis); // List of postponed entries for further "processing". List<PostponedEntry> peList = new ArrayList<PostponedEntry>(6); // Output stream ZipArchiveOutputStream zop = new ZipArchiveOutputStream(fos); zop.setLevel(9); // Read the archive ZipArchiveEntry ze = zip.getNextZipEntry(); while (ze != null) { ZipExtraField[] extra = ze.getExtraFields(true); byte[] lextra = ze.getLocalFileDataExtra(); UnparseableExtraFieldData uextra = ze.getUnparseableExtraFieldData(); byte[] uextrab = uextra != null ? uextra.getLocalFileDataData() : null; // ZipArchiveOutputStream.DEFLATED // // Data for entry byte[] byteData = Utils.readAll(zip); byte[] deflData = new byte[0]; int infl = byteData.length; int defl = 0; // If method is deflated, get the raw data (compress again). if (ze.getMethod() == ZipArchiveOutputStream.DEFLATED) { def.reset(); def.setInput(byteData); def.finish(); byte[] deflDataTmp = new byte[byteData.length * 2]; defl = def.deflate(deflDataTmp); deflData = new byte[defl]; System.arraycopy(deflDataTmp, 0, deflData, 0, defl); } System.err.println(String.format( "ZipEntry: meth=%d " + "size=%010d isDir=%5s " + "compressed=%07d extra=%d lextra=%d uextra=%d " + "comment=[%s] " + "dataDesc=%s " + "UTF8=%s " + "infl=%07d defl=%07d " + "name [%s]", ze.getMethod(), ze.getSize(), ze.isDirectory(), ze.getCompressedSize(), extra != null ? extra.length : -1, lextra != null ? lextra.length : -1, uextrab != null ? uextrab.length : -1, ze.getComment(), ze.getGeneralPurposeBit().usesDataDescriptor(), ze.getGeneralPurposeBit().usesUTF8ForNames(), infl, defl, ze.getName())); final String curName = ze.getName(); // META-INF files should be always on the end of the archive, // thus add postponed files right before them if (curName.startsWith("META-INF") && peList.size() > 0) { System.err.println( "Now is the time to put things back, but at first, I'll perform some \"facelifting\"..."); // Simulate som evil being done Thread.sleep(5000); System.err.println("OK its done, let's do this."); for (PostponedEntry pe : peList) { System.err.println( "Adding postponed entry at the end of the archive! deflSize=" + pe.deflData.length + "; inflSize=" + pe.byteData.length + "; meth: " + pe.ze.getMethod()); pe.dump(zop, false); } peList.clear(); } // Capturing interesting files for us and store for later. // If the file is not interesting, send directly to the stream. if ("classes.dex".equalsIgnoreCase(curName) || "AndroidManifest.xml".equalsIgnoreCase(curName)) { System.err.println("### Interesting file, postpone sending!!!"); PostponedEntry pe = new PostponedEntry(ze, byteData, deflData); peList.add(pe); } else { // Write ZIP entry to the archive zop.putArchiveEntry(ze); // Add file data to the stream zop.write(byteData, 0, infl); zop.closeArchiveEntry(); } ze = zip.getNextZipEntry(); } // Cleaning up stuff zip.close(); fis.close(); zop.finish(); zop.close(); fos.close(); System.err.println("THE END!"); }
From source file:at.spardat.xma.xdelta.JarDelta.java
/** * Entry to new name.//from www .ja v a 2 s . c o m * * @param source the source * @param name the name * @return the zip archive entry * @throws ZipException the zip exception */ public static ZipArchiveEntry entryToNewName(ZipArchiveEntry source, String name) throws ZipException { if (source.getName().equals(name)) return new ZipArchiveEntry(source); ZipArchiveEntry ret = new ZipArchiveEntry(name); byte[] extra = source.getExtra(); if (extra != null) { ret.setExtraFields(ExtraFieldUtils.parse(extra, true, ExtraFieldUtils.UnparseableExtraField.READ)); } else { ret.setExtra(ExtraFieldUtils.mergeLocalFileDataData(source.getExtraFields(true))); } ret.setInternalAttributes(source.getInternalAttributes()); ret.setExternalAttributes(source.getExternalAttributes()); ret.setExtraFields(source.getExtraFields(true)); ret.setCrc(source.getCrc()); ret.setMethod(source.getMethod()); ret.setSize(source.getSize()); return ret; }
From source file:com.taobao.android.builder.tools.zip.ZipUtils.java
public static List<String> unzip(final File zipFile, final String destination, String encoding, Map<String, ZipEntry> zipEntryMethodMap, boolean isRelativePath) { List<String> fileNames = new ArrayList<String>(); String dest = destination;/*from w w w . j a v a 2s . c om*/ if (!destination.endsWith(File.separator)) { dest = destination + File.separator; } ZipFile file; try { file = null; if (null == encoding) { file = new ZipFile(zipFile); } else { file = new ZipFile(zipFile, encoding); } Enumeration<ZipArchiveEntry> en = file.getEntries(); ZipArchiveEntry ze = null; while (en.hasMoreElements()) { ze = en.nextElement(); File f = new File(dest, ze.getName()); if (ze.isDirectory()) { f.mkdirs(); continue; } else { f.getParentFile().mkdirs(); InputStream is = file.getInputStream(ze); OutputStream os = new FileOutputStream(f); IOUtils.copy(is, os); is.close(); os.close(); fileNames.add(f.getAbsolutePath()); if (zipEntryMethodMap != null && ze.getMethod() == STORED) { zipEntryMethodMap.put(isRelativePath ? ze.getName() : f.getAbsolutePath(), ze); } } } file.close(); } catch (IOException e) { e.printStackTrace(); } return fileNames; }
From source file:brut.androlib.ApkDecoder.java
public void decode() throws AndrolibException, IOException { File outDir = getOutDir();//from w ww . ja v a 2 s .c o m if (!mForceDelete && outDir.exists()) { throw new OutDirExistsException(); } if (!mApkFile.isFile() || !mApkFile.canRead()) { throw new InFileNotFoundException(); } try { OS.rmdir(outDir); } catch (BrutException ex) { throw new AndrolibException(ex); } outDir.mkdirs(); LOGGER.info("Using Apktool " + Androlib.getVersion() + " on " + mApkFile.getName()); if (hasResources()) { Map<String, String> sdkInfo = mAndrolib.getResTable(mApkFile).getSdkInfo(); if (sdkInfo.get("targetSdkVersion") != null) { mApi = Integer.parseInt(sdkInfo.get("targetSdkVersion")); } setAnalysisMode(mAnalysisMode, true); // read the resources.arsc checking for STORED vs DEFLATE // this will determine whether we compress on rebuild or not. ZipExtFile zef = new ZipExtFile(mApkFile.getAbsolutePath()); ZipArchiveEntry ze = zef.getEntry("resources.arsc"); if (ze != null) { int compression = ze.getMethod(); mCompressResources = (compression == ZipEntry.DEFLATED); } zef.close(); switch (mDecodeResources) { case DECODE_RESOURCES_NONE: mAndrolib.decodeResourcesRaw(mApkFile, outDir); break; case DECODE_RESOURCES_FULL: mAndrolib.decodeResourcesFull(mApkFile, outDir, getResTable()); break; } } else { // if there's no resources.asrc, decode the manifest without looking // up attribute references if (hasManifest()) { switch (mDecodeResources) { case DECODE_RESOURCES_NONE: mAndrolib.decodeManifestRaw(mApkFile, outDir); break; case DECODE_RESOURCES_FULL: mAndrolib.decodeManifestFull(mApkFile, outDir, getResTable()); break; } } } if (hasSources()) { switch (mDecodeSources) { case DECODE_SOURCES_NONE: mAndrolib.decodeSourcesRaw(mApkFile, outDir, mDebug); break; case DECODE_SOURCES_SMALI: mAndrolib.decodeSourcesSmali(mApkFile, outDir, mDebug, mDebugLinePrefix, mBakDeb, mApi); break; case DECODE_SOURCES_JAVA: mAndrolib.decodeSourcesJava(mApkFile, outDir, mDebug); break; } } mAndrolib.decodeRawFiles(mApkFile, outDir); mAndrolib.decodeUnknownFiles(mApkFile, outDir, mResTable); mAndrolib.writeOriginalFiles(mApkFile, outDir); writeMetaFile(); }
From source file:cz.muni.fi.xklinec.zipstream.Mallory.java
/** * Returns true if given file name should be postponed (is modified in tampering process). * @param ze //from w w w . j av a2 s .com * @return */ public boolean isPostponed(ZipArchiveEntry ze) { final String curName = ze.getName(); if (curName.startsWith(META_INF) || CLASSES.equalsIgnoreCase(curName) || ANDROID_MANIFEST.equalsIgnoreCase(curName) || RESOURCES.equalsIgnoreCase(curName) || curName.endsWith(".xml") || (ze.getMethod() == ZipArchiveOutputStream.DEFLATED && curName.endsWith(".png"))) { return true; } if (exclude != null && !exclude.isEmpty()) { for (String regex : exclude) { if (curName.matches(regex)) { return true; } } } return false; }
From source file:cz.muni.fi.xklinec.zipstream.Mallory.java
/** * Reads tampered APK file (zip object is prepared for this file prior * this function call).//from w ww . j a v a2s .c o m * * If a) file differs or b) file is new, it is added to the output zip stream. * * Method also handles padding to a given size. Attribute padlen is used, * if addPadding is true, padlen bytes are distributed to {new, modiffied} * files in extra field in central directory. * * @param addPadding * @throws IOException */ public void mergeTamperedApk(boolean addPadding, boolean forReal) throws IOException { // Read the tampered archive ZipArchiveEntry ze = zip.getNextZipEntry(); Set<String> files = new HashSet<String>(); long padlenLeft = padlen; while (ze != null) { // Data for entry byte[] byteData = Utils.readAll(zip); byte[] deflData = new byte[0]; int defl = 0; long padd2add = -1; if (addPadding) { padd2add = compPadding(padlenLeft); } // If method is deflated, get the raw data (compress again). if (ze.getMethod() == ZipArchiveOutputStream.DEFLATED) { def.reset(); def.setInput(byteData); def.finish(); byte[] deflDataTmp = new byte[byteData.length * 2]; defl = def.deflate(deflDataTmp); deflData = new byte[defl]; System.arraycopy(deflDataTmp, 0, deflData, 0, defl); } final String curName = ze.getName(); PostponedEntry al = new PostponedEntry(ze, byteData, deflData); files.add(curName); // Compare posponed entry with entry in previous if (alMap.containsKey(curName) == false || alMap.get(curName) == null) { // This element is not in the archive at all! // Add it to the zop if (!quiet) System.err.println( "Detected newly added file [" + curName + "] written prior dump: " + zop.getWritten()); // Apply padding if (padd2add > 0) { addExtraPadding(al.ze, (int) padd2add); padlenLeft -= padd2add; if (!quiet) System.err.println(" Added padding: " + padd2add + "; left: " + padlenLeft); } al.dump(zop, recomputeCrc); } else { // Check the entry against the old entry hash // All files are read linary from the new APK file // thus it will be put to the archive in the right order. PostponedEntry oldEntry = alMap.get(curName); boolean wasPostponed = isPostponed(oldEntry.ze); if ((oldEntry.hashByte == null && al.hashByte != null) || (oldEntry.hashByte != null && oldEntry.hashByte.equals(al.hashByte) == false) || (defl > 0 && (oldEntry.hashDefl == null && al.hashDefl != null)) || (defl > 0 && (oldEntry.hashDefl != null && oldEntry.hashDefl.equals(al.hashDefl) == false))) { // Element was changed, add it to the zop // if (!quiet) { System.err.println( "Detected modified file [" + curName + "] written prior dump: " + zop.getWritten()); System.err.println(" t1=" + oldEntry.hashByte.equals(al.hashByte) + "; t2=" + oldEntry.hashDefl.equals(al.hashDefl)); } if (!wasPostponed && !quiet) { System.err.println( " Warning: This file was already sent to the victim (file was not postponed) !!!"); } // Apply padding if (padd2add > 0) { addExtraPadding(al.ze, (int) padd2add); padlenLeft -= padd2add; if (!quiet) System.err.println(" Added padding: " + padd2add + "; left: " + padlenLeft); } al.dump(zop, recomputeCrc); } else if (wasPostponed) { // File was not modified but is one of the postponed files, thus has to // be flushed also. if (!quiet) System.err.println("Postponed file not modified [" + curName + "] written prior dump: " + zop.getWritten()); // Apply padding if (padd2add > 0) { addExtraPadding(al.ze, (int) padd2add); padlenLeft -= padd2add; if (!quiet) System.err.println(" Added padding: " + padd2add + "; left: " + padlenLeft); } al.dump(zop, recomputeCrc); } } ze = zip.getNextZipEntry(); } // Check if some file from the original file is not in the modified file. if (forReal && !quiet) { // Iterate over map files and lookup the same among modified files. for (String oldFile : alMap.keySet()) { if (files.contains(oldFile) == false) { if (sentFiles.contains(oldFile)) { System.err.println("Warning: File from original file [" + oldFile + "] was not found in tampered file and file was already sent!!!"); } else { System.err.println("Warning: File from original file [" + oldFile + "] was not found in tampered file!"); } } } } // If omitMissing is specified, remove ZIP entries from ZOP that are not present // in tampered file (no signature for them). if (omitMissing) { List<ZipArchiveEntry> entries = zop.getEntries(); // Iterate over map files and lookup the same among modified files. for (String oldFile : alMap.keySet()) { if (files.contains(oldFile) == false) { if (!sentFiles.contains(oldFile)) { continue; } // Remove from ZOP entries list - will be not added to central directory if (alMap.containsKey(oldFile) == false) { if (!quiet) { System.err.println("Warning: File from original file [" + oldFile + "] was not found in tampered file and file was already sent, no ZIP entry!!!"); } continue; } boolean deleted = false; // Delete file based on filename (do not rely on .equals()). Iterator<ZipArchiveEntry> it = entries.iterator(); while (it.hasNext()) { ZipArchiveEntry tmpZe = it.next(); if (tmpZe.getName().equals(oldFile)) { it.remove(); deleted = true; break; } } if (!quiet) { System.err.println( "Removed [" + deleted + "] File [" + oldFile + "] remove from zip entries."); } } } } if (!quiet && addPadding && padlenLeft > 0) { System.err.println("Warning! Not enough modified files to add required padding. Left: " + padlenLeft + "/" + padlen); } }
From source file:cz.muni.fi.xklinec.zipstream.Mallory.java
/** * Entry point. //from www .ja v a 2 s . co m * * @param args * @throws FileNotFoundException * @throws IOException * @throws NoSuchFieldException * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws java.lang.InterruptedException * @throws java.lang.CloneNotSupportedException */ public void doMain(String[] args) throws FileNotFoundException, IOException, NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InterruptedException, CloneNotSupportedException { // command line argument parser CmdLineParser parser = new CmdLineParser(this); // if you have a wider console, you could increase the value; // here 80 is also the default parser.setUsageWidth(80); try { // parse the arguments. parser.parseArgument(args); } catch (CmdLineException e) { // if there's a problem in the command line, // you'll get this exception. this will report // an error message. System.err.println(e.getMessage()); System.err.println("java Mallory [options...] arguments..."); // print the list of available options parser.printUsage(System.err); System.err.println(); // print option sample. This is useful some time System.err.println(" Example: java Mallory " + parser.printExample(ExampleMode.ALL)); return; } if (arguments.size() == 2) { final String a0 = arguments.get(0); final String a1 = arguments.get(1); if (!quiet) System.err .println(String.format("Will use file [%s] as input file and [%s] as output file", a0, a1)); fis = new FileInputStream(a0); fos = new FileOutputStream(a1); } else if (arguments.isEmpty()) { if (!quiet) System.err .println(String.format("Will use file [STDIN] as input file and [STDOUT] as output file")); fis = System.in; fos = System.out; } else { if (!quiet) System.err.println("I do not understand the usage."); return; } if (zipAlign) { System.err.println("WARNING: ZIP Align feature not implemented yet..."); return; } // Deflater to re-compress uncompressed data read from ZIP stream. def = new Deflater(9, true); sentFiles = new HashSet<String>(); // Buffer input stream so input stream is read in chunks bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); // Effective temporary dir - if separate is required if (separateTempDir) { effectiveTempDir = File.createTempFile("temp_apk_dir_", "", new File(TEMP_DIR)); effectiveTempDir.delete(); effectiveTempDir.mkdir(); } else { effectiveTempDir = new File(TEMP_DIR); } // Generate temporary APK filename tempApk = File.createTempFile("temp_apk_", ".apk", effectiveTempDir); if (tempApk.canWrite() == false) { throw new IOException("Temp file is not writable!"); } FileOutputStream tos = new FileOutputStream(tempApk); // What we want here is to read input stream from the socket/pipe // whatever, process it in ZIP logic and simultaneously to copy // all read data to the temporary file - this reminds tee command // logic. This functionality can be found in TeeInputStream. TeeInputStream tis = new TeeInputStream(bis, tos); // Providing tis to ZipArchiveInputStream will copy all read data // to temporary tos file. zip = new ZipArchiveInputStream(tis); // List of all sent files, with data and hashes alMap = new HashMap<String, PostponedEntry>(); // Output stream // If there is defined slow down stream, it is used for user output to // mitigate tampering time gap. OutputStream osToUse = bos; SlowDownStream sdStream = null; if (slowDownStream) { // New slow down output stream with internal pipe buffer 15MB. sdStream = new SlowDownStream(osToUse, 15 * 1024 * 1024); // If size of the APK is known, use it to set slow down parameters correctly. if (apkSize > 0) { setSlowDownParams(); } if (!quiet) { System.err.println(String.format("Slown down stream will be used; apkSize=%d buffer=%d timeout=%d", apkSize, slowDownBuffer, slowDownTimeout)); } sdStream.setFlushBufferSize(slowDownBuffer); sdStream.setFlushBufferTimeout(slowDownTimeout); sdStream.start(); osToUse = sdStream; } zop = new ZipArchiveOutputStream(osToUse); zop.setLevel(9); if (!quiet) { System.err.println("Patterns that will be excluded:"); for (String regex : exclude) { System.err.println(" '" + regex + "'"); } System.err.println(); } // Read the archive ZipArchiveEntry ze = zip.getNextZipEntry(); while (ze != null) { ZipExtraField[] extra = ze.getExtraFields(true); byte[] lextra = ze.getLocalFileDataExtra(); UnparseableExtraFieldData uextra = ze.getUnparseableExtraFieldData(); byte[] uextrab = uextra != null ? uextra.getLocalFileDataData() : null; byte[] ex = ze.getExtra(); // ZipArchiveOutputStream.DEFLATED // // Data for entry byte[] byteData = Utils.readAll(zip); byte[] deflData = new byte[0]; int infl = byteData.length; int defl = 0; // If method is deflated, get the raw data (compress again). // Since ZIPStream automatically decompresses deflated files in read(). if (ze.getMethod() == ZipArchiveOutputStream.DEFLATED) { def.reset(); def.setInput(byteData); def.finish(); byte[] deflDataTmp = new byte[byteData.length * 2]; defl = def.deflate(deflDataTmp); deflData = new byte[defl]; System.arraycopy(deflDataTmp, 0, deflData, 0, defl); } if (!quiet) System.err.println(String.format( "ZipEntry: meth=%d " + "size=%010d isDir=%5s " + "compressed=%07d extra=%d lextra=%d uextra=%d ex=%d " + "comment=[%s] " + "dataDesc=%s " + "UTF8=%s " + "infl=%07d defl=%07d " + "name [%s]", ze.getMethod(), ze.getSize(), ze.isDirectory(), ze.getCompressedSize(), extra != null ? extra.length : -1, lextra != null ? lextra.length : -1, uextrab != null ? uextrab.length : -1, ex != null ? ex.length : -1, ze.getComment(), ze.getGeneralPurposeBit().usesDataDescriptor(), ze.getGeneralPurposeBit().usesUTF8ForNames(), infl, defl, ze.getName())); final String curName = ze.getName(); // Store zip entry to the map for later check after the APK is recompiled. // Hashes will be compared with the modified APK files after the process. PostponedEntry al = new PostponedEntry(ze, byteData, deflData); alMap.put(curName, al); // META-INF files should be always on the end of the archive, // thus add postponed files right before them if (isPostponed(ze)) { // Capturing interesting files for us and store for later. // If the file is not interesting, send directly to the stream. if (!quiet) System.err.println(" Interesting file, postpone sending!!!"); } else { // recompute CRC? if (recomputeCrc) { crc.reset(); crc.update(byteData); final long newCrc = crc.getValue(); if (!quiet && ze.getCrc() != newCrc && ze.getCrc() != -1) { System.err.println(" Warning: file CRC mismatch!!! Original: [" + ze.getCrc() + "] real: [" + newCrc + "]"); } ze.setCrc(newCrc); } // Write ZIP entry to the archive zop.putArchiveEntry(ze); // Add file data to the stream zop.write(byteData, 0, infl); zop.closeArchiveEntry(); zop.flush(); // Mark file as sent. addSent(curName); } ze = zip.getNextZipEntry(); } // Flush buffers zop.flush(); fos.flush(); // Cleaning up stuff, all reading streams can be closed now. zip.close(); bis.close(); fis.close(); tis.close(); tos.close(); // // APK is finished here, all non-interesting files were sent to the // zop strem (socket to the victim). Now APK transformation will // be performed, diff, sending rest of the files to zop. // boolean doPadding = paddExtra > 0 || outBytes > 0; long flen = tempApk.length(); if (outBytes <= 0) { outBytes = flen + paddExtra; } if (!quiet) { System.err.println("\nAPK reading finished, going to tamper downloaded " + " APK file [" + tempApk.toString() + "]; filezise=[" + flen + "]"); System.err.println(String.format("Sent so far: %d kB in %f %% after adding padding it is %f %%", zop.getWritten() / 1024, 100.0 * (double) zop.getWritten() / (double) flen, 100.0 * (double) zop.getWritten() / ((double) (outBytes > 0 ? outBytes : flen)))); } // New APK was generated, new filename = "tempApk_tampered" newApk = new File(outFile == null ? getFileName(tempApk.getAbsolutePath()) : outFile); if (cmd == null) { // Simulation of doing some evil stuff on the temporary apk Thread.sleep(3000); if (!quiet) System.err.println( "Tampered APK file: " + " [" + newApk.toString() + "]; filezise=[" + newApk.length() + "]"); // // Since no tampering was performed right now we will simulate it by just simple // copying the APK file // FileUtils.copyFile(tempApk, newApk); } else { try { // Execute command String cmd2exec; switch (cmdFormat) { case 0: cmd2exec = cmd + " " + tempApk.getAbsolutePath(); break; case 1: cmd2exec = cmd.replaceAll(INPUT_APK_PLACEHOLDER, tempApk.getAbsolutePath()); break; case 2: cmd2exec = cmd.replaceAll(INPUT_APK_PLACEHOLDER, tempApk.getAbsolutePath()); cmd2exec = cmd2exec.replaceAll(OUTPUT_APK_PLACEHOLDER, newApk.getAbsolutePath()); break; default: throw new IllegalArgumentException("Unknown command format number"); } if (!quiet) { System.err.println("Command to be executed: " + cmd2exec); System.err.println("\n<CMDOUTPUT>"); } long cmdStartTime = System.currentTimeMillis(); CmdExecutionResult resExec = execute(cmd2exec, OutputOpt.EXECUTE_STD_COMBINE, null, quiet ? null : System.err); long cmdStopTime = System.currentTimeMillis(); if (!quiet) { System.err.println("</CMDOUTPUT>\n"); System.err.println("Command executed. Return value: " + resExec.exitValue + "; tamperingTime=" + (cmdStopTime - cmdStartTime)); } } catch (IOException e) { if (!quiet) e.printStackTrace(System.err); } } // // Now read new APK file with ZipInputStream and push new/modified files to the ZOP. // fis = new FileInputStream(newApk); bis = new BufferedInputStream(fis); zip = new ZipArchiveInputStream(bis); // Merge tampered APK to the final, but in this first time // do it to the external buffer in order to get final apk size. // Backup ZOP state to the clonned instance. zop.flush(); long writtenBeforeDiff = zop.getWritten(); ZipArchiveOutputStream zop_back = zop; zop = zop.cloneThis(); // Set temporary byte array output stream, so original output stream is not // touched in this phase. ByteArrayOutputStream bbos = new ByteArrayOutputStream(); zop.setOut(bbos); mergeTamperedApk(false, false); zop.flush(); // Now output stream almost contains APK file, central directory is not written yet. long writtenAfterDiff = zop.getWritten(); if (!quiet) System.err.println(String.format("Tampered apk size yet; writtenBeforeDiff=%d writtenAfterDiff=%d", writtenBeforeDiff, writtenAfterDiff)); // Write central directory header to temporary buffer to discover its size. zop.writeFinish(); zop.flush(); bbos.flush(); // Read new values long writtenAfterCentralDir = zop.getWritten(); long centralDirLen = zop.getCdLength(); byte[] buffAfterMerge = bbos.toByteArray(); //int endOfCentralDir = (int) (buffAfterMerge.length - (writtenAfterCentralDir-writtenBeforeDiff)); long endOfCentralDir = END_OF_CENTRAL_DIR_SIZE; // Determine number of bytes to add to APK. // padlen is number of bytes missing in APK to meet desired size in bytes. padlen = doPadding ? (outBytes - (writtenAfterCentralDir + endOfCentralDir)) : 0; // Compute number of files needed for padding. int padfiles = (int) Math.ceil((double) padlen / (double) (PAD_BLOCK_MAX)); if (!quiet) System.err.println(String.format("Remaining to pad=%d, padfiles=%d " + "writtenAfterCentralDir=%d " + "centralDir=%d endOfCentralDir=%d centralDirOffset=%d " + "buffSize=%d total=%d desired=%d ", padlen, padfiles, writtenAfterCentralDir, centralDirLen, endOfCentralDir, zop.getCdOffset(), buffAfterMerge.length, writtenAfterCentralDir + endOfCentralDir, outBytes)); if (padlen < 0) { throw new IllegalStateException("Padlen cannot be negative, please increase padding size"); } // Close input streams for tampered APK try { zip.close(); bis.close(); fis.close(); } catch (Exception e) { if (!quiet) e.printStackTrace(System.err); } // Merge again, now with pre-defined padding size. fis = new FileInputStream(newApk); bis = new BufferedInputStream(fis); zip = new ZipArchiveInputStream(bis); // Revert changes - use clonned writer stream. zop = zop_back; long writtenBeforeDiff2 = zop.getWritten(); // Merge tampered APK, now for real, now with computed padding. mergeTamperedApk(true, true); zop.flush(); long writtenAfterMerge2 = zop.getWritten(); // Finish really zop.finish(); zop.flush(); long writtenReally = zop.getWritten(); long centralDirLen2 = zop.getCdLength(); if (!quiet) System.err.println(String.format( "Write stats; " + "writtenBeforeDiff=%d writtenAfterDiff=%d " + "writtenAfterCentralDir=%d centralDir=%d endOfCd=%d centralDirOffset=%d " + "padlen=%d total=%d desired=%d", writtenBeforeDiff2, writtenAfterMerge2, writtenReally, centralDirLen2, endOfCentralDir, zop.getCdOffset(), padlen, writtenReally + endOfCentralDir, outBytes)); // Will definitelly close (and finish if not yet) ZOP stream // and close underlying stream. zop.close(); if (sdStream != null) { if (!quiet) { System.err.println("Waiting for sdStream to finish..."); } // Wait for stream to finish dumping with pre-set speed, if it takes // too long (1 minute) switch slown down stream to dumping mode // without any waiting. long startedDump = System.currentTimeMillis(); while (sdStream.isRunning()) { long curTime = System.currentTimeMillis(); if (startedDump != -1 && (curTime - startedDump) > 1000 * 120) { startedDump = -1; sdStream.flushPipes(); } Thread.sleep(10); } if (!quiet) { System.err.println("SD stream finished, terminating..."); } } // Should always be same if (!quiet && doPadding && writtenBeforeDiff != writtenBeforeDiff2) { System.err.println(String.format("Warning! Size before merge from pass1 and pass2 does not match.")); } // If size is different, something went wrong. if (!quiet && doPadding && ((writtenReally + endOfCentralDir) != outBytes)) { System.err.println(String.format("Warning! Output size differs from desired size.")); } bos.close(); fos.close(); // Delete temporary files if required if (deleteArtefacts) { try { if (newApk.exists()) { newApk.delete(); if (!quiet) System.err.println("Tampered APK removed. " + newApk.getAbsolutePath()); } if (tempApk.exists()) { tempApk.delete(); if (!quiet) System.err.println("Original APK removed. " + tempApk.getAbsolutePath()); } if (separateTempDir && effectiveTempDir.exists()) { FileUtils.deleteDirectory(effectiveTempDir); if (!quiet) System.err.println("Temporary directory removed. " + effectiveTempDir.getAbsolutePath()); } if (!quiet) System.err.println("Temporary files were removed."); } catch (IOException e) { if (!quiet) e.printStackTrace(System.err); } } if (!quiet) System.err.println("THE END!"); }
From source file:org.apache.ant.compress.resources.ZipResource.java
protected void setEntry(ArchiveEntry e) { super.setEntry(e); if (e != null) { ZipArchiveEntry ze = (ZipArchiveEntry) e; extras = ze.getExtraFields(true); method = ze.getMethod(); }//ww w . j a v a 2 s . c o m }
From source file:org.callimachusproject.behaviours.ZipArchiveSupport.java
public void validateZipAndClose(InputStream in) throws IOException { ZipArchiveInputStream zip = new ZipArchiveInputStream(in); try {/*w w w . jav a2 s . c o m*/ byte[] buf = new byte[1024]; ZipArchiveEntry entry = zip.getNextZipEntry(); if (entry == null) throw new BadRequest("Archive is empty"); do { entry.getName(); entry.getMethod(); entry.getSize(); while (zip.read(buf, 0, buf.length) >= 0) ; entry = zip.getNextZipEntry(); } while (entry != null); } finally { zip.close(); } }
From source file:org.codehaus.plexus.archiver.zip.ConcurrentJarCreator.java
/** * Adds an archive entry to this archive. * <p/>//from w ww . j av a2 s. c o m * This method is expected to be called from a single client thread * * @param zipArchiveEntry The entry to add. Compression method * @param source The source input stream supplier * @throws java.io.IOException */ public void addArchiveEntry(final ZipArchiveEntry zipArchiveEntry, final InputStreamSupplier source) throws IOException { final int method = zipArchiveEntry.getMethod(); if (method == -1) throw new IllegalArgumentException("Method must be set on the supplied zipArchiveEntry"); if (zipArchiveEntry.isDirectory() && !zipArchiveEntry.isUnixSymlink()) { final ByteArrayInputStream payload = new ByteArrayInputStream(new byte[] {}); directories.addArchiveEntry( createZipArchiveEntryRequest(zipArchiveEntry, createInputStreamSupplier(payload))); payload.close(); } else if ("META-INF".equals(zipArchiveEntry.getName())) { InputStream payload = source.get(); if (zipArchiveEntry.isDirectory()) zipArchiveEntry.setMethod(ZipEntry.STORED); metaInfDir.addArchiveEntry( createZipArchiveEntryRequest(zipArchiveEntry, createInputStreamSupplier(payload))); payload.close(); } else if ("META-INF/MANIFEST.MF".equals(zipArchiveEntry.getName())) { InputStream payload = source.get(); if (zipArchiveEntry.isDirectory()) zipArchiveEntry.setMethod(ZipEntry.STORED); manifest.addArchiveEntry( createZipArchiveEntryRequest(zipArchiveEntry, createInputStreamSupplier(payload))); payload.close(); } else { parallelScatterZipCreator.addArchiveEntry(zipArchiveEntry, source); } }