Example #1
0
        void CalcHeaders()
        {
            _dosHeader   = (IMAGE_DOS_HEADER *)_address;
            _ntHeaders32 = (IMAGE_NT_HEADERS32 *)(_address + _dosHeader->e_lfanew);
            _ntHeaders64 = (IMAGE_NT_HEADERS64 *)(_address + _dosHeader->e_lfanew);
            _isPE64      = _ntHeaders32->OptionalHeader.Magic == (ushort)OptionalHeaderMagic.PE32Plus;

            _fileHeader = _isPE64 ? &_ntHeaders64->FileHeader : &_ntHeaders32->FileHeader;

            _header32 = &_ntHeaders32->OptionalHeader;
            _header64 = &_ntHeaders64->OptionalHeader;
            _sections = new IMAGE_SECTION_HEADER[_fileHeader->NumberOfSections];

            var offset = _isPE64 ? sizeof(IMAGE_NT_HEADERS64) : sizeof(IMAGE_NT_HEADERS32);

            fixed(void *sections = _sections)
            {
                Buffer.MemoryCopy((byte *)_ntHeaders32 + offset, sections, _sections.Length * sizeof(IMAGE_SECTION_HEADER), _sections.Length * sizeof(IMAGE_SECTION_HEADER));
            }

            FileHeader = new FileHeader(_fileHeader);
            if (IsPE64)
            {
                OptionalHeader = new OptionalHeader(_header64);
            }
            else
            {
                OptionalHeader = new OptionalHeader(_header32);
            }

            _workBuffer = Marshal.AllocCoTaskMem(1 << 12);
        }
Example #2
0
        //[FieldOffset(96)] public IMAGE_DATA_DIRECTORY  DataDirectory0;
        //[FieldOffset(104)] public IMAGE_DATA_DIRECTORY DataDirectory1;
        //[FieldOffset(112)] public IMAGE_DATA_DIRECTORY DataDirectory2;
        //[FieldOffset(120)] public IMAGE_DATA_DIRECTORY DataDirectory3;
        //[FieldOffset(128)] public IMAGE_DATA_DIRECTORY DataDirectory4;
        //[FieldOffset(136)] public IMAGE_DATA_DIRECTORY DataDirectory5;
        //[FieldOffset(144)] public IMAGE_DATA_DIRECTORY DataDirectory6;
        //[FieldOffset(152)] public IMAGE_DATA_DIRECTORY DataDirectory7;
        //[FieldOffset(160)] public IMAGE_DATA_DIRECTORY DataDirectory8;
        //[FieldOffset(168)] public IMAGE_DATA_DIRECTORY DataDirectory9;
        //[FieldOffset(176)] public IMAGE_DATA_DIRECTORY DataDirectory10;
        //[FieldOffset(284)] public IMAGE_DATA_DIRECTORY DataDirectory11;
        //[FieldOffset(292)] public IMAGE_DATA_DIRECTORY DataDirectory12;
        //[FieldOffset(300)] public IMAGE_DATA_DIRECTORY DataDirectory13;
        //[FieldOffset(308)] public IMAGE_DATA_DIRECTORY DataDirectory14;
        //[FieldOffset(316)] public IMAGE_DATA_DIRECTORY DataDirectory15;

        public static unsafe IMAGE_DATA_DIRECTORY *GetDataDirectory(IMAGE_OPTIONAL_HEADER32 *header, int zeroBasedIndex)
        {
            return((&header->ExportTable) + zeroBasedIndex);
        }
        /// <summary>
        /// Locates version resource in a PE image
        /// </summary>
        /// <param name="FileData">Pointer to raw or mapped exe or dll</param>
        /// <param name="ResourceSize">Returns size of found resource</param>
        /// <returns>Pointer to located version resource or null if none found</returns>
        public unsafe static VS_VERSIONINFO *GetRawFileVersionResource(void *FileData, out int ResourceSize)
        {
            ResourceSize = 0;

            var dos_header = (IMAGE_DOS_HEADER *)FileData;

            var header = (IMAGE_NT_HEADERS *)((byte *)FileData + dos_header->e_lfanew);

            if (header == null || header->Signature != 0x4550 || header->FileHeader.SizeOfOptionalHeader == 0)
            {
                SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
                return(null);
            }

            IMAGE_DATA_DIRECTORY *resource_header;

            if (header->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32))
            {
                IMAGE_OPTIONAL_HEADER32 *optional_header = (IMAGE_OPTIONAL_HEADER32 *)&header->OptionalHeader;
                var data_directory = (IMAGE_DATA_DIRECTORY *)&optional_header->DataDirectory[0];
                resource_header = data_directory + 2;
            }
            else if (header->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64))
            {
                IMAGE_OPTIONAL_HEADER64 *optional_header = (IMAGE_OPTIONAL_HEADER64 *)&header->OptionalHeader;
                var data_directory = (IMAGE_DATA_DIRECTORY *)&optional_header->DataDirectory[0];
                resource_header = data_directory + 2;
            }
            else
            {
                SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
                return(null);
            }

            var section_table = (IMAGE_SECTION_HEADER *)((BYTE *)&header->OptionalHeader + header->FileHeader.SizeOfOptionalHeader);
            IMAGE_SECTION_HEADER *section_header = null;

            for (int i = 0; i < header->FileHeader.NumberOfSections; i++)
            {
                if (section_table[i].Name != _rsrc_id)
                {
                    continue;
                }

                section_header = section_table + i;
                break;
            }

            if (section_header == null)
            {
                SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
                return(null);
            }

            var raw = (BYTE *)FileData + section_header->PointerToRawData;

            var resource_section   = (IMAGE_RESOURCE_DIRECTORY *)(raw + (resource_header->VirtualAddress - section_header->VirtualAddress));
            var resource_dir_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resource_section + 1);

            for (int i = 0; i < resource_section->NumberOfNamedEntries + resource_section->NumberOfIdEntries; i++)
            {
                if (!resource_dir_entry[i].NameIsString &&
                    resource_dir_entry[i].Id == RT_VERSION &&
                    resource_dir_entry[i].DataIsDirectory)
                {
                    var found_entry = resource_dir_entry + i;

                    var found_dir = (IMAGE_RESOURCE_DIRECTORY *)((BYTE *)resource_section + found_entry->OffsetToDirectory);

                    if ((found_dir->NumberOfIdEntries + found_dir->NumberOfNamedEntries) == 0)
                    {
                        continue;
                    }

                    var found_dir_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(found_dir + 1);

                    for (int j = 0; j < found_dir->NumberOfNamedEntries + found_dir->NumberOfIdEntries; j++)
                    {
                        if (!found_dir_entry[j].DataIsDirectory)
                        {
                            continue;
                        }

                        var found_subdir = (IMAGE_RESOURCE_DIRECTORY *)((BYTE *)resource_section + found_dir_entry->OffsetToDirectory);

                        if ((found_subdir->NumberOfIdEntries + found_subdir->NumberOfNamedEntries) == 0)
                        {
                            continue;
                        }

                        var found_subdir_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(found_subdir + 1);

                        if (found_subdir_entry->DataIsDirectory)
                        {
                            continue;
                        }

                        var found_data_entry = (IMAGE_RESOURCE_DATA_ENTRY *)((BYTE *)resource_section + found_subdir_entry->OffsetToData);

                        var resptr = (VS_VERSIONINFO *)(raw + (found_data_entry->OffsetToData - section_header->VirtualAddress));

                        if (resptr->wType != 0 ||
                            !StringComparer.Ordinal.Equals(new string(resptr->szKey, 0, 15), "VS_VERSION_INFO") ||
                            resptr->FixedFileInfo.Signature != FixedFileVerInfo.FixedFileVerSignature)
                        {
                            SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
                            return(null);
                        }

                        ResourceSize = (int)found_data_entry->Size;

                        return(resptr);
                    }
                }
            }

            SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
            return(null);
        }
Example #4
0
 internal OptionalHeader(IMAGE_OPTIONAL_HEADER32 *header)
 {
     _header32 = header;
 }