FlashFSUnWiggler.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package de.nplusc.izc.senabitwiggler;
  2. import com.google.common.primitives.Ints;
  3. import com.google.common.primitives.Shorts;
  4. import java.io.File;
  5. import java.io.FileNotFoundException;
  6. import java.io.IOException;
  7. import java.io.RandomAccessFile;
  8. import java.util.Random;
  9. public class FlashFSUnWiggler {
  10. private static class FileMetadata
  11. {
  12. private int offset;
  13. private boolean is_dir;
  14. private int length;
  15. private int offset_fname;
  16. private String filename;
  17. private String parentpath;
  18. }
  19. public static void unpackFSQCC512x(File firmware, File outfolder)
  20. {
  21. try (RandomAccessFile f = new RandomAccessFile(firmware,"r")) {
  22. byte[] javaisDipshit = new byte[4];
  23. byte[] javaShorty = new byte[2];
  24. int magic = f.readInt(); //ignored
  25. f.read(javaisDipshit);
  26. int sizeFile = Ints.fromBytes(javaisDipshit[3],javaisDipshit[2],javaisDipshit[1],javaisDipshit[0]);
  27. if(sizeFile>f.length())
  28. {
  29. System.out.println(sizeFile);
  30. System.err.println("ZOINKS!!!, mismatch");
  31. return;
  32. }
  33. f.read(javaisDipshit);
  34. int countFileRecords = Ints.fromBytes(javaisDipshit[3],javaisDipshit[2],javaisDipshit[1],javaisDipshit[0]);
  35. FileMetadata[] files = new FileMetadata[countFileRecords];
  36. for(int i=0;i<countFileRecords;i++)
  37. {
  38. FileMetadata fmd = new FileMetadata();
  39. f.read(javaisDipshit);
  40. int sizeAndFlags = Ints.fromBytes(javaisDipshit[3],javaisDipshit[2],javaisDipshit[1],javaisDipshit[0]);
  41. int size = sizeAndFlags&0x00FFFFFF;
  42. System.out.println(sizeAndFlags);
  43. System.out.println(size);
  44. fmd.offset_fname=size;
  45. if((sizeAndFlags&0xFF000000)<0)
  46. {
  47. System.out.println("dir");
  48. fmd.is_dir=true;
  49. }
  50. f.read(javaisDipshit);
  51. fmd.offset=Ints.fromBytes(javaisDipshit[3],javaisDipshit[2],javaisDipshit[1],javaisDipshit[0]);
  52. f.read(javaisDipshit);
  53. fmd.length=Ints.fromBytes(javaisDipshit[3],javaisDipshit[2],javaisDipshit[1],javaisDipshit[0]);
  54. files[i]=fmd;
  55. }
  56. for(int i=0;i<countFileRecords;i++)
  57. {
  58. FileMetadata fmd = files[i];
  59. if(fmd.offset_fname==0)
  60. {
  61. fmd.filename="";
  62. fmd.parentpath="";
  63. }
  64. else
  65. {
  66. f.seek(fmd.offset_fname);
  67. f.read(javaShorty);
  68. short fnlength = Shorts.fromBytes(javaShorty[1],javaShorty[0]);
  69. byte[] fname = new byte[fnlength];
  70. f.read(fname);
  71. String s = File.separator+new String(fname);
  72. fmd.filename=s;
  73. }
  74. if(fmd.is_dir)
  75. {
  76. new File(outfolder+fmd.parentpath+fmd.filename).mkdirs();
  77. for(int j= 0;j< fmd.length;j++)
  78. {
  79. int subfiles = fmd.offset+j-1;
  80. files[subfiles].parentpath=fmd.parentpath+fmd.filename;
  81. }
  82. }
  83. else
  84. {
  85. System.out.println("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
  86. byte[] filecontent = new byte[fmd.length];
  87. if(fmd.length>0)
  88. {
  89. f.seek(fmd.offset);
  90. f.read(filecontent);
  91. RandomAccessFile out = new RandomAccessFile(outfolder+fmd.parentpath+fmd.filename,"rw");
  92. out.write(filecontent);
  93. }
  94. }
  95. }
  96. } catch (FileNotFoundException e) {
  97. e.printStackTrace();
  98. } catch (IOException e) {
  99. e.printStackTrace();
  100. }
  101. }
  102. public static void unpackCSRFS(File firmware, File outfolder)
  103. {
  104. try (RandomAccessFile f = new RandomAccessFile(firmware,"r")) {
  105. int filler = -1;
  106. byte[] fillershort = new byte[]{(byte)0xff,(byte)0xff};
  107. RandomAccessFile boobs = new RandomAccessFile(new File(outfolder,"debug.dat"),"rw");
  108. byte[] javaisDipshit = new byte[4];
  109. byte[] javaShorty = new byte[2];
  110. int magic = f.readInt(); //ignored
  111. f.read(javaisDipshit);
  112. boobs.write(filler);
  113. int sizeFile = Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
  114. //old shit calculates in words and not in bytes on sizes
  115. if((sizeFile*2)>f.length())
  116. {
  117. System.out.println(sizeFile);
  118. System.err.println("ZOINKS!!!, mismatch");
  119. return;
  120. }
  121. byte[] background = new byte[(int)f.length()];
  122. for(int i=0;i<background.length;i++)
  123. {
  124. background[i]=0;
  125. }
  126. boobs.seek(0);
  127. boobs.write(background);
  128. boobs.seek(0);
  129. boobs.write(filler);
  130. boobs.write(filler);
  131. f.read(javaisDipshit);
  132. int countFileRecords = (Ints.fromBytes(javaisDipshit[2],javaisDipshit[3],javaisDipshit[0],javaisDipshit[1]) &0x00FFFFFF);
  133. System.out.println(countFileRecords);
  134. int countFileRecordsXXX = (Ints.fromBytes(javaisDipshit[1],javaisDipshit[0],javaisDipshit[3],javaisDipshit[2])&0x00FFFFFF);
  135. System.out.println(countFileRecordsXXX);
  136. boobs.write(fillershort);
  137. boobs.seek(10);
  138. f.seek(10);
  139. byte[] fakeFileRecord = new byte[12];
  140. for(int i=0;i<12;i++)
  141. {
  142. fakeFileRecord[i]=(byte)0xee;
  143. }
  144. FileMetadata[] files = new FileMetadata[countFileRecords];
  145. for(int i=0;i<countFileRecords;i++)
  146. {
  147. FileMetadata fmd = new FileMetadata();
  148. f.read(javaisDipshit);
  149. int sizeAndFlags = Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
  150. int size = sizeAndFlags&0x00FFFFFF;
  151. System.out.println("SZFlg>>"+sizeAndFlags);
  152. System.out.println("SZExtr>>"+size);
  153. fmd.offset_fname=size;
  154. if((sizeAndFlags&0xFF000000)<0)
  155. {
  156. System.out.println("dir");
  157. fmd.is_dir=true;
  158. }
  159. f.read(javaisDipshit);
  160. fmd.offset=Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
  161. f.read(javaisDipshit);
  162. fmd.length=Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
  163. files[i]=fmd;
  164. boobs.write(fakeFileRecord);
  165. }
  166. for(int i=0;i<countFileRecords;i++)
  167. {
  168. FileMetadata fmd = files[i];
  169. if(fmd.offset_fname==0)
  170. {
  171. fmd.filename="";
  172. fmd.parentpath="";
  173. }
  174. else
  175. {
  176. f.seek(fmd.offset_fname*2); //words again...
  177. f.read(javaShorty);
  178. short fnlength = Shorts.fromBytes(javaShorty[0],javaShorty[1]);
  179. byte[] fname = new byte[fnlength*2];
  180. f.read(fname);
  181. byte[] fname_real = new byte[fnlength];
  182. for(int fi=0;fi<fname_real.length;fi++)
  183. {
  184. fname_real[fi]=fname[fi*2+1]; //zapping each upper bit...
  185. }
  186. for(int j=0;j<fname.length;j++)
  187. {
  188. fname[j]=(byte) 0xCC;
  189. }
  190. boobs.seek(fmd.offset_fname*2); //words again...
  191. boobs.write(new byte[]{(byte)0xDD,(byte)0xDD});
  192. boobs.write(fname);
  193. String s = File.separator+new String(fname_real);
  194. fmd.filename=s;
  195. }
  196. if(fmd.is_dir)
  197. {
  198. new File(outfolder+fmd.parentpath+fmd.filename).mkdirs();
  199. for(int j= 0;j< fmd.length;j++)
  200. {
  201. int subfiles = fmd.offset+j-1;
  202. if(subfiles==-1)
  203. {
  204. System.out.println("WTF?");
  205. }
  206. files[subfiles].parentpath=fmd.parentpath+fmd.filename;
  207. }
  208. }
  209. else
  210. {
  211. System.out.println("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
  212. byte[] filecontent = new byte[fmd.length];
  213. if(fmd.length>0)
  214. {
  215. f.seek(fmd.offset*2);
  216. int readme = f.read(filecontent);
  217. RandomAccessFile out = new RandomAccessFile(outfolder+fmd.parentpath+fmd.filename,"rw");
  218. out.write(filecontent);
  219. if(readme<filecontent.length)
  220. {
  221. throw new IndexOutOfBoundsException("ZARF");
  222. }
  223. for(int k=0;k<filecontent.length;k++)
  224. {
  225. filecontent[k]=(byte)0xBB;
  226. }
  227. boobs.seek(fmd.offset*2);
  228. boobs.write(filecontent);
  229. }
  230. }
  231. }
  232. } catch (FileNotFoundException e) {
  233. e.printStackTrace();
  234. } catch (IOException e) {
  235. e.printStackTrace();
  236. }
  237. }
  238. public static void unpackQCC512DFU(File firmware, File outfolder)
  239. {
  240. System.out.println("0x00!");
  241. try (RandomAccessFile f = new RandomAccessFile(firmware,"r"))
  242. {
  243. outfolder.mkdirs();
  244. f.read(new byte[8]); //skip header
  245. int hdrsize = f.readInt();
  246. f.read(new byte[hdrsize]);
  247. // 1346458196
  248. // 1145132097
  249. int i = 0;
  250. while(true)
  251. {
  252. if(f.readInt() != 1346458196)
  253. {
  254. System.out.println("Zarf!");
  255. break; //end of file
  256. }
  257. if(f.readInt() != 1145132097)
  258. {
  259. System.out.println("Zarf2!");
  260. break; //end of file
  261. }
  262. int sizeData = f.readInt();
  263. System.out.println("Reading" +sizeData);
  264. byte[] innerFile = new byte[sizeData];
  265. f.read(innerFile);
  266. RandomAccessFile fo = new RandomAccessFile(new File(outfolder,i+".dat"),"rw");
  267. fo.write(innerFile);
  268. fo.close();
  269. i++;
  270. }
  271. } catch (FileNotFoundException e) {
  272. e.printStackTrace();
  273. } catch (IOException e) {
  274. e.printStackTrace();
  275. }
  276. }
  277. }