Exemplo n.º 1
0
        public void LoadElfIdentification()
        {
            var rdr      = new BeImageReader(base.RawImage, 0);
            var elfMagic = rdr.ReadBeInt32();

            if (elfMagic != ELF_MAGIC)
            {
                throw new BadImageFormatException("File is not in ELF format.");
            }
            this.fileClass   = rdr.ReadByte();
            this.endianness  = rdr.ReadByte();
            this.fileVersion = rdr.ReadByte();
            this.osAbi       = rdr.ReadByte();
        }
Exemplo n.º 2
0
        private int GetRunLengthValue(BeImageReader a5dr, ref int a5repeat)
        {
            // Run length returned is in byte(s).
            // next byte read - see bit pattern from the following table for the return value
            // 0xxxxxxx - 0 - $7F
            // 10xxxxxx - 0 - $3FFF(run length and $3F + next byte, 14 bits)
            // 110xxxxx - 0 - $1FFFFF(run length and $1F + next two bytes, 21 bits)
            // 1110xxxx - next 4 bytes, 32 bits
            // 1111xxxx - get both new runtime length copy in bytes and new runtime length repeat count

            int runLength = a5dr.ReadByte();

            if ((runLength & 0x80) == 0)
            {
                return(runLength);
            }
            if ((runLength & 0x40) == 0)
            {
                runLength = runLength & 0x3F;
                runLength = (runLength << 8) + a5dr.ReadByte();
                return(runLength);
            }
            if ((runLength & 0x20) == 0)
            {
                runLength = runLength & 0x1F;
                runLength = (runLength << 16) + a5dr.ReadBeInt16();
                return(runLength);
            }
            if ((runLength & 0x10) == 0)
            {
                return(a5dr.ReadBeInt32());
            }
            runLength = GetRunLengthValue(a5dr, ref a5repeat);
            a5repeat  = GetRunLengthValue(a5dr, ref a5repeat);
            return(runLength);
        }
Exemplo n.º 3
0
        private void A5Expand(BeImageReader a5dr, UInt32 a5dbelow)
        {
            var  a5belowWriter       = new BeImageWriter(platform.A5World.MemoryArea, platform.A5Offset - a5dbelow);
            int  a5RunLengthToken    = 0;
            int  a5RunLengthCopySize = 0;
            int  a5globalSkip        = 0;
            int  a5repeat            = 0;
            var  a5copylength        = 0;
            bool a5dataEnd           = false;

            // Compressed data
            // set Repeat count = 1, reset after each completed copy cycle
            // byte token lower 4 bits number of words to copy from compressed data
            // byte token upper 4 bits number of words to skip in global application data space
            // if either value is 0 then get run length value which is in bytes.
            // if the new run length value for copy is 0 then it's the end of compression data.

            do
            {
                a5repeat = 1;
                // Token value - upper nibble is words to skip, lower nibble is words to copy
                a5RunLengthToken    = a5dr.ReadByte();
                a5globalSkip        = a5RunLengthToken;
                a5RunLengthCopySize = a5RunLengthToken & 0x0F;
                if (a5RunLengthCopySize == 0)
                {
                    a5RunLengthCopySize = GetRunLengthValue(a5dr, ref a5repeat);
                    if (a5RunLengthCopySize == 0)
                    {
                        a5dataEnd = true;
                    }
                }
                else
                {
                    a5RunLengthCopySize = a5RunLengthCopySize * 2;
                }
                if (!a5dataEnd)
                {
                    a5globalSkip = a5globalSkip & 0xF0;
                    if (a5globalSkip == 0)
                    {
                        a5globalSkip = GetRunLengthValue(a5dr, ref a5repeat);
                    }
                    else
                    {
                        // convert value 0x01 - 0x0F number of words to skip in upper nibble to number of bytes to skip
                        a5globalSkip = a5globalSkip >> 3;
                    }
                    do
                    {
                        a5belowWriter.Position = a5belowWriter.Position + a5globalSkip;
                        a5copylength           = a5RunLengthCopySize;
                        do
                        {
                            a5belowWriter.WriteByte(a5dr.ReadByte());
                            a5copylength -= 1;
                        } while (a5copylength > 0);
                        a5repeat -= 1;
                    } while (a5repeat > 0);
                }
            } while (!a5dataEnd);
        }
Exemplo n.º 4
0
        public void Relocate()
        {
            var  memA5          = (ByteMemoryArea)platform.A5World.MemoryArea;
            var  a5belowWriter  = new BeImageWriter(memA5, 0);
            var  a5belowReader  = new BeImageReader(memA5, 0);
            uint a5globalOffset = platform.A5Offset - a5dbelow;

            var a5WorldAddress = (UInt32)((platform.A5World.Address.Offset + platform.A5Offset) & 0xFFFFFFFF);

            // set Repeat count = 1, reset after each completed copy cycle
            // byte token lower 4 bits number of words to copy from compressed data
            // byte token upper 4 bits number of words to skip in global application data space
            // if either value is 0 then get run length value which is in bytes.
            // if the new run length value for copy is 0 then it's the end of compression data.

            for (;;)
            {
                int a5repeat = 1;
                // Skip is number of 16-bit words to skip
                uint a5globalSkip = a5dr.ReadByte();
                if (a5globalSkip == 0)
                {
                    a5globalSkip = a5dr.ReadByte();
                    if (a5globalSkip == 0)
                    {
                        break;
                    }
                    if (a5globalSkip > 0x7F)
                    {
                        a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte();
                        a5globalSkip = (a5globalSkip << 16) + a5dr.ReadBeUInt16();
                    }
                    else
                    {
                        a5repeat = ResourceFork.GetRunLengthValue(a5dr, ref a5repeat);
                        //$BUG: a5repeat could return the value 0. The do-while below will
                        // decrement a5repeat before testing. This will lead to an effective
                        // repeat count of 2^32; likely not wanted.
                    }
                }
                else
                {
                    if ((a5globalSkip & 0x80) == 0x80)
                    {
                        a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte();
                    }
                }
                a5globalSkip = a5globalSkip * 2;
                do
                {
                    a5globalOffset += a5globalSkip;
                    a5belowReader.Seek(a5globalOffset, SeekOrigin.Begin);
                    uint a5ptrOffset = a5belowReader.ReadBeUInt32();
                    a5belowWriter.Position = (int)a5globalOffset;

                    // write relocated A5World pointers to absolute address in A5World segment
                    // Possible register/mark as Global pointer references to strings

                    a5belowWriter.WriteBeUInt32((a5WorldAddress + a5ptrOffset) & 0xFFFFFFFF);
                    --a5repeat;
                } while (a5repeat > 0);
            }
        }