public void ToggleSetting(ulong address, AddressInfo info) { // Set AddressInfo at a particular line. Nothing happens if the line is in a range but isn't an instruction(e.g mid way through one), // but one will be created if it is out of any existing range. // Find the address range the address lies in AddressMap.BinarySearchResult index = Map.Search(address); // If it not present, disassemble it and toggle it. I would imagine the only time for this to happen would be if instructions were // unpacked onto the stack then executed there. A rare case but one worth accounting for. if ((index.Info | AddressMap.BinarySearchResult.ResultInfo.PRESENT) != index.Info) { DisassembleStep(address); ToggleSetting(address, info); } else { // Iterate through each line in the address range until the desired is found, then OR its $Info with $info. ListeningList <ParsedLine> Lines = ParsedLines[Map[index.Index]]; for (int i = 0; i < Lines.Count; i++) { if (Lines[i].Address == address) { Lines[i] = new ParsedLine(Lines[i], info); } } } }
public static void SetNotifyingColorKeys() { var colors = new[] { new UnityEngine.Color(0.1f, 0.2f, 0.3f), new UnityEngine.Color(0.4f, 0.5f, 0.6f), new UnityEngine.Color(0.7f, 0.8f, 0.9f) }; var keys = new ListeningList <UnityEngine.GradientColorKey>(); keys.Add(new UnityEngine.GradientColorKey(colors[0], 0)); keys.Add(new UnityEngine.GradientColorKey(colors[1], 1)); var gradient = new Mux.Markup.Gradient { ColorKeys = keys }; keys.AssertNotNull(); Assert.AreEqual(keys, gradient.ColorKeys); CollectionAssert.AreEqual(keys, gradient); CollectionAssert.AreEqual(keys, gradient.Body.colorKeys); keys.Replace(0, new UnityEngine.GradientColorKey(colors[2], 0)); CollectionAssert.AreEqual(keys, gradient); CollectionAssert.AreEqual(keys, gradient.Body.colorKeys); gradient.ColorKeys = null; keys.AssertNull(); }
private void SetLines(AddressRange range, ListeningList <ParsedLine> lines) { // SetLines() generalises adding lines to ParsedLines. It is much simpler and consistent than having a specific method tailored to each use case. // The result of TryGetValue() is discarded because it is not useful, the value is about to be overwritten. It is also slightly faster than ContainsKey(). if (ParsedLines.TryGetValue(range, out _)) { ParsedLines[range] = lines; } else { ParsedLines.Add(range, lines); } }
private Context(Context toClone) { // Create a deep copy of each member in the context // This means that each variable will have a different instance, but with the same data as that of $toClone // If this wasn't used, changing addresses in $this.Memory would change the same addresses in $toClone.Memory // as with $Breakpoints and $Registers. However this isn't necessary for $Flags and $InstructionPointer because // they are value types--a deep copy is taken regardless. Flags = toClone.Flags; InstructionPointer = toClone.InstructionPointer; Memory = toClone.Memory.DeepCopy(); Breakpoints = toClone.Breakpoints.DeepCopy(); Registers = toClone.Registers.DeepCopy(); }
private void AddNewLines(ListeningList <ParsedLine> lines) { // Format each struct in the input and set its index to where it is in the items of this control. This makes // life easier later. for (int i = 0; i < lines.Count; i++) { lines[i] = new ParsedLine(lines[i]) { Index = Items.Count }; FormatAndApply(lines[i]); } // Update the lines automatically later. lines.OnSet += (line, index) => FormatAndApply(line); lines.OnAdd += (line, index) => FormatAndApply(line); }
public static void SetNotifyingAlphaKeys() { var keys = new ListeningList <UnityEngine.GradientAlphaKey>(); keys.Add(new UnityEngine.GradientAlphaKey(0.1f, 0)); keys.Add(new UnityEngine.GradientAlphaKey(0.2f, 1)); var gradient = new Mux.Markup.Gradient { AlphaKeys = keys }; keys.AssertNotNull(); Assert.AreEqual(keys, gradient.AlphaKeys); CollectionAssert.AreEqual(keys, gradient); CollectionAssert.AreEqual(keys, gradient.Body.alphaKeys); keys.Replace(0, new UnityEngine.GradientAlphaKey(0.3f, 0)); CollectionAssert.AreEqual(keys, gradient); CollectionAssert.AreEqual(keys, gradient.Body.alphaKeys); gradient.AlphaKeys = null; keys.AssertNull(); }
private List <ParsedLine> ParseLines(List <DisassembledLine> rawLines) { // Firstly get any useful information from the target context. $TargetContext is only used to avoid calling GetContextByID() twice. Context TargetContext = Handle.GetContextByID(Target.HandleID); // The breakpoints list will be useful for setting the AddressInfo value when necessary. ListeningList <ulong> TargetBreakpoints = TargetContext.Breakpoints; // Similar to above. ulong targetRIP = TargetContext.InstructionPointer; List <ParsedLine> OutputLines = new List <ParsedLine>(); // Every raw line is iterated as every line is to be parsed. for (int i = 0; i < rawLines.Count; i++) { // Start with the assumption that it is an ordinary line. This information will be useful to other classes that // use the output of the Disassembler. AddressInfo Info = 0; // If the address is the same as $RIP, mark it as RIP. if (rawLines[i].Address == targetRIP) { Info |= AddressInfo.RIP; } // If it is a breakpoint, mark it like so. if (TargetBreakpoints.Contains(rawLines[i].Address)) { Info |= AddressInfo.BREAKPOINT; } // Add the result to the output. The constructor of ParsedLine will do the rest of the work. OutputLines.Add(new ParsedLine(rawLines[i], Info)); } return(OutputLines); }