import java.io.*; import java.util.*; import java.util.zip.*; class Unpack2 { public static void main ( String args [] ) throws IOException { if (args.length != 1 && args.length != 2) {System.out.print("\n Unpack v. 2.02 © CplFilth\n\n Usage : \n 1. Unpack adbFileIn\n For example : Unpack elements.adb\n Outputs to the correspondingly named .txt file \n\n 2. Unpack inFileName outFilename\n For example Unpack c:\\temp\\elements.adb e:\\elements.hex\n\n"); System.exit(0); } int ta; String inputFileName = new String(args[0]); File inputFile = new File(inputFileName); String cha="."; String txtFileString =""; int index=0; File txtFile; // initialize txtFileString while ( cha.compareTo(inputFileName.substring(index,index+1)) != 0) { txtFileString = txtFileString + inputFileName.substring(index,index+1); index++; } txtFileString = txtFileString + ".txt"; if ( args.length != 2 ) {txtFile = new File(txtFileString);} else { txtFile = new File(args[1]);} // read adbFile to byte array "data" // considerably faster than the previous method DataInputStream read = new DataInputStream(new FileInputStream(inputFile)); int adbLength = read.available(); byte[] data = new byte[adbLength]; read.readFully(data); int zipStart=0; read.close(); // find the bytes 78 9C, which indicate start of compressed data for ( index = 0 ; index < adbLength ; index++ ) { if ( (data[index] & 0xFF )== 0x78 && (data[index+1] & 0xFF)== 0x9C ) {zipStart = index;index = adbLength;} } // create a stream into memory, which is used to depict a dummy zip file ByteArrayOutputStream zipOut = new ByteArrayOutputStream(); // Insert zip header zipOut.write(80);zipOut.write(75);zipOut.write(3);zipOut.write(4); zipOut.write(20);zipOut.write(0);zipOut.write(8);zipOut.write(0); zipOut.write(8);zipOut.write(0); zipOut.write(206);zipOut.write(102);zipOut.write(119);zipOut.write(39); // write 4 bytes of zeros as the CRC zipOut.write(0);zipOut.write(0);zipOut.write(0);zipOut.write(0); // insert compressed length int compLength = adbLength - zipStart; zipOut.write(intToByteArray(compLength)); // insert uncompressed size FF FF FF 00, should be enough zipOut.write(255);zipOut.write(255);zipOut.write(255);zipOut.write(0); // insert number of characters in txt file name zipOut.write(CountChars(txtFileString));zipOut.write(0); // and 2 zeros , extra field length zipOut.write(0);zipOut.write(0); // insert txt file name StringReader inString = new StringReader (txtFileString); int a; while ( (a = inString.read() ) != -1 ) zipOut.write(a); // insert data int i; zipOut.write(data,zipStart+2,compLength-2); // insert local file header String localFileHeader1 = "PK..........f.as"; StringReader readString = new StringReader(localFileHeader1); ta=0; while ((ta = readString.read()) != -1 ) { zipOut.write(ta); } // another CRC of 4 nulls zipOut.write(0);zipOut.write(0);zipOut.write(0);zipOut.write(0); //insert compressed size 00 00 00 00 for now zipOut.write(0);zipOut.write(0);zipOut.write(0);zipOut.write(0); // insert uncompressed size FF FF FF 00 zipOut.write(255);zipOut.write(255);zipOut.write(255);zipOut.write(0); // insert filename length zipOut.write(CountChars(txtFileString));zipOut.write(0); // insert extra field length 00 00 zipOut.write(0);zipOut.write(0); // insert file comment length 00 00 zipOut.write(0);zipOut.write(0); // get current number of bytes, used later int start=zipOut.size(); // insert disk number start 00 00 zipOut.write(0);zipOut.write(0); // insert internal file attributes 00 00 zipOut.write(0);zipOut.write(0); // insert external file attributes 20 00 zipOut.write(32);zipOut.write(0); // insert txt file name inString = new StringReader (txtFileString); while ( (a = inString.read() ) != -1 ) zipOut.write(a); // end of central dir sig String endOfCentralDir = "PK"; int b; StringReader readEnd = new StringReader(endOfCentralDir); a=0; while ( (a = readEnd.read() ) != -1 ) { zipOut.write(a); } readEnd.close(); zipOut.write(6);zipOut.write(5); // insert number of disk, number of disk with central dir, total number of entries on disk, // total number of entries in central dir 00 00 00 00 01 00 01 00 zipOut.write(0);zipOut.write(0);zipOut.write(0);zipOut.write(0);zipOut.write(1);zipOut.write(0); zipOut.write(1);zipOut.write(0); // insert size of central dir int size; size = CountChars(txtFileString); size = size + 46; zipOut.write(size);zipOut.write(0);zipOut.write(0);zipOut.write(0); // offset of central dir in respect to starting disk number zipOut.write(start); zipOut.write(start >> 8 ); // insert comment length 00 00 zipOut.write(0);zipOut.write(0); // dump stream into a byte array byte[] zipData = new byte[zipOut.size()]; zipData = zipOut.toByteArray(); // decompress to name.txt, method shamelessly copied from some Sun document or another String inFilename2; ByteArrayInputStream zipIn = new ByteArrayInputStream(zipData); ZipInputStream in2 = new ZipInputStream(zipIn); OutputStream out2 = new FileOutputStream(txtFile); try { ZipEntry entry; byte[] buff = new byte[1024]; int leng; if ((entry = in2.getNextEntry()) != null) { while ((leng = in2.read(buff)) > 0) { out2.write(buff, 0, leng); } } } catch (IOException e) { } out2.close(); in2.close(); zipIn.close(); zipOut.close(); } // helper method to convert an integer value into a array of bytes 4 cells in length static byte[] intToByteArray ( int value ) { byte[] arr = new byte[4]; arr[0] = (byte ) (value); arr[1] = (byte ) (value >> 8 ); arr[2] = (byte ) (value >> 16 ); arr[3] = (byte ) (value >> 24); return(arr); } public static int CountChars(String stringin) throws IOException { String stringhere = stringin; int count=0; int tempo; StringReader thisString = new StringReader(stringhere); while ( (tempo = thisString.read() ) != -1 ) { count++; } thisString.close(); return(count); } }