static void saveBlo1(bloPane pane, aBinaryWriter writer, ref uint blockcount) { var typeID = cPAN1; if (pane is bloTextbox) { typeID = cTBX1; } else if (pane is bloWindow) { typeID = cWIN1; } else if (pane is bloPicture) { typeID = cPIC1; } var blockstart = writer.Position; writer.Write32(typeID); writer.Write32(0u); // dummy size pane.saveBlo1(writer); writer.WritePadding(4, 0); var blockend = writer.Position; writer.Goto(blockstart + 4); writer.Write32((uint)(blockend - blockstart)); writer.Goto(blockend); ++blockcount; if (pane.getChildPane() > 0) { writer.Write32(cBGN1); writer.Write32(0x8u); ++blockcount; foreach (var childpane in pane) { saveBlo1(childpane, writer, ref blockcount); } writer.Write32(cEND1); writer.Write32(0x8u); ++blockcount; } }
public void saveBlo1(Stream stream) { aBinaryWriter writer = new aBinaryWriter(stream, Endianness.Big, Encoding.GetEncoding(1252)); var blockstart = writer.Position; var blockcount = 0u; writer.Write32(cSCRN); writer.Write32(cBLO1); writer.Write32(0u); // dummy size writer.Write32(0u); // dummy block count writer.WritePadding(32, 0); writer.Write32(cINF1); writer.Write32(0x10u); writer.WriteS16((short)mRect.width); writer.WriteS16((short)mRect.height); writer.Write32(mTintColor.rgba); ++blockcount; foreach (var childpane in this) { saveBlo1(childpane, writer, ref blockcount); } writer.Write32(cEXT1); writer.Write32(0x8u); ++blockcount; writer.WritePadding(32, 0); var blockend = writer.Position; writer.Goto(blockstart + 8); writer.Write32((uint)(blockend - blockstart)); writer.Write32(blockcount); writer.Goto(blockend); }
static void Main(string[] arguments) { Message("doomwadcorrupter v{0} arookas", new Version(0, 1, 12)); Separator(); if (arguments == null || arguments.Length < 2) { Message("Usage: doomwadcorrupter <input.wad> <output.wad> [options]"); Message(); Message("Options:"); Message(" -start <value>"); Message(" -end <value>"); Message(" -inc <value>"); Message(" -mode <type> [<value>]"); Message(" -skip <filter> [<filter> [...]]"); Message(" -only <filter> [<filter> [...]]"); Message(" -zdoom"); Message(); Message("For more detailed instructions, refer to the official repo page."); Pause(); Exit(false); } var inputWAD = arguments[0]; var outputWAD = arguments[1]; cmd = new aCommandLine(arguments.Skip(2).ToArray()); options = new CorrupterOptions(cmd); DisplayOptions(inputWAD, outputWAD); int lumpCount; var lumpsCorrupted = 0; var lumpsSkipped = 0; var bytesCorrupted = 0; rnd = new Random((uint)options.CorruptSeed); var timeTaken = Stopwatch.StartNew(); using (var instream = OpenWAD(inputWAD)) { var reader = new aBinaryReader(instream, Endianness.Little, Encoding.ASCII); // header var wadType = reader.ReadString(4); if (wadType != "IWAD" && wadType != "PWAD") { Error("Input file is not a DOOM WAD."); } lumpCount = reader.ReadS32(); var directoryOffset = reader.ReadS32(); // directory reader.Goto(directoryOffset); var lumps = aCollection.Initialize(lumpCount, () => new Lump(reader)); using (var outstream = CreateWAD(outputWAD)) { var writer = new aBinaryWriter(outstream, Endianness.Little, Encoding.ASCII); // header writer.WriteString(wadType); writer.WriteS32(lumpCount); writer.WriteS32(directoryOffset); // data var corruptBuff = new byte[options.Increment]; var startBuff = new byte[options.Start]; var ns = LumpNamespace.Global; foreach (var lump in lumps) { reader.Goto(lump.Start); writer.Goto(lump.Start); CheckNamespaceMarker(lump, ref ns); if (options.Filter.IsCorruptable(lump.Name, ns) && !(options.ZDOOM && IsZDOOMLump(lump.Name))) { ++lumpsCorrupted; var i = options.Start; var end = options.End ?? lump.Length; if (i > 0) { var count = (int)System.Math.Min(lump.Length, i); reader.Read(startBuff, count); writer.Write8s(startBuff, count); } while (i < lump.Length && i < end) { Status("Corrupting '{0}'... (0x{1:X8} / 0x{2:X8})", lump.Name, i, lump.Length); var count = (int)System.Math.Min(lump.Length - i, options.Increment); reader.Read(corruptBuff, count); CorruptByte(ref corruptBuff[0], options.CorruptMode, options.CorruptValue); writer.Write8s(corruptBuff, count); ++bytesCorrupted; i += count; } } else { ++lumpsSkipped; writer.Write8s(reader.Read8s(lump.Length)); } } // directory writer.Goto(directoryOffset); foreach (var lump in lumps) { Status("Writing lump directory for '{0}'...", lump.Name); lump.ToStream(writer); } } } timeTaken.Stop(); Status("Finished corrupting."); Message(); Separator(); Message(" Files : {0}", lumpCount); Message(" Files corrupted : {0}", lumpsCorrupted); Message(" Files skipped : {0}", lumpsSkipped); Message("Bytes mercilessly sacrificed : {0}", bytesCorrupted); Message(" Time taken : {0}", timeTaken.Elapsed.ToString("g")); Message(" Finished at : {0}", DateTime.Now.ToString("HH:mm:ss tt")); Pause(); }
public void save(aBinaryWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } // calculate entry shit var entryOffset = calculateEntryOffset(FieldCount); var entrySize = calculateEntrySize(mFields); // write header writer.WriteS32(EntryCount); writer.WriteS32(FieldCount); writer.Write32(entryOffset); writer.WriteS32(entrySize); // write field LUT foreach (var field in mFields) { writer.Write32(field.hash); writer.Write32(field.bitmask); writer.Write16(field.start); writer.Write8(field.shift); writer.Write8((byte)field.type); } // since the stream is write-only, we must write packed integer fields to an intermediate, R/W buffer var buffer = new Dictionary <ushort, uint>(FieldCount); for (var entry = 0; entry < EntryCount; ++entry) { buffer.Clear(); for (var field = 0; field < FieldCount; ++field) { writer.Goto(entryOffset + (entrySize * entry) + mFields[field].start); switch (mFields[field].type) { case jmpValueType.INTEGER: { if (mFields[field].bitmask == 0xFFFFFFFFu) { // field is unpacked; write directly to stream writer.WriteS32(mEntries[entry, field]); } else { // field is packed; write to intermediate buffer if (!buffer.ContainsKey(mFields[field].start)) { buffer[mFields[field].start] = 0u; // if there's no key yet, create one } buffer[mFields[field].start] |= ((uint)mEntries[entry, field] << mFields[field].shift) & mFields[field].bitmask; } break; } case jmpValueType.FLOAT: { writer.WriteF32(mEntries[entry, field]); break; } case jmpValueType.STRING: { writer.WriteString <aCSTR>(mEntries[entry, field], 0x20); break; } } } // flush intermediate buffer foreach (var point in buffer) { writer.Goto(entryOffset + (entrySize * entry) + point.Key); writer.Write32(point.Value); } } }
static bool WriteAafHeader(aBinaryReader reader, aBinaryWriter writer, int id, int index, byte[] data) { long reader_base = reader.Position; long writer_base = writer.Position; int old_offset, old_size; if (!ReadAafHeader(reader, id, index, out old_offset, out old_size)) { return(false); } int difference = (data.Length - old_size); reader.Goto(reader_base); int section; while ((section = reader.ReadS32()) != 0) { bool has_vnum = (section == 2 || section == 3); writer.WriteS32(section); int offset, size; int i = 0; while ((offset = reader.ReadS32()) != 0) { size = reader.ReadS32(); if (offset > old_offset) { offset += difference; } writer.Keep(); writer.Goto(writer_base + offset); if (section == id && i == index) { writer.Write8s(data); size = data.Length; } else { reader.Keep(); reader.Goto(reader_base + offset); writer.Write8s(reader.Read8s(size)); reader.Back(); } writer.Back(); writer.WriteS32(offset); writer.WriteS32(size); if (has_vnum) { writer.WriteS32(reader.ReadS32()); } ++i; } writer.WriteS32(0); } writer.WriteS32(0); writer.Goto(writer.Length); writer.WritePadding(32, 0); return(true); }
void DoReplaceSeq() { if (mAafInPath == null) { mareep.WriteError("CHARGE: missing -init-data-file parameter"); } if (mArcInPath == null) { mareep.WriteError("CHARGE: missing -seq-data-file parameter"); } byte[] arc_data = ReadFileData(mArcInPath); if (mInput == null) { mareep.WriteError("CHARGE: missing -input parameter"); } byte[] seq_data = ReadFileData(mInput); if (mTarget == null) { mareep.WriteError("CHARGE: missing -target parameter"); } byte[] barc_data = null; using (Stream input = mareep.OpenFile(mAafInPath)) { mareep.WriteMessage("Scanning AAF header...\n"); aBinaryReader reader = new aBinaryReader(input, Endianness.Big); int offset, size; if (!ReadAafHeader(reader, 4, 0, out offset, out size)) { mareep.WriteError("CHARGE: failed to find sequence info block"); } reader.Goto(offset); if (reader.ReadS32() != 0x42415243) // 'BARC' { mareep.WriteError("CHARGE: could not find 'BARC' header"); } reader.Goto(offset + 12); int count = reader.ReadS32(); barc_data = new byte[32 + 32 * count]; reader.Goto(offset + 32); int index, old_offset, old_size; mareep.WriteMessage("Found sequence info data (0x{0:X6}, 0x{1:X6}), {2} sequence(s)\n", offset, size, count); mareep.WriteMessage("Scanning sequence list...\n"); if (!ReadBarcHeader(reader, mTarget, count, out index, out old_offset, out old_size)) { mareep.WriteError("CHARGE: could not find sequence {0}", mTarget); } mareep.WriteMessage("Found sequence {0} (0x{1:X6}, 0x{2:X6})\n", index, offset, size); int new_offset, new_size = ((seq_data.Length + 31) & ~31); int difference = (new_size - old_size); reader.Goto(offset + 16); using (Stream arc_stream = mareep.CreateFile(mArcOutPath)) using (MemoryStream barc_stream = new MemoryStream(barc_data, true)) { mareep.WriteMessage("Writing new sequence data...\n"); aBinaryWriter arc_writer = new aBinaryWriter(arc_stream); aBinaryWriter barc_writer = new aBinaryWriter(barc_stream, Endianness.Big); barc_writer.WriteS32(0x42415243); // 'BARC' barc_writer.WriteS32(0x2D2D2D2D); // '----' barc_writer.WriteS32(0); barc_writer.WriteS32(count); barc_writer.Write8s(reader.Read8s(16)); for (int i = 0; i < count; ++i) { barc_writer.Write8s(reader.Read8s(14)); barc_writer.WriteS16(reader.ReadS16()); barc_writer.WriteS32(reader.ReadS32()); barc_writer.WriteS32(reader.ReadS32()); offset = reader.ReadS32(); size = reader.ReadS32(); new_offset = offset; if (offset > old_offset) { new_offset += difference; } arc_writer.Goto(new_offset); if (i == index) { arc_writer.Write8s(seq_data); arc_writer.WritePadding(32, 0); size = new_size; } else { arc_writer.Write8s(arc_data, offset, size); } barc_writer.WriteS32(new_offset); barc_writer.WriteS32(size); } } reader.Goto(0); using (Stream output = mareep.CreateFile(mAafOutPath)) { mareep.WriteMessage("Writing new AAF file...\n"); aBinaryWriter writer = new aBinaryWriter(output, Endianness.Big); if (!WriteAafHeader(reader, writer, 4, 0, barc_data)) { mareep.WriteError("CHARGE: failed to write aaf file"); } } } }
static bool WriteAafHeader(aBinaryReader reader, aBinaryWriter writer, int id, int index, byte[] data) { long reader_base = reader.Position; long writer_base = writer.Position; int old_offset, old_size; if (!ReadAafHeader(reader, id, index, out old_offset, out old_size)) { return(false); } int difference = (data.Length - old_size); mareep.WriteMessage("Entry size difference: {0} byte(s)\n", difference); int danger_level = 0; reader.Goto(reader_base); int section; while ((section = reader.ReadS32()) != 0) { if (danger_level++ > 1000) { mareep.WriteError("CHARGE: malformed AAF file (endless loop detected)"); } bool has_vnum = (section == 2 || section == 3); writer.WriteS32(section); int offset, size; int i = 0; while ((offset = reader.ReadS32()) != 0) { if (danger_level++ > 1000) { mareep.WriteError("CHARGE: malformed AAF file (endless loop detected)"); } size = reader.ReadS32(); int new_offset = offset; if (new_offset > old_offset) { new_offset += difference; } writer.Keep(); writer.Goto(writer_base + new_offset); if (section == id && i == index) { writer.Write8s(data); size = data.Length; } else { reader.Keep(); reader.Goto(reader_base + offset); writer.Write8s(reader.Read8s(size)); reader.Back(); } writer.Back(); writer.WriteS32(new_offset); writer.WriteS32(size); if (has_vnum) { writer.WriteS32(reader.ReadS32()); } ++i; } writer.WriteS32(0); } writer.WriteS32(0); writer.Goto(writer.Length); writer.WritePadding(32, 0); return(true); }