private static LogicalSegment ConvertSegmentDefinition( SegmentDefinition def, Dictionary <object, object> objectMap, ObjectModule module) { // Convert the record. LogicalSegment segment = new LogicalSegment(def, objectMap, module); return(segment); }
internal LogicalSegment( SegmentDefinition def, Dictionary<object, object> objectMap, ObjectModule module) { if (def.IsUse32) throw new NotSupportedException("Use32 is not supported."); if (def.Length > 0x10000) throw new NotSupportedException("Segments larger than 64KB are not supported."); this.definition = def; this.fullName = module.Name + "." + def.SegmentName; this.data = def.Data; }
/// <summary> /// Loads a LIB file from a BinaryReader. /// </summary> /// <param name="reader"></param> /// <returns></returns> public static ObjectLibrary LoadLibrary(BinaryReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } ObjectLibrary library = new ObjectLibrary(); foreach (var context in FileFormats.Omf.OmfLoader.LoadLibrary(reader)) { ObjectModule module = LoadObject(context); library.Modules.Add(module); } return(library); }
internal LogicalSegment( SegmentDefinition def, Dictionary <object, object> objectMap, ObjectModule module) { if (def.IsUse32) { throw new NotSupportedException("Use32 is not supported."); } if (def.Length > 0x10000) { throw new NotSupportedException("Segments larger than 64KB are not supported."); } this.definition = def; this.fullName = module.Name + "." + def.SegmentName; this.data = def.Data; }
public static ObjectLibrary LoadObject(string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } using (Stream stream = File.OpenRead(fileName)) using (BinaryReader reader = new BinaryReader(stream)) { ObjectLibrary library = new ObjectLibrary(); var context = FileFormats.Omf.OmfLoader.LoadObject(reader); ObjectModule module = LoadObject(context); library.Modules.Add(module); library.AssignIdsToSegments(); library.FileName = fileName; return(library); } }
public SegmentItem(LogicalSegment segment, ObjectModule module) { this.segment = segment; this.symbols = new List<SymbolItem>( from symbol in module.DefinedNames where symbol.BaseSegment == segment orderby symbol.Offset, symbol.Name select new SymbolItem(symbol)); }
public ModuleItem(ObjectModule module) { if (module == null) throw new ArgumentNullException("module"); this.Module = module; this.Symbols = new List<ITreeNode>(); ConstantSegmentItem constantGroup = new ConstantSegmentItem(module); if (constantGroup.HasChildren) this.Symbols.Add(constantGroup); // Hide zero-length segments. this.Symbols.AddRange( from segment in module.Segments where segment.Length > 0 orderby segment.Class, segment.Name select new SegmentItem(segment, module)); this.Symbols.AddRange( from alias in module.Aliases select (ITreeNode)new SymbolAliasItem(alias)); #if false this.Symbols.AddRange( from symbol in module.DefinedNames where symbol.BaseSegment != null orderby symbol.BaseSegment.Name, symbol.Offset, symbol.Name select new SymbolItem(symbol)); #endif }
public ConstantSegmentItem(ObjectModule module) { this.module = module; // Find all defined names with absolute segment. These // symbols are most likely constants. this.constants = new List<SymbolItem>( from symbol in module.DefinedNames where symbol.BaseSegment == null orderby symbol.Name select new SymbolItem(symbol)); }
/// <summary> /// Returns null if LibraryEnd record is encountered before /// MODEND or MODEND32 record is encountered. /// </summary> /// <param name="reader"></param> /// <returns></returns> private static ObjectModule LoadObject(FileFormats.Omf.Records.RecordContext context) { ObjectModule module = new ObjectModule(); Dictionary<object, object> objectMap = new Dictionary<object, object>(); // Convert meta-data. module.Name = context.ObjectName; module.SourceName = context.SourceName; // Convert segments. foreach (SegmentDefinition def in context.Segments) { LogicalSegment segment = ConvertSegmentDefinition(def, objectMap, module); objectMap[def] = segment; module.Segments.Add(segment); } // Convert segment groups. foreach (GroupDefinition def in context.Groups) { SegmentGroup group = ConvertGroupDefinition(def, objectMap); module.Groups.Add(group); objectMap[def] = group; } // Convert external names. foreach (ExternalNameDefinition def in context.ExternalNames) { ExternalSymbol symbol = new ExternalSymbol { Name = def.Name, TypeIndex = def.TypeIndex, }; module.ExternalNames.Add(symbol); objectMap[def] = symbol; } // Convert aliases. foreach (AliasDefinition def in context.Aliases) { module.Aliases.Add(new SymbolAlias { AliasName = def.AliasName, SubstituteName = def.SubstituteName }); } // Convert public names. foreach (PublicNameDefinition def in context.PublicNames) { module.DefinedNames.Add(ConvertPublicNameDefinition(def, objectMap)); } // Convert fixups. foreach (SegmentDefinition def in context.Segments) { LogicalSegment segment = (LogicalSegment)objectMap[def]; foreach (FixupDefinition f in def.Fixups) { segment.Fixups.Add(ConvertFixupDefinition(f, objectMap)); } } return module; }
private static LogicalSegment ConvertSegmentDefinition( SegmentDefinition def, Dictionary<object, object> objectMap, ObjectModule module) { // Convert the record. LogicalSegment segment = new LogicalSegment(def, objectMap, module); return segment; }
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 }
private static string FormatSymbolicOperand( X86Codec.Instruction instruction, X86Codec.Operand operand, FixupDefinition fixup, ObjectModule module) { if (fixup.Target.Method == FixupTargetMethod.ExternalPlusDisplacement || fixup.Target.Method == FixupTargetMethod.ExternalWithoutDisplacement) { var extIndex = fixup.Target.IndexOrFrame; var extName = module.ExternalNames[extIndex - 1]; var disp = fixup.Target.Displacement; //System.Diagnostics.Debug.WriteLine(string.Format( // "{0} : operand {4} refers to {1}+{2} : {3}", // instruction, extName, disp, fixup.Location, operand)); return extName.Name; } return null; }
/// <summary> /// Returns null if LibraryEnd record is encountered before /// MODEND or MODEND32 record is encountered. /// </summary> /// <param name="reader"></param> /// <returns></returns> private static ObjectModule LoadObject(FileFormats.Omf.Records.RecordContext context) { ObjectModule module = new ObjectModule(); Dictionary <object, object> objectMap = new Dictionary <object, object>(); // Convert meta-data. module.Name = context.ObjectName; module.SourceName = context.SourceName; // Convert segments. foreach (SegmentDefinition def in context.Segments) { LogicalSegment segment = ConvertSegmentDefinition(def, objectMap, module); objectMap[def] = segment; module.Segments.Add(segment); } // Convert segment groups. foreach (GroupDefinition def in context.Groups) { SegmentGroup group = ConvertGroupDefinition(def, objectMap); module.Groups.Add(group); objectMap[def] = group; } // Convert external names. foreach (ExternalNameDefinition def in context.ExternalNames) { ExternalSymbol symbol = new ExternalSymbol { Name = def.Name, TypeIndex = def.TypeIndex, }; module.ExternalNames.Add(symbol); objectMap[def] = symbol; } // Convert aliases. foreach (AliasDefinition def in context.Aliases) { module.Aliases.Add(new SymbolAlias { AliasName = def.AliasName, SubstituteName = def.SubstituteName }); } // Convert public names. foreach (PublicNameDefinition def in context.PublicNames) { module.DefinedNames.Add(ConvertPublicNameDefinition(def, objectMap)); } // Convert fixups. foreach (SegmentDefinition def in context.Segments) { LogicalSegment segment = (LogicalSegment)objectMap[def]; foreach (FixupDefinition f in def.Fixups) { segment.Fixups.Add(ConvertFixupDefinition(f, objectMap)); } } return(module); }