private void lvListing_SelectedIndexChanged(object sender, EventArgs e)
        {
            txtStatus.Text = "";
            if (lvListing.SelectedIndices.Count == 0)
            {
                return;
            }

            int i = lvListing.SelectedIndices[0];

            activeRowIndex = i;

            // Display brief description of instruction.
            ListingRow row = viewModel.Rows[viewportBeginIndex + i];

            if (row is CodeListingRow)
            {
                Operation op   = ((CodeListingRow)row).Instruction.Operation;
                string    desc = op.GetDescription();
                if (desc != null)
                {
                    txtStatus.Text = string.Format("{0} - {1}",
                                                   op.ToString().ToUpperInvariant(), desc);
                }
            }

            Pointer        address = row.Location;
            ByteProperties b       = document.Image[address];

            if (b == null) // TBD: we should also do something for an unanalyzed byte.
            {
                return;
            }

            // Update the current location.
            document.Navigator.SetLocation(row.Location, this, LocationChangeType.Minor);

            // this.ActiveSegment = address.Segment;
        }
        private BasicBlock AnalyzeBasicBlock(XRef start, ICollection <XRef> xrefs)
        {
            Pointer pos = start.Target;

            // Check if we are running into the middle of code or data. This
            // can only happen when we process the first instruction in the
            // block.
            if (image[pos].Type != ByteType.Unknown && !image[pos].IsLeadByte)
            {
                AddError(pos, ErrorCategory.Error,
                         "XRef target is in the middle of code/data (referred from {0})",
                         start.Source);
                return(null);
            }

            // Check if this location is already analyzed as code.
            if (image[pos].Type == ByteType.Code)
            {
                ByteProperties b = image[pos];

                // Now we are already covered by a basic block. If the
                // basic block *starts* from this address, do nothing.
                // Otherwise, split the basic block into two.
                if (b.BasicBlock.StartAddress == pos.LinearAddress)
                {
                    return(null);
                }
                else
                {
                    if (image[b.BasicBlock.StartAddress].Address.Segment != pos.Segment)
                    {
                        AddError(pos, ErrorCategory.Error,
                                 "Ran into the middle of a block [{0},{1}) from another segment " +
                                 "when processing block {2} referred from {3}",
                                 b.BasicBlock.StartAddress, b.BasicBlock.EndAddress,
                                 start.Target, start.Source);
                        return(null);
                    }
                    BasicBlock newBlock = b.BasicBlock.Split(pos.LinearAddress);
                    return(null); // newBlock;
                }
            }

            // Analyze each instruction in sequence until we encounter
            // analyzed code, flow instruction, or an error condition.
            while (true)
            {
                // Decode an instruction at this location.
                Pointer     insnPos = pos;
                Instruction insn;
                try
                {
                    insn = image.DecodeInstruction(pos);
                }
                catch (Exception ex)
                {
                    AddError(pos, ErrorCategory.Error, "Bad instruction: {0}", ex.Message);
                    break;
                }

                // Create a code piece for this instruction.
                if (!image.CheckByteType(pos, pos + insn.EncodedLength, ByteType.Unknown))
                {
                    AddError(pos,
                             "Ran into the middle of code when processing block {0} referred from {1}",
                             start.Target, start.Source);
                    break;
                }

                // Advance the byte pointer. Note: the IP may wrap around 0xFFFF
                // if pos.off + count > 0xFFFF. This is probably not intended.
                try
                {
                    Piece piece = image.CreatePiece(pos, pos + insn.EncodedLength, ByteType.Code);
                    pos += insn.EncodedLength;
                }
                catch (AddressWrappedException)
                {
                    AddError(pos, ErrorCategory.Error,
                             "CS:IP wrapped when processing block {1} referred from {2}",
                             start.Target, start.Source);
                    break;
                }

                // Check if this instruction terminates the block.
                if (insn.Operation == Operation.RET ||
                    insn.Operation == Operation.RETF ||
                    insn.Operation == Operation.HLT)
                {
                    break;
                }

                // Analyze BCJ (branch, jump, call) instructions. Such an
                // instruction will create a cross reference.
                XRef xref = AnalyzeFlowInstruction(insnPos, insn);
                if (xref != null)
                {
                    xrefs.Add(xref);

                    // If the instruction is a conditional jump, add xref to
                    // the 'no-jump' branch.
                    // TODO: adding a no-jump xref causes confusion when we
                    // browse xrefs in the disassembly listing window. Is it
                    // truely necessary to add these xrefs?
                    if (xref.Type == XRefType.ConditionalJump)
                    {
                        xrefs.Add(new XRef(
                                      type: XRefType.ConditionalJump,
                                      source: insnPos,
                                      target: pos
                                      ));
                    }

                    // Finish basic block unless this is a CALL instruction.
                    if (xref.Type == XRefType.ConditionalJump ||
                        xref.Type == XRefType.NearJump ||
                        xref.Type == XRefType.FarJump ||
                        xref.Type == XRefType.NearIndexedJump)
                    {
                        break;
                    }
                }

                // If the new location is already analyzed as code, create a
                // control-flow edge from the previous block to the existing
                // block, and we are done.
                if (image[pos].Type == ByteType.Code)
                {
                    System.Diagnostics.Debug.Assert(image[pos].IsLeadByte);
                    break;
                }
            }

            // Create a basic block unless we failed on the first instruction.
            if (pos.LinearAddress > start.Target.LinearAddress)
            {
                return(image.CreateBasicBlock(start.Target.LinearAddress, pos.LinearAddress));
            }
            else
            {
                return(null);
            }
        }
Exemple #3
0
 private static bool IsLeadByteOfData(ByteProperties b)
 {
     return(b.Type == ByteType.Data && b.IsLeadByte);
 }
Exemple #4
0
        public ListingViewModel(BinaryImage image)
        {
            this.image = image;

            // Make a dictionary that maps a location to the error at that location.
            // TODO: there may be multiple errors at a single location.
            Dictionary <LinearPointer, Error> errorMap = new Dictionary <LinearPointer, Error>();

            foreach (Error error in image.Errors)
            {
                errorMap[error.Location.LinearAddress] = error;
            }

            // Display analyzed code and data.
            Pointer address = image.BaseAddress;

            for (var i = image.StartAddress; i < image.EndAddress;)
            {
                ByteProperties b = image[i];

                if (IsLeadByteOfCode(b))
                {
                    if (b.BasicBlock != null && b.BasicBlock.StartAddress == i)
                    {
                        rows.Add(new LabelListingRow(0, b.BasicBlock));
                    }

                    Instruction insn = image.DecodeInstruction(b.Address);
                    rows.Add(new CodeListingRow(0, b.Address, insn, image.GetBytes(i, insn.EncodedLength)));
                    address = b.Address + insn.EncodedLength;
                    i      += insn.EncodedLength;
                }
                else if (IsLeadByteOfData(b))
                {
                    var j = i + 1;
                    while (j < image.EndAddress &&
                           image[j].Type == ByteType.Data &&
                           !image[j].IsLeadByte)
                    {
                        j++;
                    }

                    rows.Add(new DataListingRow(0, b.Address, image.GetBytes(i, j - i)));
                    address = b.Address + (j - i);
                    i       = j;
                }
                else
                {
                    if (errorMap.ContainsKey(i))
                    {
                        //    rows.Add(new ErrorListingRow(errorMap[i]));
                    }
                    var j = i + 1;
                    while (j < image.EndAddress &&
                           !IsLeadByteOfCode(image[j]) &&
                           !IsLeadByteOfData(image[j]))
                    {
                        j++;
                    }

                    rows.Add(new BlankListingRow(0, address, image.GetBytes(i, j - i)));
                    try
                    {
                        address += (j - i);
                    }
                    catch (AddressWrappedException)
                    {
                        address = Pointer.Invalid;
                    }
                    i = j;
                }
            }

            // Create a sorted array containing the address of each row.
            rowAddresses = new LinearPointer[rows.Count];
            for (int i = 0; i < rows.Count; i++)
            {
                rowAddresses[i] = rows[i].Location.LinearAddress;
            }

            // Create a ProcedureItem view object for each non-empty
            // procedure.
            // TODO: display an error for empty procedures.
            foreach (Procedure proc in image.Procedures)
            {
                if (proc.IsEmpty)
                {
                    continue;
                }

                ProcedureItem item = new ProcedureItem(proc);
                //var range = proc.Bounds;
                //item.FirstRowIndex = FindRowIndex(range.Begin);
                //item.LastRowIndex = FindRowIndex(range.End - 1);

                // TBD: need to check broken instruction conditions
                // as well as leading/trailing unanalyzed bytes.
                procItems.Add(item);
            }

            // Create segment items.
            foreach (Segment segment in image.Segments)
            {
                segmentItems.Add(new SegmentItem(segment));
            }
        }
Exemple #5
0
 private static bool IsLeadByteOfCode(ByteProperties b)
 {
     return(b.Type == ByteType.Code && b.IsLeadByte);
 }