Example #1
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!");
        }
Example #2
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);
        }
Example #3
0
        internal bool PreProcessBytes()
        {
            if (myMemoryMap != null)
            {
                return(true);
            }

            var declaredSize = BundleDlInterceptor.GetTotalSize(OriginalBundleDownload);

            if (declaredSize <= 0)
            {
                return(false);
            }

            try
            {
                var memName = "BundleVerifier-" + Guid.NewGuid();
                myMemoryMap = MemoryMappedFile.CreateNew(memName, declaredSize + 8,
                                                         MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);
                myWriterStream = new MemoryMapWriterStream(myMemoryMap);
                myWriterStream.SetLength(declaredSize);


                myVerifierProcess = new BundleVerifierProcessHandle(BundleVerifierMod.BundleVerifierPath, memName,
                                                                    TimeSpan.FromSeconds(BundleVerifierMod.TimeLimit.Value),
                                                                    (ulong)BundleVerifierMod.MemoryLimit.Value * 1024L * 1024L, 20,
                                                                    BundleVerifierMod.ComponentLimit.Value);
            }
            catch (Exception ex)
            {
                MelonLogger.Error($"Error while initializing verifier internals: {ex}");
                return(false);
            }

            return(true);
        }