/// <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);
Example #2
0
        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);
        }