Beispiel #1
0
        public static Stream ReadCombinedAssets(this IAssetsFileProvider fp, string assetsFilePath)
        {
            string actualName = fp.CorrectAssetFilename(assetsFilePath);

            List <string> assetFiles = new List <string>();

            if (actualName.ToLower().EndsWith("split0"))
            {
                assetFiles.AddRange(fp.FindFiles(actualName.Replace(".split0", ".split*"))
                                    .OrderBy(x => Convert.ToInt32(x.Split(new string[] { ".split" }, StringSplitOptions.None).Last())));
            }
            else
            {
                return(fp.GetReadStream(actualName));
            }
            MemoryStream msFullFile = new MemoryStream();

            foreach (string assetsFile in assetFiles)
            {
                byte[] fileBytes = fp.Read(assetsFile);
                msFullFile.Write(fileBytes, 0, fileBytes.Length);
            }

            return(msFullFile);
        }
Beispiel #2
0
        public static bool Patch(IAssetsFileProvider apk, FilePatch patch)
        {
            string binaryFile = patch.Filename;

            if (!apk.FileExists(binaryFile))
            {
                Console.WriteLine("Binary file to patch doesn't exist in the APK!");
                return(false);
            }
            byte[] binaryBytes = apk.Read(binaryFile);
            if (binaryBytes.Length != patch.ExpectedFileSize)
            {
                Console.WriteLine("Binary file to patch is the wrong length!");
                return(false);
            }
            List <Patch> toApply = new List <Patch>();

            Console.WriteLine("Verifying patches binary...");
            using (MemoryStream msBinary = new MemoryStream(binaryBytes))
            {
                //verify each of the patches can be applied or already are applied
                foreach (Patch p in patch.Patches)
                {
                    msBinary.Seek(p.Address, SeekOrigin.Begin);
                    byte[] readVals = new byte[p.ExpectedData.Count];
                    msBinary.Read(readVals, 0, p.ExpectedData.Count);

                    if (!readVals.SequenceEqual(p.ExpectedData))
                    {
                        msBinary.Seek(p.Address, SeekOrigin.Begin);
                        readVals = new byte[p.PatchData.Count];
                        msBinary.Read(readVals, 0, p.PatchData.Count);
                        if (readVals.SequenceEqual(p.PatchData))
                        {
                            Console.WriteLine($"Patch {p.Name} already appears to be applied.");
                            continue;
                        }
                        else
                        {
                            Console.WriteLine($"Patch {p.Name} can't be applied to this binary, the code at the patch location doesn't match what was expected.  Aborting any patching...");
                            //if one patch can't be applied, abort the whole thing
                            return(false);
                        }
                    }
                }
                foreach (Patch p in toApply)
                {
                    msBinary.Seek(p.Address, SeekOrigin.Begin);
                    msBinary.Write(p.PatchData.ToArray(), 0, p.PatchData.Count);
                }
                msBinary.Seek(0, SeekOrigin.Begin);

                apk.Write(binaryFile, msBinary.ToArray(), true, true);
            }
            Console.WriteLine("Done patching binary!");
            return(true);
        }
Beispiel #3
0
        public static Stream ReadCombinedAssets(this IAssetsFileProvider fp, string assetsFilePath, out bool wasCombined)
        {
            string actualName = fp.CorrectAssetFilename(assetsFilePath);

            List <string> assetFiles = new List <string>();

            if (actualName.ToLower().EndsWith("split0"))
            {
                assetFiles.AddRange(fp.FindFiles(actualName.Replace(".split0", ".split*"))
                                    .OrderBy(x => Convert.ToInt32(x.Split(new string[] { ".split" }, StringSplitOptions.None).Last())));
            }
            else
            {
                wasCombined = false;
                return(fp.GetReadStream(actualName));
            }
            wasCombined = true;
            //TODO: property or something on the file provider interface letting this code know if it should use the combined stream
            //      I think combined stream may perform horribly on zip files or cause other issues.

            if (true)
            {
                return(new CombinedStream(assetFiles, fp));
            }
            else
            {
                MemoryStream msFullFile = new MemoryStream();
                foreach (string assetsFile in assetFiles)
                {
                    byte[] fileBytes = fp.Read(assetsFile);
                    msFullFile.Write(fileBytes, 0, fileBytes.Length);
                }

                return(msFullFile);
            }
        }
Beispiel #4
0
        public static string ReadToString(this IAssetsFileProvider provider, string filename)
        {
            var data = provider.Read(filename);

            return(System.Text.Encoding.UTF8.GetString(data));
        }