예제 #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>
        /// Attempt to extract a Wise installer
        /// </summary>
        /// <param name="file">Possible Wise installer</param>
        /// <param name="outputPath">Output directory for extracted files</param>
        public bool ExtractTo(string file, string outputPath)
        {
            file       = Path.GetFullPath(file);
            outputPath = Path.GetFullPath(outputPath);
            Directory.CreateDirectory(outputPath);

            if (!Open(file))
            {
                return(false);
            }

            // Move to data and determine if this is a known format
            JumpToTheData();
            inputFile.Seek(dataBase + currentFormat.ExecutableOffset);
            for (int i = 0; i < knownFormats.Length; i++)
            {
                if (currentFormat.Equals(knownFormats[i]))
                {
                    currentFormat = knownFormats[i];
                    break;
                }
            }

            // Fall back on heuristics if we couldn't match
            if (currentFormat.ArchiveEnd == 0)
            {
                inputFile.Seek(0);
                Approximate();
                if (!pkzip)
                {
                    if (FindReal(outputPath))
                    {
                        ExtractFiles(outputPath);
                        RenameFiles(outputPath);
                        Close();
                        return(true);
                    }
                }
                else
                {
                    offsetReal = offsetApproximate;
                    ExtractFiles(outputPath);
                    RenameFiles(outputPath);
                    Close();
                    return(true);
                }

                Close();
                return(false);
            }

            // Skip over the addditional DLL name, if we expect it
            long dataStart = currentFormat.ExecutableOffset;

            if (currentFormat.Dll)
            {
                byte[] dll = new byte[256];
                inputFile.Read(dll, 0, 1);
                dataStart++;

                if (dll[0] != 0x00)
                {
                    inputFile.Read(dll, 1, dll[0]);
                    dataStart += dll[0];

                    int dllLength = inputFile.ReadInt32();
                    dataStart += 4;
                }
            }

            // Check if flags are consistent
            if (!currentFormat.NoCrc)
            {
                int flags = inputFile.ReadInt32();
                if ((flags & 0x0100) != 0)
                {
                    return(false);
                }
            }

            if (currentFormat.ArchiveEnd > 0)
            {
                inputFile.Seek(dataBase + dataStart + currentFormat.ArchiveEnd);
                int archiveEndLoaded = inputFile.ReadInt32();
                if (archiveEndLoaded != 0)
                {
                    currentFormat.ArchiveEnd = archiveEndLoaded + dataBase;
                }
            }

            inputFile.Seek(dataBase + dataStart + currentFormat.ArchiveStart);

            // Skip over the initialization text, if we expect it
            if (currentFormat.InitText)
            {
                byte[] waitingBytes = new byte[256];
                inputFile.Read(waitingBytes, 0, 1);
                inputFile.Read(waitingBytes, 1, waitingBytes[0]);
            }

            offsetReal = inputFile.Position;
            ExtractFiles(outputPath);
            RenameFiles(outputPath);

            Close();
            return(true);
        }