Пример #1
0
 private void Given_Omf(RecordType rt, ushort length, params Action [] mutators)
 {
     writer.WriteByte((byte)rt);
     writer.WriteLeUInt16(length);
     foreach (var mutator in mutators)
     {
         mutator();
     }
 }
Пример #2
0
        /// <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));
        }
Пример #3
0
 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
 }
Пример #4
0
 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);
     }
 }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        /// <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);
                        }
                    }
                }
            }
        }