Example #1
0
        public static object ReadPointer(Type pointerType, int size, ImageReader rdr, ReaderContext ctx)
        {
            Debug.Print("Reading pointer at offset {0}, size {1}", rdr.Offset, size);
            uint newOffset;
            switch (size)
            {
            default:
                throw new InvalidOperationException("Field size must be > 0.");
            case 1: newOffset = rdr.ReadByte(); break;
            case 2: newOffset = rdr.ReadUInt16(); break;
            case 4: newOffset = rdr.ReadUInt32(); break;
            }
            Debug.Print("Structure of type {0} must start at offset {1:X}", pointerType.Name, newOffset);
            rdr = rdr.Clone();
            rdr.Offset = newOffset;

            var dst = Activator.CreateInstance(pointerType);
            var sr = new StructureReader(dst);
            sr.Read(rdr);
            return dst;
        }
Example #2
0
        private MachineOperand ParseOperandInner(byte addressMode, byte operandBits, PrimitiveType dataWidth, ImageReader rdr)
        {
            Constant offset;
            switch (addressMode)
            {
            case 0: // Data register direct.
                return DataRegisterOperand(operandBits, 0);
            case 1: // Address register direct
                return new RegisterOperand(AddressRegister(operandBits, 0));
            case 2:  // Address register indirect
                return MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0));
            case 3:  // Address register indirect with postincrement.
                return MemoryOperand.PostIncrement(dataWidth, AddressRegister(operandBits, 0));
            case 4:  // Address register indirect with predecrement.
                return MemoryOperand.PreDecrement(dataWidth, AddressRegister(operandBits, 0));
            case 5: // Address register indirect with displacement.
                offset = Constant.Int16(rdr.ReadBeInt16());
                return MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0), offset);
            case 6: // Address register indirect with index
                return AddressRegisterIndirectWithIndex(dataWidth, rdr);
            case 7:
                switch (operandBits)
                {
                case 0: // Absolute short address
                    return new M68kAddressOperand(rdr.ReadBeUInt16());
                case 1: // Absolute long address
                    return new M68kAddressOperand(rdr.ReadBeUInt32());
                case 2: // Program counter with displacement
                    var off = rdr.Address - dasm.instr.Address;
                    off += rdr.ReadBeInt16();
                    return new MemoryOperand(dataWidth, Registers.pc, Constant.Int16((short) off));
                case 3:
                    // Program counter with index
                    var addrExt = rdr.Address;
                    ushort extension = rdr.ReadBeUInt16();

                    if (EXT_FULL(extension))
                    {
                        if (EXT_EFFECTIVE_ZERO(extension))
                        {
                            return new M68kImmediateOperand(Constant.Word32(0));
                        }
                        Constant @base = null;
                        Constant outer = null;
                        if (EXT_BASE_DISPLACEMENT_PRESENT(extension)) 
                            @base = EXT_BASE_DISPLACEMENT_LONG(extension) 
                                ? rdr.ReadBe(PrimitiveType.Word32)
                                : rdr.ReadBe(PrimitiveType.Int16);
                        if (EXT_OUTER_DISPLACEMENT_PRESENT(extension))
                            outer = EXT_OUTER_DISPLACEMENT_LONG(extension)
                                ? rdr.ReadBe(PrimitiveType.Word32)
                                : rdr.ReadBe(PrimitiveType.Int16);
                        RegisterStorage base_reg = EXT_BASE_REGISTER_PRESENT(extension)
                            ? Registers.pc
                            : null;
                        RegisterStorage index_reg = null;
                        PrimitiveType index_width = null;
                        int index_scale = 0;
                        if (EXT_INDEX_REGISTER_PRESENT(extension))
                        {
                            index_reg = EXT_INDEX_AR(extension)
                                ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension))
                                : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension));
                            index_width = EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16;
                            index_scale = (EXT_INDEX_SCALE(extension) != 0)
                                ? 1 << EXT_INDEX_SCALE(extension)
                                : 0;
                        }
                       return new IndexedOperand(dataWidth, @base, outer, base_reg, index_reg, index_width, index_scale, 
                           (extension & 7) > 0 && (extension & 7) < 4,
                           (extension & 7) > 4);
                    }
                    return new IndirectIndexedOperand(
                        EXT_8BIT_DISPLACEMENT(extension), 
                        Registers.pc,
                        EXT_INDEX_AR(extension) ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension)) : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension)),
                        EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16,
                        1 << EXT_INDEX_SCALE(extension));

                case 4:
                    //  Immediate
                    if (dataWidth.Size == 1)        // don't want the instruction stream to get misaligned!
                        rdr.ReadByte();
                    return new M68kImmediateOperand(rdr.ReadBe(dataWidth));
                default:
                    throw new NotImplementedException(string.Format("Address mode {0}:{1} not implemented.", addressMode, operandBits));
                }
            default: 
                throw new NotImplementedException(string.Format("Address mode {0:X1} not implemented.", addressMode));
            }
        }
Example #3
0
 private static M68kImmediateOperand GetImmediate(ImageReader rdr, PrimitiveType type)
 {
     if (type.Size == 1)
     {
         rdr.ReadByte();     // skip a byte so we get the appropriate lsb byte and align the word stream.
     }
     return new M68kImmediateOperand(rdr.ReadBe(type));
 }
Example #4
0
		private static string ReadSectionName(ImageReader rdr)
		{
			byte [] bytes = new Byte[8];
			for (int b = 0; b < bytes.Length; ++b)
			{
				bytes[b] = rdr.ReadByte();
			}

			Encoding asc = Encoding.ASCII;
			char [] chars = asc.GetChars(bytes);
			int i;
			for (i = chars.Length - 1; i >= 0; --i)
			{
				if (chars[i] != 0)
				{
					++i;
					break;
				}
			}
			return new String(chars, 0, i);
		}
Example #5
0
		public void ReadOptionalHeader(ImageReader rdr, short expectedMagic)
		{
			if (optionalHeaderSize <= 0)
				throw new BadImageFormatException("Optional header size should be larger than 0 in a PE executable image file.");

			short magic = rdr.ReadLeInt16();
			if (magic != expectedMagic) 
				throw new BadImageFormatException("Not a valid PE Header.");
			rdr.ReadByte();		// Linker major version
			rdr.ReadByte();		// Linker minor version
			rdr.ReadLeUInt32();		// code size (== .text section size)
			rdr.ReadLeUInt32();		// size of initialized data
			rdr.ReadLeUInt32();		// size of uninitialized data
			rvaStartAddress = rdr.ReadLeUInt32();
			uint rvaBaseOfCode = rdr.ReadLeUInt32();
            preferredBaseOfImage = innerLoader.ReadPreferredImageBase(rdr);
			rdr.ReadLeUInt32();		// section alignment
			rdr.ReadLeUInt32();		// file alignment
			rdr.ReadLeUInt16();		// OS major version
			rdr.ReadLeUInt16();		// OS minor version
			rdr.ReadLeUInt16();		// Image major version
			rdr.ReadLeUInt16();		// Image minor version
			rdr.ReadLeUInt16();		// Subsystem major version
			rdr.ReadLeUInt16();		// Subsystem minor version
			rdr.ReadLeUInt32();		// reserved
			uint sizeOfImage = rdr.ReadLeUInt32();
			uint sizeOfHeaders = rdr.ReadLeUInt32();
			uint checksum = rdr.ReadLeUInt32();
			ushort subsystem = rdr.ReadLeUInt16();
			ushort dllFlags = rdr.ReadLeUInt16();
            var stackReserve = rdr.Read(arch.WordWidth);
            var stackCommit = rdr.Read(arch.WordWidth);
            var heapReserve = rdr.Read(arch.WordWidth);
            var heapCommit = rdr.Read(arch.WordWidth);
			rdr.ReadLeUInt32();			// loader flags
			uint dictionaryCount = rdr.ReadLeUInt32();

            if (dictionaryCount == 0) return;
			rvaExportTable = rdr.ReadLeUInt32();
			sizeExportTable = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            rvaImportTable = rdr.ReadLeUInt32();
			uint importTableSize = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
			rdr.ReadLeUInt32();			// resource address
			rdr.ReadLeUInt32();			// resource size

            if (--dictionaryCount == 0) return;
			rdr.ReadLeUInt32();			// exception address
			rdr.ReadLeUInt32();			// exception size

            if (--dictionaryCount == 0) return;
			rdr.ReadLeUInt32();			// certificate address
			rdr.ReadLeUInt32();			// certificate size

            if (--dictionaryCount == 0) return;
            uint rvaBaseRelocAddress = rdr.ReadLeUInt32();
			uint baseRelocSize = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            uint rvaDebug = rdr.ReadLeUInt32();
            uint cbDebug = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            uint rvaArchitecture = rdr.ReadLeUInt32();
            uint cbArchitecture = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            uint rvaGlobalPointer = rdr.ReadLeUInt32();
            uint cbGlobalPointer = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            uint rvaTls = rdr.ReadLeUInt32();
            uint cbTls = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            uint rvaLoadConfig = rdr.ReadLeUInt32();
            uint cbLoadConfig = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            uint rvaBoundImport = rdr.ReadLeUInt32();
            uint cbBoundImport = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            uint rvaIat = rdr.ReadLeUInt32();
            uint cbIat = rdr.ReadLeUInt32();

            if (--dictionaryCount == 0) return;
            this.rvaDelayImportDescriptor = rdr.ReadLeUInt32();
            uint cbDelayImportDescriptor = rdr.ReadLeUInt32();
		}
Example #6
0
            /// <summary>
            /// Paints a line of the memory control, starting with the address. 
            /// </summary>
            /// <remarks>
            /// The strategy is to find any items present at the current address, and try
            /// to paint as many adjacent items as possible.
            /// </remarks>
            /// <param name="g"></param>
            /// <param name="rc"></param>
            /// <param name="rdr"></param>
            private Address PaintLine(Graphics g, Rectangle rc, ImageReader rdr, Point ptAddr, bool render)
            {
                StringBuilder sbCode = new StringBuilder(" ");

                // Draw the address part.

                rc.X = 0;
                string s = string.Format("{0}", rdr.Address);
                int cx = (int) g.MeasureString(s + "X", ctrl.Font, rc.Width, StringFormat.GenericTypographic).Width;
                if (!render && new Rectangle(rc.X, rc.Y, cx, rc.Height).Contains(ctrl.ptDown))
                {
                    return rdr.Address;
                }
                else
                {
                    g.FillRectangle(SystemBrushes.Window, rc.X, rc.Y, cx, rc.Height);
                    g.DrawString(s, ctrl.Font, SystemBrushes.ControlText, rc.X, rc.Y, StringFormat.GenericTypographic);
                }
                cx -= cellSize.Width / 2;
                rc = new Rectangle(cx, rc.Top, rc.Width - cx, rc.Height);

                uint rowBytesLeft = ctrl.cbRow;
                ulong linearSelected = ctrl.addrSelected != null ? ctrl.addrSelected.ToLinear() : ~0UL;
                ulong linearAnchor = ctrl.addrAnchor != null ? ctrl.addrAnchor.ToLinear() : ~0UL;
                ulong linearBeginSelection = Math.Min(linearSelected, linearAnchor);
                ulong linearEndSelection = Math.Max(linearSelected, linearAnchor);

                do
                {
                    Address addr = rdr.Address;
                    ulong linear = addr.ToLinear();

                    ImageMapItem item;
                    if (!ctrl.ImageMap.TryFindItem(addr, out item))
                        break;
                    ulong cbIn = (linear - item.Address.ToLinear());			// # of bytes 'inside' the block we are.
                    uint cbToDraw = 16; // item.Size - cbIn;

                    // See if the chunk goes off the edge of the line. If so, clip it.
                    if (cbToDraw > rowBytesLeft)
                        cbToDraw = rowBytesLeft;

                    // Now paint the bytes in this span.

                    for (int i = 0; i < cbToDraw; ++i)
                    {
                        Address addrByte = rdr.Address;
                        ctrl.ImageMap.TryFindItem(addrByte, out item);
                        bool isSelected = linearBeginSelection <= addrByte.ToLinear() && addrByte.ToLinear() <= linearEndSelection;
                        bool isCursor = addrByte.ToLinear() == linearSelected;
                        if (rdr.IsValid)
                        {
                            byte b = rdr.ReadByte();
                            s = string.Format("{0:X2}", b);
                            char ch = (char) b;
                            sbCode.Append(Char.IsControl(ch) ? '.' : ch);
                        }
                        else
                        {
                            s = "??";
                            sbCode.Append(' ');
                        }

                        cx = cellSize.Width * 3;
                        Rectangle rcByte = new Rectangle(
                            rc.Left,
                            rc.Top,
                            cx,
                            rc.Height);

                        if (!render && rcByte.Contains(ptAddr))
                            return addrByte;

                        var theme = GetBrushTheme(item, isSelected);
                        g.FillRectangle(theme.Background, rc.Left, rc.Top, cx, rc.Height);
                        if (!isSelected && theme.StartMarker != null && addrByte.ToLinear() == item.Address.ToLinear())
                        {
                            var pts = new Point[] 
                            {
                                rc.Location,
                                rc.Location,
                                rc.Location,
                            };
                            pts[1].Offset(4, 0);
                            pts[2].Offset(0, 4);
                            g.FillClosedCurve(theme.StartMarker, pts);
                        }
                        g.DrawString(s, ctrl.Font, theme.Foreground, rc.Left + cellSize.Width / 2, rc.Top, StringFormat.GenericTypographic);
                        if (isCursor)
                        {
                            ControlPaint.DrawFocusRectangle(g, rc);
                        }
                        rc = new Rectangle(rc.X + cx, rc.Y, rc.Width - cx, rc.Height);
                    }
                    rowBytesLeft -= cbToDraw;
                } while (rowBytesLeft > 0);

                if (render)
                {
                    g.FillRectangle(SystemBrushes.Window, rc);
                    g.DrawString(sbCode.ToString(), ctrl.Font, SystemBrushes.WindowText, rc.X + cellSize.Width, rc.Top, StringFormat.GenericTypographic);
                }
                return null;
            }