internal unsafe int GetModuleVersionInformation( IntPtr self, uint index, ulong baseAddress, [MarshalAs(UnmanagedType.LPStr)] string item, byte *buffer, uint bufferSize, uint *verInfoSize) { if (item == null || buffer == null || bufferSize == 0) { return(HResult.E_INVALIDARG); } IModule module; try { if (index != uint.MaxValue) { module = ModuleService.GetModuleFromIndex(unchecked ((int)index)); } else { module = ModuleService.GetModuleFromBaseAddress(baseAddress); } } catch (DiagnosticsException) { return(HResult.E_FAIL); } if (item == "\\") { int versionSize = Marshal.SizeOf(typeof(VS_FIXEDFILEINFO)); Write(verInfoSize, (uint)versionSize); if (bufferSize < versionSize) { return(HResult.E_INVALIDARG); } if (!module.Version.HasValue) { return(HResult.E_FAIL); } VS_FIXEDFILEINFO *fileInfo = (VS_FIXEDFILEINFO *)buffer; fileInfo->dwSignature = 0; fileInfo->dwStrucVersion = 0; fileInfo->dwFileFlagsMask = 0; fileInfo->dwFileFlags = 0; VersionInfo versionInfo = module.Version.Value; fileInfo->dwFileVersionMS = (uint)versionInfo.Minor | (uint)versionInfo.Major << 16; fileInfo->dwFileVersionLS = (uint)versionInfo.Patch | (uint)versionInfo.Revision << 16; } else if (item == "\\StringFileInfo\\040904B0\\FileVersion") { * buffer = 0; string versionString = module.VersionString; if (versionString == null) { return(HResult.E_FAIL); } try { byte[] source = Encoding.ASCII.GetBytes(versionString + '\0'); Marshal.Copy(source, 0, new IntPtr(buffer), Math.Min(source.Length, (int)bufferSize)); } catch (ArgumentOutOfRangeException) { return(HResult.E_INVALIDARG); } } else { return(HResult.E_INVALIDARG); } return(HResult.S_OK); }
internal unsafe int GetModuleVersionInformation( IntPtr self, uint index, ulong baseAddress, [MarshalAs(UnmanagedType.LPStr)] string item, byte *buffer, uint bufferSize, uint *verInfoSize) { Debug.Assert(buffer != null); Debug.Assert(verInfoSize == null); uint i = 0; foreach (ModuleInfo module in DataReader.EnumerateModules()) { if ((index != uint.MaxValue && i == index) || (index == uint.MaxValue && baseAddress == module.ImageBase)) { if (item == "\\") { uint versionSize = (uint)Marshal.SizeOf(typeof(VS_FIXEDFILEINFO)); Write(verInfoSize, versionSize); if (bufferSize < versionSize) { return(E_INVALIDARG); } VS_FIXEDFILEINFO *fileInfo = (VS_FIXEDFILEINFO *)buffer; fileInfo->dwSignature = 0; fileInfo->dwStrucVersion = 0; fileInfo->dwFileFlagsMask = 0; fileInfo->dwFileFlags = 0; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { VersionInfo versionInfo = module.Version; fileInfo->dwFileVersionMS = (uint)versionInfo.Minor | (uint)versionInfo.Major << 16; fileInfo->dwFileVersionLS = (uint)versionInfo.Patch | (uint)versionInfo.Revision << 16; return(S_OK); } else { if (SearchVersionString(module, out string versionString)) { int spaceIndex = versionString.IndexOf(' '); if (spaceIndex > 0) { if (versionString[spaceIndex - 1] == '.') { spaceIndex--; } string versionToParse = versionString.Substring(0, spaceIndex); try { Version versionInfo = Version.Parse(versionToParse); fileInfo->dwFileVersionMS = (uint)versionInfo.Minor | (uint)versionInfo.Major << 16; fileInfo->dwFileVersionLS = (uint)versionInfo.Revision | (uint)versionInfo.Build << 16; return(S_OK); } catch (ArgumentException ex) { Trace.TraceError($"GetModuleVersion FAILURE: '{versionToParse}' '{versionString}' {ex.ToString()}"); } } } break; } } else if (item == "\\StringFileInfo\\040904B0\\FileVersion") { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return(E_INVALIDARG); } else { if (SearchVersionString(module, out string versionString)) { byte[] source = Encoding.ASCII.GetBytes(versionString + '\0'); Marshal.Copy(source, 0, new IntPtr(buffer), Math.Min(source.Length, (int)bufferSize)); return(S_OK); } break; } } else { return(E_INVALIDARG); } } i++; } return(E_FAIL); }
private unsafe bool processVersion_Information(IMAGE_RESOURCE_DATA_ENTRY *irdata, uint baserva, IMAGE_SECTION_HEADER *pIsh, byte *pData) { uint offset; uint ustr_offset; string sVersionInfoString; offset = (irdata->OffsetToData - pIsh->VirtualAddress) + pIsh->PointerToRawData; // OffsetFromRVA VS_VERSIONINFO *pVI = (VS_VERSIONINFO *)(offset + pData); ustr_offset = (irdata->OffsetToData - pIsh->VirtualAddress) + pIsh->PointerToRawData + (uint)sizeof(VS_VERSIONINFO) + (uint)pData; IMAGE_RESOURCE_INFO_STRING_U *pDirStringUnicode = (IMAGE_RESOURCE_INFO_STRING_U *)(ustr_offset); sVersionInfoString = MakeStringFromUTF8_2((byte *)&pDirStringUnicode->String, (int)pVI->wValueLength); if (sVersionInfoString != "VS_VERSION_INFO") { throw new Exception("Invalid VS_VERSION_INFO block detected"); } uint fixedfileinfo_offset = dword_align(((uint)sizeof(VS_VERSIONINFO) + 2 * ((uint)sVersionInfoString.Length + 1)), (uint)irdata->OffsetToData); VS_FIXEDFILEINFO *pFFI = (VS_FIXEDFILEINFO *)(fixedfileinfo_offset + offset + pData); if (pFFI->dwSignature != 0xfeef04bd) // 4277077181 { throw new Exception("Wrong VS_FIXED_FILE_INFO signature detected."); } uint stringfileinfo_offset = dword_align((fixedfileinfo_offset + (uint)sizeof(VS_FIXEDFILEINFO)), (uint)irdata->OffsetToData); uint original_stringfileinfo_offset = stringfileinfo_offset; while (true) { STRING_FILE_INFO * pSFI = (STRING_FILE_INFO *)(stringfileinfo_offset + offset + pData); IMAGE_RESOURCE_INFO_STRING_U *pDirStringUnicode_2 = (IMAGE_RESOURCE_INFO_STRING_U *)(ustr_offset + stringfileinfo_offset); string stringfileinfo_string = MakeStringFromUTF8_2((byte *)&pDirStringUnicode_2->String, pSFI->Length); if (stringfileinfo_string.StartsWith("StringFileInfo")) { //if (pSFI->Type == 1 && pSFI->ValueLength == 0) //{ uint stringtable_offset = dword_align((stringfileinfo_offset + (uint)sizeof(STRING_FILE_INFO) + 2 * ((uint)stringfileinfo_string.Length) + 1), (uint)irdata->OffsetToData); while (true) { STRING_TABLE *pST = (STRING_TABLE *)(stringtable_offset + offset + pData); if ((pST->Length + pST->ValueLength) == 0) { break; } IMAGE_RESOURCE_INFO_STRING_U *pDirStringUnicode_3 = (IMAGE_RESOURCE_INFO_STRING_U *)(ustr_offset + stringtable_offset); string stringtable_string = MakeStringFromUTF8_2((byte *)&pDirStringUnicode_3->String, pST->Length); uint entry_offset = dword_align(stringtable_offset + (uint)sizeof(STRING_TABLE) + 2 * ((uint)stringtable_string.Length + 1), (uint)irdata->OffsetToData); // Now get all entries while (entry_offset < stringtable_offset + pST->Length) { STRING_FORMAT *pSF = (STRING_FORMAT *)(entry_offset + offset + pData); if ((pSF->Length + pSF->ValueLength) == 0) { break; } IMAGE_RESOURCE_INFO_STRING_U *pDirStringUnicode_Key = (IMAGE_RESOURCE_INFO_STRING_U *)(ustr_offset + entry_offset); string key = MakeStringFromUTF8_2((byte *)&pDirStringUnicode_Key->String, pSF->Length); uint value_offset = dword_align(entry_offset + 2 + (2 * (uint)key.Length + 1), (uint)irdata->OffsetToData); IMAGE_RESOURCE_INFO_STRING_U *pDirStringUnicode_Value = (IMAGE_RESOURCE_INFO_STRING_U *)(ustr_offset + value_offset - 2); string value = MakeStringFromUTF8_2((byte *)&pDirStringUnicode_Value->String, pSF->ValueLength); if (!m_VersionInfo.ContainsKey(key)) { m_VersionInfo.Add(key, value); } else { System.Diagnostics.Debug.WriteLine("Schon drinne"); } if (pSF->Length == 0) { entry_offset = stringtable_offset + pST->Length; } else { entry_offset = dword_align(pSF->Length + entry_offset, (uint)irdata->OffsetToData); } } break; } //} } else if (stringfileinfo_string.StartsWith("VarFileInfo")) { // TODO: Handle VarFileInfo } stringfileinfo_offset = stringfileinfo_offset + pSFI->Length; if (pSFI->Length == 0 || stringfileinfo_offset >= pVI->wLength) { break; } } return(true); }