Пример #1
0
        public override ILoadedImage Load(Address?addrLoad)
        {
            var rdr     = new ByteImageReader(base.RawImage);
            var archive = new TarArchive(this.ImageLocation);

            for (; ;)
            {
                var tarHeader = rdr.ReadStruct <tar_header>();
                if (tarHeader.filename.All(b => b == 0))
                {
                    break;
                }
                if (PeekString(rdr, "ustar"))
                {
                    var ustarHeader = rdr.ReadStruct <ustar_header>();
                    Align(rdr, TarBlockSize);

                    var filename = TarFile.GetString(tarHeader.filename);
                    var file     = archive.AddFile(filename, (a, p, n) => TarFile.Load(a, p, n, tarHeader, ustarHeader, rdr));

                    rdr.Offset += file.Length;
                    Align(rdr, TarBlockSize);
                }
            }
            return(archive);
        }
Пример #2
0
 private TarFile(IArchive archive, ArchiveDirectoryEntry?parent, ByteImageReader rdr)
 {
     this.archive  = archive;
     this.Parent   = parent;
     this.rdr      = rdr;
     this.offset   = rdr.Offset;
     this.Name     = default !;
Пример #3
0
 private static void AlignReader(ByteImageReader rdr)
 {
     if ((rdr.Offset & 1) != 0)
     {
         rdr.Offset += 1;
     }
 }
Пример #4
0
        public void ArLdr_LoadHeader()
        {
            var arldr = new ArLoader(sc, ImageLocation.FromUri("foo.a"), Encoding.ASCII.GetBytes("!<arch>\n"));
            var rdr   = new ByteImageReader(arldr.RawImage);

            arldr.ReadHeader(rdr);
        }
Пример #5
0
        public void ImrReadOffTheEnd()
        {
            var rdr  = new ByteImageReader(new byte[] { 1, 2, 3, 4 });
            var buf  = new byte[10];
            var read = rdr.Read(buf, 0, buf.Length);

            Assert.AreEqual(4, read);
            Assert.AreEqual(4, rdr.Offset);
        }
Пример #6
0
        public override ILoadedImage Load(Address?addrLoad)
        {
            var rdr = new ByteImageReader(RawImage);

            ReadHeader(rdr);
            var archive = new ArArchive(this.ImageLocation);

            ReadFiles(rdr, archive);
            return(archive);
        }
Пример #7
0
        private static string ReadNullTerminatedString(ByteImageReader rdr)
        {
            var iStart = rdr.Offset;

            while (rdr.IsValid && rdr.ReadByte() != 0)
            {
                ;
            }
            return(Encoding.ASCII.GetString(rdr.Bytes, (int)iStart, (int)(rdr.Offset - iStart) - 1));
        }
Пример #8
0
 public HunkFileParser(ByteImageReader f, bool?v37_compat = null)
 {
     this.f          = f;
     this.v37_compat = v37_compat;
     // Commodore famously used ISO 8859-1 for the Amiga. Different
     // national variants may need to override this.
     this.textEncoding = Encoding.GetEncoding("ISO_8859-1");
     this.hunk_file    = new HunkFile();
     this.hunks        = hunk_file.hunks;
 }
Пример #9
0
 private bool PeekString(ByteImageReader rdr, string v)
 {
     for (int i = 0; i < v.Length; ++i)
     {
         if (!rdr.TryPeekByte(i, out byte b) || (char)b != v[i])
         {
             return(false);
         }
     }
     return(true);
 }
Пример #10
0
 public virtual short read_word(ByteImageReader f)
 {
     if (!f.IsValid)
     {
         return(-1);
     }
     if (!f.IsValidOffset(1))
     {
         return(-2);
     }
     return(f.ReadBeInt16());
 }
Пример #11
0
 private void ReadFiles(ByteImageReader rdr, ArArchive archive)
 {
     for (; ;)
     {
         var header = ArFileHeader.Load(rdr);
         if (header == null)
         {
             return;
         }
         ReadFile(header, rdr, archive);
     }
 }
Пример #12
0
        public void ImrReadIntoMiddleOfBuffer()
        {
            var rdr  = new ByteImageReader(new byte[] { 1, 2, 3, 4 });
            var buf  = new byte[10];
            var read = rdr.Read(buf, 2, buf.Length);

            Assert.AreEqual(2, read);
            Assert.AreEqual(2, rdr.Offset);
            Assert.AreEqual(0, buf[0]);
            Assert.AreEqual(0, buf[1]);
            Assert.AreEqual(1, buf[2]);
            Assert.AreEqual(2, buf[3]);
        }
Пример #13
0
        public void Sr_ReadLeInt32_String()
        {
            var rdr = new ByteImageReader(new byte[] {
                0x34, 0x12,
                0xAB, 0xCD,
                0x48, 0x69, 0x00,
                0x42, 0x79, 0x65, 0x21, 0x00
            });

            var test = rdr.ReadStruct <TestStruct4>();

            Assert.AreEqual("Hi", test.sField04);
            Assert.AreEqual("Bye!", test.sFieldnn);
        }
Пример #14
0
        private void ReadFile(ArFileHeader fileHeader, ByteImageReader rdr, ArArchive archive)
        {
            if (!int.TryParse(fileHeader.FileSize, out int dataSize))
            {
                throw new BadImageFormatException("Invalid archive file header.");
            }
            if (dataSize + rdr.Offset > rdr.Bytes.Length)
            {
                throw new BadImageFormatException("The archive file is corrupt.");
            }

            string name = fileHeader.Name;

            if (name.StartsWith("// "))
            {
                throw new NotImplementedException("Extended file names not implemented yet.");
            }
            else if (name.StartsWith("/ ") || name.StartsWith("__.SYMDEF"))
            {
                // System V symbol lookup table.
                var symbolData = rdr.ReadBytes(dataSize);
                ReadSymbolTable(symbolData);
                return;
            }
            else if (name.StartsWith("#1/ "))
            {
                // File name length follows #1/ as decimal digits.
                // This variant is used by Mac and some versions of BSD.
                var  fileNameLength = Convert.ToInt32(name + 3);
                long fileDataOffset = rdr.Offset + fileNameLength;
                name = Encoding.ASCII.GetString(rdr.ReadBytes(fileNameLength));
                if (dataSize > fileNameLength)
                {
                    // The length of the name is included in the dataSize.
                    dataSize -= fileNameLength;
                }
                rdr.Offset = fileDataOffset;
            }
            else
            {
                // Ordinary short name
                char[] charsToTrim = { '/', ' ' };
                name = name.TrimEnd(charsToTrim);
            }

            archive.AddFile(name, (a, p, name) => new ArFile(a, p, name, rdr, rdr.Offset, dataSize));
            rdr.Offset += dataSize;
            AlignReader(rdr);
        }
Пример #15
0
 public ArFile(
     IArchive archive,
     ArchiveDirectoryEntry?parent,
     string name,
     ByteImageReader rdr,
     long fileDataStart,
     long filesize)
 {
     this.archive       = archive;
     this.Parent        = parent;
     this.Name          = name;
     this.rdr           = rdr;
     this.fileDataStart = fileDataStart;
     this.Length        = filesize;
 }
Пример #16
0
        private Dictionary <string, uint> ReadSymbolTable(byte[] fileData)
        {
            var rdr      = new ByteImageReader(fileData);
            var nEntries = rdr.ReadBeUInt32();
            var offsets  = new uint[nEntries];
            var dict     = new Dictionary <string, uint>();

            for (int i = 0; i < nEntries; ++i)
            {
                offsets[i] = rdr.ReadBeUInt32();
            }
            for (int i = 0; i < nEntries; ++i)
            {
                var name = ReadNullTerminatedString(rdr);
                dict[name] = offsets[i];
            }
            return(dict);
        }
Пример #17
0
        public IArchive LoadDiskDirectory()
        {
            var  entries = new List <ArchiveDirectoryEntry>();
            var  rdr     = new ByteImageReader(RawImage, (uint)SectorOffset(18, 0));
            byte track   = rdr.ReadByte();
            var  archive = new D64Archive(Services, ImageLocation, entries);

            if (track != 0)
            {
                byte sector = rdr.ReadByte();
                rdr.Offset = (uint)D64Loader.SectorOffset(track, sector);
                while (ReadDirectorySector(rdr, archive, entries))
                {
                    ;
                }
            }
            return(archive);
        }
Пример #18
0
        public List <ArchiveDirectoryEntry> LoadDiskDirectory()
        {
            var  entries = new List <ArchiveDirectoryEntry>();
            var  rdr     = new ByteImageReader(RawImage, (uint)SectorOffset(18, 0));
            byte track   = rdr.ReadByte();

            if (track == 0)
            {
                return(entries);
            }
            byte sector = rdr.ReadByte();

            rdr.Offset = (uint)D64Loader.SectorOffset(track, sector);
            while (ReadDirectorySector(rdr, entries))
            {
                ;
            }
            return(entries);
        }
Пример #19
0
            public byte[] GetBytes()
            {
                byte[] data;
                var    stm       = new MemoryStream();
                var    rdr       = new ByteImageReader(image, (uint)offset);
                byte   trackNext = rdr.ReadByte();

                while (trackNext != 0)
                {
                    byte sectorNext = rdr.ReadByte();
                    data = rdr.ReadBytes(0xFE);
                    stm.Write(data, 0, data.Length);

                    rdr.Offset = (uint)SectorOffset(trackNext, sectorNext);
                    trackNext  = rdr.ReadByte();
                }
                byte lastUsed = rdr.ReadByte();

                data = rdr.ReadBytes(lastUsed - 2);
                stm.Write(data, 0, data.Length);
                return(stm.ToArray());
            }
Пример #20
0
        private List <ArchiveDirectoryEntry> LoadTapeDirectory()
        {
            var rdr = new ByteImageReader(RawImage);
            var sig = Encoding.ASCII.GetString(rdr.ReadBytes(0x20));

            if (!sig.StartsWith("C64"))
            {
                throw new BadImageFormatException("Expected T64 file to begin with C64 signature.");
            }

            if (!rdr.TryReadLeUInt16(out ushort version) ||
                (version != 0x0100 && version != 0x0101))
            {
                throw new BadImageFormatException("Unsupported T64 version.");
            }

            if (!rdr.TryReadLeUInt16(out ushort cTotalEntries) ||
                !rdr.TryReadLeUInt16(out ushort cEntriesInUse) ||
                !rdr.TryReadLeUInt16(out ushort padding))
            {
                throw new BadImageFormatException("Unable to read T64 header.");
            }
            var containerName = Encoding.ASCII.GetString(rdr.ReadBytes(0x18)).TrimEnd();

            // Now read the directory entries.

            var entries = new List <ArchiveDirectoryEntry>();

            for (int i = 0; i < cTotalEntries; ++i)
            {
                var entry = ReadDirectoryEntry(rdr);
                if (entry != null)
                {
                    entries.Add(entry);
                }
            }
            return(entries);
        }
Пример #21
0
 public StructureReader(ByteImageReader reader) : this(reader.ReadBytes)
 {
 }
Пример #22
0
        /// <summary>
        /// Parse a single Intel Hex32 hexadecimal record.
        /// </summary>
        /// <param name="hexRecord">The hexadecimal record as a string.</param>
        /// <param name="lineNum">(Optional) The line number in the IHex32 binary stream.</param>
        /// <returns>
        /// An <see cref="IntelHexRecord"/> .
        /// </returns>
        /// <exception cref="IntelHex32Exception">Thrown whenever an error is found in the IHex32 record.</exception>
        public static IntelHexRecord ParseRecord(string hexRecord, int lineNum = 0)
        {
            List <byte> ParseHexData()
            {
                try
                {
                    return(Enumerable.Range(1, hexRecord.Length - 1)
                           .Where(i => (i & 1) != 0)
                           .Select(i => Convert.ToByte(hexRecord.Substring(i, 2), 16))
                           .ToList());
                }
                catch (Exception ex)
                {
                    throw new IntelHexException($"Unable to parse hexedecimal numbers in Intel Hex line [{hexRecord}]", ex, lineNum);
                }
            }

            if (hexRecord == null)
            {
                throw new IntelHexException("Intel Hex line can not be null.", lineNum);
            }
            if (hexRecord.Length < MinHexRecordSize)
            {
                throw new IntelHexException($"Intel Hex line [{hexRecord}] is less than {MinHexRecordSize} characters long.", lineNum);
            }
            if (hexRecord.Length % 2 == 0)
            {
                throw new IntelHexException($"Intel Hex line has an even number of characters [{hexRecord}].", lineNum);
            }
            if (!hexRecord.StartsWith(":"))
            {
                throw new IntelHexException($"Illegal Intel Hex line start character [{hexRecord}].", lineNum);
            }

            var hexData = ParseHexData();

            if (hexData.Count != hexData[0] + 5)
            {
                throw new IntelHexException($"Intel Hex line [{hexRecord}] does not have required record length of [{hexData[0] + 5}].", lineNum);
            }

            if (!Enum.IsDefined(typeof(IntelHexRecordType), hexData[3]))
            {
                throw new IntelHexException($"Intel Hex line has an invalid/unsupported record type value: [{hexData[3]}].", lineNum);
            }

            if ((hexData.Sum(b => b) % 256) != 0)
            {
                throw new IntelHexException($"Checksum for Intel Hex line [{hexRecord}] is incorrect.", lineNum);
            }

            var rdr      = new ByteImageReader(hexData.ToArray());
            var datasize = rdr.ReadByte();

            var newRecord = new IntelHexRecord
            {
                ByteCount  = datasize,
                Address    = rdr.ReadBeUInt16(),
                RecordType = (IntelHexRecordType)rdr.ReadByte(),
                Data       = rdr.ReadBytes(datasize).ToList(),
                CheckSum   = rdr.ReadByte()
            };

            return(newRecord);
        }
Пример #23
0
        private void Align(ByteImageReader rdr, int alignment)
        {
            var blockOffset = (rdr.Offset + alignment - 1) / alignment;

            rdr.Offset = blockOffset * alignment;
        }
Пример #24
0
        public bool SetupLibCheck(IServiceProvider services, string fpath, byte[] bytes)
        {
            var listener = services.RequireService<DecompilerEventListener>();
            var rdr = new ByteImageReader(bytes);
            ushort w, len;
            int i;

            //readProtoFile();

            /* Read the parameters */
            if (!rdr.TryReadLeUInt32(out uint fileSig) || fileSig != 0x73636364) // "dccs"
            {
                listener.Warn(string.Format("{0} is not a DCC signature file.", fpath));
                return false;
            }

            numKeys = rdr.ReadLeUInt16();
            numVert = rdr.ReadLeUInt16();
            PatLen = rdr.ReadLeUInt16();
            SymLen = rdr.ReadLeUInt16();
            if ((PatLen != PATLEN) || (SymLen != SYMLEN))
            {
                listener.Warn(string.Format("Can't use signature file with sym and pattern lengths of {0} and {1}.", SymLen, PatLen));
                return false;
            }

            // Initialise the perfhlib stuff. Also allocates T1, T2, g, etc
            // Set the parameters for the hash table
            g_pattern_hasher.setHashParams(
                            numKeys,                // The number of symbols
                            PatLen,                 // The length of the pattern to be hashed
                            256,                    // The character set of the pattern (0-FF)
                            (char)0,                // Minimum pattern character value
                            numVert);               // Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details
            T1base = g_pattern_hasher.readT1();
            T2base = g_pattern_hasher.readT2();
            g = g_pattern_hasher.readG();

            /* Read T1 and T2 tables */
            ushort ww;
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3154)    // "T1"
            {
                Debug.Print("Expected 'T1'");
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            len = (ushort) (PatLen * 256u * 2);        // 2 = sizeof ushort
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of T1: file {0}, calc {1}", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(T1base, len, rdr);

            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3254)    // "T2"
            {
                Debug.Print("Expected 'T2'");
                return false;
            }
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of T2: file %d, calc %d\n", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(T2base, len, rdr);

            /* Now read the function g[] */
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x6767)    // "gg"
            {
                Debug.Print("Expected 'gg'");
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            len = (ushort) (numVert * 2); //  sizeof(uint16_t));
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of g[]: file {0}, calc {1}", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(g, len, rdr);

            /* This is now the hash table */
            /* First allocate space for the table */
            ht = new HT[numKeys];
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x7468)    // "ht"
            {
                Debug.Print("Expected 'ht'");
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            w = rdr.ReadLeUInt16();
            if (w != numKeys * (SymLen + PatLen + 2)) // sizeof(uint16_t)))
            {
                Debug.Print("Problem with size of hash table: file {0}, calc {1}", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }

            ht = new HT[numKeys];
            for (i = 0; i < numKeys; i++)
            {
                var aSym = rdr.ReadBytes(SymLen)
                    .TakeWhile(b => b != 0).ToArray();

                ht[i] = new HT
                {
                    htSym = Encoding.ASCII.GetString(aSym),
                    htPat = rdr.ReadBytes(PatLen)
                };
            }
            return true;
        }