Exemple #1
0
        public void Add(Address address, Instruction instruction)
        {
            if (!image.IsAddressValid(address))
            {
                throw new ArgumentOutOfRangeException("address");
            }
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }

            this.instructions.Add(address, instruction);
        }
        public void SetAt(Address address, ByteAttribute attribute)
        {
            if (!image.IsAddressValid(address))
            {
                throw new ArgumentOutOfRangeException("address");
            }

            for (int i = attrs.Count; i < image.Segments.Count; i++)
            {
                attrs.Add(new ByteAttribute[image.Segments[i].OffsetBounds.End]);
            }

            attrs[address.Segment][address.Offset] = attribute;
        }
        /// <summary>
        /// Fills the Target of an IndexedJump xref heuristically by plugging
        /// in the jump target stored in DataLocation and performing various
        /// sanity checks.
        /// </summary>
        /// <param name="entry">A xref of type IndexedJump whose Target field
        /// is Invalid.</param>
        /// <param name="xrefs">Collection to add a new dynamic IndexedJump
        /// xref to, if any.</param>
        /// <returns>The updated xref, or null if the jump table ends.</returns>
        private XRef ProcessJumpTableEntry(XRef entry, ICollection <XRef> xrefs)
        {
#if true
            return(null);
#else
            System.Diagnostics.Debug.Assert(
                entry.Type == XRefType.NearIndexedJump &&
                entry.Target == LogicalAddress.Invalid,
                "Entry must be NearIndexedJump with unknown target");

            // Verify that the location that supposedly stores the jump table
            // entry is not analyzed as anything else. If it is, it indicates
            // that the jump table ends here.
            LinearPointer b = entry.DataLocation.LinearAddress;
            if (image[b].Type != ByteType.Unknown ||
                image[b + 1].Type != ByteType.Unknown)
            {
                return(null);
            }

            // If the data location looks like in another segment, stop.
            if (image.LargestSegmentThatStartsBefore(b)
                > entry.Source.Segment)
            {
                return(null);
            }

            // TBD: it's always a problem if CS:IP wraps. We need a more
            // general way to detect and fix it. For this particular case,
            // we need to check that the jump target is within the space
            // of this segment.
            if (entry.DataLocation.Offset >= 0xFFFE)
            {
                AddError(entry.DataLocation, ErrorCategory.Error,
                         "Jump table is too big (jumped from {0}).",
                         entry.Source);
                return(null);
            }

            // Find the target address of the jump table entry.
            ushort  jumpOffset = image.GetUInt16(b);
            Pointer jumpTarget = new Pointer(entry.Source.Segment, jumpOffset);

            // Check that the target address looks valid. If it doesn't, it
            // probably indicates that the jump table ends here.
            if (!image.IsAddressValid(jumpTarget.LinearAddress))
            {
                return(null);
            }

            // If the jump target is outside the range of the current segment
            // but inside the range of a later segment, it likely indicates
            // that the jump table ends here.
            // TBD: this heuristic is kind of a hack... we should do better.
#if true
            if (image.LargestSegmentThatStartsBefore(jumpTarget.LinearAddress)
                > entry.Source.Segment)
            {
                return(null);
            }
#endif

            // BUG: We really do need to check that the destination
            // is valid. If not, we should stop immediately.
            if (!(image[jumpTarget].Type == ByteType.Unknown ||
                  image[jumpTarget].Type == ByteType.Code &&
                  image[jumpTarget].IsLeadByte))
            {
                return(null);
            }

            // ...

            // Mark DataLocation as data and add it to the owning procedure's
            // byte range.
            Piece piece = image.CreatePiece(
                entry.DataLocation, entry.DataLocation + 2, ByteType.Data);
            Procedure proc = image[entry.Source].Procedure;
            proc.AddDataBlock(piece.StartAddress, piece.EndAddress);

            // Add a dynamic xref from the JMP instruction to the next jump
            // table entry.
            xrefs.Add(new XRef(
                          type: XRefType.NearIndexedJump,
                          source: entry.Source,
                          target: Pointer.Invalid,
                          dataLocation: entry.DataLocation + 2
                          ));

            // Return the updated xref with Target field filled.
            return(new XRef(
                       type: XRefType.NearIndexedJump,
                       source: entry.Source,
                       target: jumpTarget,
                       dataLocation: entry.DataLocation
                       ));
#endif
        }