private void Given_Omf(RecordType rt, ushort length, params Action [] mutators) { writer.WriteByte((byte)rt); writer.WriteLeUInt16(length); foreach (var mutator in mutators) { mutator(); } }
/// <summary> /// Create a segment for the MS-DOS program segment prefix (PSP). /// </summary> /// <param name="addrPsp">The address of the PSP</param> /// <param name="segMemTop">The segment address (paragraph) of the first byte /// beyond the image.</param> /// <returns> /// An <see cref="ImageSegment"/> that can be added to a <see cref="SegmentMap"/>. /// </returns> private ImageSegment MakeProgramSegmentPrefix(Address addrPsp, ushort segMemTop) { var mem = new ByteMemoryArea(addrPsp, new byte[0x100]); var w = new LeImageWriter(mem, 0); w.WriteByte(0xCD); w.WriteByte(0x20); w.WriteLeUInt16(segMemTop); // Some unpackers rely on this value. return(new ImageSegment("PSP", mem, AccessMode.ReadWriteExecute)); }
public void Given_DebugHeader(short nSymbols, short nTypes) { writer.WriteLeUInt16(SymbolLoader.MagicNumber); // magic_number writer.WriteLeUInt16(0); // version_id // Remember this position so we can backpatch later. this.offNames = writer.Position; writer.WriteLeUInt32(0); // names writer.WriteLeUInt16(0); // names_count writer.WriteLeInt16(nTypes); // types_count writer.WriteLeUInt16(0); // members_count writer.WriteLeInt16(nSymbols); // symbols_count writer.WriteLeUInt16(0); // globals_count writer.WriteLeUInt16(0); // modules_count writer.WriteLeUInt16(0); // locals_count writer.WriteLeUInt16(0); // scopes_count writer.WriteLeUInt16(0); // lines_count writer.WriteLeUInt16(0); // source_count writer.WriteLeUInt16(0); // segment_count writer.WriteLeUInt16(0); // correlation_count writer.WriteUInt32(0); // image_size writer.WriteUInt32(0); // /*void far * */debugger_hook writer.WriteByte(0); // program_flags writer.WriteLeUInt16(0); // stringsegoffset writer.WriteLeUInt16(0); // data_count writer.WriteByte(0); // filler writer.WriteLeUInt16(0x00); // extension_size }
private void Given_Bundle(byte nEntries, byte iSeg, params BundleEntry[] entries) { writer.WriteByte(nEntries); writer.WriteByte(iSeg); foreach (var entry in entries) { writer.WriteByte(entry.flags); if (entry.flags == 0) { break; } if (entry.iSeg != 0) { writer.WriteBeUInt16(0xCD3F); // INT 3F [sic] writer.WriteByte(entry.iSeg); } writer.WriteLeUInt16(entry.offset); } }
private void Given_IndirectTable_UInt32(Address address, Address addrIndirect, params uint[] entries) { ImageSegment seg; program.SegmentMap.Segments.TryGetValue(address, out seg); var writer = new LeImageWriter(seg.MemoryArea, address); foreach (uint entry in entries) { writer.WriteLeUInt32(entry); } writer = new LeImageWriter(seg.MemoryArea, addrIndirect); for (int i = 0; i < entries.Length; ++i) { writer.WriteByte((byte)i); } }
private int Given_ImportDescriptor32( int rvaIlt, string dllName, int rvaIat) { var rvaDllName = writer.Position; writer.WriteString(dllName, Encoding.UTF8); writer.WriteByte(0); var rvaId = writer.Position; writer.WriteLeInt32(rvaIlt); writer.WriteLeInt32(0); // (ignored) datestamp writer.WriteLeInt32(0); // forwarder chain writer.WriteLeInt32((int)rvaDllName); writer.WriteLeInt32(rvaIat); return((int)rvaId); }
private byte[] CreateMsdosHeader() { ImageWriter stm = new LeImageWriter(new byte[16]); stm.WriteByte(0x4D); // MZ stm.WriteByte(0x5A); stm.WriteBytes(0xCC, 4); stm.WriteLeUInt16(0x0090); stm.WriteBytes(0xCC, 0x12); stm.WriteByte(0x00); stm.WriteByte(0x00); stm.WriteByte(0x05); stm.WriteByte(0x21); stm.WriteString("PKLITE", Encoding.ASCII); stm.WriteBytes(0xCC, 0x0C); return(stm.Bytes); }
/// <summary> /// Unpacks the packed raw image into <paramref name="image" />. /// </summary> private void UnpackImage(FileHeader fileHeader, ByteMemoryArea image) { var w = new LeImageWriter(image.Bytes); // // Still looking for additional information on Pharlap file packing // // Packing implemented is currently based on reviewing code and interpretation of data against loading program in debugger. // Record is 16 bit word. // If bit 15 is clear ie 0-7FFF, load the next record number of bytes into memory // // If bit 15 is set, ie 8000-FFFF use value lower 15 bits for size of repeat area // Next byte (dataSize) defines size of item to be repeated // If dataSize size is larger than size of repeat area, corrupt file // if dataSize is 0, then is either fill with zero or skip, size of repeat area // Read itemSize number of bytes for the repeatData // copying repeatData until filled size of repeat area // var rdr = new LeImageReader(RawImage, FileHeaderOffset + fileHeader.offset_load_image); while (w.Position < fileHeader.memory_requirements) { if (!rdr.TryReadUInt16(out ushort us)) { throw new BadImageFormatException("Unexpected EOF while loading program."); } if ((us & 0x8000) == 0) { rdr.ReadBytes(w.Bytes, w.Position, us); w.Position += us; } else { us &= 0x7FFF; if (!rdr.TryReadByte(out var dataSize)) { throw new BadImageFormatException("Unexpected EOF while loading program."); } if (dataSize > us) { throw new BadImageFormatException("Corrupt file"); // Corrupt file, Repeated data shouldn't be bigger than size of repeat block } if (dataSize == 0) { for (int i = 0; i < us; ++i) { w.WriteByte(dataSize); } } else { var repeatData = new byte[dataSize]; for (int i = 0; i < dataSize; ++i) { if (!rdr.TryReadByte(out var b)) { throw new BadImageFormatException("Unexpected EOF while loading program."); } repeatData[i] = b; } for (int i = 0; i < us; i += dataSize) { w.WriteBytes(repeatData); } } } } }