Exemple #1
0
        private unsafe bool processImageResourceDirectoryEntry(IMAGE_RESOURCE_DIRECTORY *pIrd, IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde, uint baserva, string sResType, IMAGE_SECTION_HEADER *pIsh, byte *pData)
        {
            //string sResName;
            UInt16 nEntries;
            uint   i;

            /*
             * if (Convert.ToBoolean((pIrde->Name & 0x80000000) >> 31)) // pIrde->Name ==> NameIsString? see Winnt.h
             * {
             * IMAGE_RESOURCE_DIR_STRING_U* pDirStringUnicode = (IMAGE_RESOURCE_DIR_STRING_U*)(pIrd + pIrde->OffsetToData);
             * sResName = MakeStringFromUTF8((byte*)&pDirStringUnicode->NameString);
             * }
             */

            if (!Convert.ToBoolean((pIrde->OffsetToData & 0x80000000) >> 31)) // pIrde->OffsetToData ==> DataIsDirectory? see Winnt.h
            {
                throw new Exception("A resource directory was expected but parsing failed");
            }

            IMAGE_RESOURCE_DIRECTORY *      pIrdLevel_2  = (IMAGE_RESOURCE_DIRECTORY *)((baserva + pIrde->OffsetToData & 0x7fffffff));
            IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrdeLevel_2 = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrdLevel_2 + 1);

            nEntries = (UInt16)(pIrdLevel_2->NumberOfIdEntries + pIrdLevel_2->NumberOfNamedEntries);

            for (i = 0; i < nEntries; i++)
            {
                IMAGE_RESOURCE_DATA_ENTRY *irdata = (IMAGE_RESOURCE_DATA_ENTRY *)(baserva + pIrdeLevel_2->OffsetToData);

                if (sResType == ResourceType.RT_VERSION.ToString())
                {
                    if (!processVersion_Information(irdata, baserva, pIsh, pData))
                    {
                        return(false);
                    }
                }

                if (sResType == ResourceType.RT_GROUP_ICON.ToString())
                {
                    if (!processVersion_Icon(irdata, baserva, pIsh, pData))
                    {
                        return(false);
                    }
                }

                pIrdeLevel_2++;
            }

            return(true);
        }
        private static IMAGE_RESOURCE_DIRECTORY_ENTRY *_MemorySearchResourceEntry(void *root, IMAGE_RESOURCE_DIRECTORY *resources, byte *key, bool unicode)
        {
            const uint MAX_LOCAL_KEY_LENGTH         = 2048;
            IMAGE_RESOURCE_DIRECTORY_ENTRY *entries = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resources + 1);
            IMAGE_RESOURCE_DIRECTORY_ENTRY *result  = null;
            uint start;
            uint end;
            uint middle;

            if (!IS_INTRESOURCE(key) && key[0] == (byte)'#')
            {
                // special case: resource id given as string
                byte *endpos = null;
                int   tmpkey = (ushort)_tcstol(&key[1], (void **)&endpos, 10, unicode);
                if (tmpkey <= 0xffff && lstrlen(endpos, unicode) == 0)
                {
                    key = (byte *)MAKEINTRESOURCE((uint)tmpkey);
                }
            }

            // entries are stored as ordered list of named entries,
            // followed by an ordered list of id entries - we can do
            // a binary search to find faster...
            if (IS_INTRESOURCE(key))
            {
                ushort check = (ushort)(void *)key;
                start = resources->NumberOfNamedEntries;
                end   = start + resources->NumberOfIdEntries;

                while (end > start)
                {
                    ushort entryName;
                    middle    = (start + end) >> 1;
                    entryName = (ushort)entries[middle].Name;
                    if (check < entryName)
                    {
                        end = (end != middle ? middle : middle - 1);
                    }
                    else if (check > entryName)
                    {
                        start = (start != middle ? middle : middle + 1);
                    }
                    else
                    {
                        result = &entries[middle];
                        break;
                    }
                }
            }
            else
            {
                char *searchKey;
                uint  searchKeyLen = (uint)_tcslen(key, unicode);
                char *_searchKey   = null;
                if (unicode)
                {
                    searchKey = (char *)key;
                }
                else
                {
                    // Resource names are always stored using 16bit characters, need to
                    // convert string we search for.
                    // In most cases resource names are short, so optimize for that by
                    // using a pre-allocated array.
                    char *_searchKeySpace;

                    fixed(char *p = new char[MAX_LOCAL_KEY_LENGTH + 1])
                    _searchKeySpace = p;

                    if ((ulong)searchKeyLen > MAX_LOCAL_KEY_LENGTH)
                    {
                        void *_searchKeySize = (void *)(((ulong)searchKeyLen + 1) * sizeof(char));
                        _searchKey = (char *)malloc(_searchKeySize);
                        if (_searchKey == null)
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        _searchKey = _searchKeySpace;
                    }

                    mbstowcs(_searchKey, key, (void *)searchKeyLen);
                    _searchKey[searchKeyLen] = (char)0;
                    searchKey = _searchKey;
                }
                start = 0;
                end   = resources->NumberOfNamedEntries;
                while (end > start)
                {
                    int cmp;
                    IMAGE_RESOURCE_DIR_STRING_U *resourceString;
                    middle         = (start + end) >> 1;
                    resourceString = (IMAGE_RESOURCE_DIR_STRING_U *)OffsetPointer(root, (void *)(entries[middle].Name & 0x7FFFFFFF));
                    cmp            = _wcsnicmp(searchKey, resourceString->NameString, (void *)resourceString->Length);
                    if (cmp == 0)
                    {
                        // Handle partial match
                        if (searchKeyLen > resourceString->Length)
                        {
                            cmp = 1;
                        }
                        else if (searchKeyLen < resourceString->Length)
                        {
                            cmp = -1;
                        }
                    }
                    if (cmp < 0)
                    {
                        end = (middle != end ? middle : middle - 1);
                    }
                    else if (cmp > 0)
                    {
                        start = (middle != start ? middle : middle + 1);
                    }
                    else
                    {
                        result = &entries[middle];
                        break;
                    }
                }
                if (!unicode)
                {
                    if (searchKeyLen > MAX_LOCAL_KEY_LENGTH)
                    {
                        free(_searchKey);
                    }
                }
            }

            return(result);
        }
 internal unsafe Win32ResourceName(byte *pRoot, IMAGE_RESOURCE_DIRECTORY_ENTRY *pEntry)
 {
     _name = (pEntry->Name & 0x80000000) == 0 ? (object)(ushort)pEntry->Name : ReadString(pRoot, (int)(pEntry->Name & 0x7FFFFFFF));
Exemple #4
0
        public PEFile(FileStream Fin, int BufferLength)
        {
            this.fin          = Fin;
            this.BufferLength = BufferLength;
            this.bData        = ReadFile(fin, BufferLength);
            bool b64 = false;

            unsafe
            {
                fixed(byte *pData = this.bData)
                {
                    IMAGE_DOS_HEADER *  pIdh    = (IMAGE_DOS_HEADER *)pData;
                    IMAGE_NT_HEADERS32 *pInhs32 = (IMAGE_NT_HEADERS32 *)(pIdh->e_lfanew + pData);
                    IMAGE_NT_HEADERS64 *pInhs64 = (IMAGE_NT_HEADERS64 *)(pIdh->e_lfanew + pData);

                    if (pInhs32->FileHeader.SizeOfOptionalHeader > 0) // check for non object file
                    {
                        if (pInhs32->OptionalHeader.Magic == 0x10b)
                        {
                            // 32 Bit
                        }

                        if (pInhs32->OptionalHeader.Magic == 0x20b)
                        {
                            // 64 Bit
                            b64 = true;
                        }

                        if (pInhs32->OptionalHeader.CLRDataDirectory.Size > 0)
                        {
                            m_IsManaged = true;
                        }
                        else
                        {
                            m_IsManaged = false;
                        }

                        if ((this.bData.Length < 9192) && (pInhs32->OptionalHeader.BaseOfCode > 2048))
                        {
                            iEntryPoint = 2048;
                        }
                        else
                        {
                            if (b64)
                            {
                                iEntryPoint = pInhs64->OptionalHeader.BaseOfCode;
                            }
                            else
                            {
                                iEntryPoint = pInhs32->OptionalHeader.BaseOfCode;
                            }
                        }

                        m_BinImprint = viGetFullImprint_ByteArray(bData, iEntryPoint);

                        iNTHeaderOffset       = pIdh->e_lfanew;
                        iOptionalHeaderOffset = iNTHeaderOffset + 4 + (int)sizeof(IMAGE_FILE_HEADER);
                        iSectionOffset        = iOptionalHeaderOffset + (int)pInhs32->FileHeader.SizeOfOptionalHeader;
                        iOffset = iSectionOffset + (int)pData;

                        for (int i = 0; i < pInhs32->FileHeader.NumberOfSections; i++)
                        {
                            IMAGE_SECTION_HEADER *pIsh = (IMAGE_SECTION_HEADER *)(iOffset + (int)(sizeof(IMAGE_SECTION_HEADER) * i));
                            iBaseRVA = pIsh->PointerToRawData + (uint)pData;

                            if (MakeStringFromUTF8((byte *)&pIsh->Name) == ".rsrc")
                            {
                                if (pIsh->VirtualSize > 0)
                                {
                                    iImageSectionHeaderSize = pIsh->VirtualSize;
                                }
                                else
                                {
                                    iImageSectionHeaderSize = pIsh->SizeOfRawData;
                                }

                                if (b64)
                                {
                                    if (pInhs64->OptionalHeader.ResourceDataDirectory.VirtualAddress >= pIsh->VirtualAddress &&
                                        pInhs64->OptionalHeader.ResourceDataDirectory.VirtualAddress < pIsh->VirtualAddress + iImageSectionHeaderSize)
                                    {
                                        IMAGE_RESOURCE_DIRECTORY *      pIrd  = (IMAGE_RESOURCE_DIRECTORY *)(pIsh->PointerToRawData + (uint)pData);
                                        IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrd + 1);
                                        nEntries = (UInt16)(pIrd->NumberOfIdEntries + pIrd->NumberOfNamedEntries);

                                        for (int j = 0; j < nEntries; j++)
                                        {
                                            if (!processImageResourceDirectory(pIrd, pIrde, iBaseRVA, pIsh, pData))
                                            {
                                                throw new Exception("Error during resource directory parsing.");
                                            }
                                            pIrde++;
                                        }
                                    }
                                }
                                else
                                {
                                    if (pInhs32->OptionalHeader.ResourceDataDirectory.VirtualAddress >= pIsh->VirtualAddress &&
                                        pInhs32->OptionalHeader.ResourceDataDirectory.VirtualAddress < pIsh->VirtualAddress + iImageSectionHeaderSize)
                                    {
                                        IMAGE_RESOURCE_DIRECTORY *      pIrd  = (IMAGE_RESOURCE_DIRECTORY *)(pIsh->PointerToRawData + (uint)pData);
                                        IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrd + 1);
                                        nEntries = (UInt16)(pIrd->NumberOfIdEntries + pIrd->NumberOfNamedEntries);

                                        for (int j = 0; j < nEntries; j++)
                                        {
                                            if (!processImageResourceDirectory(pIrd, pIrde, iBaseRVA, pIsh, pData))
                                            {
                                                throw new Exception("Error during resource directory parsing.");
                                            }
                                            pIrde++;
                                        }
                                    }
                                }
                            }

                            if (iOffset >= iOptionalHeaderOffset + (int)sizeof(IMAGE_OPTIONAL_HEADER32) + 8 * 16 + (int)pData) // just for savety reasons
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
Exemple #5
0
        private unsafe bool processImageResourceDirectory(IMAGE_RESOURCE_DIRECTORY *pIrd, IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde, uint baserva, IMAGE_SECTION_HEADER *pIsh, byte *pData)
        {
            string sResType;
            UInt16 nEntries;
            uint   i;

            if (Convert.ToBoolean((pIrde->Name & 0x80000000) >> 31)) // pIrde->Name ==> NameIsString? see Winnt.h
            {
                return(true);

                IMAGE_RESOURCE_DIR_STRING_U *pDirStringUnicode = (IMAGE_RESOURCE_DIR_STRING_U *)(pIrd + pIrde->OffsetToData);
                sResType = MakeStringFromUTF8((byte *)&pDirStringUnicode->NameString);
            }
            else
            {
                ResourceType eRT = (ResourceType)pIrde->Name;
                switch (eRT)
                {
                case ResourceType.RT_VERSION:
                    sResType = ResourceType.RT_VERSION.ToString();
                    break;

                case ResourceType.RT_ICON:
                    sResType = ResourceType.RT_ICON.ToString();
                    break;

                case ResourceType.RT_GROUP_ICON:
                    sResType = ResourceType.RT_GROUP_ICON.ToString();
                    break;

                default:
                    sResType = "Unknown";
                    break;
                }
            }

            if (!Convert.ToBoolean((pIrde->OffsetToData & 0x80000000) >> 31)) // pIrde->OffsetToData ==> DataIsDirectory? see Winnt.h
            {
                throw new Exception("A resource directory was expected but parsing failed");
            }

            IMAGE_RESOURCE_DIRECTORY *pIrdLevel_1 = (IMAGE_RESOURCE_DIRECTORY *)((baserva + pIrde->OffsetToData & 0x7fffffff));

            pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrdLevel_1 + 1);

            nEntries = (UInt16)(pIrdLevel_1->NumberOfIdEntries + pIrdLevel_1->NumberOfNamedEntries);
            for (i = 0; i < nEntries; i++)
            {
                if (!processImageResourceDirectoryEntry(pIrdLevel_1, pIrde, baserva, sResType, pIsh, pData))
                {
                    throw new Exception("Error during image resource directory entry parsing.");
                }
                pIrde++;
            }

            return(true);
        }