/// <summary> /// Gets fixed numeric fields from PE version resource /// </summary> /// <param name="versionResource">Pointer to version resource</param> /// <returns>FixedFileVerInfo structure with fixed numeric version fields</returns> public unsafe static FixedFileVerInfo GetFixedVersionInfo(VS_VERSIONINFO *versionResource) { if (versionResource == null || versionResource->wType != 0 || !StringComparer.Ordinal.Equals(new string(versionResource->szKey, 0, 15), "VS_VERSION_INFO") || versionResource->FixedFileInfo.Signature != FixedFileVerInfo.FixedFileVerSignature) { SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); return(default);
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); }