Ejemplo n.º 1
0
        private unsafe void DoBackSpew()
        {
            var returnSizeStep = 65536;

            // reset it back to zero
            *(long *)(OriginalBundleDownload + 0x40) = 0;

            var rawPointer      = myWriterStream.GetPointer() + 8;
            var currentPosition = 0;
            var totalLength     = (int)myWriterStream.Length;

            while (currentPosition < totalLength)
            {
                var currentRead   = Math.Min(returnSizeStep, totalLength - currentPosition);
                var bytesConsumed = BundleDownloadMethods.OriginalReceiveBytes(OriginalBundleDownload,
                                                                               (IntPtr)(rawPointer + currentPosition), currentRead);
                currentPosition += currentRead;

                if (bytesConsumed != currentRead)
                {
                    // The thing refused to eat our data?
                    break;
                }
            }

            myWriterStream.ReleasePointer();
        }
Ejemplo n.º 2
0
        internal void CompleteDownload()
        {
            if (myMemoryMap == null)
            {
                MelonDebug.Msg($"Did not succ any bytes for ptr {OriginalBundleDownload}, just completing");
                BundleDownloadMethods.OriginalCompleteDownload(OriginalBundleDownload);
                return;
            }

            MelonDebug.Msg($"Succed {myWriterStream.Position} bytes out of declared {BundleDlInterceptor.GetTotalSize(OriginalBundleDownload)}; waiting for victim process");

            var stopwatch = Stopwatch.StartNew();
            var exitCode  = myVerifierProcess.WaitForExit(TimeSpan.FromSeconds(BundleVerifierMod.TimeLimit.Value));

            MelonDebug.Msg($"Process wait done after {stopwatch.ElapsedMilliseconds}ms extra wait");
            if (exitCode != 0)
            {
                var cleanedUrl = BundleVerifierMod.SanitizeUrl(Url);
                MelonLogger.Msg($"Verifier process failed with exit code {exitCode} ({VerifierExitCodes.GetExitCodeDescription(exitCode)}) for bundle uid={cleanedUrl.Item1}+{cleanedUrl.Item2}");
                BundleVerifierMod.BadBundleCache.Add(Url);
                MelonDebug.Msg("Reporting completion without data");
                // feed some garbage into it, otherwise it dies
                unsafe
                {
                    *(long *)(OriginalBundleDownload + 0x40) = 0;
                    var stub  = "UnityFS\0";
                    var bytes = Encoding.UTF8.GetBytes(stub);

                    fixed(byte *bytesPtr = bytes)
                    BundleDownloadMethods.OriginalReceiveBytes(OriginalBundleDownload, (IntPtr)bytesPtr, bytes.Length);
                }

                BundleDownloadMethods.OriginalCompleteDownload(OriginalBundleDownload);
                return;
            }

            MelonDebug.Msg("Bundle looks clean, spewing back...");
            DoBackSpew();
            MelonDebug.Msg("Back-spew done, completing");
            BundleDownloadMethods.OriginalCompleteDownload(OriginalBundleDownload);
            MelonDebug.Msg("Completed!");
        }
Ejemplo n.º 3
0
        internal int ProcessBytes(byte[] bytes, int offset, int length)
        {
            try
            {
                myWriterStream.Write(bytes, offset, length);
            }
            catch (IOException ex)
            {
                MelonLogger.Error($"Received more bytes than declared for bundle URL {Url} (declared: {BundleDlInterceptor.GetTotalSize(OriginalBundleDownload)})");
                MelonLogger.Error(ex.ToString());
                DoBackSpew();
                unsafe
                {
                    fixed(byte *bytesPtr = bytes)
                    BundleDownloadMethods.OriginalReceiveBytes(OriginalBundleDownload, (IntPtr)bytesPtr, length);
                }

                BundleDlInterceptor.CancelIntercept(this);
            }

            return(length);
        }