private static void UpdatePaths() { var pathList = new List <FilePaths>(); using (TextReader reader = File.OpenText(pathsFile)) { var pattern = new Regex("[/\"]|[/]{2}"); while (reader.Peek() >= 0) { var line = reader.ReadLine(); if (!string.IsNullOrWhiteSpace(line)) { line = pattern.Replace(line, "/").ToLower(); try { Path.GetFullPath(line); var lineMD5 = MD5Tools.CreateMD5(line); line = line.Replace("/", "\\"); pathList.Add(new FilePaths(line, lineMD5)); } catch { } } } } pathsArray = pathList.ToArray(); }
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("."); }