예제 #1
0
        public bool DoPatch(Queue <CodeInstruction> buffer, int origPos, int written)
        {
            if (buffer.Count < match.Length)
            {
                return(false);
            }
            if (QuickPatcher.StartsWith(buffer, match))
            {
                //match!
                if (Target == null)
                {
                    throw new Exception("Can't steal labels, target not set!");
                }

                var enumr = buffer.GetEnumerator();
                for (int i = 0; i < markOffset; i++)
                {
                    enumr.MoveNext();
                }
                enumr.MoveNext();
                var mark = enumr.Current;
                if (mark.labels.Count == 0)
                {
                    throw new Exception("Can't steal labels, mark didn't have any labels to steal!");
                }

                foreach (var label in mark.labels)
                {
                    Target.labels.Add(label);
                }

                mark.labels.Clear();

                PatchedOriginalLocation = origPos;
                PatchedWrittenLocation  = written;
                if (DebugVerbosity >= 1)
                {
                    Debug.Log(string.Format("PATCH: Stole {6} labels from [{2} {3}], gave them to [{4} {5}] at {0} / {1} ", PatchedOriginalLocation, PatchedWrittenLocation, mark.opcode, mark.operand, Target.opcode, Target.operand, Target.labels.Count));
                }
                return(true);
            }
            return(false);
        }
예제 #2
0
        public bool DoPatch(Queue <CodeInstruction> buffer, int origPos, int written)
        {
            if (buffer.Count < match.Length)
            {
                return(false);
            }
            if (QuickPatcher.StartsWith(buffer, match))
            {
                //match!
                if (insert != null)
                {
                    //Debug.Log("Before: \n" + string.Join("\n", new List<string>(buffer.Select(i => i.ToString())).ToArray() ) );
                    if (!after)
                    {
                        //Ugh. C#'s Queue class kinda sucks.
                        //This is like, the worst way to do this, but Queue's interface is so strict we don't have a choice.
                        CodeInstruction[] orig = buffer.ToArray();

                        buffer.Clear();
                        foreach (var e in insert)
                        {
                            buffer.Enqueue(e);
                        }
                        foreach (var e in orig)
                        {
                            buffer.Enqueue(e);
                        }
                    }
                    else
                    {
                        CodeInstruction[] orig = null;

                        //If the buffer is exactly the size of the match, we can cheat, we *only* need to append the patch.
                        if (buffer.Count != match.Length)
                        {
                            //Otherwise, we have to split the Queue to make sure our patch is inserted only after the match.
                            orig = buffer.ToArray();
                            buffer.Clear(); //clear the buffer
                            //Enqueue the match again.
                            for (int i = 0; i < match.Length; i++)
                            {
                                buffer.Enqueue(orig[i]);
                            }
                        }
                        //Enqueue the patch.
                        foreach (var e in insert)
                        {
                            buffer.Enqueue(e);
                        }

                        //Append what's left of the buffer if necessary
                        if (orig != null)
                        {
                            for (int i = match.Length; i < orig.Length; i++)
                            {
                                buffer.Enqueue(orig[i]);
                            }
                        }
                    }
                    //Debug.Log("After: \n" + string.Join("\n", new List<string>(buffer.Select(i => i.ToString())).ToArray()));
                } //else Null patch
                PatchedOriginalLocation = !after ? origPos : origPos + match.Length;
                PatchedWrittenLocation  = !after ? written : written + match.Length;
                if (DebugVerbosity >= 1)
                {
                    Debug.Log(string.Format("PATCH: Inserted patch ({2} instructions) at {0} / {1} ", PatchedOriginalLocation, PatchedWrittenLocation, insert == null ? 0 : insert.Length));
                }
                return(true);
            }
            return(false);
        }