Camtech075

Untitled

Oct 13th, 2011
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.24 KB | None | 0 0
  1. /*
  2. * Nightmare 2.0 - General purpose file editor
  3. *
  4. * Copyright (C) 2009 Hextator,
  5. * hectorofchad (AIM) [email protected] (MSN)
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 3
  9. * as published by the Free Software Foundation
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * <Description> Wrapper class for the file to be edited by modules.
  21. */
  22.  
  23. package IO;
  24.  
  25. import java.io.File;
  26. import java.io.FileInputStream;
  27. import java.io.FileOutputStream;
  28. import java.io.IOException;
  29. import java.io.UnsupportedEncodingException;
  30. import java.util.zip.CRC32;
  31.  
  32. /**
  33. * Wrapper class for the file to be edited by modules.
  34. * @author Hextator
  35. */
  36. public class Target_File
  37. {
  38. /**
  39. * For referencing the size of the file
  40. */
  41. public static int SIZE = -1;
  42. /**
  43. * For help keeping track of where something was written to
  44. */
  45. public static int LAST_WRITE_INDEX;
  46. /**
  47. * For checking if the file has been saved before
  48. */
  49. public static boolean named = false;
  50. /**
  51. * For checking if the file has been saved with the most recent changes
  52. */
  53. public static boolean saved = true;
  54. /**
  55. * For knowing where to save
  56. */
  57. public static String fileName;
  58. /**
  59. * Enumeration listing possible "genders" of data orientation
  60. */
  61. public static enum byteSex
  62. {
  63. /**
  64. * Reverse ordered bytes
  65. */
  66. little,
  67. /**
  68. * Generically linear bytes
  69. */
  70. big
  71. }
  72. /**
  73. * Static container of the enumeration detailing whether the file is
  74. * meant to be interpreted as being in a little or big endian format<br>
  75. * Little endianness is chosen by default
  76. */
  77. public static byteSex endianness = byteSex.little;
  78.  
  79. /**
  80. * Wrapped field: the open file
  81. */
  82. private static byte file[];
  83. /**
  84. * For allowing much needed Module attachment leniency
  85. */
  86. private static boolean originalLittleChecksumValid;
  87. /**
  88. * For allowing much needed Module attachment leniency
  89. */
  90. private static boolean originalBigChecksumValid;
  91. /**
  92. * For allowing much needed Module attachment leniency
  93. */
  94. private static int originalChecksum;
  95.  
  96. //The following six functions are for performing variable endian
  97. //data accesses on byte arrays; accesses supported are
  98. //8, 16 and 32 bit read and write
  99. //All are tested and working
  100.  
  101. /**
  102. * Uses endianness static variable to variably perform a big
  103. * or little endian access of a file
  104. * @param source byte array to read from
  105. * @param address Address of byte array to read from
  106. * @return the byte at the address in the given byte array
  107. */
  108. public static Byte getByte(byte source[], int address)
  109. {
  110. try
  111. {
  112. return source[address];
  113. }
  114. catch (Exception e)
  115. {
  116. return null;
  117. }
  118. }
  119.  
  120. /**
  121. * Uses endianness static variable to variably perform a big
  122. * or little endian access of a file
  123. * @param source byte array to read from
  124. * @param address Address of byte array to read from
  125. * @return the halfword at the address in the given byte array
  126. */
  127. public static Short getShort(byte source[], int address)
  128. {
  129. try
  130. {
  131. short tempShort;
  132. if (endianness == byteSex.little)
  133. {
  134. tempShort = (short) ((source[address + 1] & 0xFF) << 0x8);
  135. tempShort |= source[address] & 0xFF;
  136. }
  137. else
  138. {
  139. tempShort = (short) (source[address + 1] & 0xFF);
  140. tempShort |= (source[address] & 0xFF) << 0x8;
  141. }
  142. return tempShort;
  143. }
  144. catch (Exception e)
  145. {
  146. return null;
  147. }
  148. }
  149.  
  150. /**
  151. * Uses endianness static variable to variably perform a big
  152. * or little endian access of a file
  153. * @param source byte array to read from
  154. * @param address Address of byte array to read from
  155. * @return the word at the address in the given byte array
  156. */
  157. public static Integer getInt(byte source[], int address)
  158. {
  159. try
  160. {
  161. int tempInt;
  162. if (endianness == byteSex.little)
  163. {
  164. tempInt = (source[address + 3] & 0xFF) << 0x18;
  165. tempInt |= (source[address + 2] & 0xFF) << 0x10;
  166. tempInt |= (source[address + 1] & 0xFF) << 0x8;
  167. tempInt |= source[address] & 0xFF;
  168. }
  169. else
  170. {
  171. tempInt = source[address + 3] & 0xFF;
  172. tempInt |= (source[address + 2] & 0xFF) << 0x8;
  173. tempInt |= (source[address + 1] & 0xFF) << 0x10;
  174. tempInt |= (source[address] & 0xFF) << 0x18;
  175. }
  176. return tempInt;
  177. }
  178. catch (Exception e)
  179. {
  180. return null;
  181. }
  182. }
  183.  
  184. /**
  185. * Uses endianness static variable to variably perform a big
  186. * or little endian access of a file
  187. * @param dest byte array to write to
  188. * @param address Address of byte array to write to
  189. * @param input The byte to write at the address of a given byte array
  190. */
  191. public static void putByte(byte dest[], int address, byte input)
  192. {
  193. try
  194. {
  195. dest[address] = input;
  196. if (dest == file)
  197. saved = false;
  198. }
  199. catch (Exception e)
  200. {
  201.  
  202. }
  203. }
  204.  
  205. /**
  206. * Uses endianness static variable to variably perform a big
  207. * or little endian access of a file
  208. * @param dest byte array to write to
  209. * @param address Address of byte array to write to
  210. * @param input The halfword to write at the address of a given byte
  211. * array
  212. */
  213. public static void putShort(byte dest[], int address, short input)
  214. {
  215. try
  216. {
  217. if (endianness == byteSex.little)
  218. {
  219. dest[address + 1] = (byte) ((int) input >> 0x8);
  220. dest[address] = (byte) ((int) input & 0xFF);
  221. }
  222. else
  223. {
  224. dest[address] = (byte) ((int) input >> 0x8);
  225. dest[address + 1] = (byte) ((int) input & 0xFF);
  226. }
  227. if (dest == file)
  228. saved = false;
  229. }
  230. catch (Exception e)
  231. {
  232.  
  233. }
  234. }
  235.  
  236. /**
  237. * Uses endianness static variable to variably perform a big
  238. * or little endian access of a file
  239. * @param dest byte array to write to
  240. * @param address Address of byte array to write to
  241. * @param input The word to write at the address of a given byte array
  242. */
  243. public static void putInt(byte dest[], int address, int input)
  244. {
  245. try
  246. {
  247. if (endianness == byteSex.little)
  248. {
  249. dest[address + 3] = (byte) (input >> 0x18);
  250. dest[address + 2] =
  251. (byte) ((input >> 0x10) & 0xFF);
  252. dest[address + 1] =
  253. (byte) ((input >> 0x8) & 0xFF);
  254. dest[address] = (byte) (input & 0xFF);
  255. }
  256. else
  257. {
  258. dest[address] = (byte) (input >> 0x18);
  259. dest[address + 1] =
  260. (byte) ((input >> 0x10) & 0xFF);
  261. dest[address + 2] =
  262. (byte) ((input >> 0x8) & 0xFF);
  263. dest[address + 3] = (byte) (input & 0xFF);
  264. }
  265. if (dest == file)
  266. saved = false;
  267. }
  268. catch (Exception e)
  269. {
  270.  
  271. }
  272. }
  273.  
  274. //These two functions handle bit array reading and writing
  275. //Both are tested and working
  276.  
  277. /**
  278. * Pulls a series of bits from the given byte array
  279. * @param source byte array to read from
  280. * @param address Address of byte containing first bit to be read
  281. * @param offset Bits closer to the LSB from the MSB of the byte that
  282. * the first bit of the bit set is located at
  283. * @param length The number of bits in the bit set being retrieved
  284. * @return null if an error occurs when loading the bits, or else the
  285. * value of the bits as a long such that the lowest addressed bit is
  286. * the MSB and the highest addressed bit is the LSB
  287. */
  288. public static Integer getBits
  289. (
  290. byte source[],
  291. int address,
  292. int offset,
  293. int length
  294. )
  295. {
  296. if (length > 32 || length <= 0)
  297. return null;
  298.  
  299. int output = 0;
  300. while (length > 0)
  301. {
  302. if (offset == 8)
  303. address++;
  304. offset %= 8;
  305. output <<= 1;
  306. try
  307. {
  308. output |=
  309. (
  310. source[address]
  311. & (1 << (7 - offset))
  312. )
  313. >>
  314. (
  315. 7 - offset
  316. );
  317. }
  318. catch (Exception e)
  319. {
  320. return null;
  321. }
  322. offset++;
  323. length--;
  324. }
  325. return output;
  326. }
  327.  
  328. /**
  329. * Puts a series of bits from the given input into the given byte array
  330. * @param dest byte array to write to
  331. * @param address Address of byte containing first bit to be
  332. * overwritten
  333. * @param offset The bit this many bits closer to the LSB from the MSB
  334. * of the first byte that the first bit of the bit set being written
  335. * will be placed at
  336. * @param length The number of bits in the bit set being written
  337. */
  338. public static void putBits
  339. (
  340. byte dest[],
  341. int address,
  342. int offset,
  343. int length,
  344. int input
  345. )
  346. {
  347. if (length > 32 || length <= 0)
  348. return;
  349.  
  350. int mask = 1 << (length - 1);
  351. while (length > 0)
  352. {
  353. if (offset == 8)
  354. address++;
  355. offset %= 8;
  356. try
  357. {
  358. dest[address] =
  359. (byte)
  360. (
  361. (
  362. dest[address]
  363. & ~(1 << (7 - offset))
  364. )
  365. |
  366. (
  367. (
  368. (input & mask)
  369. >> (length - 1)
  370. )
  371. << (7 - offset)
  372. )
  373. );
  374. if (dest == file)
  375. saved = false;
  376. }
  377. catch (Exception e)
  378. {
  379. return;
  380. }
  381. offset++;
  382. mask >>= 1;
  383. length--;
  384. }
  385. }
  386.  
  387. /**
  388. * file is private...hurf
  389. */
  390. public static byte[] getFile()
  391. {
  392. return file;
  393. } //getFile accessor
  394.  
  395. /**
  396. * For testing whether this file was clean when it was opened
  397. * @param checksum Checksum expected
  398. * @return true if the original checksum of the file matches the given
  399. * checksum
  400. */
  401. public static boolean isValid(int checksum)
  402. {
  403. if
  404. (
  405. originalLittleChecksumValid
  406. && endianness == byteSex.little
  407. )
  408. return true;
  409. else if
  410. (
  411. originalBigChecksumValid
  412. && endianness == byteSex.big
  413. )
  414. return true;
  415. else
  416. return originalChecksum == checksum ? true : false;
  417. } //isClean method; doesn't need testing
  418.  
  419. /**
  420. * Mutator for editing interfaces to update the file
  421. * @param input byte array to replace the current file
  422. */
  423. public static void setFile(byte input[])
  424. {
  425. file = input;
  426. } //setfile mutator
  427.  
  428. /**
  429. * Method for acquiring ASCII strings from a byte array, usually the
  430. * file itself
  431. * @param source byte array to read from
  432. * @param start Start address to pull the string from
  433. * @param end Address of first byte following the ASCII string
  434. * @return the selected ASCII string as a String
  435. */
  436. public static String pullString(byte source[], int start, int end)
  437. {
  438. String tempString = "";
  439. try
  440. {
  441. tempString = new String
  442. (
  443. java.util.Arrays.copyOfRange
  444. (
  445. source,
  446. start,
  447. end
  448. ),
  449. "ASCII"
  450. );
  451. }
  452. catch (UnsupportedEncodingException e)
  453. {
  454.  
  455. }
  456. return tempString;
  457. } //pullString method; tested and working!
  458.  
  459. /**
  460. * Method for inserting Strings as ASCII strings into a byte array,
  461. * usually the file itself
  462. * @param dest byte array to write to
  463. * @param start Start address to put the ASCII version of the input
  464. * String at
  465. * @param input The String to insert
  466. */
  467. public static void putString(byte dest[], int start, String input)
  468. {
  469. byte inputArray[] = new byte[input.length()];
  470. for (int i = 0; i < inputArray.length; i++)
  471. inputArray[i] = (byte) input.charAt(i);
  472. System.arraycopy(inputArray, 0, file, start, inputArray.length);
  473. if (dest == file)
  474. saved = false;
  475. } //putString method; doesn't need testing
  476.  
  477. /**
  478. * Gives user a file open dialog for selecting the file to edit
  479. * @param what Description of what to open
  480. * @param initPath Optional default path (use null if no default path
  481. * is desired)
  482. */
  483. public static void open(String what, String initPath)
  484. {
  485. saved = true;
  486.  
  487. String inputFileName;
  488.  
  489. if (initPath == null)
  490. {
  491. java.awt.FileDialog chooser = new java.awt.FileDialog
  492. (
  493. new java.awt.Frame(),
  494. "Select " + what + " for opening"
  495. );
  496. chooser.setVisible(true);
  497. chooser.setLocationRelativeTo(null);
  498. inputFileName = chooser.getDirectory() + chooser.getFile();
  499.  
  500. if (inputFileName.equals("nullnull"))
  501. {
  502. /*
  503. javax.swing.JOptionPane.showMessageDialog
  504. (
  505. null,
  506. "No file was selected.\n",
  507. "Action canceled",
  508. javax.swing.JOptionPane.PLAIN_MESSAGE
  509. );
  510. */
  511. file = new byte[] {-1};
  512. SIZE = -1;
  513. return;
  514. }
  515. }
  516. else
  517. inputFileName = initPath;
  518.  
  519. FileInputStream inputFile;
  520. File tempFile; //Just for getting the file size quickly
  521.  
  522. try
  523. {
  524. inputFile = new FileInputStream(inputFileName);
  525. tempFile = new File(inputFileName);
  526. }
  527. catch (IOException e)
  528. {
  529. file = new byte[] {-1};
  530. SIZE = -1;
  531. return;
  532. }
  533.  
  534. SIZE = (int) tempFile.length();
  535. tempFile = null; //Toss it; don't need it anymore
  536. file = new byte[SIZE];
  537. try
  538. {
  539. inputFile.read(file);
  540. inputFile.close();
  541. fileName = inputFileName;
  542. }
  543. catch (IOException e)
  544. {
  545. System.out.println("Error reading file");
  546. file = new byte[] {-1};
  547. SIZE = -1;
  548. return;
  549. }
  550.  
  551. expand(0);
  552.  
  553. CRC32 checksum = new CRC32();
  554. checksum.update(file);
  555. originalChecksum = (int) checksum.getValue();
  556. checksum.reset();
  557. checksum.update
  558. (
  559. java.util.Arrays.copyOf(file, SIZE - 4)
  560. );
  561. originalLittleChecksumValid = false;
  562. originalBigChecksumValid = false;
  563. int originalLittleChecksum = getInt(file, SIZE - 4);
  564. if (originalLittleChecksum == (int) checksum.getValue())
  565. originalLittleChecksumValid = true;
  566. endianness = byteSex.big;
  567. int originalBigChecksum = getInt(file, SIZE - 4);
  568. if (originalBigChecksum == (int) checksum.getValue())
  569. originalBigChecksumValid = true;
  570. endianness = byteSex.little;
  571. if (originalLittleChecksumValid || originalBigChecksumValid)
  572. {
  573. file = java.util.Arrays.copyOf(file, SIZE - 4);
  574. SIZE -= 4;
  575. }
  576. } //open method; tested and working!
  577.  
  578. /**
  579. * Queries whether the user wants to save the modified file<br>
  580. * Tacks on a verification checksum onto the end of the file,
  581. * then saves it at the location specified by the user<br>
  582. * Rips the checksum back off so checksums won't accumulate
  583. * @param saveAs boolean of whether to force choosing of a file path
  584. * instead of using the last path
  585. */
  586. public static boolean save(boolean saveAs)
  587. {
  588. //Append checksum onto end of file for validation purposes
  589. CRC32 checksum = new CRC32();
  590. checksum.update(file);
  591. expand(4);
  592. putInt(file, SIZE - 4, (int) checksum.getValue());
  593.  
  594. String outputFileName;
  595.  
  596. if (!named || saveAs)
  597. {
  598. java.awt.FileDialog chooser = new java.awt.FileDialog
  599. (
  600. new java.awt.Frame(),
  601. "Save",
  602. java.awt.FileDialog.SAVE
  603. );
  604. chooser.setVisible(true);
  605. outputFileName = chooser.getDirectory() + chooser.getFile();
  606.  
  607. if (outputFileName.equals("nullnull"))
  608. {
  609. //Rip off checksum so further editing without reopening
  610. //doesn't generate a checksum chain
  611. file = java.util.Arrays.copyOf(file, SIZE - 4);
  612. SIZE -= 4;
  613. return false;
  614. }
  615. }
  616. else
  617. outputFileName = fileName;
  618.  
  619. FileOutputStream outputFile;
  620.  
  621. try
  622. {
  623. outputFile = new FileOutputStream(outputFileName);
  624. outputFile.write(file);
  625. outputFile.close();
  626. saved = true;
  627. named = true;
  628. fileName = outputFileName;
  629. }
  630. catch (IOException e)
  631. {
  632. //Rip off checksum so further editing without reopening
  633. //doesn't generate a checksum chain
  634. file = java.util.Arrays.copyOf(file, SIZE - 4);
  635. SIZE -= 4;
  636. return false;
  637. }
  638.  
  639. //Rip off checksum so further editing without reopening
  640. //doesn't generate a checksum chain
  641. file = java.util.Arrays.copyOf(file, SIZE - 4);
  642. SIZE -= 4;
  643. return true;
  644. } //save method; tested and working!
  645.  
  646. /**
  647. * Adds a number of 0 filled bytes to the end of the file equal to
  648. * the given size with padding to the nearest word
  649. * @param size The number of bytes to expand the file by
  650. * @return the number of bytes the file was expanded by after
  651. * considering word alignment
  652. */
  653. public static int expand(int size)
  654. {
  655. int originalSize = size;
  656. size += 3;
  657. size >>= 2;
  658. size <<= 2;
  659. file = java.util.Arrays.copyOf(file, SIZE + size);
  660. SIZE += size;
  661. return size - originalSize;
  662. } //expand method; tested and working!
  663.  
  664. /**
  665. * Uses a call to expand(int) to get space for the given appendix,
  666. * then fills the expanded area with the appendix
  667. * @param input A byte array of the data to append onto the end of the
  668. * open file
  669. */
  670. public static void append(byte input[])
  671. {
  672. int tempInt = expand(input.length);
  673. System.arraycopy(input, 0, file, SIZE - input.length - tempInt, input.length);
  674. } //append method; tested and working!
  675.  
  676. /**
  677. * Performs file writing of given input array of bytes
  678. * at end of file
  679. * @param input A byte array of the data to write to the file
  680. */
  681. public static void writeToFile(byte input[])
  682. {
  683. LAST_WRITE_INDEX = SIZE;
  684. byte tempByte[] = new byte[input.length];
  685. System.arraycopy(input, 0, tempByte, 0, input.length);
  686. append(tempByte);
  687.  
  688. saved = false;
  689. } //writeToFile method; tested and working!
  690.  
  691. /**
  692. * This method is for overwriting invalid data and is very insecure<br>
  693. * The data in file from address to input.length + address is forcefully
  694. * filled with input's contents<br>
  695. * Because this method should only be used by methods that have knowledge
  696. * of what they're doing with this method, there are no index validations
  697. * or checks to make sure the data being overwritten is truly unnecessary
  698. * @param input A byte array of the data to overwrite part of the open
  699. * file with
  700. * @param address The address to write the input to within the
  701. * open file
  702. */
  703. public static void overwriteFile(byte input[], int address)
  704. {
  705. System.arraycopy(input, 0, file, address, input.length);
  706. saved = false;
  707. } //overwriteFile method; doesn't need testing
  708.  
  709. /**
  710. * Performs a writeToFile call and places a pointer to the area
  711. * where the given data was written at the index of pointerAddress<br>
  712. * LAST_WRITE_INDEX is updated to equal pointerAddress
  713. * @param input A byte array of the data to overwrite part of the open
  714. * file with
  715. * @param pointerAddress The address of the pointer pointing to the
  716. * data being replaced so that it can be updated to point to the data
  717. * it is being replaced with
  718. */
  719. public static void writeAndRepoint
  720. (
  721. byte input[],
  722. int pointerAddress
  723. )
  724. {
  725. writeToFile(input);
  726. putInt(file, pointerAddress, LAST_WRITE_INDEX);
  727. LAST_WRITE_INDEX = pointerAddress;
  728. } //writeAndRepoint method; tested and working!
  729.  
  730. /**
  731. * This method is for replacing aligned integer values
  732. * (emphasis on aligned)<br>
  733. * This is great for replacing old pointers with new pointers for
  734. * expansion purposes
  735. * @param oldVal Integer value to replace occurrences of
  736. * @param newVal Integer value to replace occurrences of oldVal with
  737. */
  738. public static void findAndReplace(int oldVal, int newVal)
  739. {
  740. for (int i = 0; i < SIZE; i += 4)
  741. if (getInt(file, i) == oldVal)
  742. putInt(file, i, newVal);
  743.  
  744. saved = false;
  745. } //findAndReplace method; tested and working!
  746.  
  747. /**
  748. * For resetting file variables to their "closed" status
  749. */
  750. public static void closeFile()
  751. {
  752. SIZE = -1;
  753. file = new byte[] {-1};
  754. LAST_WRITE_INDEX = 0;
  755. saved = true;
  756. fileName = "";
  757. } //closeFile method; doesn't need testing
  758. }
  759.  
  760.  
Advertisement
Add Comment
Please, Sign In to add comment