public static void main(String[] argv) { String victim = "Beginner"; // What's the name of the target? int fpointer = 0; // Where are we in the target class file? // How on earth do I use this thing? if (argv.length != 0) { System.out.println("Try \"java Attacker" + "\"."); System.exit(1); } // If the target isn't writeable, then forget the whole deal. File testit = new File(victim + ".class"); if (!(testit.canWrite())) { System.out.println(victim + ".class must be writeable. Fix it!"); System.exit(2); } try { RandomAccessFile target = new RandomAccessFile(victim + ".class", "rw"); /* Adjust the proper attribute_length and code_length in order to maintain the hacked class file's verifiability. */ // Increase the attacked method's attribute_lenth by 3. fpointer = 455; target.seek(fpointer); int changed_byte = (int) target.readUnsignedByte() + 3; target.seek(fpointer); target.writeByte(changed_byte); // Increase the attacked method's code_length by 3. fpointer = 463; target.seek(fpointer); changed_byte = (int) target.readUnsignedByte() + 3; target.seek(fpointer); target.writeByte(changed_byte); /* Insert the 3 bytes of code to make Beginner.class deviant */ // Get to where we want to insert code. fpointer = 506; target.seek(fpointer); // Save the remainder of the target class file. int diff = (int) target.length() - fpointer; byte[] tail = new byte[diff]; target.read(tail, 0, diff); // Insert the 3 bytes. target.seek(fpointer); target.writeByte(167); target.writeByte(255); target.writeByte(214); // Restore the tail. target.write(tail); // All the changes are made, so close the file and get out of here target.close(); } catch (IOException ioe) { } }
private void loadDataIT(RandomAccessFile fp) throws IOException { byte[] b = new byte[26]; this.name = Util.readString(fp, b, 26); System.out.printf("name: \"%s\"\n", name); this.philigt = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); int ordnum = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); int insnum = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); int smpnum = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); int patnum = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); this.cwtv = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); this.cmwt = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); this.flags = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); this.special = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); this.gv = fp.read(); this.mv = fp.read(); this.spd = fp.read(); this.bpm = fp.read(); this.pwd = fp.read(); this.sep = fp.read(); int msglgth = 0xFFFF & (int) Short.reverseBytes(fp.readShort()); int msgoffs = Integer.reverseBytes(fp.readInt()); this.timestamp = Integer.reverseBytes(fp.readInt()); fp.read(chnpan, 0, 64); fp.read(chnvol, 0, 64); System.out.printf("ver: %04X / compat: %04X\n", cwtv, cmwt); // Load orderlist for (int i = 0; i < ordnum; i++) orderlist[i] = fp.readUnsignedByte(); for (int i = ordnum; i < 256; i++) orderlist[i] = 255; // Load pointers int[] insptrs = new int[insnum]; int[] smpptrs = new int[smpnum]; int[] patptrs = new int[patnum]; for (int i = 0; i < insnum; i++) insptrs[i] = Integer.reverseBytes(fp.readInt()); for (int i = 0; i < smpnum; i++) smpptrs[i] = Integer.reverseBytes(fp.readInt()); for (int i = 0; i < patnum; i++) patptrs[i] = Integer.reverseBytes(fp.readInt()); // TODO: read MIDI + timestamp bollocks // TODO: look up and/or reverse engineer said bollocks // Load data for (int i = 0; i < insnum; i++) { if (insptrs[i] != 0) { fp.seek(insptrs[i]); map_ins.put( (Integer) (i + 1), new SessionInstrument( fp, cmwt < 0x200 ? SessionInstrument.FORMAT_IT100 : SessionInstrument.FORMAT_IT200)); } } for (int i = 0; i < smpnum; i++) { if (smpptrs[i] != 0) { fp.seek(smpptrs[i]); map_smp.put((Integer) (i + 1), new SessionSample(fp, SessionSample.FORMAT_IT)); } } for (int i = 0; i < patnum; i++) { if (patptrs[i] != 0) { fp.seek(patptrs[i]); map_pat.put((Integer) i, new SessionPattern(this, fp, SessionPattern.FORMAT_IT)); } } }