2

I'm trying to load a specific JNLP file from a Java program and get its .jar files. I've downloaded the .pack.gz files (because it uses compressing), but now I can't unpack them. I'm trying it by using the class java.util.jar.Pack200.Unpacker, but it throws an Exception with the following information:

SEVERE: null
java.io.IOException: Corrupted pack file: magic/ver = 1F8B0800/0.0 should be CAFED00D/150.7 OR CAFED00D/160.1 OR CAFED00D/170.1 OR CAFED00D/171.0

    at com.sun.java.util.jar.pack.NativeUnpack.start(Native Method)
    at com.sun.java.util.jar.pack.NativeUnpack.run(NativeUnpack.java:198)
    at com.sun.java.util.jar.pack.NativeUnpack.run(NativeUnpack.java:247)
    at com.sun.java.util.jar.pack.UnpackerImpl.unpack(UnpackerImpl.java:138)
    at com.sun.java.util.jar.pack.UnpackerImpl.unpack(UnpackerImpl.java:174)
    at rmiattack.Util.loadJNLP(Util.java:186)
    at rmiattack.RmiAttack.debugFunction(RmiAttack.java:50)
    at rmiattack.RmiAttack.main(RmiAttack.java:74)

I've looked for that error and then I tried to unpack the file with the command "unpack200" and it works. Then I tried to find the unpack200 sources in the openjdk project, but I didn't found them. So, could anyone tell me where can I find those sources to know how to use the Unpacker class? I'm attaching the code I'm using:

public static void loadJNLP(String file, String outDir) throws IOException, ParserConfigurationException, SAXException {
        byte[] encoded = Files.readAllBytes(Paths.get(file));
        Document document = stringToXML(new String(encoded, Charset.defaultCharset()), false);
        System.out.println(document.getElementsByTagName("title").item(0));
        String baseURL = document.getElementsByTagName("jnlp").item(0).getAttributes().getNamedItem("codebase").getTextContent();
        int i;
        NodeList nodeList = document.getElementsByTagName("jar");
        Unpacker unpacker = Pack200.newUnpacker();
        SortedMap<String,String> properties = unpacker.properties();
        properties.entrySet().stream().forEach((entry) -> {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        });
        for (i = 0; i < nodeList.getLength(); i++) {
            //This can be threaded
            NamedNodeMap attributes = nodeList.item(i).getAttributes();
            String fileName = attributes.getNamedItem("href").getTextContent().replace(".jar", "") + "__V" + attributes.getNamedItem("version").getTextContent() + ".jar.pack.gz";
            File packedJar = new File(outDir + '/' + fileName); //File path to download packed jar
            FileUtils.copyURLToFile(new URL(baseURL + '/' + fileName), packedJar); //Download packed jar
            FileOutputStream fileOutputStream = new FileOutputStream(outDir+'/'+attributes.getNamedItem("href").getTextContent()); //Save jar without version
            try (JarOutputStream jarOutputStream = new JarOutputStream(fileOutputStream)) {
                unpacker.unpack(packedJar, jarOutputStream);
            } finally {
                fileOutputStream.close();
            }
            packedJar.delete();
        }
        System.out.println("Save to " + outDir);
    }

The output before the exception is this:

[title: null]
com.sun.java.util.jar.pack.class.format.error - pass
com.sun.java.util.jar.pack.default.timezone - false
com.sun.java.util.jar.pack.disable.native - false
com.sun.java.util.jar.pack.verbose - 0
pack.class.attribute.CompilationID - RUH
pack.class.attribute.SourceID - RUH
pack.code.attribute.CharacterRangeTable - NH[PHPOHIIH]
pack.code.attribute.CoverageTable - NH[PHHII]
pack.deflate.hint - keep
pack.effort - 5
pack.keep.file.order - true
pack.modification.time - keep
pack.segment.limit - -1
pack.unknown.attribute - pass

Thanks in advance.

Edit: Thanks to @Thorbjoern comment I've solved it. I just had to uncompress files and then unpack them. File code looks like this:

public static void loadJNLP(String file, String outDir) throws IOException, ParserConfigurationException, SAXException {
        byte[] encoded = Files.readAllBytes(Paths.get(file));
        Document document = stringToXML(new String(encoded, Charset.defaultCharset()), false);
        System.out.println(document.getElementsByTagName("title").item(0));
        String baseURL = document.getElementsByTagName("jnlp").item(0).getAttributes().getNamedItem("codebase").getTextContent();
        int i;
        int length;
        byte[] buffer = new byte[1024];
        NodeList nodeList = document.getElementsByTagName("jar");
        Unpacker unpacker = Pack200.newUnpacker();
        for (i = 0; i < nodeList.getLength(); i++) {
            //This can be threaded
            NamedNodeMap attributes = nodeList.item(i).getAttributes();
            String fileName = attributes.getNamedItem("href").getTextContent().replace(".jar", "") + "__V" + attributes.getNamedItem("version").getTextContent() + ".jar";

            File compressedPackedIn = new File(outDir + '/' + fileName + ".pack.gz"); //File path to download compressed packed jar
            FileUtils.copyURLToFile(new URL(baseURL + '/' + fileName + ".pack.gz"), compressedPackedIn); //Download packed jar
            FileOutputStream uncompressedPackedOut;
            try (GZIPInputStream compressed = new GZIPInputStream(new FileInputStream(outDir + '/' + fileName + ".pack.gz"))) {
                uncompressedPackedOut = new FileOutputStream(outDir + '/' + fileName + ".pack");
                //http://www.mkyong.com/java/how-to-decompress-file-from-gzip-file/
                while ((length = compressed.read(buffer))> 0) {
                    uncompressedPackedOut.write(buffer, 0, length);
                }
            }
            uncompressedPackedOut.close();
            File uncompressedPackedIn = new File(outDir + '/' + fileName + ".pack");

            FileOutputStream uncompressedUnpacked = new FileOutputStream(outDir + '/' + fileName);
            try (JarOutputStream jarOutputStream = new JarOutputStream(uncompressedUnpacked)) {
                unpacker.unpack(uncompressedPackedIn, jarOutputStream);
            } finally {
                uncompressedUnpacked.close();
            }
            compressedPackedIn.delete();
            uncompressedPackedIn.delete();

        }
    }
nicovell3
  • 60
  • 8

0 Answers0