FirmwareWrapperExtraction.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package de.nplusc.izc.senabitwiggler;
  2. import com.google.common.base.Charsets;
  3. import com.google.common.primitives.Longs;
  4. import org.apache.logging.log4j.LogManager;
  5. import org.apache.logging.log4j.Logger;
  6. import org.yaml.snakeyaml.Yaml;
  7. import java.io.*;
  8. import java.security.MessageDigest;
  9. import java.security.NoSuchAlgorithmException;
  10. public class FirmwareWrapperExtraction {
  11. private static final Logger l = LogManager.getLogger();
  12. public static void assembleFirmware(File output, String inputfolder)
  13. {
  14. Yaml y = new Yaml();
  15. try {
  16. LongHeader h = y.loadAs(new FileReader(new File(inputfolder+File.separator+"header.yml")),LongHeader.class);
  17. RandomAccessFile f = new RandomAccessFile(output,"rw");
  18. f.write(h.getVersion_raw());
  19. f.write(Utils.LongToRawBytes(h.getMagicShit()));
  20. f.write(Utils.LongToRawBytes(h.getRandom_id()));
  21. HeaderRecord[] records = h.getHeaderRecords();
  22. int count = records.length;
  23. f.write(Utils.LongToRawBytes(count));
  24. long offset = records[0].getOffset();
  25. for(int i=0;i<count;i++)
  26. {
  27. HeaderRecord r = records[i];
  28. File handle = new File(inputfolder+File.separator+r.getFilename());
  29. r.setLength(handle.length());
  30. r.setOffset(offset+0);
  31. offset+=handle.length();
  32. RandomAccessFile file = new RandomAccessFile(handle,"r");
  33. byte[] bfr = new byte[(int)handle.length()];
  34. file.read(bfr);
  35. byte[] newmd5 = MessageDigest.getInstance("MD5").digest(bfr);
  36. r.setMd5sum(newmd5);
  37. }
  38. for(int i=0;i<count;i++)
  39. {
  40. HeaderRecord r = records[i];
  41. f.write(Utils.LongToRawBytes(r.getShortflag_1()));
  42. f.write(Utils.LongToRawBytes(r.getShortflag_2()));
  43. f.write(Utils.LongToRawBytes(r.getOffset()));
  44. f.write(Utils.LongToRawBytes(r.getLength()));
  45. f.write(r.getMd5sum());
  46. }
  47. for(int i=0;i<count;i++)
  48. {
  49. HeaderRecord r = records[i];
  50. f.write(Utils.LongToRawBytes(r.getShortflag_1()));
  51. f.write(Utils.LongToRawBytes(r.getShortflag_2()));
  52. f.write(Utils.LongToRawBytes(r.getOffset()));
  53. f.write(Utils.LongToRawBytes(r.getLength()));
  54. f.write(Utils.LongToRawBytes(r.getFlag_1()));
  55. f.write(Utils.LongToRawBytes(r.getFlag_2()));
  56. f.write(Utils.LongToRawBytes(r.getFlag_3()));
  57. f.write(Utils.LongToRawBytes(r.getFlag_4()));
  58. f.write(Utils.LongToRawBytes(r.getFlag_5()));
  59. f.write(Utils.LongToRawBytes(r.getUnknown_id()));
  60. f.write(r.getPadding());
  61. byte[] filenamebytes = r.getFilename().getBytes(Charsets.US_ASCII);
  62. byte[] filename = new byte[128];
  63. for(int j=0;j<128;j++)
  64. {
  65. if(j<filenamebytes.length)
  66. {
  67. filename[j]=filenamebytes[j];
  68. }
  69. else
  70. {
  71. filename[j]=0;
  72. }
  73. }
  74. f.write(filename);
  75. f.write(r.getMd5sum());
  76. }
  77. for(int i=0;i<count;i++)
  78. {
  79. HeaderRecord r = records[i];
  80. File handle = new File(inputfolder+File.separator+r.getFilename());
  81. RandomAccessFile file = new RandomAccessFile(handle,"r");
  82. byte[] bfr = new byte[(int)handle.length()];
  83. file.read(bfr);
  84. f.write(bfr);
  85. }
  86. f.close();
  87. } catch (FileNotFoundException e) {
  88. e.printStackTrace();
  89. } catch (IOException e) {
  90. e.printStackTrace();
  91. } catch (NoSuchAlgorithmException e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. public static void extractFirmwareLong(File input, String output) throws InputInvalidException {
  96. byte filler = 0x00;
  97. try (RandomAccessFile f = new RandomAccessFile(input,"r")) {
  98. LongHeader hdr = new LongHeader();
  99. byte[] headermagic = new byte[24];
  100. f.read(headermagic);
  101. String versionName = new String(headermagic, Charsets.US_ASCII).split("\0")[0]; //hack, can be done since strings are shorty. https://stackoverflow.com/a/8843313/1405227
  102. hdr.setVersion_raw(headermagic);
  103. hdr.setVersion(versionName);
  104. //12 more bytes
  105. byte[] magic = new byte[4];
  106. f.read(magic);
  107. hdr.setMagicShit(Longs.fromBytes(filler,filler,filler,filler,magic[3],magic[2],magic[1],magic[0]));
  108. // magic[] = {0x19,0x28,0xc5,0xe6}
  109. byte[] unknown_id = new byte[4];
  110. f.read(unknown_id); //product id
  111. hdr.setRandom_id(Longs.fromBytes(filler,filler,filler,filler,unknown_id[3],unknown_id[2],unknown_id[1],unknown_id[0]));
  112. byte[] count_raw = new byte[4];
  113. f.read(count_raw);
  114. long count_l = (Longs.fromBytes(filler,filler,filler,filler,count_raw[3],count_raw[2],count_raw[1],count_raw[0]));
  115. if(count_l>Integer.MAX_VALUE)
  116. {
  117. throw new InputInvalidException();
  118. }
  119. int count = (int)count_l;
  120. HeaderRecord[] records = new HeaderRecord[count];
  121. byte[] skip = new byte[count*32]; /*skipping over shorty header, repeats content with long one*/
  122. f.read(skip);
  123. for(int i=0;i<count;i++)
  124. {
  125. HeaderRecord record = new HeaderRecord();
  126. byte[] flags1 = new byte[4];
  127. f.read(flags1);
  128. record.setShortflag_1(Longs.fromBytes(filler,filler,filler,filler,flags1[3],flags1[2],flags1[1],flags1[0]));
  129. byte[] flags2 = new byte[4];
  130. f.read(flags2);
  131. record.setShortflag_2(Longs.fromBytes(filler,filler,filler,filler,flags2[3],flags2[2],flags2[1],flags2[0]));
  132. byte[] offset = new byte[4];
  133. f.read(offset);
  134. record.setOffset(Longs.fromBytes(filler,filler,filler,filler,offset[3],offset[2],offset[1],offset[0]));
  135. byte[] length = new byte[4];
  136. f.read(length);
  137. record.setLength(Longs.fromBytes(filler,filler,filler,filler,length[3],length[2],length[1],length[0]));
  138. long[] flags = new long[5];
  139. for(int j=0;j<5;j++)
  140. {
  141. byte[] flags_raw = new byte[4];
  142. f.read(flags_raw);
  143. flags[j] = (Longs.fromBytes(filler,filler,filler,filler,flags_raw[3],flags_raw[2],flags_raw[1],flags_raw[0]));
  144. }
  145. record.setFlag_1(flags[0]);
  146. record.setFlag_2(flags[1]);
  147. record.setFlag_3(flags[2]);
  148. record.setFlag_4(flags[3]);
  149. record.setFlag_5(flags[4]);
  150. byte[] unknown = new byte[4];
  151. f.read(unknown);
  152. record.setUnknown_id(Longs.fromBytes(filler,filler,filler,filler,unknown[3],unknown[2],unknown[1],unknown[0]));
  153. byte[] padding = new byte[128];
  154. f.read(padding);
  155. record.setPadding(padding);
  156. byte[] filename_raw = new byte[128];
  157. f.read(filename_raw);
  158. String filename = new String(filename_raw, Charsets.US_ASCII).split("\0")[0]; //hack, can be done since strings are shorty. https://stackoverflow.com/a/8843313/1405227
  159. record.setFilename(filename);
  160. byte[] md5 = new byte[16];
  161. f.read(md5);
  162. record.setMd5sum(md5);
  163. records[i]=record;
  164. }
  165. hdr.setHeaderRecords(records);
  166. Yaml y = new Yaml();
  167. y.dump(hdr, new FileWriter(new File(output+File.separator+"header.yml")));
  168. for(int i=0;i<records.length;i++)
  169. {
  170. HeaderRecord r = records[i];
  171. String target = output+File.separator+r.getFilename();
  172. long offset = r.getOffset();
  173. int len = (int)r.getLength();
  174. byte[] file = new byte[len];
  175. f.seek(offset);
  176. f.read(file);
  177. RandomAccessFile out = new RandomAccessFile(target,"rw");
  178. out.write(file);
  179. out.close();
  180. }
  181. } catch (FileNotFoundException e) {
  182. e.printStackTrace();
  183. } catch (IOException e) {
  184. e.printStackTrace();
  185. }
  186. }
  187. }