Example usage for org.apache.commons.compress.archivers.zip ZipArchiveEntry getMethod

List of usage examples for org.apache.commons.compress.archivers.zip ZipArchiveEntry getMethod

Introduction

In this page you can find the example usage for org.apache.commons.compress.archivers.zip ZipArchiveEntry getMethod.

Prototype

public int getMethod() 

Source Link

Document

Returns the compression method of this entry, or -1 if the compression method has not been specified.

Usage

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);
    }
}