Преглед на файлове

more wiggling around in the wiggler, and some loose crap

LH преди 2 години
родител
ревизия
a648b13333

+ 1 - 0
QuickStuff/build.gradle

@@ -4,4 +4,5 @@ apply plugin: 'java-library'
 dependencies{
     api(project(':ToolKit')) {
     }
+    implementation 'org.bouncycastle:bcprov-ext-jdk18on:1.71'
 }

+ 37 - 0
QuickStuff/src/main/java/QuickVerifyCrap/Lazy.java

@@ -0,0 +1,37 @@
+package QuickVerifyCrap;
+
+import java.io.File;
+
+public class Lazy {
+    public static void main(String[] args) {
+        /*for(int i=1;i<256;i++)
+        {
+            System.out.print("0x");
+            System.out.print(Long.toHexString(i));
+            System.out.print(" ");
+        }*/
+        SplitSecondArkSplitter.HACK=true;
+        SplitSecondArkSplitter.main(null);
+        SplitSecondArkSplitter.HACK=false;
+        sweep("O:\\SplitSecond\\data");
+
+    }
+
+
+
+    public static void sweep(String path)
+    {
+        File f = new File(path);
+        for (File file : f.listFiles()) {
+            if(file.getName().endsWith(".ark"))
+            {
+                //System.out.println(file.getAbsolutePath());
+                SplitSecondArkSplitter.main(new String[]{file.getAbsolutePath()});
+            }
+            if(file.isDirectory())
+            {
+                sweep(file.getAbsolutePath());
+            }
+        }
+    }
+}

+ 41 - 0
QuickStuff/src/main/java/QuickVerifyCrap/SonyUnXml.java

@@ -0,0 +1,41 @@
+package QuickVerifyCrap;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.*;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+public class SonyUnXml {
+    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
+
+        Security.addProvider(new BouncyCastleProvider());
+
+        byte[] c = new byte[] {
+                79, -94, 121, -103, -1, -48, -117, 31, -28, -46,
+                96, -43, 123, 109, 60, 23 };
+        SecretKeySpec secretKeySpec = new SecretKeySpec(c, "AES");
+        Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");
+        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
+        File f = new File("Q:\\LOA\\000013\\S0NY\\decr\\01\\info.xml");
+        RandomAccessFile f2 = new RandomAccessFile(f,"r");
+        //f2.seek(0x4A);
+        int fl = (int)f.length();
+        byte[] file = new byte[fl];
+
+        int read = f2.read(file);
+        if(read<fl)
+        {
+            System.err.println("ZARF");
+        }
+
+        byte[] out = cipher.doFinal(file);
+        FileOutputStream os = new FileOutputStream(new File("Q:\\LOA\\000013\\S0NY\\decr\\01\\info.xml.dec"));
+        os.write(out);
+    }
+}

+ 101 - 94
QuickStuff/src/main/java/QuickVerifyCrap/SplitSecondArkSplitter.java

@@ -6,103 +6,113 @@ import java.util.LinkedList;
 import java.util.List;
 
 public class SplitSecondArkSplitter {
-    public static void main(String[] args) {
-        HashMap<String,String> filehashes = new HashMap<>();
-        try (BufferedReader br = new BufferedReader(new FileReader("D:\\LOA\\000014\\filenames_preprocessed.txt"))) {
-            br.lines().forEach((line)->
-            {
-                filehashes.put(SplitSecondChecksumCheck.wiggleChecksum(line)+"",line);
-            });
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
+    public static boolean HACK = true;
 
-        String[] levelbases = {"airport_test_03","docks","downtown","end_sequence",
-        "graveyard","nem_downtown","nem_graveyard","nem_storm","nem_training","nem_warehouse","powerplant"};
+    public static void main(String[] args) {
+        HashMap<String, String> filehashes = new HashMap<>();
+        try (PrintWriter bw = new PrintWriter(new FileWriter("D:\\LOA\\000014\\filenames_debugdump.txt",true))) {
 
-        //synthesizing a few patterned names
-        for(int i=0;i<1000;i++)
-        {
-            String prefix = String.format("%03d", i);;
-            for(int j=0;j<5;j++)
-            {
-                filehashes.put(SplitSecondChecksumCheck.wiggleChecksum("q"+prefix+"_rig"+j+"MD.model.stream")+"","q"+prefix+"_rig"+j+"MD.model.stream");
-                filehashes.put(SplitSecondChecksumCheck.wiggleChecksum("q"+prefix+"_rig"+j+"L.model.stream")+"","q"+prefix+"_rig"+j+"L.model.stream");
+            try (BufferedReader br = new BufferedReader(new FileReader("D:\\LOA\\000014\\filenames_preprocessed.txt"))) {
+                br.lines().forEach((line) ->
+                {
+                    long wiggled = SplitSecondChecksumCheck.wiggleChecksum(line);
+                    filehashes.put(wiggled + "", line);
+                    if(HACK)
+                        bw.println(Long.toHexString(wiggled) + "|" + line);
+                });
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
             }
+            if (HACK)
+                return;
+            String[] levelbases = {"airport_test_03", "docks", "downtown", "end_sequence",
+                    "graveyard", "nem_downtown", "nem_graveyard", "nem_storm", "nem_training", "nem_warehouse", "powerplant"};
 
-            for(String base:levelbases)
-            filehashes.put(SplitSecondChecksumCheck.wiggleChecksum("airport_test_03.streamtex."+prefix)+"","airport_test_03.streamtex."+prefix);
-        }
+            //synthesizing a few patterned names
+            for (int i = 0; i < 1000; i++) {
+                String prefix = String.format("%03d", i);
+                ;
+                for (int j = 0; j < 5; j++) {
+                    filehashes.put(SplitSecondChecksumCheck.wiggleChecksum("q" + prefix + "_rig" + j + "MD.model.stream") + "", "q" + prefix + "_rig" + j + "MD.model.stream");
+                    filehashes.put(SplitSecondChecksumCheck.wiggleChecksum("q" + prefix + "_rig" + j + "L.model.stream") + "", "q" + prefix + "_rig" + j + "L.model.stream");
+                }
 
-        try {
-            RandomAccessFile f = new RandomAccessFile("O:\\splitsecond\\data\\environments\\levels\\nem_training\\sectors\\nem_training.stream.ark","r");
-            f.readInt();
-            f.readInt();
-            int files = Integer.reverseBytes(f.readInt());
-            System.out.println(files);
-            f.readInt();
-            f.readInt();
-            f.readInt(); //some bullshit;
-            List<FileMetaData> fileslst = new LinkedList<>();
-            for(int i=0;i<files;i++)
-            {
-                FileMetaData fmd = new FileMetaData();
-                fmd.zipped = f.readInt() != 0;
-                fmd.offset = Integer.reverseBytes(f.readInt());
-                fmd.zsize = Integer.reverseBytes(f.readInt());
-                fmd.size = Integer.reverseBytes(f.readInt());
-                byte[] csum = new byte[4];
-                f.read(csum);
-                long csum2 =
-                         (((long)csum[0])&0xFFL)
-                        +((((long)csum[1])&0xFFL)<<8)
-                        +((((long)csum[2])&0xFFL)<<16)
-                        +((((long)csum[3])&0xFFL)<<24);
-                csum2 = csum2&0xFFFFFFFFL;
-                String filename = filehashes.get(""+csum2);
-                System.out.println(filename);
-                System.out.println(Long.toHexString(csum2));
-                fmd.filename=filename!=null?filename:"UNKNOWN_"+csum2;
-                fmd.checksum=csum2;
-                fileslst.add(fmd);
+                for (String base : levelbases) {
+                    filehashes.put(SplitSecondChecksumCheck.wiggleChecksum(base + ".streamtex." + prefix) + "", base + ".streamtex." + prefix);
+                }
             }
-            for(FileMetaData fmd:fileslst)
-            {
-                String realresult = "D:\\LOA\\000014\\result\\"+fmd.filename;
-                File dst = new File(realresult);
-                dst.getParentFile().mkdirs();
-
-                if(fmd.zipped)
-                {
 
-                    String outfile = "D:\\LOA\\000014\\scratch\\out.dat";
-                    File of = new File(outfile);
-                    of.delete(); //zapping old file leftovers
-                    byte[] compressed = new byte[fmd.zsize-4];
-                    f.seek(fmd.offset);
-                    int size = Integer.reverseBytes(f.readInt());
-                    f.read(compressed);
-                    RandomAccessFile rof = new RandomAccessFile(of,"rw");
-                    rof.writeInt(fmd.zsize-4);
-                    rof.writeInt(size);
-                    rof.write(compressed);
-                    rof.close();
-                    File workdir = new File("D:\\LOA\\000014\\scratch");
-                    runTool(workdir,"D:\\LOA\\000014\\quickbms.exe","-R","D:\\LOA\\000014\\helper.bms",outfile);
-                    String transferfile = "D:\\LOA\\000014\\scratch\\result.dat";
-                    new File(transferfile).renameTo(dst);
+            try {
+                RandomAccessFile f = new RandomAccessFile(args[0], "r");
+                f.readInt();
+                f.readInt();
+                int files = Integer.reverseBytes(f.readInt());
+                System.out.println(files);
+                f.readInt();
+                f.readInt();
+                f.readInt(); //some bullshit;
+                List<FileMetaData> fileslst = new LinkedList<>();
+                for (int i = 0; i < files; i++) {
+                    FileMetaData fmd = new FileMetaData();
+                    fmd.zipped = f.readInt() != 0;
+                    fmd.offset = Integer.reverseBytes(f.readInt());
+                    fmd.zsize = Integer.reverseBytes(f.readInt());
+                    fmd.size = Integer.reverseBytes(f.readInt());
+                    byte[] csum = new byte[4];
+                    f.read(csum);
+                    long csum2 =
+                            (((long) csum[0]) & 0xFFL)
+                                    + ((((long) csum[1]) & 0xFFL) << 8)
+                                    + ((((long) csum[2]) & 0xFFL) << 16)
+                                    + ((((long) csum[3]) & 0xFFL) << 24);
+                    csum2 = csum2 & 0xFFFFFFFFL;
+                    String filename = filehashes.get("" + csum2);
+                    System.out.println(filename);
+                    System.out.println(Long.toHexString(csum2));
+                    fmd.filename = filename != null ? filename : "UNKNOWN_" + csum2;
+                    fmd.checksum = csum2;
+                    fileslst.add(fmd);
                 }
-                else
-                {
-                    byte[] compressed = new byte[fmd.zsize];
-                    f.seek(fmd.offset);
-                    f.read(compressed);
-                    RandomAccessFile rof = new RandomAccessFile(dst,"rw");
-                    rof.write(compressed);
-                    rof.close();
+                for (FileMetaData fmd : fileslst) {
+                    String arkbasename = new File(args[0]).getName();
+                    String realresult = "Q:\\LOA\\000014\\result\\" + arkbasename + "\\" + fmd.filename;
+                    File dst = new File(realresult);
+                    dst.getParentFile().mkdirs();
+                    bw.println(">>"+arkbasename+"||"+Long.toHexString(fmd.checksum)+"||"+fmd.filename);
+                    if (fmd.zipped) {
+
+                        String outfile = "Q:\\LOA\\000014\\scratch\\out.dat";
+                        File of = new File(outfile);
+                        of.getParentFile().mkdirs();
+                        of.delete(); //zapping old file leftovers
+                        byte[] compressed = new byte[fmd.zsize - 4];
+                        f.seek(fmd.offset);
+                        int size = Integer.reverseBytes(f.readInt());
+                        f.read(compressed);
+                        RandomAccessFile rof = new RandomAccessFile(of, "rw");
+                        rof.writeInt(fmd.zsize - 4);
+                        rof.writeInt(size);
+                        rof.write(compressed);
+                        rof.close();
+                        File workdir = new File("D:\\LOA\\000014\\scratch");
+                        runTool(workdir, "D:\\LOA\\000014\\quickbms.exe", "-R", "D:\\LOA\\000014\\helper.bms", outfile);
+                        String transferfile = "D:\\LOA\\000014\\scratch\\result.dat";
+                        new File(transferfile).renameTo(dst);
+                    } else {
+                        byte[] compressed = new byte[fmd.zsize];
+                        f.seek(fmd.offset);
+                        f.read(compressed);
+                        RandomAccessFile rof = new RandomAccessFile(dst, "rw");
+                        rof.write(compressed);
+                        rof.close();
+                    }
                 }
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
             }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
@@ -111,8 +121,7 @@ public class SplitSecondArkSplitter {
         }
     }
 
-    static class FileMetaData
-    {
+    static class FileMetaData {
         int size;
         int zsize;
         int offset;
@@ -124,16 +133,14 @@ public class SplitSecondArkSplitter {
 
     public static void runTool(String... args) throws IOException {
 
-        runTool(null,args);
+        runTool(null, args);
     }
 
 
-
     public static void runTool(File workdir, String... args) throws IOException {
         ProcessBuilder pb = new ProcessBuilder();
         pb.command(args);
-        if(workdir !=null&&workdir.isDirectory())
-        {
+        if (workdir != null && workdir.isDirectory()) {
             pb.directory(workdir);
         }
         pb.redirectOutput(new File("D:\\LOA\\000014\\scratch\\out.txt"));

+ 41 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/DataStructures/QualCommHeaderRecord.java

@@ -0,0 +1,41 @@
+package de.nplusc.izc.senabitwiggler.DataStructures;
+
+public class QualCommHeaderRecord {
+    public int size;
+    public String filename;
+
+    public short location;
+    public short sublocation;
+
+    public short getLocation() {
+        return location;
+    }
+
+    public void setLocation(short location) {
+        this.location = location;
+    }
+
+    public short getSublocation() {
+        return sublocation;
+    }
+
+    public void setSublocation(short sublocation) {
+        this.sublocation = sublocation;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public void setSize(int size) {
+        this.size = size;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public void setFilename(String filename) {
+        this.filename = filename;
+    }
+}

+ 33 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/DataStructures/QualCommWrapper.java

@@ -0,0 +1,33 @@
+package de.nplusc.izc.senabitwiggler.DataStructures;
+
+public class QualCommWrapper {
+    public byte[] header;
+    public byte[] footer;
+    public QualCommHeaderRecord[] files;
+
+    public byte[] getHeader() {
+        return header;
+    }
+
+    public void setHeader(byte[] header) {
+        this.header = header;
+    }
+
+    public byte[] getFooter() {
+        return footer;
+    }
+
+    public void setFooter(byte[] footer) {
+        this.footer = footer;
+    }
+
+    public QualCommHeaderRecord[] getFiles() {
+        return files;
+    }
+
+    public void setFiles(QualCommHeaderRecord[] files) {
+        this.files = files;
+    }
+
+
+}

+ 4 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/EntryPoint.java

@@ -154,6 +154,9 @@ public class EntryPoint implements Runnable
             case DfuS512x:
                 FlashFSUnWiggler.unpackQCC512DFU(input,output);
                 break;
+            case WriteDfuS512x:
+                FlashFSUnWiggler.repackQualcommWrapper(input,output);
+                break;
             case ScanForSenaFirmware:
                 FirmwareAutoDumper.pullFirmwares(input,output,weNeedToGoDeeper);
                 break;
@@ -176,6 +179,7 @@ enum Modes
     FlashFS512x,
     FlashFSCSR86xx,
     DfuS512x,
+    WriteDfuS512x,
     ScanForSenaFirmware
 }
 

+ 87 - 7
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FlashFSUnWiggler.java

@@ -2,13 +2,15 @@ package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Shorts;
+import de.nplusc.izc.senabitwiggler.DataStructures.QualCommHeaderRecord;
+import de.nplusc.izc.senabitwiggler.DataStructures.QualCommWrapper;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.yaml.snakeyaml.Yaml;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
 
 public class FlashFSUnWiggler {
@@ -265,18 +267,23 @@ public class FlashFSUnWiggler {
 
     public static void unpackQCC512DFU(File firmware, File outfolder)
     {
+        QualCommWrapper w = new QualCommWrapper();
         l.info("0x00!");
         try (RandomAccessFile f = new RandomAccessFile(firmware,"r"))
         {
             outfolder.mkdirs();
             f.read(new byte[8]); //skip header
             int hdrsize = f.readInt();
-            f.read(new byte[hdrsize]);
+            byte[] header = new byte[hdrsize];
+            f.read(header);
+            w.header=header;
             // 1346458196
             // 1145132097
             int i = 0;
+            List<QualCommHeaderRecord> files = new ArrayList<>();
             while(true)
             {
+                QualCommHeaderRecord r = new QualCommHeaderRecord();
                 if(f.readInt() != 1346458196)
                 {
                     l.info("Zarf!");
@@ -288,20 +295,93 @@ public class FlashFSUnWiggler {
                     break; //end of file
                 }
                 int sizeData = f.readInt();
+                r.size = sizeData;
                 l.info("Reading" +sizeData);
-                byte[] innerFile = new byte[sizeData];
+                short location = f.readShort();
+                short sublocation = f.readShort();
+                r.location=location;
+                r.sublocation=sublocation;
+                String filename = location+"_"+sublocation+".dat";
+                r.filename=filename;
+                byte[] innerFile = new byte[sizeData-4];
+
                 f.read(innerFile);
-                RandomAccessFile fo = new RandomAccessFile(new File(outfolder,i+".dat"),"rw");
+                RandomAccessFile fo = new RandomAccessFile(new File(outfolder,filename),"rw");
                 fo.write(innerFile);
                 fo.close();
                 i++;
+                files.add(r);
             }
+            int bytesLeft = 4+((int)(f.length()-f.getFilePointer()));
+            byte[] rest = new byte[bytesLeft];
+            f.seek(f.getFilePointer()-4);
+             f.read(rest);
+             w.footer=rest;
+
+            w.files = files.toArray(new QualCommHeaderRecord[files.size()]);
+            Yaml y = new Yaml();
 
+            y.dump(w, new FileWriter(new File(outfolder,"header.yml")));
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
+    }
+
+    public static void repackQualcommWrapper(File newfirmware, File inputfolder)
+    {
+        QualCommWrapper header;
+        try {
+             header = new Yaml().loadAs(new FileReader(new File(inputfolder,File.separator+"header.yml")),QualCommWrapper.class);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            return;
+        }
+        l.info("0x00!");
+
+        if(newfirmware.exists())
+        {
+            l.error("Refusing to overwrite a existing file!!!");
+            return;
+        }
 
+        try (RandomAccessFile f = new RandomAccessFile(newfirmware,"rw"))
+        {
+            f.writeInt(0x41505055);
+            f.writeInt(0x48445232);
+            f.writeInt(header.header.length);
+            f.write(header.header);
+
+            // 1346458196
+            // 1145132097
+
+            for(QualCommHeaderRecord r:header.files)
+            {
+                RandomAccessFile f2 = new RandomAccessFile(new File(inputfolder,r.filename),"r");
+                int size = (int) f2.length();
+                byte[] file = new byte[size];
+                f2.read(file);
+                f.writeInt(1346458196);
+                f.writeInt(1145132097);
+                f.writeInt(size+4);
+                f.writeShort(r.location);
+                f.writeShort(r.sublocation);
+                f.write(file);
+                f2.close();
+            }
+            f.write(header.footer);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
     }
+
+
+
+
+
+
+
 }