/// <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); }
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); }