/// <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="pdbInfo">the pdb record or null</param>
        /// <param name="version">the PE version 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 PdbInfo pdbInfo, ref VersionInfo?version, 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;
                    pdbInfo = peImage.DefaultPdb;
                    if (!version.HasValue)
                    {
                        FileVersionInfo fileVersionInfo = peImage.GetFileVersionInfo();
                        if (fileVersionInfo != null)
                        {
                            version = fileVersionInfo.VersionInfo;
                        }
                    }
                    flags &= ~(Module.Flags.IsLoadedLayout | Module.Flags.IsFileLayout);
                    flags |= isVirtual ? Module.Flags.IsLoadedLayout : Module.Flags.IsFileLayout;
                    return(peImage);
                }
            }
            catch (Exception ex) when(ex is BadImageFormatException || ex is EndOfStreamException || ex is IOException)
            {
                Trace.TraceError($"GetPEInfo: loaded {address:X16} exception {ex.Message}");
            }
            return(null);
        }
Example #2
0
        protected VersionData GetVersion()
        {
            VersionData versionData = null;

            PEImage peImage = GetPEInfo();

            if (peImage != null)
            {
                FileVersionInfo fileVersionInfo = peImage.GetFileVersionInfo();
                if (fileVersionInfo != null)
                {
                    versionData = fileVersionInfo.VersionInfo.ToVersionData();
                }
            }
            else
            {
                // If we can't get the version from the PE, search for version string embedded in the module data
                string versionString = VersionString;
                if (versionString != null)
                {
                    int spaceIndex = versionString.IndexOf(' ');
                    if (spaceIndex < 0)
                    {
                        // It is probably a private build version that doesn't end with a space (no commit id after)
                        spaceIndex = versionString.Length;
                    }
                    if (spaceIndex > 0)
                    {
                        if (versionString[spaceIndex - 1] == '.')
                        {
                            spaceIndex--;
                        }
                        string versionToParse = versionString.Substring(0, spaceIndex);
                        try
                        {
                            Version version = System.Version.Parse(versionToParse);
                            versionData = new VersionData(version.Major, version.Minor, version.Build, version.Revision);
                        }
                        catch (ArgumentException ex)
                        {
                            Trace.TraceError($"Module.Version FAILURE: '{versionToParse}' '{versionString}' {ex}");
                        }
                    }
                }
            }

            return(versionData);
        }