Example #1
0
        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;
        }
Example #3
0
        /// <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;
        }
Example #5
0
        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));
            }
Example #9
0
        /// <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;
        }
Example #10
0
 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;
        }
Example #13
0
        /// <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);
        }