alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (CreateBadJar.java)

This example Java source code file (CreateBadJar.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

arguments, censig, createbadjar, endhdr, fileinputstream, fileoutputstream, runtimeexception, string, util, where\'s, zip, zipentry, zipoutputstream

The CreateBadJar.java Java example source code

/*
 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * Borrowing significantly from Martin Buchholz's CorruptedZipFiles.java
 *
 * Needed a way of testing the checks for corrupt zip/jar entry in
 * inflate_file from file j2se/src/share/bin/parse_manifest.c
 * and running them with the 64-bit launcher. e.g.
 * sparcv9/bin/java -jar badjar.jar
 *
 * Run from a script driver Test6842838.sh as we want to specifically run
 * bin/sparcv9/java, the 64-bit launcher.
 *
 * So this program will create a zip file and damage it in the way
 * required to tickle this bug.
 *
 * It will cause a buffer overrun: but that will not always crash.
 * Use libumem preloaded by the script driver in order to
 * abort quickly when the overrun happens.  That makes the test
 * Solaris-specific.
 */

import java.util.*;
import java.util.zip.*;
import java.io.*;
import static java.lang.System.*;
import static java.util.zip.ZipFile.*;

public class CreateBadJar {

public static void main(String [] arguments) {

        if (arguments.length != 2) {
            throw new RuntimeException("Arguments: jarfilename entryname");
        }
        String outFile = arguments[0];
        String entryName = arguments[1];

        try {
        // If the named file doesn't exist, create it.
        // If it does, we are expecting it to contain the named entry, for
        // alteration.
        if (!new File(outFile).exists()) {
          System.out.println("Creating file " + outFile);

          // Create the requested zip/jar file.
          ZipOutputStream zos = null;
          zos = new ZipOutputStream(
            new FileOutputStream(outFile));

          ZipEntry e = new ZipEntry(entryName);
          zos.putNextEntry(e);
          for (int j=0; j<50000; j++) {
            zos.write((int)'a');
          }
          zos.closeEntry();
          zos.close();
          zos = null;
        }

        // Read it.
        int len = (int)(new File(outFile).length());
        byte[] good = new byte[len];
        FileInputStream fis = new FileInputStream(outFile);
        fis.read(good);
        fis.close();
        fis = null;

        int endpos = len - ENDHDR;
        int cenpos = u16(good, endpos+ENDOFF);
        if (u32(good, cenpos) != CENSIG) throw new RuntimeException("Where's CENSIG?");

        byte[] bad;
        bad = good.clone();

        // Corrupt it...
        int pos = findInCEN(bad, cenpos, entryName);

        // What bad stuff are we doing to it?
        // Store a 32-bit -1 in uncomp size.
        bad[pos+0x18]=(byte)0xff;
        bad[pos+0x19]=(byte)0xff;
        bad[pos+0x1a]=(byte)0xff;
        bad[pos+0x1b]=(byte)0xff;

        // Bad work complete, delete the original.
        new File(outFile).delete();

        // Write it.
        FileOutputStream fos = new FileOutputStream(outFile);
        fos.write(bad);
        fos.close();
        fos = null;

        } catch (Exception e) {
            e.printStackTrace();
        }

}

        /*
         * Scan Central Directory File Headers looking for the named entry.
         */

    static int findInCEN(byte[] bytes, int cenpos, String entryName) {
        int pos = cenpos;
        int nextPos = 0;
        String filename = null;
        do {
            if (nextPos != 0) {
                pos = nextPos;
            }
            System.out.println("entry at pos = " + pos);
            if (u32(bytes, pos) != CENSIG) throw new RuntimeException ("entry not found in CEN or premature end...");

            int csize = u32(bytes, pos+0x14);          // +0x14 1 dword csize
            int uncompsize = u32(bytes, pos+0x18);     // +0x18 1 dword uncomp size
            int filenameLength = u16(bytes, pos+0x1c); // +0x1c 1 word length of filename
            int extraLength = u16(bytes, pos+0x1e);    // +0x1e 1 world length of extra field
            int commentLength = u16(bytes, pos+0x20);  // +0x20 1 world length of file comment
            filename = new String(bytes, pos+0x2e, filenameLength); // +0x2e chars of filename
            int offset = u32(bytes, pos+0x2a);         // +0x2a chars of filename

            System.out.println("filename = " + filename + "\ncsize = " + csize +
                               " uncomp.size = " + uncompsize +" file offset = " + offset);
            nextPos =  pos + 0x2e + filenameLength + extraLength + commentLength;

        } while (!filename.equals(entryName));

        System.out.println("entry found at pos = " + pos);
        return pos;
    }

    static int u8(byte[] data, int offset) {
        return data[offset]&0xff;
    }

    static int u16(byte[] data, int offset) {
        return u8(data,offset) + (u8(data,offset+1)<<8);
    }

    static int u32(byte[] data, int offset) {
        return u16(data,offset) + (u16(data,offset+2)<<16);
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java CreateBadJar.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.