Exemple #1
0
        public static void ProcessFile(string filePath)
        {
            Console.WriteLine($"Processing {Path.GetFileName(filePath)}...");
            HIPFileInfo hipFileInfo = null;
            var         outputDir   = string.IsNullOrWhiteSpace(outputPath) ? Path.GetDirectoryName(filePath) : outputPath;
            var         ext         = Path.GetExtension(filePath).ToLower();

            if (ImageTools.nativeImageExtensions.Contains(ext) || ext == ".dds")
            {
                if (options.HasFlag(Options.ReferencedHIP))
                {
                    if (string.IsNullOrWhiteSpace(referencedHIPPath) || referencedHIPPath == "auto")
                    {
                        referencedHIPPath =
                            Path.Combine(outputDir, Path.GetFileNameWithoutExtension(filePath) + ".hip");
                    }

                    if (File.Exists(referencedHIPPath) || Directory.Exists(referencedHIPPath))
                    {
                        var referencedHIPFilePath = referencedHIPPath;
                        if (File.GetAttributes(referencedHIPPath).HasFlag(FileAttributes.Directory))
                        {
                            referencedHIPFilePath = Path.Combine(referencedHIPPath,
                                                                 Path.GetFileNameWithoutExtension(filePath) + ".hip");
                        }

                        var referencedHIPFileInfo = new HIPFileInfo(referencedHIPFilePath);
                        hipFileInfo = new HIPFileInfo(filePath, Encoding, ref referencedHIPFileInfo, endianness);
                    }
                    else
                    {
                        WarningMessage($"\"{referencedHIPPath}\" does not exist. Ignoring...");
                        hipFileInfo = new HIPFileInfo(filePath, Encoding, Layered, Offsets.Item1, Offsets.Item2,
                                                      CanvasDimensions.Item1, CanvasDimensions.Item2, endianness);
                    }
                }
                else
                {
                    hipFileInfo = new HIPFileInfo(filePath, Encoding, Layered, Offsets.Item1, Offsets.Item2,
                                                  CanvasDimensions.Item1, CanvasDimensions.Item2, endianness);
                }

                File.WriteAllBytes(Path.Combine(outputDir, Path.GetFileNameWithoutExtension(filePath) + ".hip"),
                                   hipFileInfo.GetBytes());
            }
            else
            {
                hipFileInfo = new HIPFileInfo(filePath);
                if (hipFileInfo.IsValidHIP)
                {
                    hipFileInfo.GetImage()
                    .Save(Path.Combine(outputDir, Path.GetFileNameWithoutExtension(filePath) + ".png"),
                          ImageFormat.Png);
                }
                else
                {
                    WarningMessage($"{hipFileInfo.Name} is not a valid HIP file. Skipping...");
                }
            }
            Console.WriteLine($"Finished {Path.GetFileName(filePath)}.");
        }
        public static void ProcessFile(string file)
        {
            currentFile = file;
            var fileName = Path.GetFileName(file);

            Console.WriteLine($"Processing {fileName}...");

            if (!File.Exists(file))
            {
                WarningMessage("File does not exist. Skipping...");
                return;
            }

            var ext = Path.GetExtension(file).ToLower();

            if ((games.HasFlag(Games.BBCT) ||
                 games.HasFlag(Games.BBCSEX) ||
                 games.HasFlag(Games.BBCPEX)) && ext != ".pac")
            {
                InfoMessage("Specified game only obfuscates .pac files. Skipping...");
                return;
            }

            if (games.HasFlag(Games.BBTAG) && !BBTAGObfuscatedFiles.Contains(ext))
            {
                InfoMessage($"Specified game does not obfuscate {ext} files. Skipping...");
                return;
            }

            if (ext == ".pacgz" && !modes.HasFlag(Modes.SwitchDeflate) && !modes.HasFlag(Modes.SwitchInflate) &&
                !modes.HasFlag(Modes.Auto))
            {
                InfoMessage($"Specified game and mode does not obfuscate {ext} files. Skipping...");
                return;
            }

            if (string.IsNullOrWhiteSpace(ext) &&
                (modes.HasFlag(Modes.SwitchDeflate) || modes.HasFlag(Modes.SwitchInflate)))
            {
                InfoMessage("Specified game and mode does not obfuscate empty exetension files. Skipping...");
                return;
            }

            byte[] fileBytes     = null;
            var    fileDirectory = outputPath;

            var magicBytes = new byte[4];

            using (var fs =
                       new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                fs.Read(magicBytes, 0, 4);
                fs.Close();
            }

            var isPACMB = magicBytes.SequenceEqual(new byte[] { 0x46, 0x50, 0x41, 0x43 });
            var isHIPMB = magicBytes.SequenceEqual(new byte[] { 0x48, 0x49, 0x50, 0x00 });
            var isHPLMB = magicBytes.SequenceEqual(new byte[] { 0x48, 0x50, 0x41, 0x4C });

            var fileIsKnown = isPACMB || isHIPMB || isHPLMB;

            if (modes == Modes.Auto || (games == Games.BBCSEX || games == Games.BBCPEX) && modes == 0)
            {
                if (magicBytes.SequenceEqual(new byte[] { 0x44, 0x46, 0x41, 0x53 }))
                {
                    modes = Modes.Inflate;
                }
            }

            if (modes == Modes.Auto || games == Games.BBTAG && modes == 0)
            {
                if (magicBytes.Take(3).SequenceEqual(new byte[] { 0x1F, 0x8B, 0x08 }))
                {
                    modes = Modes.SwitchInflate;
                }
                else if (MD5Tools.IsMD5(fileName))
                {
                    modes = Modes.MD5Decrypt;
                }
                else if (fileName.Length > 32 && MD5Tools.IsMD5(fileName.Substring(0, 32)))
                {
                    modes = Modes.MD5Encrypt;
                }
            }

            if (modes == Modes.Auto || games != 0 && modes == 0)
            {
                switch (games)
                {
                case Games.BBCT:
                    modes = fileIsKnown ? Modes.Encrypt : Modes.Decrypt;
                    break;

                case Games.BBTAG:
                    modes = fileIsKnown ? Modes.MD5Encrypt : Modes.MD5Decrypt;
                    break;

                case Games.BBCSEX:
                case Games.BBCPEX:
                case 0:
                    modes = fileIsKnown ? Modes.Deflate | Modes.Encrypt : Modes.Inflate | Modes.Decrypt;
                    break;
                }
            }

            if (modes == Modes.Auto || fileIsKnown && (modes.HasFlag(Modes.Decrypt) ||
                                                       modes.HasFlag(Modes.MD5Decrypt) ||
                                                       modes.HasFlag(Modes.Inflate) ||
                                                       modes.HasFlag(Modes.SwitchInflate)))
            {
                var pacFile = new PACFileInfo(file);
                if (pacFile.IsValidPAC)
                {
                    fileBytes = pacFile.GetBytes();
                }
                else
                {
                    var hipFile = new HIPFileInfo(file);
                    if (hipFile.IsValidHIP)
                    {
                        fileBytes = pacFile.GetBytes();
                    }
                    else
                    {
                        var hplFile = new HPLFileInfo(file);
                        if (hplFile.IsValidHPL)
                        {
                            fileBytes = pacFile.GetBytes();
                        }
                    }
                }
            }

            if (fileBytes == null)
            {
                var changed   = false;
                var memStream = new MemoryStream();
                using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    fs.CopyTo(memStream);
                }

                if (modes.HasFlag(Modes.Deflate))
                {
                    memStream.Position      = 0;
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine($"Deflating {fileName}...");
                    var ms = BBObfuscatorTools.DFASFPACDeflateStream(memStream);
                    memStream.Close();
                    memStream.Dispose();
                    memStream = ms;
                    changed   = true;
                }
                else if (modes.HasFlag(Modes.Decrypt))
                {
                    memStream.Position      = 0;
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine($"Decrypting {fileName}...");
                    var ms = BBObfuscatorTools.FPACCryptStream(memStream, file, CryptMode.Decrypt);
                    memStream.Close();
                    memStream.Dispose();
                    memStream = ms;
                    changed   = true;
                }

                if (modes.HasFlag(Modes.Encrypt))
                {
                    memStream.Position      = 0;
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine($"Encrypting {fileName}...");
                    var ms = BBObfuscatorTools.FPACCryptStream(memStream, file, CryptMode.Encrypt);
                    memStream.Close();
                    memStream.Dispose();
                    memStream = ms;
                    changed   = true;
                }
                else if (modes.HasFlag(Modes.Inflate))
                {
                    memStream.Position      = 0;
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine($"Inflating {fileName}...");
                    var ms = BBObfuscatorTools.DFASFPACInflateStream(memStream);
                    memStream.Close();
                    memStream.Dispose();
                    memStream = ms;
                    changed   = true;
                }
                else if (modes.HasFlag(Modes.MD5Encrypt))
                {
                    memStream.Position = 0;
                    if (fileName.Length > 32 && MD5Tools.IsMD5(fileName.Substring(0, 32)) ||
                        file.LastIndexOf("data") >= 0)
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine($"MD5 Encrypting {fileName}...");
                        var ms = BBTAGMD5CryptTools.BBTAGMD5CryptStream(memStream, file, CryptMode.Encrypt);
                        memStream.Close();
                        memStream.Dispose();
                        memStream = ms;
                        if (fileName.Length > 32 && MD5Tools.IsMD5(fileName.Substring(0, 32)))
                        {
                            fileName = fileName.Substring(0, 32);
                        }
                        else if (!MD5Tools.IsMD5(fileName))
                        {
                            var lastIndex = file.LastIndexOf("data");
                            var datapath  = file.Substring(lastIndex, file.Length - lastIndex);
                            fileName = MD5Tools.CreateMD5(datapath.Replace("\\", "/"));
                            file     = fileName;
                        }

                        changed = true;
                    }
                    else
                    {
                        WarningMessage(
                            "File's name and/or directory does not follow the rules for MD5 Encryption. Ignoring...");
                    }
                }
                else if (modes.HasFlag(Modes.MD5Decrypt))
                {
                    memStream.Position      = 0;
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine($"MD5 Decrypting {fileName}...");
                    var ms = BBTAGMD5CryptTools.BBTAGMD5CryptStream(memStream, file, CryptMode.Decrypt);
                    memStream.Close();
                    memStream.Dispose();
                    memStream = ms;
                    if (MD5Tools.IsMD5(fileName))
                    {
                        if (!string.IsNullOrWhiteSpace(pathsFile))
                        {
                            var length = pathsArray.Length;
                            for (var i = 0; i < length; i++)
                            {
                                if (pathsArray[i].filepathMD5 == fileName)
                                {
                                    var filepath = pathsArray[i].filepath;
                                    fileName      = Path.GetFileName(filepath);
                                    fileDirectory = Path.Combine(outputPath, Path.GetDirectoryName(filepath));
                                }
                            }
                        }

                        if (MD5Tools.IsMD5(fileName))
                        {
                            fileName = fileName + "_" + StringToByteArray(fileName)[7] % 43;
                        }
                    }

                    changed = true;
                }
                else if (modes.HasFlag(Modes.SwitchDeflate))
                {
                    memStream.Position      = 0;
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine($"Switch Deflating {fileName}...");
                    var output = new MemoryStream();
                    var data   = memStream.ToArray();
                    using (Stream input = new GZipStream(output,
                                                         CompressionLevel.Optimal, true))
                    {
                        input.Write(data, 0, data.Length);
                        input.Close();
                    }

                    memStream.Close();
                    memStream.Dispose();
                    memStream = output;
                    changed   = true;
                    if (ext == ".pac")
                    {
                        fileName = Path.GetFileNameWithoutExtension(fileName) + ".pacgz";
                    }
                }
                else if (modes.HasFlag(Modes.SwitchInflate))
                {
                    memStream.Position      = 0;
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine($"Switch Inflating {fileName}...");
                    using (Stream input = new GZipStream(new MemoryStream(memStream.GetBuffer()),
                                                         CompressionMode.Decompress, true))
                    {
                        using (var output = new MemoryStream())
                        {
                            input.CopyTo(output);
                            input.Close();
                            memStream.Close();
                            memStream.Dispose();
                            memStream = new MemoryStream(output.ToArray());
                        }
                    }

                    changed = true;

                    if (ext == ".pacgz")
                    {
                        fileName = Path.GetFileNameWithoutExtension(fileName) + ".pac";
                    }
                }

                Console.ForegroundColor = ConsoleColor.White;
                if (changed)
                {
                    fileBytes = memStream.ToArray();
                }
                memStream.Close();
                memStream.Dispose();
            }

            if (fileBytes == null)
            {
                var automaticString = modes == Modes.Auto || games != 0 && modes == 0 ? " automatically" : string.Empty;
                WarningMessage($"Could not{automaticString} process {fileName}.");
                return;
            }

            var directory = initFilePath == file || file == fileName
                ? fileDirectory
                : Path.Combine(fileDirectory, Path.GetDirectoryName(file).Replace(initFilePath, string.Empty));

            Directory.CreateDirectory(directory);
            var filePath = Path.GetFullPath(Path.Combine(directory, fileName));

            if (File.Exists(filePath) && !options.HasFlag(Options.Replace))
            {
                var backupPath = filePath + ".bak";
                if (File.Exists(backupPath))
                {
                    File.Delete(backupPath);
                }
                File.Move(filePath, backupPath);
            }

            File.WriteAllBytes(filePath, fileBytes);

            Console.Write("Finished processing ");
            var resultFileConsoleColor = ConsoleColor.White;

            if ((modes.HasFlag(Modes.Encrypt) || modes.HasFlag(Modes.MD5Encrypt)) && modes.HasFlag(Modes.Deflate))
            {
                resultFileConsoleColor = ConsoleColor.Magenta;
            }
            else if (modes.HasFlag(Modes.Deflate))
            {
                resultFileConsoleColor = ConsoleColor.Cyan;
            }
            else if (modes.HasFlag(Modes.Encrypt) || modes.HasFlag(Modes.MD5Encrypt))
            {
                resultFileConsoleColor = ConsoleColor.Green;
            }
            Console.ForegroundColor = resultFileConsoleColor;
            Console.Write($"{fileName}");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(".");
        }