Пример #1
0
        private static string FindFirstOfSplit(IAssetsFileProvider fp, string assetsFile)
        {
            int lastDot = assetsFile.LastIndexOf('.');

            if (lastDot > 0)
            {
                string afterDot = assetsFile.Substring(lastDot, assetsFile.Length - lastDot);
                string noSplit;
                if (afterDot.ToLower().StartsWith(".split"))
                {
                    noSplit = assetsFile.Substring(0, lastDot);
                    if (fp.FileExists(noSplit))
                    {
                        return(noSplit);
                    }
                }
                else
                {
                    noSplit = assetsFile;
                }
                var split0 = noSplit + ".split0";
                if (fp.FileExists(split0))
                {
                    return(split0);
                }
            }
            if (fp.FileExists(assetsFile))
            {
                return(assetsFile);
            }
            return(null);
        }
Пример #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);
        }