private void UpdateImage(ObjectModule module) { #if false // For each segment, construct a list of LEDATA/LIDATA records. // These records fill data into the segment. // It is required that the data do not overlap, and do not // exceed segment boundary (here we only support 16-bit segments, // whose maximum size is 64KB). // Find the first CODE segment. LogicalSegment codeSegment = null; foreach (var seg in module.Segments) { if (seg.Class == "CODE") { codeSegment = seg; break; } } if (codeSegment == null) { return; } // Create a BinaryImage with the code. BinaryImage image = new BinaryImage(codeSegment.Image.Data, new Pointer(0, 0)); // Disassemble the instructions literally. Note that this should // be improved, but we don't do that yet. var addr = image.BaseAddress; for (var i = image.StartAddress; i < image.EndAddress;) { var instruction = image.DecodeInstruction(addr); // An operand may have zero or one component that may be // fixed up. Check this. #if false for (int k = 0; k < instruction.Operands.Length; k++) { var operand = instruction.Operands[k]; if (operand is RelativeOperand) { var opr = (RelativeOperand)operand; var loc = opr.Offset.Location; int j = i - image.StartAddress + loc.StartOffset; int fixupIndex = codeSegment.DataFixups[j]; if (fixupIndex != 0) { FixupDefinition fixup = codeSegment.Fixups[fixupIndex - 1]; if (fixup.DataOffset != j) { continue; } var target = new SymbolicTarget(fixup, module); instruction.Operands[k] = new SymbolicRelativeOperand(target); System.Diagnostics.Debug.WriteLine(instruction.ToString()); } } } #endif image.CreatePiece(addr, addr + instruction.EncodedLength, ByteType.Code); image[addr].Instruction = instruction; addr = addr.Increment(instruction.EncodedLength); // TODO: we need to check more accurately. #if false // Check if any bytes covered by this instruction has a fixup // record associated with it. Note that an instruction might // have multiple fixup records associated with it, such as // in a far call. for (int j = 0; j < instruction.EncodedLength; j++) { int fixupIndex = codeSegment.DataFixups[i - image.StartAddress + j]; if (fixupIndex != 0) { FixupDefinition fixup = codeSegment.Fixups[fixupIndex - 1]; if (fixup.DataOffset != i - image.StartAddress + j) { continue; } if (fixup.Target.Method == FixupTargetSpecFormat.ExternalPlusDisplacement || fixup.Target.Method == FixupTargetSpecFormat.ExternalWithoutDisplacement) { var extIndex = fixup.Target.IndexOrFrame; var extName = module.ExternalNames[extIndex - 1]; var disp = fixup.Target.Displacement; System.Diagnostics.Debug.WriteLine(string.Format( "{0} refers to {1}+{2} : {3}", instruction, extName, disp, fixup.Location)); } } } #endif i += instruction.EncodedLength; } // ... // Display the code in our disassmbly window. if (this.ListingWindow != null) { Document doc = new Document(); doc.Image = image; this.ListingWindow.Document = doc; } #endif }
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)); } }