예제 #1
0
        /// <summary>
        /// Returns the ELF module build id or the MachO module uuid
        /// </summary>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <returns>build id or null</returns>
        internal byte[] GetBuildId(ulong address, ulong size)
        {
            Debug.Assert(size > 0);
            Stream stream = MemoryService.CreateMemoryStream(address, size);

            byte[] buildId = null;
            try
            {
                if (Target.OperatingSystem == OSPlatform.Linux)
                {
                    var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                    if (elfFile.IsValid())
                    {
                        buildId = elfFile.BuildID;
                    }
                }
                else if (Target.OperatingSystem == OSPlatform.OSX)
                {
                    var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                    if (machOFile.IsValid())
                    {
                        buildId = machOFile.Uuid;
                    }
                }
            }
            catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
            {
                Trace.TraceError($"GetBuildId: {address:X16} exception {ex.Message}");
            }
            return(buildId);
        }
예제 #2
0
        /// <summary>
        /// Returns information about the PE file.
        /// </summary>
        /// <param name="isVirtual">the memory layout of the module</param>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <param name="pdbFileInfo">the pdb record or null</param>
        /// <param name="flags">module flags</param>
        ///
        /// <returns>PEImage instance or null</returns>
        private PEImage GetPEInfo(bool isVirtual, ulong address, ulong size, ref PdbFileInfo pdbFileInfo, ref Module.Flags flags)
        {
            Stream stream = MemoryService.CreateMemoryStream(address, size);

            try
            {
                stream.Position = 0;
                var peImage = new PEImage(stream, leaveOpen: false, isVirtual);
                if (peImage.IsValid)
                {
                    flags      |= Module.Flags.IsPEImage;
                    flags      |= peImage.IsManaged ? Module.Flags.IsManaged : Module.Flags.None;
                    pdbFileInfo = peImage.DefaultPdb?.ToPdbFileInfo();
                    flags      &= ~(Module.Flags.IsLoadedLayout | Module.Flags.IsFileLayout);
                    flags      |= isVirtual ? Module.Flags.IsLoadedLayout : Module.Flags.IsFileLayout;
                    return(peImage);
                }
                else
                {
                    Trace.TraceError($"GetPEInfo: PE invalid {address:X16} isVirtual {isVirtual}");
                }
            }
            catch (Exception ex) when(ex is BadImageFormatException || ex is EndOfStreamException || ex is IOException)
            {
                Trace.TraceError($"GetPEInfo: {address:X16} isVirtual {isVirtual} exception {ex.Message}");
            }
            return(null);
        }
예제 #3
0
 /// <summary>
 /// Checks availability of debugging information for given assembly.
 /// </summary>
 /// <param name="assemblyPath">
 /// File path of the assembly or null if the module is in-memory or dynamic (generated by Reflection.Emit)
 /// </param>
 /// <param name="isFileLayout">type of in-memory PE layout, if true, file based layout otherwise, loaded layout</param>
 /// <param name="loadedPeAddress">
 /// Loaded PE image address or zero if the module is dynamic (generated by Reflection.Emit).
 /// Dynamic modules have their PDBs (if any) generated to an in-memory stream
 /// (pointed to by <paramref name="inMemoryPdbAddress"/> and <paramref name="inMemoryPdbSize"/>).
 /// </param>
 /// <param name="loadedPeSize">loaded PE image size</param>
 /// <param name="inMemoryPdbAddress">in memory PDB address or zero</param>
 /// <param name="inMemoryPdbSize">in memory PDB size</param>
 /// <returns>Symbol reader handle or zero if error</returns>
 private IntPtr LoadSymbolsForModule(
     IntPtr self,
     string assemblyPath,
     bool isFileLayout,
     ulong loadedPeAddress,
     uint loadedPeSize,
     ulong inMemoryPdbAddress,
     uint inMemoryPdbSize)
 {
     try
     {
         Stream peStream = null;
         if (loadedPeAddress != 0)
         {
             peStream = MemoryService.CreateMemoryStream(loadedPeAddress, loadedPeSize);
         }
         Stream pdbStream = null;
         if (inMemoryPdbAddress != 0)
         {
             pdbStream = MemoryService.CreateMemoryStream(inMemoryPdbAddress, inMemoryPdbSize);
         }
         OpenedReader openedReader = GetReader(assemblyPath, isFileLayout, peStream, pdbStream);
         if (openedReader != null)
         {
             GCHandle gch = GCHandle.Alloc(openedReader);
             return(GCHandle.ToIntPtr(gch));
         }
     }
     catch (Exception ex)
     {
         Trace.TraceError($"LoadSymbolsForModule: {ex.Message}");
     }
     return(IntPtr.Zero);
 }
예제 #4
0
        /// <summary>
        /// Get the version string from a Linux or MacOS image
        /// </summary>
        /// <param name="address">image base</param>
        /// <param name="size">image size</param>
        /// <returns>version string or null</returns>
        protected string GetVersionString(ulong address, ulong size)
        {
            Stream stream = MemoryService.CreateMemoryStream(address, size);

            try
            {
                if (Target.OperatingSystem == OSPlatform.Linux)
                {
                    var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                    if (elfFile.IsValid())
                    {
                        foreach (ELFProgramHeader programHeader in elfFile.Segments.Select((segment) => segment.Header))
                        {
                            uint flags = MemoryService.PointerSize == 8 ? programHeader.Flags : programHeader.Flags32;
                            if (programHeader.Type == ELFProgramHeaderType.Load &&
                                (flags & (uint)ELFProgramHeaderAttributes.Writable) != 0)
                            {
                                ulong loadAddress = programHeader.VirtualAddress.Value;
                                long  loadSize    = (long)programHeader.VirtualSize;
                                if (SearchVersionString(address + loadAddress, loadSize, out string productVersion))
                                {
                                    return(productVersion);
                                }
                            }
                        }
                    }
                }
                else if (Target.OperatingSystem == OSPlatform.OSX)
                {
                    var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                    if (machOFile.IsValid())
                    {
                        foreach (MachSegmentLoadCommand loadCommand in machOFile.Segments.Select((segment) => segment.LoadCommand))
                        {
                            if (loadCommand.Command == LoadCommandType.Segment64 &&
                                (loadCommand.InitProt & VmProtWrite) != 0 &&
                                loadCommand.SegName.ToString() != "__LINKEDIT")
                            {
                                ulong loadAddress = loadCommand.VMAddress;
                                long  loadSize    = (long)loadCommand.VMSize;
                                if (SearchVersionString(address + loadAddress, loadSize, out string productVersion))
                                {
                                    return(productVersion);
                                }
                            }
                        }
                    }
                }
                else
                {
                    Trace.TraceError("GetVersionString: unsupported platform {0}", Target.OperatingSystem);
                }
            }
            catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
            {
                Trace.TraceError($"GetVersionString: {address:X16} exception {ex.Message}");
            }
            return(null);
        }
예제 #5
0
        /// <summary>
        /// Load native symbols and modules (i.e. DAC, DBI).
        /// </summary>
        /// <param name="callback">called back for each symbol file loaded</param>
        /// <param name="parameter">callback parameter</param>
        /// <param name="config">Target configuration: Windows, Linux or OSX</param>
        /// <param name="moduleFilePath">module path</param>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <param name="readMemory">read memory callback delegate</param>
        private void LoadNativeSymbols(
            IntPtr self,
            SymbolFileCallback callback,
            IntPtr parameter,
            RuntimeConfiguration config,
            string moduleFilePath,
            ulong address,
            uint size)
        {
            if (_symbolService.IsSymbolStoreEnabled)
            {
                try
                {
                    Stream       stream    = MemoryService.CreateMemoryStream(address, size);
                    KeyGenerator generator = null;
                    if (config == RuntimeConfiguration.UnixCore)
                    {
                        var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                        generator = new ELFFileKeyGenerator(Tracer.Instance, elfFile, moduleFilePath);
                    }
                    else if (config == RuntimeConfiguration.OSXCore)
                    {
                        var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                        generator = new MachOFileKeyGenerator(Tracer.Instance, machOFile, moduleFilePath);
                    }
                    else if (config == RuntimeConfiguration.WindowsCore || config == RuntimeConfiguration.WindowsDesktop)
                    {
                        var peFile = new PEFile(new StreamAddressSpace(stream), true);
                        generator = new PEFileKeyGenerator(Tracer.Instance, peFile, moduleFilePath);
                    }
                    else
                    {
                        Trace.TraceError("LoadNativeSymbols: unsupported config {0}", config);
                    }
                    if (generator != null)
                    {
                        IEnumerable <SymbolStoreKey> keys = generator.GetKeys(KeyTypeFlags.SymbolKey | KeyTypeFlags.DacDbiKeys);
                        foreach (SymbolStoreKey key in keys)
                        {
                            string moduleFileName = Path.GetFileName(key.FullPathName);
                            Trace.TraceInformation("{0} {1}", key.FullPathName, key.Index);

                            string downloadFilePath = _symbolService.DownloadFile(key);
                            if (downloadFilePath != null)
                            {
                                Trace.TraceInformation("{0}: {1}", moduleFileName, downloadFilePath);
                                callback(parameter, moduleFileName, downloadFilePath);
                            }
                        }
                    }
                }
                catch (Exception ex) when
                    (ex is DiagnosticsException ||
                    ex is BadInputFormatException ||
                    ex is InvalidVirtualAddressException ||
                    ex is ArgumentOutOfRangeException ||
                    ex is IndexOutOfRangeException ||
                    ex is TaskCanceledException)
                {
                    Trace.TraceError("{0} address {1:X16}: {2}", moduleFilePath, address, ex.Message);
                }
            }
        }