コード例 #1
0
        /// <summary>
        /// Jump to the .data section of an executable stream
        /// </summary>
        private void JumpToTheData()
        {
            currentFormat = new FormatProperty();
            currentFormat.ExecutableType = ExecutableType.Unknown;
            dataBase = 0;
            currentFormat.CodeSectionLength = 0;
            currentFormat.ExecutableOffset  = 0; // dataStart

            bool searchAgainAtEnd = true;

            do
            {
                searchAgainAtEnd = false;
                dataBase        += currentFormat.ExecutableOffset;
                currentFormat.ExecutableOffset = 0;

                currentFormat.ExecutableType = ExecutableType.Unknown;
                inputFile.Seek(dataBase + currentFormat.ExecutableOffset);
                IMAGE_DOS_HEADER exeHdr = IMAGE_DOS_HEADER.Deserialize(inputFile);

                if ((exeHdr.Magic == Constants.IMAGE_NT_SIGNATURE || exeHdr.Magic == Constants.IMAGE_DOS_SIGNATURE) &&
                    exeHdr.HeaderParagraphSize >= 4 &&
                    exeHdr.NewExeHeaderAddr >= 0x40)
                {
                    currentFormat.ExecutableOffset = exeHdr.NewExeHeaderAddr;
                    inputFile.Seek(dataBase + currentFormat.ExecutableOffset);
                    exeHdr = IMAGE_DOS_HEADER.Deserialize(inputFile);
                }

                switch (exeHdr.Magic)
                {
                case Constants.IMAGE_OS2_SIGNATURE:
                    currentFormat.ExecutableType = ProcessNe();
                    break;

                case Constants.IMAGE_OS2_SIGNATURE_LE:
                case (ushort)Constants.IMAGE_NT_SIGNATURE:
                    currentFormat.ExecutableType = ProcessPe(ref searchAgainAtEnd);
                    break;

                default:
                    break;
                }
            }while (searchAgainAtEnd);
        }
コード例 #2
0
        /// <summary>
        /// Process a PE executable header
        /// </summary>
        private ExecutableType ProcessPe(ref bool searchAgainAtEnd)
        {
            inputFile.Seek(dataBase + currentFormat.ExecutableOffset + 4);
            IMAGE_FILE_HEADER     ifh = IMAGE_FILE_HEADER.Deserialize(inputFile);
            IMAGE_OPTIONAL_HEADER ioh = IMAGE_OPTIONAL_HEADER.Deserialize(inputFile);

            // Read sections until we have the ones we need
            IMAGE_SECTION_HEADER temp     = null;
            IMAGE_SECTION_HEADER resource = null;

            for (int i = 0; i < ifh.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER sectionHeader = IMAGE_SECTION_HEADER.Deserialize(inputFile);
                string headerName = Encoding.ASCII.GetString(sectionHeader.Name, 0, 8);

                // .text
                if (headerName.StartsWith(".text"))
                {
                    currentFormat.CodeSectionLength = sectionHeader.VirtualSize;
                }

                // .rdata
                else if (headerName.StartsWith(".rdata"))
                {
                    // No-op
                }

                // .data
                else if (headerName.StartsWith(".data"))
                {
                    currentFormat.DataSectionLength = sectionHeader.VirtualSize;
                    if ((ifh.Characteristics & (1 << 0)) == 0)
                    {
                        temp = sectionHeader;
                    }
                }

                // .rsrc
                else if (headerName.StartsWith(".rsrc"))
                {
                    resource = sectionHeader;
                    if ((ifh.Characteristics & (1 << 0)) != 0)
                    {
                        temp = sectionHeader;
                    }
                }
            }

            // the unpacker of the self-extractor does not use any resource functions either.
            if (temp.SizeOfRawData > 20000)
            {
                for (int f = 0; f <= 20000 - 0x80; f++)
                {
                    inputFile.Seek(dataBase + temp.PointerToRawData + f);
                    IMAGE_DOS_HEADER exeHdr = IMAGE_DOS_HEADER.Deserialize(inputFile);

                    if ((exeHdr.Magic == Constants.IMAGE_NT_SIGNATURE || exeHdr.Magic == Constants.IMAGE_DOS_SIGNATURE) &&
                        exeHdr.HeaderParagraphSize >= 4 &&
                        exeHdr.NewExeHeaderAddr >= 0x40 &&
                        (exeHdr.Relocations == 0 || exeHdr.Relocations == 3))
                    {
                        currentFormat.ExecutableOffset = (int)temp.PointerToRawData + f;
                        fileEnd          = (int)(dataBase + temp.PointerToRawData + ioh.DataDirectory[2].Size);
                        searchAgainAtEnd = true;
                        break;
                    }
                }
            }

            currentFormat.ExecutableOffset = (int)(resource.PointerToRawData + resource.SizeOfRawData);
            return(ExecutableType.PE);
        }