예제 #1
0
        static void RecursiveFTP(Arc arc, DirectoryInfo directory, string ftpRoot, string relativePath)
        {
            foreach (var folder in directory.EnumerateDirectories())
            {
                string thisRelPath = Path.Combine(relativePath, folder.Name);

                var req = (FtpWebRequest)WebRequest.Create(ftpRoot + thisRelPath.Replace('\\', '/'));
                req.Method    = "MKD";
                req.KeepAlive = true;
                req.Timeout   = 10000;
                Console.WriteLine($"Requesting folder creation: {thisRelPath}");
                using (var res = (FtpWebResponse)req.GetResponse())
                    Console.WriteLine(res.StatusDescription);

                RecursiveFTP(arc, folder, ftpRoot, thisRelPath);
            }
            foreach (var file in directory.EnumerateFiles())
            {
                GetFileRegionInfo(file.Name, out string arcFileName, out int region);
                string arcPath = Path.Combine(relativePath, arcFileName).Replace('\\', '/');

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write(arcPath);
                if (region > 0)
                {
                    Console.Write($" region={region}");
                }
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(" -> ");
                try
                {
                    arc.GetFileInformation(arcPath, out long offset, out uint compSize, out uint decompSize, out bool regional, region);

                    if (offset == 0)
                    {
                        throw new Exception("File path does not return valid data. See if the path is correct");
                    }

                    if (InjectedOffsets.Contains(offset))
                    {
                        throw new Exception("File path points to address where data is already handled");
                    }

                    if (file.Length > decompSize)
                    {
                        throw new Exception($"Decompiled size ({file.Length}) exceeds its limit: ({decompSize})");
                    }

                    if (InjectedOffsets.Contains(offset))
                    {
                        throw new Exception($"Another file already has this offset ({offset.ToString("x")})");
                    }

                    byte[] compFile = Compress(file, compSize);

                    var filepath = Path.Combine(relativePath, $"{offset.ToString("x")}_{file.Name}");
                    var ftpPath  = ftpRoot + filepath.Replace('\\', '/');

                    var req = (FtpWebRequest)WebRequest.Create(ftpPath);
                    req.Method        = "STOR";
                    req.KeepAlive     = true;
                    req.UseBinary     = true;
                    req.Timeout       = 10000;
                    req.UsePassive    = false;
                    req.ContentLength = compFile.Length;

                    using (var str = req.GetRequestStream())
                        str.Write(compFile, 0, compFile.Length);
                    using (var res = (FtpWebResponse)req.GetResponse())
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.Write("Transferred!");
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write($" (FTP status: {res.StatusDescription})");
                    }

                    InjectedOffsets.Add(offset);
                }
                catch (Exception e)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("Failed: ");
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write(e.Message);
                }
                Console.WriteLine();
            }
        }
예제 #2
0
        static void RecursiveInject(Arc arc, DirectoryInfo directory, BinaryWriter writer, string relativePath)
        {
            foreach (var folder in directory.EnumerateDirectories())
            {
                RecursiveInject(arc, folder, writer, Path.Combine(relativePath, folder.Name));
            }
            foreach (var file in directory.EnumerateFiles())
            {
                GetFileRegionInfo(file.Name, out string arcFileName, out int region);
                string arcPath = Path.Combine(relativePath, arcFileName).Replace('\\', '/');

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write(arcPath);
                if (region > 0)
                {
                    Console.Write($" region={region}");
                }
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(" -> ");
                try
                {
                    arc.GetFileInformation(arcPath, out long offset, out uint compSize, out uint decompSize, out bool regional, region);

                    if (offset == 0)
                    {
                        throw new Exception("File path does not return valid data. See if the path is correct");
                    }

                    if (InjectedOffsets.Contains(offset))
                    {
                        throw new Exception($"Another file already has this offset ({offset.ToString("x")})");
                    }

                    if (InjectUndo)
                    {
                        writer.BaseStream.Position = offset;
                        writer.Write(arc.GetFileCompressed(arcPath));

                        InjectedOffsets.Add(offset);

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.Write("Restored");
                        Console.ForegroundColor = ConsoleColor.White;
                    }
                    else if (InjectDump)
                    {
                        if (file.Length > decompSize)
                        {
                            throw new Exception($"Decompiled size ({file.Length}) exceeds its limit: ({decompSize})");
                        }

                        InjectedOffsets.Add(offset);
                        var compFile       = Compress(file, compSize);
                        var dumpFolderPath = Path.Combine(InjectDumpPath, relativePath);
                        var newName        = $"{offset.ToString("x")}_{file.Name}";
                        Directory.CreateDirectory(dumpFolderPath);
                        File.WriteAllBytes(Path.Combine(dumpFolderPath, newName), compFile);
                    }
                    else
                    {
                        if (file.Length > decompSize)
                        {
                            throw new Exception($"Decompiled size ({file.Length}) exceeds its limit: ({decompSize})");
                        }

                        writer.BaseStream.Position = offset;
                        writer.Write(Compress(file, compSize));

                        InjectedOffsets.Add(offset);

                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.Write("Injected");
                        Console.ForegroundColor = ConsoleColor.White;
                    }
                }
                catch (Exception e)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("Failed: ");
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write(e.Message);
                }
                Console.WriteLine();
            }
        }