From 45cf67044687c56fd960416090fdc99daca39d8f Mon Sep 17 00:00:00 2001 From: valarnin Date: Sun, 22 May 2016 21:20:41 -0400 Subject: [PATCH] Whoops --- tmp/.gitignore | 236 ------ tmp/NTRDebuggerTool.sln | 23 - tmp/NTRDebuggerTool/App.config | 26 - tmp/NTRDebuggerTool/Config.cs | 301 ------- tmp/NTRDebuggerTool/ConsoleHelper.cs | 33 - tmp/NTRDebuggerTool/Debug.cs | 99 --- .../Forms/ConfigDialog.Designer.cs | 128 --- tmp/NTRDebuggerTool/Forms/ConfigDialog.cs | 49 -- tmp/NTRDebuggerTool/Forms/ConfigDialog.resx | 126 --- .../Forms/FormEnums/DataType.cs | 91 -- .../Forms/FormEnums/SearchType.cs | 142 ---- .../Forms/MainForm.Designer.cs | 702 ---------------- tmp/NTRDebuggerTool/Forms/MainForm.cs | 791 ------------------ tmp/NTRDebuggerTool/Forms/MainForm.resx | 314 ------- .../Forms/MainFormThreadButtonState.cs | 91 -- .../Forms/MainFormThreadEventDispatcher.cs | 387 --------- .../Forms/PointerScanDialog.Designer.cs | 183 ---- .../Forms/PointerScanDialog.cs | 68 -- .../Forms/PointerScanDialog.resx | 126 --- tmp/NTRDebuggerTool/NTRDebuggerTool.csproj | 182 ---- tmp/NTRDebuggerTool/Objects/GateSharkCode.cs | 126 --- tmp/NTRDebuggerTool/Objects/MemoryDispatch.cs | 12 - .../Objects/Saving/SaveCode.cs | 28 - .../Objects/Saving/SaveManager.cs | 66 -- tmp/NTRDebuggerTool/Objects/SearchCriteria.cs | 25 - tmp/NTRDebuggerTool/Program.cs | 85 -- .../Properties/AssemblyInfo.cs | 15 - .../Properties/Resources.Designer.cs | 73 -- tmp/NTRDebuggerTool/Properties/Resources.resx | 124 --- .../Properties/Settings.Designer.cs | 26 - .../Properties/Settings.settings | 7 - .../Remote/NTRPacketReceiverThread.cs | 479 ----------- .../Remote/NTRRemoteConnection.cs | 384 --------- tmp/NTRDebuggerTool/Remote/PacketCommand.cs | 17 - tmp/NTRDebuggerTool/Remote/PacketType.cs | 9 - tmp/NTRDebuggerTool/Resources/cog2.png | Bin 430 -> 0 bytes tmp/NTRDebuggerTool/Resources/log4net.dll | Bin 304640 -> 0 bytes tmp/NTRDebuggerTool/Utilities.cs | 22 - tmp/NTRDebuggerTool/packages.config | 6 - tmp/README.md | 23 - 40 files changed, 5625 deletions(-) delete mode 100644 tmp/.gitignore delete mode 100644 tmp/NTRDebuggerTool.sln delete mode 100644 tmp/NTRDebuggerTool/App.config delete mode 100644 tmp/NTRDebuggerTool/Config.cs delete mode 100644 tmp/NTRDebuggerTool/ConsoleHelper.cs delete mode 100644 tmp/NTRDebuggerTool/Debug.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/ConfigDialog.Designer.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/ConfigDialog.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/ConfigDialog.resx delete mode 100644 tmp/NTRDebuggerTool/Forms/FormEnums/DataType.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/FormEnums/SearchType.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/MainForm.Designer.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/MainForm.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/MainForm.resx delete mode 100644 tmp/NTRDebuggerTool/Forms/MainFormThreadButtonState.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/MainFormThreadEventDispatcher.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/PointerScanDialog.Designer.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/PointerScanDialog.cs delete mode 100644 tmp/NTRDebuggerTool/Forms/PointerScanDialog.resx delete mode 100644 tmp/NTRDebuggerTool/NTRDebuggerTool.csproj delete mode 100644 tmp/NTRDebuggerTool/Objects/GateSharkCode.cs delete mode 100644 tmp/NTRDebuggerTool/Objects/MemoryDispatch.cs delete mode 100644 tmp/NTRDebuggerTool/Objects/Saving/SaveCode.cs delete mode 100644 tmp/NTRDebuggerTool/Objects/Saving/SaveManager.cs delete mode 100644 tmp/NTRDebuggerTool/Objects/SearchCriteria.cs delete mode 100644 tmp/NTRDebuggerTool/Program.cs delete mode 100644 tmp/NTRDebuggerTool/Properties/AssemblyInfo.cs delete mode 100644 tmp/NTRDebuggerTool/Properties/Resources.Designer.cs delete mode 100644 tmp/NTRDebuggerTool/Properties/Resources.resx delete mode 100644 tmp/NTRDebuggerTool/Properties/Settings.Designer.cs delete mode 100644 tmp/NTRDebuggerTool/Properties/Settings.settings delete mode 100644 tmp/NTRDebuggerTool/Remote/NTRPacketReceiverThread.cs delete mode 100644 tmp/NTRDebuggerTool/Remote/NTRRemoteConnection.cs delete mode 100644 tmp/NTRDebuggerTool/Remote/PacketCommand.cs delete mode 100644 tmp/NTRDebuggerTool/Remote/PacketType.cs delete mode 100644 tmp/NTRDebuggerTool/Resources/cog2.png delete mode 100644 tmp/NTRDebuggerTool/Resources/log4net.dll delete mode 100644 tmp/NTRDebuggerTool/Utilities.cs delete mode 100644 tmp/NTRDebuggerTool/packages.config delete mode 100644 tmp/README.md diff --git a/tmp/.gitignore b/tmp/.gitignore deleted file mode 100644 index 94420dc..0000000 --- a/tmp/.gitignore +++ /dev/null @@ -1,236 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Microsoft Azure ApplicationInsights config file -ApplicationInsights.config - -# Windows Store app package directory -AppPackages/ -BundleArtifacts/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe - -# FAKE - F# Make -.fake/ diff --git a/tmp/NTRDebuggerTool.sln b/tmp/NTRDebuggerTool.sln deleted file mode 100644 index a5010af..0000000 --- a/tmp/NTRDebuggerTool.sln +++ /dev/null @@ -1,23 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NTRDebuggerTool", "NTRDebuggerTool\NTRDebuggerTool.csproj", "{86AF1318-9584-4CDE-93BC-C2F0DCF958C5}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {86AF1318-9584-4CDE-93BC-C2F0DCF958C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {86AF1318-9584-4CDE-93BC-C2F0DCF958C5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {86AF1318-9584-4CDE-93BC-C2F0DCF958C5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {86AF1318-9584-4CDE-93BC-C2F0DCF958C5}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection -EndGlobal diff --git a/tmp/NTRDebuggerTool/App.config b/tmp/NTRDebuggerTool/App.config deleted file mode 100644 index 5353446..0000000 --- a/tmp/NTRDebuggerTool/App.config +++ /dev/null @@ -1,26 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - diff --git a/tmp/NTRDebuggerTool/Config.cs b/tmp/NTRDebuggerTool/Config.cs deleted file mode 100644 index a8b7ae9..0000000 --- a/tmp/NTRDebuggerTool/Config.cs +++ /dev/null @@ -1,301 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Windows.Forms; -using System.Xml; - -namespace NTRDebuggerTool -{ - public class Config - { - #region Config Settings - #region MaxValuesToDisplay - private const uint DefaultMaxValuesToDisplay = 1000; - private static Nullable maxValuesToDisplay = null; - public static uint MaxValuesToDisplay - { - get - { - if (maxValuesToDisplay == null) - { - string TempVal = GetValue("MaxValuesToDisplay"); - maxValuesToDisplay = string.IsNullOrWhiteSpace(TempVal) ? DefaultMaxValuesToDisplay : uint.Parse(TempVal); - } - return maxValuesToDisplay.Value; - } - set - { - maxValuesToDisplay = value; - SetValue("MaxValuesToDisplay", value.ToString()); - } - } - #endregion - - #region ButtonStateUpdateInterval - private const int DefaultButtonStateUpdateInterval = 250; - private static Nullable buttonStateUpdateInterval = null; - public static int ButtonStateUpdateInterval - { - get - { - if (buttonStateUpdateInterval == null) - { - string TempVal = GetValue("ButtonStateUpdateInterval"); - buttonStateUpdateInterval = string.IsNullOrWhiteSpace(TempVal) ? DefaultButtonStateUpdateInterval : int.Parse(TempVal); - } - return buttonStateUpdateInterval.Value; - } - set - { - buttonStateUpdateInterval = value; - SetValue("ButtonStateUpdateInterval", value.ToString()); - } - } - #endregion - - #region DefaultIP - private const string DefaultDefaultIP = ""; //Stupid name but oh well - private static string defaultIP = null; - public static string DefaultIP - { - get - { - if (defaultIP == null) - { - string TempVal = GetValue("DefaultIP"); - defaultIP = string.IsNullOrWhiteSpace(TempVal) ? DefaultDefaultIP : TempVal; - } - return defaultIP; - } - set - { - defaultIP = value; - SetValue("DefaultIP", value); - } - } - #endregion - - #region ConnectTimeout - private const int DefaultConnectTimeout = 3000; - private static Nullable connectTimeout = null; - public static int ConnectTimeout - { - get - { - if (connectTimeout == null) - { - string TempVal = GetValue("ConnectTimeout"); - connectTimeout = string.IsNullOrWhiteSpace(TempVal) ? DefaultConnectTimeout : int.Parse(TempVal); - } - return connectTimeout.Value; - } - set - { - connectTimeout = value; - SetValue("ConnectTimeout", value.ToString()); - } - } - #endregion - - #region ConnectTries - private const int DefaultConnectTries = 5; - private static Nullable connectTries = null; - public static int ConnectTries - { - get - { - if (connectTries == null) - { - string TempVal = GetValue("ConnectTries"); - connectTries = string.IsNullOrWhiteSpace(TempVal) ? DefaultConnectTries : int.Parse(TempVal); - } - return connectTries.Value; - } - set - { - connectTries = value; - SetValue("ConnectTries", value.ToString()); - } - } - #endregion - - #region LockValuesDelay - private const int DefaultLockValuesDelay = 5; - private static Nullable lockValuesDelay = null; - public static int LockValuesDelay - { - get - { - if (lockValuesDelay == null) - { - string TempVal = GetValue("LockValuesDelay"); - lockValuesDelay = string.IsNullOrWhiteSpace(TempVal) ? DefaultLockValuesDelay : int.Parse(TempVal); - } - return lockValuesDelay.Value; - } - set - { - lockValuesDelay = value; - SetValue("LockValuesDelay", value.ToString()); - } - } - #endregion - - #region DevkitProPath - private const string DefaultDevkitProPath = ""; - private static string devkitProPath = null; - public static string DevkitProPath - { - get - { - if (devkitProPath == null) - { - string TempVal = GetValue("DevkitProPath"); - devkitProPath = string.IsNullOrWhiteSpace(TempVal) ? DefaultDevkitProPath : TempVal; - } - return devkitProPath; - } - set - { - devkitProPath = value; - SetValue("DevkitProPath", value); - } - } - #endregion - #endregion - - #region Add to default set here - public static Dictionary All - { - get - { - Dictionary All = new Dictionary(); - foreach (XmlNode Node in RootXmlElement.ChildNodes) - { - All.Add(Node.Name, Node.InnerText); - } - if (!All.ContainsKey("MaxValuesToDisplay")) - { - All.Add("MaxValuesToDisplay", MaxValuesToDisplay.ToString()); - } - if (!All.ContainsKey("ButtonStateUpdateInterval")) - { - All.Add("ButtonStateUpdateInterval", ButtonStateUpdateInterval.ToString()); - } - if (!All.ContainsKey("DefaultIP")) - { - All.Add("DefaultIP", DefaultIP.ToString()); - } - if (!All.ContainsKey("ConnectTimeout")) - { - All.Add("ConnectTimeout", ConnectTimeout.ToString()); - } - if (!All.ContainsKey("ConnectTries")) - { - All.Add("ConnectTries", ConnectTries.ToString()); - } - if (!All.ContainsKey("LockValuesDelay")) - { - All.Add("LockValuesDelay", LockValuesDelay.ToString()); - } - if (!All.ContainsKey("DevkitProPath")) - { - All.Add("DevkitProPath", DevkitProPath.ToString()); - } - return All; - } - set - { - foreach (string Key in value.Keys) - { - SetValue(Key, value[Key]); - } - ConfigFile = null; - InitializeConfigFile(); - } - } - - private static void CreateConfigFile() - { - Directory.CreateDirectory(ConfigFileDirectory); - ConfigFile.LoadXml(""); - ConfigFile.Save(ConfigFilePath); - MaxValuesToDisplay = DefaultMaxValuesToDisplay; - ButtonStateUpdateInterval = DefaultButtonStateUpdateInterval; - DefaultIP = DefaultDefaultIP; - ConnectTimeout = DefaultConnectTimeout; - ConnectTries = DefaultConnectTries; - LockValuesDelay = DefaultLockValuesDelay; - DevkitProPath = DefaultDevkitProPath; - } - - #endregion - - #region XML Stuff - - public static string ConfigFileDirectory = Directory.GetParent(Application.UserAppDataPath).FullName; - private static string ConfigFilePath = ConfigFileDirectory + Path.DirectorySeparatorChar + "NTRDebuggerTool.config.xml"; - private static XmlDocument ConfigFile; - - private static void SetValue(string Key, string Value) - { - XmlElement XmlNode = (XmlElement)RootXmlElement.SelectSingleNode("//" + Key); - if (XmlNode == null) - { - XmlNode = ConfigFile.CreateElement(Key); - RootXmlElement.AppendChild(XmlNode); - } - XmlNode.InnerText = Value; - ConfigFile.Save(ConfigFilePath); - } - private static string GetValue(string Key) - { - XmlElement XmlNode = (XmlElement)RootXmlElement.SelectSingleNode("//" + Key); - if (XmlNode != null) { return XmlNode.InnerText; } - return ""; - } - - private static XmlElement RootXmlElement - { - get - { - if (ConfigFile == null || ConfigFile.FirstChild == null) - { - InitializeConfigFile(); - } - return (XmlElement)ConfigFile.FirstChild; - } - } - - private static void NodeChangedHandler(Object src, XmlNodeChangedEventArgs args) - { - if (ConfigFile != null) - { - ConfigFile.Save(ConfigFilePath); - } - } - - private static void InitializeConfigFile() - { - ConfigFile = new XmlDocument(); - try - { - ConfigFile.Load(ConfigFilePath); - } - catch (Exception) - { - CreateConfigFile(); - } - ConfigFile.NodeChanged += new XmlNodeChangedEventHandler(NodeChangedHandler); - ConfigFile.NodeInserted += new XmlNodeChangedEventHandler(NodeChangedHandler); - ConfigFile.NodeRemoved += new XmlNodeChangedEventHandler(NodeChangedHandler); - } - - static Config() - { - if (All != null) ; - } - - #endregion - } -} diff --git a/tmp/NTRDebuggerTool/ConsoleHelper.cs b/tmp/NTRDebuggerTool/ConsoleHelper.cs deleted file mode 100644 index c283f77..0000000 --- a/tmp/NTRDebuggerTool/ConsoleHelper.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace NTRDebuggerTool -{ - class ConsoleHelper - { - [DllImport("kernel32.dll", SetLastError = true)] - static extern bool AllocConsole(); - - [DllImport("kernel32.dll")] - static extern IntPtr GetConsoleWindow(); - - [DllImport("user32.dll")] - static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - - const int SW_HIDE = 0; - const int SW_SHOW = 5; - - public static void EnableConsole() - { - IntPtr Handle = GetConsoleWindow(); - if (Handle == IntPtr.Zero) - { - AllocConsole(); - } - else - { - ShowWindow(Handle, SW_SHOW); - } - } - } -} diff --git a/tmp/NTRDebuggerTool/Debug.cs b/tmp/NTRDebuggerTool/Debug.cs deleted file mode 100644 index 2bb1a98..0000000 --- a/tmp/NTRDebuggerTool/Debug.cs +++ /dev/null @@ -1,99 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using NTRDebuggerTool.Objects; -using NTRDebuggerTool.Remote; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; - -namespace NTRDebuggerTool -{ - class Debug - { - internal static void Execute() - { - NTRRemoteConnection Conn = new NTRRemoteConnection(); - Console.WriteLine("Connecting..."); - Conn.IP = "192.168.1.29"; - Conn.Port = 8000; - while (!Conn.Connect()) ; - Thread t = new Thread(delegate() - { - while (true) - { - Conn.SendHeartbeatPacket(); - Thread.Sleep(100); - } - }); - - t.Start(); - Thread.Sleep(1000); - Console.WriteLine("Getting Processes..."); - Conn.SendListProcessesPacket(); - while (!Conn.IsProcessListUpdated) - { - Thread.Sleep(10); - } - Dictionary> Procs = new Dictionary>(); - foreach (string ProcFull in Conn.Processes) - { - string Proc = ProcFull.Split('|')[0]; - Console.WriteLine("Fetching memregions for process " + Proc); - Conn.SendReadMemoryAddressesPacket(Proc); - while (!Conn.IsMemoryListUpdated) - { - Thread.Sleep(10); - } - Procs.Add(Proc, Conn.AddressSpaces); - Conn.IsMemoryListUpdated = false; - } - - Directory.CreateDirectory("Temp"); - - for (int i = 0; i < 3; ++i) - { - Directory.CreateDirectory("Temp" + Path.DirectorySeparatorChar + i); - Console.WriteLine("Dumping memory set " + i + "..."); - - foreach (string Proc in Procs.Keys) - { - foreach (uint Start in Procs[Proc].Keys) - { - uint Size = Procs[Proc][Start]; - SearchCriteria Criteria = new SearchCriteria(); - Criteria.ProcessID = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Proc), 0); - Criteria.DataType = DataTypeExact.Bytes1; - Criteria.StartAddress = Start; - Criteria.Length = Size; - Criteria.SearchType = SearchTypeBase.Unknown; - Criteria.SearchValue = new byte[] { 0 }; - Criteria.Size = 1; - Conn.SearchCriteria.Add(Criteria); - byte[] Data = new byte[Size]; - Console.WriteLine("Dumping PID " + Proc + ", MR " + Start + "+" + Size + "..."); - Conn.SendReadMemoryPacket(Criteria); - while (!Criteria.SearchComplete) - { - Thread.Sleep(10); - } - foreach (uint Addr in Criteria.AddressesFound.Keys) - { - Data[Addr - Start] = Criteria.AddressesFound[Addr][0]; - } - File.WriteAllBytes("Temp" + Path.DirectorySeparatorChar + i + Path.DirectorySeparatorChar + Proc + "_" + Start + ".raw", Data); - } - } - - if (i == 1) - { - Console.WriteLine("Press any key..."); - Console.ReadKey(false); - Console.WriteLine(); - } - } - - t.Abort(); - Conn.Disconnect(); - } - } -} diff --git a/tmp/NTRDebuggerTool/Forms/ConfigDialog.Designer.cs b/tmp/NTRDebuggerTool/Forms/ConfigDialog.Designer.cs deleted file mode 100644 index 57832ed..0000000 --- a/tmp/NTRDebuggerTool/Forms/ConfigDialog.Designer.cs +++ /dev/null @@ -1,128 +0,0 @@ -namespace NTRDebuggerTool.Forms -{ - partial class ConfigDialog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.ButtonCancel = new System.Windows.Forms.Button(); - this.ButtonSave = new System.Windows.Forms.Button(); - this.ConfigDataGrid = new System.Windows.Forms.DataGridView(); - this.Key = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Value = new System.Windows.Forms.DataGridViewTextBoxColumn(); - ((System.ComponentModel.ISupportInitialize)(this.ConfigDataGrid)).BeginInit(); - this.SuspendLayout(); - // - // ButtonCancel - // - this.ButtonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.ButtonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.ButtonCancel.Location = new System.Drawing.Point(13, 227); - this.ButtonCancel.Name = "ButtonCancel"; - this.ButtonCancel.Size = new System.Drawing.Size(75, 23); - this.ButtonCancel.TabIndex = 0; - this.ButtonCancel.Text = "Cancel"; - this.ButtonCancel.UseVisualStyleBackColor = true; - this.ButtonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); - // - // ButtonSave - // - this.ButtonSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonSave.Location = new System.Drawing.Point(197, 227); - this.ButtonSave.Name = "ButtonSave"; - this.ButtonSave.Size = new System.Drawing.Size(75, 23); - this.ButtonSave.TabIndex = 1; - this.ButtonSave.Text = "Save"; - this.ButtonSave.UseVisualStyleBackColor = true; - this.ButtonSave.Click += new System.EventHandler(this.ButtonSave_Click); - // - // ConfigDataGrid - // - this.ConfigDataGrid.AllowUserToAddRows = false; - this.ConfigDataGrid.AllowUserToResizeRows = false; - this.ConfigDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.ConfigDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.ConfigDataGrid.ColumnHeadersVisible = false; - this.ConfigDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.Key, - this.Value}); - this.ConfigDataGrid.Location = new System.Drawing.Point(13, 12); - this.ConfigDataGrid.Name = "ConfigDataGrid"; - this.ConfigDataGrid.RowHeadersVisible = false; - this.ConfigDataGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; - this.ConfigDataGrid.ShowCellErrors = false; - this.ConfigDataGrid.ShowCellToolTips = false; - this.ConfigDataGrid.ShowEditingIcon = false; - this.ConfigDataGrid.ShowRowErrors = false; - this.ConfigDataGrid.Size = new System.Drawing.Size(259, 209); - this.ConfigDataGrid.TabIndex = 2; - this.ConfigDataGrid.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.ConfigDataGrid_CellDoubleClick); - this.ConfigDataGrid.CellLeave += new System.Windows.Forms.DataGridViewCellEventHandler(this.ConfigDataGrid_CellLeave); - // - // Key - // - this.Key.HeaderText = "ColumnKey"; - this.Key.MinimumWidth = 20; - this.Key.Name = "Key"; - this.Key.ReadOnly = true; - // - // Value - // - this.Value.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.Value.HeaderText = "ColumnValue"; - this.Value.MinimumWidth = 20; - this.Value.Name = "Value"; - // - // ConfigDialog - // - this.AcceptButton = this.ButtonSave; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.ButtonCancel; - this.ClientSize = new System.Drawing.Size(284, 284); - this.ControlBox = false; - this.Controls.Add(this.ConfigDataGrid); - this.Controls.Add(this.ButtonSave); - this.Controls.Add(this.ButtonCancel); - this.MinimumSize = new System.Drawing.Size(300, 300); - this.Name = "ConfigDialog"; - this.ShowIcon = false; - this.Text = "Configuration"; - ((System.ComponentModel.ISupportInitialize)(this.ConfigDataGrid)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Button ButtonCancel; - private System.Windows.Forms.Button ButtonSave; - private System.Windows.Forms.DataGridView ConfigDataGrid; - private System.Windows.Forms.DataGridViewTextBoxColumn Key; - private System.Windows.Forms.DataGridViewTextBoxColumn Value; - } -} \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/Forms/ConfigDialog.cs b/tmp/NTRDebuggerTool/Forms/ConfigDialog.cs deleted file mode 100644 index f581643..0000000 --- a/tmp/NTRDebuggerTool/Forms/ConfigDialog.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Collections.Generic; -using System.Windows.Forms; - -namespace NTRDebuggerTool.Forms -{ - public partial class ConfigDialog : Form - { - MainForm Form; - - public ConfigDialog(MainForm Form) - { - this.Form = Form; - InitializeComponent(); - Dictionary ConfigValues = Config.All; - foreach (string Key in ConfigValues.Keys) - { - int Row = ConfigDataGrid.Rows.Add(); - ConfigDataGrid[0, Row].Value = Key; - ConfigDataGrid[1, Row].Value = ConfigValues[Key]; - } - } - - private void ConfigDataGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - ConfigDataGrid.BeginEdit(true); - } - - private void ConfigDataGrid_CellLeave(object sender, DataGridViewCellEventArgs e) - { - ConfigDataGrid.EndEdit(); - } - - private void ButtonCancel_Click(object sender, System.EventArgs e) - { - Close(); - } - - private void ButtonSave_Click(object sender, System.EventArgs e) - { - Dictionary ConfigValues = new Dictionary(); - for (int Row = 0; Row < ConfigDataGrid.RowCount; ++Row) - { - ConfigValues.Add(ConfigDataGrid[0, Row].Value.ToString(), ConfigDataGrid[1, Row].Value.ToString()); - } - Config.All = ConfigValues; - Close(); - } - } -} diff --git a/tmp/NTRDebuggerTool/Forms/ConfigDialog.resx b/tmp/NTRDebuggerTool/Forms/ConfigDialog.resx deleted file mode 100644 index 5bca008..0000000 --- a/tmp/NTRDebuggerTool/Forms/ConfigDialog.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - True - - \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/Forms/FormEnums/DataType.cs b/tmp/NTRDebuggerTool/Forms/FormEnums/DataType.cs deleted file mode 100644 index 043e68f..0000000 --- a/tmp/NTRDebuggerTool/Forms/FormEnums/DataType.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace NTRDebuggerTool.Forms.FormEnums -{ - public static class DataTypeExactTool - { - static Dictionary Mapping = new Dictionary(); - - static DataTypeExactTool() - { - Mapping.Add("1 Byte", DataTypeExact.Bytes1); - Mapping.Add("2 Bytes", DataTypeExact.Bytes2); - Mapping.Add("4 Bytes", DataTypeExact.Bytes4); - Mapping.Add("8 Bytes", DataTypeExact.Bytes8); - Mapping.Add("Float", DataTypeExact.Float); - Mapping.Add("Double", DataTypeExact.Double); - Mapping.Add("Raw", DataTypeExact.Raw); - Mapping.Add("Text", DataTypeExact.Text); - } - - public static string[] GetValues() - { - return Mapping.Keys.ToArray(); - } - - public static DataTypeExact GetValue(string key) - { - return Mapping[key]; - } - - public static string GetKey(DataTypeExact value) - { - foreach (string key in Mapping.Keys) - { - if (Mapping[key] == value) - { - return key; - } - } - return null; - } - } - - public enum DataTypeExact - { - Bytes1 = 1, - Bytes2 = 2, - Bytes4 = 3, - Bytes8 = 4, - Float = 5, - Double = 6, - Raw = 7, - Text = 8 - } - - public static class DataTypeNumericTool - { - static Dictionary Mapping = new Dictionary(); - - static DataTypeNumericTool() - { - Mapping.Add("1 Byte", DataTypeNumeric.Bytes1); - Mapping.Add("2 Bytes", DataTypeNumeric.Bytes2); - Mapping.Add("4 Bytes", DataTypeNumeric.Bytes4); - Mapping.Add("8 Bytes", DataTypeNumeric.Bytes8); - Mapping.Add("Float", DataTypeNumeric.Float); - Mapping.Add("Double", DataTypeNumeric.Double); - } - - public static string[] GetValues() - { - return Mapping.Keys.ToArray(); - } - - public static DataTypeNumeric GetValue(string key) - { - return Mapping[key]; - } - } - - public enum DataTypeNumeric - { - Bytes1 = 1, - Bytes2 = 2, - Bytes4 = 3, - Bytes8 = 4, - Float = 5, - Double = 6 - } -} diff --git a/tmp/NTRDebuggerTool/Forms/FormEnums/SearchType.cs b/tmp/NTRDebuggerTool/Forms/FormEnums/SearchType.cs deleted file mode 100644 index bb0b7df..0000000 --- a/tmp/NTRDebuggerTool/Forms/FormEnums/SearchType.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace NTRDebuggerTool.Forms.FormEnums -{ - - public static class SearchTypeInitialTool - { - static Dictionary Mapping = new Dictionary(); - - static SearchTypeInitialTool() - { - Mapping.Add("Exact", SearchTypeInitial.Exact); - Mapping.Add("Range", SearchTypeInitial.Range); - Mapping.Add("Unknown", SearchTypeInitial.Unknown); - } - - public static string[] GetValues() - { - return Mapping.Keys.ToArray(); - } - - public static SearchTypeInitial GetValue(string key) - { - return Mapping[key]; - } - } - - public enum SearchTypeInitial - { - Exact = 1, - Range = 2, - Unknown = 9 - } - - public static class SearchTypeNumericTool - { - static Dictionary Mapping = new Dictionary(); - - static SearchTypeNumericTool() - { - Mapping.Add("Exact", SearchTypeNumeric.Exact); - Mapping.Add("Range", SearchTypeNumeric.Range); - Mapping.Add("Increased By", SearchTypeNumeric.IncreasedBy); - Mapping.Add("Decreased By", SearchTypeNumeric.DecreasedBy); - Mapping.Add("Increased", SearchTypeNumeric.Increased); - Mapping.Add("Decreased", SearchTypeNumeric.Decreased); - Mapping.Add("Same", SearchTypeNumeric.Same); - Mapping.Add("Different", SearchTypeNumeric.Different); - } - - public static string[] GetValues() - { - return Mapping.Keys.ToArray(); - } - - public static SearchTypeNumeric GetValue(string key) - { - return Mapping[key]; - } - } - - public enum SearchTypeNumeric - { - Exact = 1, - Range = 2, - IncreasedBy = 3, - DecreasedBy = 4, - Increased = 5, - Decreased = 6, - Same = 7, - Different = 8 - } - - public static class SearchTypeTextTool - { - static Dictionary Mapping = new Dictionary(); - - static SearchTypeTextTool() - { - Mapping.Add("Exact", SearchTypeText.Exact); - } - - public static string[] GetValues() - { - return Mapping.Keys.ToArray(); - } - - public static SearchTypeText GetValue(string key) - { - return Mapping[key]; - } - } - - public enum SearchTypeText - { - Exact = 1, - Same = 7, - Different = 8 - } - - public static class SearchTypeBaseTool - { - static Dictionary Mapping = new Dictionary(); - - static SearchTypeBaseTool() - { - Mapping.Add("Exact", SearchTypeBase.Exact); - Mapping.Add("Range", SearchTypeBase.Range); - Mapping.Add("Increased By", SearchTypeBase.IncreasedBy); - Mapping.Add("Decreased By", SearchTypeBase.DecreasedBy); - Mapping.Add("Increased", SearchTypeBase.Increased); - Mapping.Add("Decreased", SearchTypeBase.Decreased); - Mapping.Add("Same", SearchTypeBase.Same); - Mapping.Add("Different", SearchTypeBase.Different); - Mapping.Add("Unknown", SearchTypeBase.Unknown); - } - - public static string[] GetValues() - { - return Mapping.Keys.ToArray(); - } - - public static SearchTypeBase GetValue(string key) - { - return Mapping[key]; - } - } - - public enum SearchTypeBase - { - Exact = 1, - Range = 2, - IncreasedBy = 3, - DecreasedBy = 4, - Increased = 5, - Decreased = 6, - Same = 7, - Different = 8, - Unknown = 9 - } -} diff --git a/tmp/NTRDebuggerTool/Forms/MainForm.Designer.cs b/tmp/NTRDebuggerTool/Forms/MainForm.Designer.cs deleted file mode 100644 index db7801f..0000000 --- a/tmp/NTRDebuggerTool/Forms/MainForm.Designer.cs +++ /dev/null @@ -1,702 +0,0 @@ -namespace NTRDebuggerTool.Forms -{ - partial class MainForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.ComboDataType = new System.Windows.Forms.ComboBox(); - this.SearchValue = new System.Windows.Forms.TextBox(); - this.ResultsGrid = new System.Windows.Forms.DataGridView(); - this.SearchResultsAddressColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.SearchResultsValueColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ButtonAddResults = new System.Windows.Forms.Button(); - this.SearchButton = new System.Windows.Forms.Button(); - this.ResetButton = new System.Windows.Forms.Button(); - this.ValuesGrid = new System.Windows.Forms.DataGridView(); - this.ValuesGridLockColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); - this.ValuesGridAddressColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ValuesGridValueColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ValuesGridTypeColumn = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.ValuesGridContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); - this.ValuesGridRefreshItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ValuesGridAddItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ValuesGridDeleteItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ValuesGridConvertCode = new System.Windows.Forms.ToolStripMenuItem(); - this.ValuesGridPointerSearch = new System.Windows.Forms.ToolStripMenuItem(); - this.ValuesGridCopyResolvedAddress = new System.Windows.Forms.ToolStripMenuItem(); - this.LabelIPPort = new System.Windows.Forms.Label(); - this.LabelProcess = new System.Windows.Forms.Label(); - this.LabelMemoryRange = new System.Windows.Forms.Label(); - this.ButtonConnectDisconnect = new System.Windows.Forms.Button(); - this.ButtonOpenProcess = new System.Windows.Forms.Button(); - this.ButtonRefreshMemoryRange = new System.Windows.Forms.Button(); - this.IP = new System.Windows.Forms.TextBox(); - this.Port = new System.Windows.Forms.TextBox(); - this.Processes = new System.Windows.Forms.ComboBox(); - this.MemoryRange = new System.Windows.Forms.ComboBox(); - this.ProgressBarStatusStrip = new System.Windows.Forms.StatusStrip(); - this.ProgressBarMemoryRead = new System.Windows.Forms.ProgressBar(); - this.GUIUpdateTimer = new System.Windows.Forms.Timer(this.components); - this.LabelCustomRange = new System.Windows.Forms.Label(); - this.MemoryStart = new System.Windows.Forms.TextBox(); - this.MemorySize = new System.Windows.Forms.TextBox(); - this.LabelCurrentOperation = new System.Windows.Forms.Label(); - this.ProgressBarMemoryScan = new System.Windows.Forms.ProgressBar(); - this.LabelLastSearch = new System.Windows.Forms.Label(); - this.LabelDataType = new System.Windows.Forms.Label(); - this.LabelSearchValue = new System.Windows.Forms.Label(); - this.LabelSearchType = new System.Windows.Forms.Label(); - this.ComboSearchType = new System.Windows.Forms.ComboBox(); - this.TextEndAddress = new System.Windows.Forms.TextBox(); - this.LabelEndAddress = new System.Windows.Forms.Label(); - this.SearchValue2 = new System.Windows.Forms.TextBox(); - this.LabelDash = new System.Windows.Forms.Label(); - this.ButtonConfig = new System.Windows.Forms.Button(); - this.LabelButtonState = new System.Windows.Forms.Label(); - this.SaveButton = new System.Windows.Forms.Button(); - this.LoadButton = new System.Windows.Forms.Button(); - ((System.ComponentModel.ISupportInitialize)(this.ResultsGrid)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.ValuesGrid)).BeginInit(); - this.ValuesGridContextMenuStrip.SuspendLayout(); - this.SuspendLayout(); - // - // ComboDataType - // - this.ComboDataType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ComboDataType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.ComboDataType.FormattingEnabled = true; - this.ComboDataType.Location = new System.Drawing.Point(602, 109); - this.ComboDataType.Name = "ComboDataType"; - this.ComboDataType.Size = new System.Drawing.Size(91, 21); - this.ComboDataType.TabIndex = 1; - this.ComboDataType.SelectionChangeCommitted += new System.EventHandler(this.ComboDataType_SelectedValueChanged); - // - // SearchValue - // - this.SearchValue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.SearchValue.Location = new System.Drawing.Point(486, 134); - this.SearchValue.Name = "SearchValue"; - this.SearchValue.Size = new System.Drawing.Size(286, 20); - this.SearchValue.TabIndex = 4; - // - // ResultsGrid - // - this.ResultsGrid.AllowUserToAddRows = false; - this.ResultsGrid.AllowUserToDeleteRows = false; - this.ResultsGrid.AllowUserToResizeRows = false; - this.ResultsGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.ResultsGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.ResultsGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.SearchResultsAddressColumn, - this.SearchResultsValueColumn}); - this.ResultsGrid.Location = new System.Drawing.Point(12, 39); - this.ResultsGrid.Name = "ResultsGrid"; - this.ResultsGrid.ReadOnly = true; - this.ResultsGrid.RowHeadersVisible = false; - this.ResultsGrid.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.ResultsGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; - this.ResultsGrid.ShowCellErrors = false; - this.ResultsGrid.ShowCellToolTips = false; - this.ResultsGrid.ShowEditingIcon = false; - this.ResultsGrid.ShowRowErrors = false; - this.ResultsGrid.Size = new System.Drawing.Size(377, 476); - this.ResultsGrid.TabIndex = 7; - // - // SearchResultsAddressColumn - // - this.SearchResultsAddressColumn.HeaderText = "Address"; - this.SearchResultsAddressColumn.Name = "SearchResultsAddressColumn"; - this.SearchResultsAddressColumn.ReadOnly = true; - this.SearchResultsAddressColumn.Width = 62; - // - // SearchResultsValueColumn - // - this.SearchResultsValueColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.SearchResultsValueColumn.HeaderText = "Value on Search"; - this.SearchResultsValueColumn.Name = "SearchResultsValueColumn"; - this.SearchResultsValueColumn.ReadOnly = true; - // - // ButtonAddResults - // - this.ButtonAddResults.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonAddResults.Location = new System.Drawing.Point(272, 10); - this.ButtonAddResults.Name = "ButtonAddResults"; - this.ButtonAddResults.Size = new System.Drawing.Size(117, 23); - this.ButtonAddResults.TabIndex = 8; - this.ButtonAddResults.Text = "Add Selected Results"; - this.ButtonAddResults.UseVisualStyleBackColor = true; - this.ButtonAddResults.Click += new System.EventHandler(this.ButtonAddResults_Click); - // - // SearchButton - // - this.SearchButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.SearchButton.Location = new System.Drawing.Point(620, 159); - this.SearchButton.Name = "SearchButton"; - this.SearchButton.Size = new System.Drawing.Size(73, 23); - this.SearchButton.TabIndex = 9; - this.SearchButton.Text = "Search"; - this.SearchButton.UseVisualStyleBackColor = true; - this.SearchButton.Click += new System.EventHandler(this.SearchButton_Click); - // - // ResetButton - // - this.ResetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ResetButton.Location = new System.Drawing.Point(699, 159); - this.ResetButton.Name = "ResetButton"; - this.ResetButton.Size = new System.Drawing.Size(73, 23); - this.ResetButton.TabIndex = 10; - this.ResetButton.Text = "Reset"; - this.ResetButton.UseVisualStyleBackColor = true; - this.ResetButton.Click += new System.EventHandler(this.ResetButton_Click); - // - // ValuesGrid - // - this.ValuesGrid.AllowUserToAddRows = false; - this.ValuesGrid.AllowUserToResizeRows = false; - this.ValuesGrid.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Right))); - this.ValuesGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.ValuesGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.ValuesGridLockColumn, - this.ValuesGridAddressColumn, - this.ValuesGridValueColumn, - this.ValuesGridTypeColumn}); - this.ValuesGrid.ContextMenuStrip = this.ValuesGridContextMenuStrip; - this.ValuesGrid.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; - this.ValuesGrid.Location = new System.Drawing.Point(395, 188); - this.ValuesGrid.MultiSelect = false; - this.ValuesGrid.Name = "ValuesGrid"; - this.ValuesGrid.RowHeadersVisible = false; - this.ValuesGrid.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.ValuesGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; - this.ValuesGrid.ShowCellErrors = false; - this.ValuesGrid.ShowEditingIcon = false; - this.ValuesGrid.ShowRowErrors = false; - this.ValuesGrid.Size = new System.Drawing.Size(377, 327); - this.ValuesGrid.TabIndex = 12; - this.ValuesGrid.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.ValuesGrid_CellClick); - this.ValuesGrid.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.ValuesGrid_CellDoubleClick); - this.ValuesGrid.CellLeave += new System.Windows.Forms.DataGridViewCellEventHandler(this.ValuesGrid_CellLeave); - this.ValuesGrid.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.ValuesGrid_CellValueChanged); - // - // ValuesGridLockColumn - // - this.ValuesGridLockColumn.HeaderText = "Lock"; - this.ValuesGridLockColumn.Name = "ValuesGridLockColumn"; - this.ValuesGridLockColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.ValuesGridLockColumn.TrueValue = "T"; - this.ValuesGridLockColumn.Width = 35; - // - // ValuesGridAddressColumn - // - this.ValuesGridAddressColumn.HeaderText = "Address"; - this.ValuesGridAddressColumn.Name = "ValuesGridAddressColumn"; - this.ValuesGridAddressColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.ValuesGridAddressColumn.Width = 62; - // - // ValuesGridValueColumn - // - this.ValuesGridValueColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.ValuesGridValueColumn.HeaderText = "Value"; - this.ValuesGridValueColumn.Name = "ValuesGridValueColumn"; - this.ValuesGridValueColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.ValuesGridValueColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - // - // ValuesGridTypeColumn - // - this.ValuesGridTypeColumn.HeaderText = "Type"; - this.ValuesGridTypeColumn.Name = "ValuesGridTypeColumn"; - this.ValuesGridTypeColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.ValuesGridTypeColumn.Width = 63; - // - // ValuesGridContextMenuStrip - // - this.ValuesGridContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.ValuesGridRefreshItem, - this.ValuesGridAddItem, - this.ValuesGridDeleteItem, - this.ValuesGridConvertCode, - this.ValuesGridPointerSearch, - this.ValuesGridCopyResolvedAddress}); - this.ValuesGridContextMenuStrip.Name = "ValuesGridContextMenuStrip"; - this.ValuesGridContextMenuStrip.Size = new System.Drawing.Size(198, 136); - this.ValuesGridContextMenuStrip.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.ValuesGridContextMenuStrip_ItemClicked); - // - // ValuesGridRefreshItem - // - this.ValuesGridRefreshItem.Name = "ValuesGridRefreshItem"; - this.ValuesGridRefreshItem.Size = new System.Drawing.Size(197, 22); - this.ValuesGridRefreshItem.Text = "Refresh"; - // - // ValuesGridAddItem - // - this.ValuesGridAddItem.Name = "ValuesGridAddItem"; - this.ValuesGridAddItem.Size = new System.Drawing.Size(197, 22); - this.ValuesGridAddItem.Text = "New"; - // - // ValuesGridDeleteItem - // - this.ValuesGridDeleteItem.Name = "ValuesGridDeleteItem"; - this.ValuesGridDeleteItem.Size = new System.Drawing.Size(197, 22); - this.ValuesGridDeleteItem.Text = "Delete"; - // - // ValuesGridConvertCode - // - this.ValuesGridConvertCode.Name = "ValuesGridConvertCode"; - this.ValuesGridConvertCode.Size = new System.Drawing.Size(197, 22); - this.ValuesGridConvertCode.Text = "Convert AR3DS Code"; - // - // ValuesGridPointerSearch - // - this.ValuesGridPointerSearch.Name = "ValuesGridPointerSearch"; - this.ValuesGridPointerSearch.Size = new System.Drawing.Size(197, 22); - this.ValuesGridPointerSearch.Text = "Pointer Scan"; - // - // ValuesGridCopyResolvedAddress - // - this.ValuesGridCopyResolvedAddress.Name = "ValuesGridCopyResolvedAddress"; - this.ValuesGridCopyResolvedAddress.Size = new System.Drawing.Size(197, 22); - this.ValuesGridCopyResolvedAddress.Text = "Copy Resolved Address"; - // - // LabelIPPort - // - this.LabelIPPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelIPPort.Location = new System.Drawing.Point(395, 9); - this.LabelIPPort.Name = "LabelIPPort"; - this.LabelIPPort.Size = new System.Drawing.Size(85, 23); - this.LabelIPPort.TabIndex = 13; - this.LabelIPPort.Text = "IP, Port"; - this.LabelIPPort.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // LabelProcess - // - this.LabelProcess.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelProcess.Location = new System.Drawing.Point(395, 34); - this.LabelProcess.Name = "LabelProcess"; - this.LabelProcess.Size = new System.Drawing.Size(85, 23); - this.LabelProcess.TabIndex = 15; - this.LabelProcess.Text = "Process"; - this.LabelProcess.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // LabelMemoryRange - // - this.LabelMemoryRange.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelMemoryRange.Location = new System.Drawing.Point(395, 59); - this.LabelMemoryRange.Name = "LabelMemoryRange"; - this.LabelMemoryRange.Size = new System.Drawing.Size(85, 23); - this.LabelMemoryRange.TabIndex = 16; - this.LabelMemoryRange.Text = "Memory Range"; - this.LabelMemoryRange.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // ButtonConnectDisconnect - // - this.ButtonConnectDisconnect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonConnectDisconnect.Location = new System.Drawing.Point(699, 9); - this.ButtonConnectDisconnect.Name = "ButtonConnectDisconnect"; - this.ButtonConnectDisconnect.Size = new System.Drawing.Size(73, 23); - this.ButtonConnectDisconnect.TabIndex = 17; - this.ButtonConnectDisconnect.Text = "Connect"; - this.ButtonConnectDisconnect.UseVisualStyleBackColor = true; - this.ButtonConnectDisconnect.Click += new System.EventHandler(this.ButtonConnectDisconnect_Click); - // - // ButtonOpenProcess - // - this.ButtonOpenProcess.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonOpenProcess.Location = new System.Drawing.Point(699, 34); - this.ButtonOpenProcess.Name = "ButtonOpenProcess"; - this.ButtonOpenProcess.Size = new System.Drawing.Size(73, 23); - this.ButtonOpenProcess.TabIndex = 18; - this.ButtonOpenProcess.Text = "Open"; - this.ButtonOpenProcess.UseVisualStyleBackColor = true; - this.ButtonOpenProcess.Click += new System.EventHandler(this.ButtonOpenProcess_Click); - // - // ButtonRefreshMemoryRange - // - this.ButtonRefreshMemoryRange.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonRefreshMemoryRange.Location = new System.Drawing.Point(699, 59); - this.ButtonRefreshMemoryRange.Name = "ButtonRefreshMemoryRange"; - this.ButtonRefreshMemoryRange.Size = new System.Drawing.Size(73, 23); - this.ButtonRefreshMemoryRange.TabIndex = 19; - this.ButtonRefreshMemoryRange.Text = "Refresh"; - this.ButtonRefreshMemoryRange.UseVisualStyleBackColor = true; - this.ButtonRefreshMemoryRange.Click += new System.EventHandler(this.ButtonRefreshMemoryRange_Click); - // - // IP - // - this.IP.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.IP.Location = new System.Drawing.Point(486, 9); - this.IP.Name = "IP"; - this.IP.Size = new System.Drawing.Size(151, 20); - this.IP.TabIndex = 20; - // - // Port - // - this.Port.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.Port.Location = new System.Drawing.Point(643, 9); - this.Port.Name = "Port"; - this.Port.Size = new System.Drawing.Size(50, 20); - this.Port.TabIndex = 21; - this.Port.Text = "8000"; - // - // Processes - // - this.Processes.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.Processes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.Processes.DropDownWidth = 200; - this.Processes.FormattingEnabled = true; - this.Processes.Location = new System.Drawing.Point(486, 34); - this.Processes.Name = "Processes"; - this.Processes.Size = new System.Drawing.Size(207, 21); - this.Processes.TabIndex = 22; - // - // MemoryRange - // - this.MemoryRange.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.MemoryRange.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.MemoryRange.FormattingEnabled = true; - this.MemoryRange.Location = new System.Drawing.Point(486, 59); - this.MemoryRange.Name = "MemoryRange"; - this.MemoryRange.Size = new System.Drawing.Size(207, 21); - this.MemoryRange.TabIndex = 23; - this.MemoryRange.SelectedIndexChanged += new System.EventHandler(this.MemoryRange_SelectedIndexChanged); - // - // ProgressBarStatusStrip - // - this.ProgressBarStatusStrip.AutoSize = false; - this.ProgressBarStatusStrip.Location = new System.Drawing.Point(0, 518); - this.ProgressBarStatusStrip.Name = "ProgressBarStatusStrip"; - this.ProgressBarStatusStrip.Size = new System.Drawing.Size(784, 44); - this.ProgressBarStatusStrip.SizingGrip = false; - this.ProgressBarStatusStrip.TabIndex = 24; - // - // ProgressBarMemoryRead - // - this.ProgressBarMemoryRead.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.ProgressBarMemoryRead.Location = new System.Drawing.Point(10, 525); - this.ProgressBarMemoryRead.Name = "ProgressBarMemoryRead"; - this.ProgressBarMemoryRead.Size = new System.Drawing.Size(377, 15); - this.ProgressBarMemoryRead.TabIndex = 25; - // - // GUIUpdateTimer - // - this.GUIUpdateTimer.Enabled = true; - this.GUIUpdateTimer.Interval = 5; - this.GUIUpdateTimer.Tick += new System.EventHandler(this.GUIUpdateTimer_Tick); - // - // LabelCustomRange - // - this.LabelCustomRange.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelCustomRange.Location = new System.Drawing.Point(395, 84); - this.LabelCustomRange.Name = "LabelCustomRange"; - this.LabelCustomRange.Size = new System.Drawing.Size(85, 23); - this.LabelCustomRange.TabIndex = 26; - this.LabelCustomRange.Text = "Start Addr, Size"; - this.LabelCustomRange.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // MemoryStart - // - this.MemoryStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.MemoryStart.Location = new System.Drawing.Point(486, 84); - this.MemoryStart.Name = "MemoryStart"; - this.MemoryStart.Size = new System.Drawing.Size(65, 20); - this.MemoryStart.TabIndex = 27; - this.MemoryStart.TextChanged += new System.EventHandler(this.Memory_TextChanged); - // - // MemorySize - // - this.MemorySize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.MemorySize.Location = new System.Drawing.Point(557, 84); - this.MemorySize.Name = "MemorySize"; - this.MemorySize.Size = new System.Drawing.Size(65, 20); - this.MemorySize.TabIndex = 28; - this.MemorySize.TextChanged += new System.EventHandler(this.Memory_TextChanged); - // - // LabelCurrentOperation - // - this.LabelCurrentOperation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.LabelCurrentOperation.Location = new System.Drawing.Point(298, 543); - this.LabelCurrentOperation.Name = "LabelCurrentOperation"; - this.LabelCurrentOperation.Size = new System.Drawing.Size(474, 15); - this.LabelCurrentOperation.TabIndex = 29; - // - // ProgressBarMemoryScan - // - this.ProgressBarMemoryScan.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.ProgressBarMemoryScan.Location = new System.Drawing.Point(395, 525); - this.ProgressBarMemoryScan.Name = "ProgressBarMemoryScan"; - this.ProgressBarMemoryScan.Size = new System.Drawing.Size(377, 15); - this.ProgressBarMemoryScan.TabIndex = 30; - // - // LabelLastSearch - // - this.LabelLastSearch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.LabelLastSearch.Location = new System.Drawing.Point(12, 9); - this.LabelLastSearch.Name = "LabelLastSearch"; - this.LabelLastSearch.Size = new System.Drawing.Size(254, 27); - this.LabelLastSearch.TabIndex = 31; - this.LabelLastSearch.Text = "Last Search"; - // - // LabelDataType - // - this.LabelDataType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelDataType.Location = new System.Drawing.Point(699, 109); - this.LabelDataType.Name = "LabelDataType"; - this.LabelDataType.Size = new System.Drawing.Size(73, 23); - this.LabelDataType.TabIndex = 32; - this.LabelDataType.Text = "Data Type"; - this.LabelDataType.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // - // LabelSearchValue - // - this.LabelSearchValue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelSearchValue.Location = new System.Drawing.Point(395, 134); - this.LabelSearchValue.Name = "LabelSearchValue"; - this.LabelSearchValue.Size = new System.Drawing.Size(85, 23); - this.LabelSearchValue.TabIndex = 33; - this.LabelSearchValue.Text = "Search Value"; - this.LabelSearchValue.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // LabelSearchType - // - this.LabelSearchType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelSearchType.Location = new System.Drawing.Point(395, 109); - this.LabelSearchType.Name = "LabelSearchType"; - this.LabelSearchType.Size = new System.Drawing.Size(85, 23); - this.LabelSearchType.TabIndex = 34; - this.LabelSearchType.Text = "Search Type"; - this.LabelSearchType.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // ComboSearchType - // - this.ComboSearchType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ComboSearchType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.ComboSearchType.FormattingEnabled = true; - this.ComboSearchType.Location = new System.Drawing.Point(486, 109); - this.ComboSearchType.Name = "ComboSearchType"; - this.ComboSearchType.Size = new System.Drawing.Size(110, 21); - this.ComboSearchType.TabIndex = 35; - this.ComboSearchType.SelectionChangeCommitted += new System.EventHandler(this.ComboSearchType_SelectedValueChanged); - // - // TextEndAddress - // - this.TextEndAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.TextEndAddress.Enabled = false; - this.TextEndAddress.Location = new System.Drawing.Point(628, 84); - this.TextEndAddress.Name = "TextEndAddress"; - this.TextEndAddress.Size = new System.Drawing.Size(65, 20); - this.TextEndAddress.TabIndex = 36; - // - // LabelEndAddress - // - this.LabelEndAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelEndAddress.Location = new System.Drawing.Point(699, 84); - this.LabelEndAddress.Name = "LabelEndAddress"; - this.LabelEndAddress.Size = new System.Drawing.Size(73, 23); - this.LabelEndAddress.TabIndex = 37; - this.LabelEndAddress.Text = "End Address"; - this.LabelEndAddress.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // - // SearchValue2 - // - this.SearchValue2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.SearchValue2.Location = new System.Drawing.Point(636, 134); - this.SearchValue2.Name = "SearchValue2"; - this.SearchValue2.Size = new System.Drawing.Size(136, 20); - this.SearchValue2.TabIndex = 38; - this.SearchValue2.Visible = false; - // - // LabelDash - // - this.LabelDash.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelDash.Location = new System.Drawing.Point(623, 132); - this.LabelDash.Name = "LabelDash"; - this.LabelDash.Size = new System.Drawing.Size(11, 23); - this.LabelDash.TabIndex = 39; - this.LabelDash.Text = "-"; - this.LabelDash.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - this.LabelDash.Visible = false; - // - // ButtonConfig - // - this.ButtonConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonConfig.Image = global::NTRDebuggerTool.Properties.Resources.cog2; - this.ButtonConfig.Location = new System.Drawing.Point(398, 9); - this.ButtonConfig.Name = "ButtonConfig"; - this.ButtonConfig.Size = new System.Drawing.Size(30, 30); - this.ButtonConfig.TabIndex = 40; - this.ButtonConfig.UseVisualStyleBackColor = true; - this.ButtonConfig.Click += new System.EventHandler(this.ButtonConfig_Click); - // - // LabelButtonState - // - this.LabelButtonState.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.LabelButtonState.Location = new System.Drawing.Point(12, 543); - this.LabelButtonState.Name = "LabelButtonState"; - this.LabelButtonState.Size = new System.Drawing.Size(280, 15); - this.LabelButtonState.TabIndex = 41; - // - // SaveButton - // - this.SaveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.SaveButton.Location = new System.Drawing.Point(398, 160); - this.SaveButton.Name = "SaveButton"; - this.SaveButton.Size = new System.Drawing.Size(73, 23); - this.SaveButton.TabIndex = 42; - this.SaveButton.Text = "Save"; - this.SaveButton.UseVisualStyleBackColor = true; - this.SaveButton.Click += new System.EventHandler(this.SaveButton_Click); - // - // LoadButton - // - this.LoadButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LoadButton.Location = new System.Drawing.Point(477, 159); - this.LoadButton.Name = "LoadButton"; - this.LoadButton.Size = new System.Drawing.Size(73, 23); - this.LoadButton.TabIndex = 43; - this.LoadButton.Text = "Load"; - this.LoadButton.UseVisualStyleBackColor = true; - this.LoadButton.Click += new System.EventHandler(this.LoadButton_Click); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(784, 562); - this.Controls.Add(this.LoadButton); - this.Controls.Add(this.SaveButton); - this.Controls.Add(this.LabelButtonState); - this.Controls.Add(this.ButtonConfig); - this.Controls.Add(this.LabelEndAddress); - this.Controls.Add(this.TextEndAddress); - this.Controls.Add(this.ComboSearchType); - this.Controls.Add(this.LabelSearchType); - this.Controls.Add(this.LabelSearchValue); - this.Controls.Add(this.LabelDataType); - this.Controls.Add(this.LabelLastSearch); - this.Controls.Add(this.ProgressBarMemoryScan); - this.Controls.Add(this.LabelCurrentOperation); - this.Controls.Add(this.MemorySize); - this.Controls.Add(this.MemoryStart); - this.Controls.Add(this.LabelCustomRange); - this.Controls.Add(this.ProgressBarMemoryRead); - this.Controls.Add(this.ProgressBarStatusStrip); - this.Controls.Add(this.MemoryRange); - this.Controls.Add(this.Processes); - this.Controls.Add(this.Port); - this.Controls.Add(this.IP); - this.Controls.Add(this.ButtonRefreshMemoryRange); - this.Controls.Add(this.ButtonOpenProcess); - this.Controls.Add(this.ButtonConnectDisconnect); - this.Controls.Add(this.LabelMemoryRange); - this.Controls.Add(this.LabelProcess); - this.Controls.Add(this.LabelIPPort); - this.Controls.Add(this.ValuesGrid); - this.Controls.Add(this.ResetButton); - this.Controls.Add(this.SearchButton); - this.Controls.Add(this.ButtonAddResults); - this.Controls.Add(this.ResultsGrid); - this.Controls.Add(this.SearchValue); - this.Controls.Add(this.ComboDataType); - this.Controls.Add(this.LabelDash); - this.Controls.Add(this.SearchValue2); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(800, 99999); - this.MinimumSize = new System.Drawing.Size(800, 600); - this.Name = "MainForm"; - this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.Text = "NTR Cheat Tool"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); - this.Load += new System.EventHandler(this.MainForm_Load); - ((System.ComponentModel.ISupportInitialize)(this.ResultsGrid)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.ValuesGrid)).EndInit(); - this.ValuesGridContextMenuStrip.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.ComboBox ComboDataType; - internal System.Windows.Forms.TextBox SearchValue; - internal System.Windows.Forms.DataGridView ResultsGrid; - private System.Windows.Forms.Button ButtonAddResults; - private System.Windows.Forms.Button SearchButton; - private System.Windows.Forms.Button ResetButton; - private System.Windows.Forms.DataGridView ValuesGrid; - private System.Windows.Forms.Label LabelIPPort; - private System.Windows.Forms.Label LabelProcess; - private System.Windows.Forms.Label LabelMemoryRange; - internal System.Windows.Forms.Button ButtonConnectDisconnect; - private System.Windows.Forms.Button ButtonOpenProcess; - private System.Windows.Forms.Button ButtonRefreshMemoryRange; - internal System.Windows.Forms.TextBox IP; - internal System.Windows.Forms.TextBox Port; - internal System.Windows.Forms.ComboBox Processes; - private System.Windows.Forms.ComboBox MemoryRange; - private System.Windows.Forms.StatusStrip ProgressBarStatusStrip; - private System.Windows.Forms.ProgressBar ProgressBarMemoryRead; - private System.Windows.Forms.Timer GUIUpdateTimer; - private System.Windows.Forms.Label LabelCustomRange; - internal System.Windows.Forms.TextBox MemoryStart; - internal System.Windows.Forms.TextBox MemorySize; - private System.Windows.Forms.Label LabelCurrentOperation; - private System.Windows.Forms.ContextMenuStrip ValuesGridContextMenuStrip; - private System.Windows.Forms.ToolStripMenuItem ValuesGridAddItem; - private System.Windows.Forms.ToolStripMenuItem ValuesGridDeleteItem; - private System.Windows.Forms.ToolStripMenuItem ValuesGridConvertCode; - private System.Windows.Forms.ProgressBar ProgressBarMemoryScan; - private System.Windows.Forms.DataGridViewTextBoxColumn SearchResultsAddressColumn; - private System.Windows.Forms.DataGridViewTextBoxColumn SearchResultsValueColumn; - private System.Windows.Forms.Label LabelLastSearch; - private System.Windows.Forms.Label LabelDataType; - private System.Windows.Forms.Label LabelSearchValue; - private System.Windows.Forms.Label LabelSearchType; - private System.Windows.Forms.ComboBox ComboSearchType; - internal System.Windows.Forms.TextBox TextEndAddress; - private System.Windows.Forms.Label LabelEndAddress; - private System.Windows.Forms.DataGridViewCheckBoxColumn ValuesGridLockColumn; - private System.Windows.Forms.DataGridViewTextBoxColumn ValuesGridAddressColumn; - private System.Windows.Forms.DataGridViewTextBoxColumn ValuesGridValueColumn; - private System.Windows.Forms.DataGridViewComboBoxColumn ValuesGridTypeColumn; - internal System.Windows.Forms.TextBox SearchValue2; - private System.Windows.Forms.Label LabelDash; - private System.Windows.Forms.Button ButtonConfig; - private System.Windows.Forms.Label LabelButtonState; - private System.Windows.Forms.ToolStripMenuItem ValuesGridRefreshItem; - private System.Windows.Forms.ToolStripMenuItem ValuesGridPointerSearch; - private System.Windows.Forms.ToolStripMenuItem ValuesGridCopyResolvedAddress; - private System.Windows.Forms.Button SaveButton; - private System.Windows.Forms.Button LoadButton; - } -} diff --git a/tmp/NTRDebuggerTool/Forms/MainForm.cs b/tmp/NTRDebuggerTool/Forms/MainForm.cs deleted file mode 100644 index 6784b36..0000000 --- a/tmp/NTRDebuggerTool/Forms/MainForm.cs +++ /dev/null @@ -1,791 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using NTRDebuggerTool.Objects; -using NTRDebuggerTool.Objects.Saving; -using NTRDebuggerTool.Remote; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using System.Windows.Forms; - -namespace NTRDebuggerTool.Forms -{ - public partial class MainForm : Form - { - internal bool ControlEnabledButtonConnectDisconnect = true; - private bool ControlEnabledIP = true; - private bool ControlEnabledPort = true; - - private bool ControlEnabledProcesses = false; - internal bool ControlEnabledButtonOpenProcess = false; - - internal bool ControlEnabledMemoryRange = false; - private bool ControlEnabledButtonRefreshMemoryRange = false; - private bool ControlEnabledButtonAddResults = false; - private bool ControlEnabledResetButton = false; - private bool ControlEnabledResultsGrid = false; - internal bool ControlEnabledSearchButton = false; - internal bool ControlEnabledDataType = false; - private bool ControlEnabledSearchType = false; - private bool ControlEnabledSearchValue = false; - private bool ControlEnabledSearchValue2 = false; - private bool ControlEnabledValuesGrid = false; - - private bool ControlEnabledStart = false; - private bool ControlEnabledSize = false; - - internal bool FormEnabled = true; - - private Thread EventDispatcherThread; - private Thread ButtonStateThread; - - private int PointerSearchRow = 0; - - internal string SetConnectText = null; - - internal NTRRemoteConnection NTRConnection; - - private MainFormThreadEventDispatcher ThreadEventDispatcher; - private MainFormThreadButtonState ThreadButtonState; - internal bool SearchComplete = false; - - internal SearchCriteria LastSearchCriteria; - - private Stopwatch LockValuesStopwatch = new Stopwatch(); - - public MainForm(NTRRemoteConnection NTRConnection) - { - InitializeComponent(); - this.NTRConnection = NTRConnection; - this.ThreadEventDispatcher = new MainFormThreadEventDispatcher(this); - this.EventDispatcherThread = new Thread(new ThreadStart(this.ThreadEventDispatcher.ThreadEventDispatcher)); - this.EventDispatcherThread.Name = "EventDispatcherThread"; - this.EventDispatcherThread.Start(); - - this.ThreadButtonState = new MainFormThreadButtonState(this); - this.ButtonStateThread = new Thread(new ThreadStart(this.ThreadButtonState.ThreadButtonState)); - this.ButtonStateThread.Name = "ButtonStateThread"; - this.ButtonStateThread.Start(); - - this.IP.Text = Config.DefaultIP; - LockValuesStopwatch.Start(); - } - - private void MainForm_Load(object sender, EventArgs e) - { - ComboSearchType.Items.AddRange(SearchTypeInitialTool.GetValues()); - ComboDataType.Items.AddRange(DataTypeExactTool.GetValues()); - ValuesGridTypeColumn.Items.AddRange(DataTypeExactTool.GetValues()); - this.ComboSearchType.SelectedIndex = 0; - this.ComboDataType.SelectedIndex = 2; - } - - private void UpdateLockedControls() - { - this.ButtonAddResults.Enabled = !NTRConnection.LockControls && this.ControlEnabledButtonAddResults; - this.ButtonConnectDisconnect.Enabled = !NTRConnection.LockControls && this.ControlEnabledButtonConnectDisconnect; - this.ButtonOpenProcess.Enabled = !NTRConnection.LockControls && this.ControlEnabledButtonOpenProcess; - this.ButtonRefreshMemoryRange.Enabled = !NTRConnection.LockControls && this.ControlEnabledButtonRefreshMemoryRange; - this.IP.Enabled = !NTRConnection.LockControls && this.ControlEnabledIP; - this.MemoryRange.Enabled = !NTRConnection.LockControls && this.ControlEnabledMemoryRange; - this.SaveButton.Enabled = !NTRConnection.LockControls && this.ControlEnabledMemoryRange; - this.LoadButton.Enabled = !NTRConnection.LockControls && this.ControlEnabledMemoryRange; - this.Port.Enabled = !NTRConnection.LockControls && this.ControlEnabledPort; - this.Processes.Enabled = !NTRConnection.LockControls && this.ControlEnabledProcesses; - this.ResetButton.Enabled = !NTRConnection.LockControls && this.ControlEnabledResetButton; - this.ResultsGrid.Enabled = !NTRConnection.LockControls && this.ControlEnabledResultsGrid; - this.SearchButton.Enabled = !NTRConnection.LockControls && this.ControlEnabledSearchButton; - this.ComboSearchType.Enabled = !NTRConnection.LockControls && this.ControlEnabledSearchType; - this.ComboDataType.Enabled = !NTRConnection.LockControls && this.ControlEnabledDataType; - this.SearchValue.Enabled = !NTRConnection.LockControls && this.ControlEnabledSearchValue; - this.SearchValue2.Enabled = !NTRConnection.LockControls && this.ControlEnabledSearchValue2; - this.ValuesGrid.Enabled = !NTRConnection.LockControls && this.ControlEnabledValuesGrid; - this.MemoryStart.Enabled = !NTRConnection.LockControls && this.ControlEnabledStart; - this.MemorySize.Enabled = !NTRConnection.LockControls && this.ControlEnabledSize; - - } - - internal void SetConnectedControls(bool Enabled) - { - ControlEnabledProcesses = Enabled; - ControlEnabledButtonOpenProcess = Enabled; - } - - internal void SetProcessSelectedControls(bool Enabled) - { - ControlEnabledMemoryRange = Enabled; - ControlEnabledButtonRefreshMemoryRange = Enabled; - ControlEnabledButtonAddResults = Enabled; - ControlEnabledResetButton = Enabled; - ControlEnabledResultsGrid = Enabled; - ControlEnabledSearchButton = Enabled; - ControlEnabledSearchType = Enabled; - ControlEnabledDataType = Enabled; - ControlEnabledSearchValue = Enabled; - ControlEnabledSearchValue2 = Enabled; - ControlEnabledValuesGrid = Enabled; - } - - internal void SetConnectionControls(bool Enabled) - { - ControlEnabledButtonConnectDisconnect = Enabled; - ControlEnabledIP = Enabled; - ControlEnabledPort = Enabled; - } - - private void GUIUpdateTimer_Tick(object sender, EventArgs e) - { - if (Enabled != FormEnabled) - { - Enabled = FormEnabled; - if (FormEnabled) - { - Activate(); - } - } - - NTRConnection.SendHeartbeatPacket(); - - int LocalReadMax = (int)NTRConnection.ProgressReadMax, LocalRead = (int)NTRConnection.ProgressRead, LocalScanMax = (int)NTRConnection.ProgressScanMax, LocalScan = (int)NTRConnection.ProgressScan; - - if (LocalReadMax > 0 && LocalRead >= 0 && LocalReadMax >= LocalRead) - { - ProgressBarMemoryRead.Maximum = LocalReadMax; - ProgressBarMemoryRead.Value = LocalRead; - } - else - { - ProgressBarMemoryRead.Maximum = ProgressBarMemoryRead.Value = 0; - } - - if (LocalScanMax > 0 && LocalScan >= 0 && LocalScanMax >= LocalScan) - { - ProgressBarMemoryScan.Maximum = LocalScanMax; - ProgressBarMemoryScan.Value = LocalScan; - } - else - { - ProgressBarMemoryScan.Maximum = ProgressBarMemoryScan.Value = 0; - } - - if (NTRConnection.IsProcessListUpdated) - { - NTRConnection.IsProcessListUpdated = false; - string CurrentProcess = Processes.SelectedValue == null ? null : Processes.SelectedValue.ToString(); - Processes.Items.Clear(); - Processes.Items.AddRange(NTRConnection.Processes.ToArray()); - if (CurrentProcess != null && Processes.Items.Contains(CurrentProcess)) - { - Processes.SelectedValue = CurrentProcess; - Processes.SelectedIndex = Processes.Items.IndexOf(CurrentProcess); - } - else if (!Processes.Items[0].ToString().Contains(',')) - { - Processes.SelectedIndex = 0; - } - SetConnectedControls(true); - ControlEnabledButtonConnectDisconnect = true; - NTRConnection.SetCurrentOperationText = ""; - } - - if (NTRConnection.IsMemoryListUpdated) - { - NTRConnection.IsMemoryListUpdated = false; - string CurrentRange = MemoryRange.SelectedValue == null ? "All" : MemoryRange.SelectedValue.ToString(); - MemoryRange.Items.Clear(); - MemoryRange.Items.Add("All"); - foreach (uint Start in NTRConnection.AddressSpaces.Keys) - { - MemoryRange.Items.Add(Utilities.GetStringFromByteArray(BitConverter.GetBytes(Start).Reverse().ToArray()) + "|" + Utilities.GetStringFromByteArray(BitConverter.GetBytes(NTRConnection.AddressSpaces[Start]).Reverse().ToArray())); - } - MemoryRange.Items.Add("Custom"); - if (CurrentRange != null && MemoryRange.Items.Contains(CurrentRange)) - { - MemoryRange.SelectedValue = CurrentRange; - MemoryRange.SelectedIndex = MemoryRange.Items.IndexOf(CurrentRange); - } - SetProcessSelectedControls(true); - SetConnectedControls(true); - NTRConnection.SetCurrentOperationText = ""; - } - - if (LastSearchCriteria != null && LastSearchCriteria.SearchValue != null) - { - LabelLastSearch.Text = "Last Search\n" + LastSearchCriteria.AddressesFound.Count + " results found for " + GetDisplayForByteArray(LastSearchCriteria.SearchValue); - - if (SearchComplete) - { - ControlEnabledSearchButton = true; - if (LastSearchCriteria.AddressesFound.Count < Config.MaxValuesToDisplay) - { - ResultsGrid.Rows.Clear(); - foreach (uint Address in LastSearchCriteria.AddressesFound.Keys) - { - int Row = ResultsGrid.Rows.Add(); - ResultsGrid[0, Row].Value = Utilities.GetStringFromByteArray(BitConverter.GetBytes(Address).Reverse().ToArray()); - ResultsGrid[1, Row].Value = GetDisplayForByteArray(LastSearchCriteria.AddressesFound[Address]); - } - } - NTRConnection.SetCurrentOperationText = ""; - ComboDataType_SelectedValueChanged(null, null); - SearchComplete = false; - } - } - - if (SetConnectText != null) - { - ButtonConnectDisconnect.Text = SetConnectText; - SetConnectText = null; - } - - LabelCurrentOperation.Text = NTRConnection.SetCurrentOperationText; - LabelButtonState.Text = NTRConnection.SetCurrentOperationText2; - - UpdateLockedControls(); - - if (NTRConnection.IsConnected) - { - if (LockValuesStopwatch.ElapsedMilliseconds > Config.LockValuesDelay) - { - for (int i = 0; i < ValuesGrid.Rows.Count; ++i) - { - if (ValuesGrid[0, i].Value is string) - { - SetMemory(i); - } - } - LockValuesStopwatch.Restart(); - } - } - - if (ThreadEventDispatcher.FoundPointerAddress != null) - { - ValuesGrid[1, PointerSearchRow].Value = ThreadEventDispatcher.FoundPointerAddress; - ThreadEventDispatcher.FoundPointerAddress = null; - } - - if (ThreadEventDispatcher.RefreshValueReturn.Count > 0) - { - MemoryDispatch MemoryDispatch; - while (ThreadEventDispatcher.RefreshValueReturn.TryDequeue(out MemoryDispatch)) - { - ValuesGrid[1, MemoryDispatch.Row].ToolTipText = MemoryDispatch.ResolvedAddress; - ValuesGrid[2, MemoryDispatch.Row].Value = GetDisplayForByteArray(MemoryDispatch.Value, MemoryDispatch.Type); - } - } - } - - public string GetDisplayForByteArray(byte[] p) - { - return GetDisplayForByteArray(p, ThreadEventDispatcher.CurrentSelectedDataType); - } - - public string GetDisplayForByteArray(byte[] p, DataTypeExact DataType) - { - switch (DataType) - { - case DataTypeExact.Bytes1: //1 Byte - return ((uint)p[0]).ToString(); - case DataTypeExact.Bytes2: //2 Bytes - return BitConverter.ToUInt16(p, 0).ToString(); - case DataTypeExact.Bytes4: //4 Bytes - return BitConverter.ToUInt32(p, 0).ToString(); - case DataTypeExact.Bytes8: //8 Bytes - return BitConverter.ToUInt64(p, 0).ToString(); - case DataTypeExact.Float: //Float - return BitConverter.ToSingle(p, 0).ToString(); - case DataTypeExact.Double: //Double - return BitConverter.ToDouble(p, 0).ToString(); - case DataTypeExact.Raw: //Raw Bytes - return Utilities.GetStringFromByteArray(p); - default: //Text - return System.Text.Encoding.Default.GetString(p); - } - } - - internal uint GetSearchMemorySize() - { - return GetSearchMemorySize(ThreadEventDispatcher.CurrentSelectedDataType); - } - - internal uint GetSearchMemorySize(DataTypeExact DataType) - { - switch (DataType) - { - case DataTypeExact.Bytes1: //1 Byte - return 1; - case DataTypeExact.Bytes2: //2 Bytes - return 2; - case DataTypeExact.Bytes4: //4 Bytes - return 4; - case DataTypeExact.Bytes8: //8 Bytes - return 8; - case DataTypeExact.Float: //Float - return (uint)BitConverter.GetBytes(float.MinValue).Length; - case DataTypeExact.Double: //Double - return (uint)BitConverter.GetBytes(double.MinValue).Length; - case DataTypeExact.Raw: //Raw Bytes - return (uint)Utilities.GetByteArrayFromByteString(SearchValue.Text).Length; - default: //Text - return (uint)System.Text.Encoding.Default.GetBytes(SearchValue.Text).Length; - } - } - - private void ResetButton_Click(object sender, EventArgs e) - { - ComboSearchType.Items.Clear(); - ComboSearchType.Items.AddRange(SearchTypeInitialTool.GetValues()); - ComboSearchType.SelectedIndex = 0; - LastSearchCriteria = null; - ResultsGrid.Rows.Clear(); - ControlEnabledSearchType = ControlEnabledMemoryRange = ControlEnabledDataType = true; - if (MemoryRange.SelectedIndex == MemoryRange.Items.Count - 1) - { - ControlEnabledStart = ControlEnabledSize = true; - } - - LabelLastSearch.Text = "Last Search\n"; - } - - private void MainForm_FormClosing(object sender, FormClosingEventArgs e) - { - NTRConnection.Disconnect(); - this.EventDispatcherThread.Abort(); - this.ButtonStateThread.Abort(); - Application.Exit(); - } - - private void ButtonAddResults_Click(object sender, EventArgs e) - { - foreach (DataGridViewRow Row in ResultsGrid.SelectedRows) - { - if (!IsInValues((string)Row.Cells[0].Value)) - { - int RowIndex = ValuesGrid.Rows.Add(); - ValuesGrid[0, RowIndex].Value = null; - ValuesGrid[3, RowIndex].Value = ComboDataType.Text; - ValuesGrid[1, RowIndex].Value = Row.Cells[0].Value; - ValuesGrid[2, RowIndex].Value = SearchValue.Text; - } - } - } - - private bool IsInValues(String Address) - { - for (int i = 0; i < ValuesGrid.RowCount; ++i) - { - if (((string)ValuesGrid[1, i].Value) == Address) - { - return true; - } - } - return false; - } - - private void ValuesGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e) - { - if (e.RowIndex >= 0 && e.ColumnIndex == 2) - { - SetMemory(e.RowIndex); - } - } - - private void SetMemory(int RowIndex) - { - string TextAddress = (string)ValuesGrid[1, RowIndex].Value; - - MemoryDispatch MemoryDispatch = new MemoryDispatch(); - MemoryDispatch.Row = RowIndex; - MemoryDispatch.TextAddress = TextAddress; - MemoryDispatch.Type = DataTypeExactTool.GetValue((string)ValuesGrid[3, RowIndex].Value); - MemoryDispatch.Value = GetByteArrayForDataType(MemoryDispatch.Type, (string)ValuesGrid[2, RowIndex].Value); - - ThreadEventDispatcher.WriteAddress.Enqueue(MemoryDispatch); - } - - private byte[] GetByteArrayForDataType(DataTypeExact DataType, string Value) - { - switch (DataType) - { - case DataTypeExact.Bytes1: //1 Byte - return new byte[] { (byte)uint.Parse(Value) }; - case DataTypeExact.Bytes2: //2 Bytes - return BitConverter.GetBytes(ushort.Parse(Value)); - case DataTypeExact.Bytes4: //4 Bytes - return BitConverter.GetBytes(uint.Parse(Value)); - case DataTypeExact.Bytes8: //8 Bytes - return BitConverter.GetBytes(ulong.Parse(Value)); - case DataTypeExact.Float: //Float - return BitConverter.GetBytes(float.Parse(Value)); - case DataTypeExact.Double: //Double - return BitConverter.GetBytes(double.Parse(Value)); - case DataTypeExact.Raw: //Raw Bytes - return Utilities.GetByteArrayFromByteString(Value); - case DataTypeExact.Text: //Raw Bytes - default: - return System.Text.Encoding.Default.GetBytes(Value); - } - } - - private void ValuesGrid_CellClick(object sender, DataGridViewCellEventArgs e) - { - if (e.ColumnIndex == 0) - { - ValuesGrid.BeginEdit(true); - } - else if (e.ColumnIndex == 3) - { - ValuesGrid.BeginEdit(true); - ((ComboBox)ValuesGrid.EditingControl).DroppedDown = true; - } - } - - private void ValuesGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - ValuesGrid.BeginEdit(true); - } - - private void ValuesGrid_CellLeave(object sender, DataGridViewCellEventArgs e) - { - ValuesGrid.EndEdit(); - } - - private void MemoryRange_SelectedIndexChanged(object sender, EventArgs e) - { - if (MemoryRange.SelectedIndex == 0) - { - this.MemoryStart.Text = this.MemorySize.Text = ""; - ControlEnabledStart = ControlEnabledSize = false; - } - else if (MemoryRange.SelectedIndex == MemoryRange.Items.Count - 1) - { - ControlEnabledStart = ControlEnabledSize = true; - } - else - { - string[] Parts = MemoryRange.Text.Split('|'); - this.MemoryStart.Text = Parts[0]; - this.MemorySize.Text = Parts[1]; - ControlEnabledStart = ControlEnabledSize = false; - } - } - - private void ButtonConnectDisconnect_Click(object sender, EventArgs e) - { - ButtonConnectDisconnect.Enabled = ControlEnabledButtonConnectDisconnect = false; - ThreadEventDispatcher.DispatchConnect = true; - } - - private void ButtonOpenProcess_Click(object sender, EventArgs e) - { - ButtonOpenProcess.Enabled = ControlEnabledButtonOpenProcess = false; - ThreadEventDispatcher.CurrentSelectedProcess = Processes.Text; - ThreadEventDispatcher.DispatchOpenProcess = true; - SaveButton.Enabled = true; - LoadButton.Enabled = true; - } - - private void ButtonRefreshMemoryRange_Click(object sender, EventArgs e) - { - ButtonRefreshMemoryRange.Enabled = ControlEnabledButtonRefreshMemoryRange = false; - ThreadEventDispatcher.CurrentSelectedProcess = Processes.Text; - ThreadEventDispatcher.DispatchOpenProcess = true; - } - - private void SearchButton_Click(object sender, EventArgs e) - { - MemoryStart.Text = MemoryStart.Text.PadLeft(8, '0'); - MemorySize.Text = MemorySize.Text.PadLeft(8, '0'); - uint StartAddress = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(MemoryStart.Text).Reverse().ToArray(), 0); - uint EndAddress = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(TextEndAddress.Text).Reverse().ToArray(), 0); - if (!MemoryRange.Text.Equals("All") && (!IsValidMemoryAddress(StartAddress) || !IsValidMemoryAddress(EndAddress))) - { - NTRConnection.SetCurrentOperationText = "Invalid start address or size!"; - return; - } - SearchButton.Enabled = ControlEnabledSearchButton = ControlEnabledDataType = ControlEnabledMemoryRange = false; - ThreadEventDispatcher.CurrentSelectedDataType = DataTypeExactTool.GetValue(ComboDataType.SelectedItem.ToString()); - ThreadEventDispatcher.CurrentSelectedSearchType = SearchTypeBaseTool.GetValue(ComboSearchType.SelectedItem.ToString()); - ThreadEventDispatcher.CurrentMemoryRange = this.MemoryRange.Text; - ThreadEventDispatcher.DispatchSearch = true; - } - - private void SaveButton_Click(object sender, EventArgs e) - { - SaveManager sm = new SaveManager(); - sm.Init(); - // Get a list of all saved addresses - foreach (DataGridViewRow row in ValuesGrid.Rows) - { - if (row.Cells[1].Value is GateSharkCode) - { - // @TODO This will be different. - } - else - { - sm.codes.Add(new SaveCode(DataTypeExactTool.GetValue(row.Cells[3].Value.ToString()), row.Cells[1].Value.ToString())); - } - } - - // Set the values - String[] parts_ = Processes.Text.Split('|'); - if (parts_.Length < 2) return; - String game = Config.ConfigFileDirectory + Path.DirectorySeparatorChar + parts_[1] + @".xml"; - sm.titleId = parts_[1]; - SaveManager.SaveToXml(game, sm); - MessageBox.Show(@"Saved selected addresses to '" + game + "'"); - } - - private void LoadButton_Click(object sender, EventArgs e) - { - String[] parts_ = Processes.Text.Split('|'); - if (parts_.Length < 2) return; - String game = Config.ConfigFileDirectory + Path.DirectorySeparatorChar + parts_[1] + @".xml"; - SaveManager sm = SaveManager.LoadFromXml(game); - if (sm.titleId != parts_[1]) - { - MessageBox.Show(@"Filename/TitleID Mismatch."); - } - else - { - foreach (SaveCode code in sm.codes) - { - if (!IsInValues(code.address)) - { - int RowIndex = ValuesGrid.Rows.Add(); - ValuesGrid[0, RowIndex].Value = null; - ValuesGrid[3, RowIndex].Value = DataTypeExactTool.GetKey(code.type); - ValuesGrid[1, RowIndex].Value = code.address; - - // Read the memory - RefreshMemory(RowIndex); - } - } - } - } - - private void RefreshMemory(int RowIndex) - { - ThreadEventDispatcher.CurrentSelectedProcess = Processes.Text.Split('|')[0]; - MemoryDispatch MemoryDispatch = new MemoryDispatch(); - MemoryDispatch.Row = RowIndex; - MemoryDispatch.TextAddress = (string)ValuesGrid[1, RowIndex].Value; - MemoryDispatch.Type = DataTypeExactTool.GetValue((string)ValuesGrid[3, RowIndex].Value); - ThreadEventDispatcher.RefreshValueAddresses.Enqueue(MemoryDispatch); - } - - private void ComboSearchType_SelectedValueChanged(object sender, EventArgs e) - { - string CurrentDataType = ComboDataType.SelectedItem == null ? null : ComboDataType.SelectedItem.ToString(); - switch (SearchTypeBaseTool.GetValue(ComboSearchType.SelectedItem.ToString())) - { - case SearchTypeBase.Exact: - ComboDataType.Items.Clear(); - ComboDataType.Items.AddRange(DataTypeExactTool.GetValues()); - SearchValue.Width = 286; - SearchValue2.Visible = LabelDash.Visible = false; - break; - case SearchTypeBase.Range: - ComboDataType.Items.Clear(); - ComboDataType.Items.AddRange(DataTypeNumericTool.GetValues()); - SearchValue.Width = 136; - SearchValue2.Visible = LabelDash.Visible = true; - break; - case SearchTypeBase.IncreasedBy: - case SearchTypeBase.DecreasedBy: - case SearchTypeBase.Increased: - case SearchTypeBase.Decreased: - case SearchTypeBase.Unknown: - ComboDataType.Items.Clear(); - ComboDataType.Items.AddRange(DataTypeNumericTool.GetValues()); - SearchValue.Width = 286; - SearchValue2.Visible = LabelDash.Visible = false; - break; - } - if (CurrentDataType != null && ComboDataType.Items.Contains(CurrentDataType)) - { - ComboDataType.SelectedIndex = ComboDataType.Items.IndexOf(CurrentDataType); - ComboDataType.SelectedItem = ComboDataType.SelectedValue = CurrentDataType; - } - else - { - ComboDataType.SelectedIndex = 0; - ComboDataType.SelectedItem = ComboDataType.SelectedValue = ComboDataType.Items[0]; - } - } - - private void ComboDataType_SelectedValueChanged(object sender, EventArgs e) - { - string CurrentSearchType = ComboSearchType.SelectedItem == null ? null : ComboSearchType.SelectedItem.ToString(); - if (LastSearchCriteria == null) - { - ComboSearchType.Items.Clear(); - ComboSearchType.Items.AddRange(SearchTypeInitialTool.GetValues()); - } - else - { - switch (DataTypeExactTool.GetValue(ComboDataType.SelectedItem.ToString())) - { - case DataTypeExact.Bytes1: - case DataTypeExact.Bytes2: - case DataTypeExact.Bytes4: - case DataTypeExact.Bytes8: - case DataTypeExact.Float: - case DataTypeExact.Double: - ComboSearchType.Items.Clear(); - ComboSearchType.Items.AddRange(SearchTypeNumericTool.GetValues()); - break; - case DataTypeExact.Raw: - case DataTypeExact.Text: - ComboSearchType.Items.Clear(); - ComboSearchType.Items.AddRange(SearchTypeTextTool.GetValues()); - break; - } - } - if (CurrentSearchType != null && ComboSearchType.Items.Contains(CurrentSearchType)) - { - ComboSearchType.SelectedIndex = ComboSearchType.Items.IndexOf(CurrentSearchType); - ComboSearchType.SelectedItem = ComboSearchType.SelectedValue = CurrentSearchType; - } - else - { - ComboSearchType.SelectedIndex = 0; - ComboSearchType.SelectedItem = ComboSearchType.SelectedValue = ComboSearchType.Items[0]; - } - } - - private void PopulateComboBox(Type enumType, ComboBox box) - { - box.Items.Clear(); - box.Items.AddRange(Enum.GetNames(enumType)); - } - - private void ValuesGridContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) - { - switch (e.ClickedItem.Name) - { - case "ValuesGridCopyResolvedAddress": - foreach (DataGridViewCell Cell in ValuesGrid.SelectedCells) - { - Clipboard.SetText(Cell.OwningRow.Cells[1].ToolTipText); - break; - } - break; - case "ValuesGridPointerSearch": - foreach (DataGridViewCell Cell in ValuesGrid.SelectedCells) - { - PointerSearchRow = Cell.OwningRow.Index; - ThreadEventDispatcher.CurrentSelectedProcess = Processes.Text.Split('|')[0]; - ThreadEventDispatcher.DispatchPointerSearch = (string)Cell.OwningRow.Cells[1].Value; - break; - } - break; - case "ValuesGridDeleteItem": - foreach (DataGridViewCell Cell in ValuesGrid.SelectedCells) - { - ValuesGrid.Rows.Remove(Cell.OwningRow); - } - break; - case "ValuesGridAddItem": - ValuesGrid.Rows.Add(); - break; - case "ValuesGridConvertCode": - foreach (DataGridViewCell Cell in ValuesGrid.SelectedCells) - { - Cell.OwningRow.Cells[1].Value = ConvertCode((string)Cell.OwningRow.Cells[1].Value); - } - break; - case "ValuesGridRefreshItem": - foreach (DataGridViewCell Cell in ValuesGrid.SelectedCells) - { - RefreshMemory(Cell.RowIndex); - } - break; - } - } - - private string ConvertCode(string Address) - { - uint OriginalCodeAddress = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Address).Reverse().ToArray(), 0); - uint ConvertedMemoryAddress = OriginalCodeAddress + 0x14000000u; //High memory region - if (IsValidMemoryAddress(ConvertedMemoryAddress)) - { - return Utilities.GetStringFromByteArray(BitConverter.GetBytes(ConvertedMemoryAddress).Reverse().ToArray()); - } - uint ConversionModifier = GetConversionModifier(ConvertedMemoryAddress); - if (ConversionModifier == 0) - { - return Address; - } - uint Offset = ConvertedMemoryAddress - ConversionModifier; - ConvertedMemoryAddress = 0x08000000 + Offset; - if (IsValidMemoryAddress(ConvertedMemoryAddress)) - { - return Utilities.GetStringFromByteArray(BitConverter.GetBytes(ConvertedMemoryAddress).Reverse().ToArray()); - } - ConvertedMemoryAddress = 0x00100000 + Offset; - if (IsValidMemoryAddress(ConvertedMemoryAddress)) - { - return Utilities.GetStringFromByteArray(BitConverter.GetBytes(ConvertedMemoryAddress).Reverse().ToArray()); - } - return Address; - } - - internal bool IsValidMemoryAddress(uint Address) - { - return GetAddressSpaceForAddress(Address) != null; - } - - internal Nullable> GetAddressSpaceForAddress(uint Address) - { - foreach (uint RangeStart in NTRConnection.AddressSpaces.Keys) - { - if (Address >= RangeStart && Address <= (RangeStart + NTRConnection.AddressSpaces[RangeStart])) - { - return new KeyValuePair(RangeStart, NTRConnection.AddressSpaces[RangeStart]); - } - } - return null; - } - - private uint GetConversionModifier(uint Address) - { - uint[] Keys = NTRConnection.AddressSpaces.Keys.ToArray(); - Array.Sort(Keys); - foreach (uint RangeStart in Keys.Reverse()) - { - if (RangeStart <= Address) - { - //This is ugly. - return BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Utilities.GetStringFromByteArray(BitConverter.GetBytes(RangeStart + NTRConnection.AddressSpaces[RangeStart]).Reverse().ToArray()).Substring(0, 3).PadRight(8, '0')).Reverse().ToArray(), 0) + 0x00100000u; - } - } - return 0; - } - - private void ButtonConfig_Click(object sender, EventArgs e) - { - ThreadEventDispatcher.DispatchConfig = true; - } - - private void Memory_TextChanged(object sender, EventArgs e) - { - if (!string.IsNullOrWhiteSpace(MemoryStart.Text) && !string.IsNullOrWhiteSpace(MemorySize.Text)) - { - string Start = MemoryStart.Text.PadLeft(8, '0'); - string Size = MemorySize.Text.PadLeft(8, '0'); - uint StartInt = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Start).Reverse().ToArray(), 0); - uint SizeInt = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Size).Reverse().ToArray(), 0); - uint EndInt = StartInt + SizeInt; - string End = Utilities.GetStringFromByteArray(BitConverter.GetBytes(EndInt).Reverse().ToArray()); - TextEndAddress.Text = End; - } - else - { - TextEndAddress.Text = ""; - } - } - } -} diff --git a/tmp/NTRDebuggerTool/Forms/MainForm.resx b/tmp/NTRDebuggerTool/Forms/MainForm.resx deleted file mode 100644 index caaea75..0000000 --- a/tmp/NTRDebuggerTool/Forms/MainForm.resx +++ /dev/null @@ -1,314 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - True - - - True - - - True - - - True - - - True - - - 335, 17 - - - 17, 17 - - - 192, 17 - - - - - AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUULPz8/DEVFRQsAAAABAAAAAAAA - AAAAAAABcllMFHJbT0NxW05+b1pNtG9bTtduWk3vclxO/nNdT/9zXU//c11P/nFdT+5xXU/VcVxNsW5Z - TYNoV01MXVVMHgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUULPz8/DEVFRQsAAAABAAAAAEdH - Rz1FRUVjVVVVAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOjo6DURE - RA86OjoNf19fCHVbTDJzXU+AcltOxnNbTe9xW039c11P/3BbTf9wW07/cFtN/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3FbTf1uWkzwblpNyWxZTIZ1XU40f1VVBgAAAAAAAAAAAAAAAAAAAAB/f38COjo6DURE - RA86OjoNREREPEJCQvlGRkb/REREuT8/PxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAf39/AkZGRhJoVktHblpMpHNdT+hzXU/+c11P/3NdT/9zXU//c11P/3NdT/9wW03/cFtO/3Bb - Tf9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//cFtN/3BbTv5uWkzpclxOoHJdUDxmZmYFAAAAAAAA - AAAAAAAAf39/Ajo6Og1FRUUsRERE5EZGRsxGRkb/RkZG/0VFRZsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAb19PIHFcTY1uW0zqcFtO/3BbTf9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//cFtN/3BbTv9wW03/c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3BbTf9wW07/cFtN/3Fd - TelyXE6Mb19PIAAAAAAAAAAAAAAAAEhISA5CQkLTRERExURERORERES+RkZG/0ZGRnAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/fwJxXU9Kc1xNzHNdT/5zXU//cFtN/3BbTv9wW03/c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//c11P/3BbTf9wW07/cFtN/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9wW03/cFtO/3BbTf9zXU/+c1xNzHFdT0p/f38CAAAAAUVFRa9GRkb/QkJC/ERERLZEREToQ0NDpgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVVVUDcVQ4CXJbTm9xXU3pc11P/3NdT/9zXU//c11P/3Bb - Tf9wW07/cFtN/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9wW03/cFtO/3BbTf9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//cFtN/3BbTv9wW03/c11P/3FdTelyW05vRkREikZGRv9GRkb/RkZG/0ZG - Rv9ERETGPDw8FX9/fwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtW0gOb1pMgnFaTvVzXU//c11P/3Nd - T/9zXU//c11P/3NdT/9wW03/cFtO/3BbTf9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//cFtN/3Bb - Tv9wW03/c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3BbTf9wW07/cFtN/3NdT/9hUkr5RkZG/0ZG - Rv9GRkb/RkZG/0VFReVDQ0MmREREDzo6Og0AAAAAAAAAAAAAAAAAAAAAAAAAAH9fPwhyXE+BcFxN+XFc - Tv9yXE7/c11P/3NdT/9zXU//c11P/3NdT/9zXU//cFtN/3BbTv9wW03/c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3BbTf9wW07/cFtN/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9wW03/cFtO/2lY - Tf9HRkb/RkZG/0ZGRv9GRkb/RUVF9kRERDR/f38COjo6DURERA8AAAAAAAAAAAAAAAAAAAAAf39/AnJb - Tm9yW0/1cVxO/3BbTv9xW07/clxN/3FbTf9zXE7/c11P/3NdT/9zXU//c11P/3BbTf9wW07/cVxO/3Re - UP9xW03/c1xO/3NdT/9zXU//c11P/3NdT/9wW03/cFtO/3BbTf9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//cFtN/2JUS/9GRkb/RkZG/0ZGRv9GRkb/RUVFWAAAAAAAAAAAf39/Ajo6Og0AAAAAAAAAAAAA - AAAAAAAAcV1PSnFdTelzXU//clxO/3BbTf+AbmP/rqSc/5aGfP96ZFf/cVtN/3NdT/9zXU//c11P/3Nd - T/9vWkz/nY+G/8K7tv+fj4b/eGNW/3FbTf9zXU//c11P/3NdT/9zXU//cFtN/3BbTv9wW03/c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//cVxP/09KR/9GRkb/RkZG/0ZGRv9ZUEn0cV1PSgAAAAAAAAAAAAAAAH9/ - fwIAAAAAAAAAAAAAAABvX08gc1tPy3NdT/9zXU//c11P/3FbTf9+bF//3dnW/+/t7f/Vzsr/n4+G/3hj - Vv9xW03/c11P/3NdT/9xW03/o5eO//Py8v/v7u7/0MnE/5eGfP91YFL/cVtN/3NdT/9zXU//c11P/3Bb - Tf9wW07/cFtN/3NdT/9zXU//c11P/3NdT/9yXE7/VE1I/0ZGRv9GRkb/VE1H/2FTS/9yXE7/c1tPy29f - TyAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVVQNyXE6Mc11P/3NdT/9zXU//c11P/3NdT/9yXE7/tqym//T0 - 9P/09PT/+Pj3/9PMyP+VhHr/dF5Q/3JcTv9yXE7/gW5i/93Z1v/09PT/9PT0//Ty8f/Iv7n/jn1y/3Re - UP9yW03/c11P/3NdT/9wW03/cFtO/3BbTf9zXU//c11P/3NdT/9ZT0n/RkZG/0ZGRv9UTUj/b1pN/3Bb - Tv9wW03/c11P/3JcToxVVVUDAAAAAAAAAAAAAAAAAAAAAHJdUDxzXU/oc11P/3NdT/9zXU//c11P/3Nd - T/9yW03/i3pv/+Xi4f/09PT/6uno/9TOyf/a1ND/uK2m/35pXP9yW03/clxO/7itpv/09PT/9PT0//T0 - 9P/9/f3/8O7s/76zrf+HdWn/clxO/3JcTv9zXU//cFtN/3BbTv9wW03/c11P/2BTS/9GRkb/RkZG/09J - Rv9xXE7/c11P/3BbTf9wW07/cFtN/3NdT+hyXVA8AAAAAAAAAAAAAAAAZmZmBXNdTp9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//dF5Q/7+1rv/z8vL/ppqT/3FdT/+HdWn/0crF/9XOyv+OfHD/cFpL/4x6 - b//v7Ov/9PT0//T09P/09PT//f39//7+/v/q5+X/saWd/31pXP9yXE3/c11P/3BbTf9wW07/Y1RL/0ND - Q/9GRkb/SkZE/29bTv9zXU//c11P/3NdT/9wW03/cFtO/3BbTf9yXE6gZmZmBQAAAAAAAAAAc19QM3Fb - T+dzXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//cltN/4l2a//j39z/kYJ3/21YS/9vWkz/fWlc/7+1 - rv/i3tv/kIJ5/2FUTP92c3H/cnJy/2ZmZv9lZWX/d3d3/5iYmP/Gxsb/9/b2/9fQzP+Jd2v/clxO/3Nd - T/9nVkz/RkVF/0ZGRv9IR0X/bFlN/3NdT/9zXU//c11P/3NdT/9zXU//cFtN/3BbTv9tWkzoc2BRNQAA - AAAAAAAAc11PgHNdT/9zXU//c11P/3NdT/9yXE//clxO/3NdT/9zXU//c11P/3JcTv+toJj/z8fD/3to - XP91YlX/g3Fl/2hYT/9dWlf/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/T09P/5iY - mP/Iwr7/fGda/2xZTf9IRkX/RkZG/0ZFRf9nV0z/c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Bb - Tf9wW07/bFlMhn9/fwJtYVQVc11NxXNdT/9zXU//c11P/3NdT/9yXE//cVxO/3JcTv9zXU//c11P/3Jc - Tv96ZVj/0MnE/8S7tf9wXlP/XFhV/0ZGRv9GRkb/RkZG/0dHRv9TTUr/cGtn/4WBfv+JhYT/fHt6/11d - Xf9GRkb/RkZG/0ZGRv9NTU3/cWhi/0tHRf9GRkb/Q0ND/2NUS/9wW07/cFtN/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/9wW03/blpMyFRNTSFyW09DcV1P7nNdT/9zXU//c11P/3NdT/9yXE//clxP/3Fc - Tv9yXE7/clxN/3NdT/9yW03/i3lu/8C9u/9OTEz/RkZG/0ZGRv9fXVz/a11U/25ZSv9zXU//emVY/3pl - WP94YlX/f2xf/5GCd/+km5b/hoSE/0tLS/9GRkb/RkZG/0ZGRv9GRkb/X1JK/3NdT/9wW03/cFtO/3Bb - Tf9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//bVpM72hUS05yXU99cVtN/XNdT/9zXU//c11P/3Nd - T/9zXU//cVxO/3BbTv91YFT/h3Zq/3lkVv9xW03/Z1ZK/0hIR/9GRkb/R0ZG/2hcVP/Ox8T/0MvH/4x7 - cP9yXE7/mop//83Gwf/Iv7n/q56V/4t6b/90YFP/e2hc/5iNhv9sa2v/RkZG/0ZGRv9MSUf/clxO/3Nd - T/9zXU//cFtN/3BbTv9wW03/c11P/3NdT/9zXU//c11P/3NdT/9zXU//cVtN/WxYS4RzXU+xc11P/3Nd - T/9zXU//c11P/3NdT/9zXU//clxO/29aTP+JeGz/39vZ/9TNyf+ZjYX/SUdG/0ZGRv9OTUz/t7Cs/3di - VP+Id2z/4N3b/+He3P+fkIb/dmFT/5+Qh//p5uT///////Ty8f/Uzcn/nY+G/3ZjVf9+a2D/XlZR/0ZG - Rv9GRkb/WE9J/3NdT/9zXU//c11P/3BbTf9wW07/cFtN/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Jd - TrJxXU/Vc11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3FbTf99al3/2dTS//T09P91dXX/RkZG/0xM - S/99bWP/kX90/3diVP9xW03/mYuD/+ro5//s6un/tami/3lkV/+KeGz/1tDM//7+/v//////+vn5/87I - xP+OfnT/bllL/1RMR/9GRkb/RkZG/2ZWTP9zXU//c11P/3NdT/9wW03/cFtO/3BbTf9zXU//c11P/3Nd - T/9zXU//c11P/3FdT9VxXU/uc11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9xW03/qJuU/7y7 - u/9GRkb/RkZG/8HBwP/r5+X/taqi/3lkVv99aFv/dmFT/66jnP/x8fD/8vLx/8zEv/+EcGT/gW1g/97Z - 1f////////////39/f/l4+H/opSM/29bT/9MSUf/RkZG/01JR/9yXE//c11P/3NdT/9zXU//cFtN/3Bb - Tv9wW03/c11P/3NdT/9zXU//c11P/3FdT+5zXU/+c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9yXE7/fmpd/2NiYf9GRkb/cnJy//39/f//////7Onn/4NwZP+gkYj/oJGI/3lkVv/DvLf/9PT0//T0 - 9P/X0c3/e2ZZ/66hmf/////////////////9/f3/7ezr/6eblP9jVUv/RkZG/0ZGRv9kVUz/c11P/3Nd - T/9zXU//c11P/3BbTf9wW07/cFtN/3NdT/9zXU//c11P/3NdT/5zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//aVdL/0ZGRv9GRkb/xsbG//T09P/9/f3/9PLx/4x6b/+aioD/5uLg/458 - cP+Bb2L/1dDO//T09P/u7ez/koF3/5OCeP/39vX//////////////////f39/+vp6P+cjoX/S0dF/0ZG - Rv9SS0f/c11P/3NdT/9zXU//c11P/3NdT/9wW03/cFtO/3BbTf9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//XVFK/0ZGRv9TUlL/8/Pz//T09P/09PT/+/v7/56P - hf+HdGj/8O7t/9nTz/9/al3/inlt/762sP/RzMj/kYF2/4t6bv/08vH///////////////////////39 - /f/g3Nr/aF9Z/0ZGRv9HRkb/cVxO/3NdT/9zXU//c11P/3NdT/9zXU//cFtN/3BbTv9wW03/c11P/3Nd - T/9zXU/+c11P/3NdT/9zXU//c11P/3NdT/9yXE//clxO/3NdT/9zXU//VE1I/0ZGRv9jXVn/9vX0//T0 - 9P/09PT/9PT0/7mup/94Y1b/29XS///////Kwbz/h3Ro/3ZhU/91YVT/cl1R/6KVjf/7+vr//f38//Ty - 8f/5+Pf////////////9/f3/qqSg/0ZGRv9GRkb/aFdM/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Bb - Tf9wW07/cFtN/3NdT/5xXU/uc11P/3NdT/9zXU//c11P/3NdT/9yXE//cVxO/3JcTv9zXU//TEhF/0ZG - Rv9eU03/y8O+//39/f/09PT/9PT0/9DLyP95Y1b/t6uk///////+/v7/7ero/9PMyP/Bt7H/wLiz/+Xk - 4v/e2tj/p5mR/458cf+YiH7/zcXA//z7+///////7ezs/0ZGRv9GRkb/YVNL/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/9wW03/cFtO/21aTO9xXU/Vc11P/3NdT/9zXU//c11P/3NdT/9yXE//clxP/3Fc - Tv9yXE7/SkdF/0ZGRv9eUkr/kYB1//Hv7v/9/f3/9PT0/+ro5/+MfHH/i3lu//Hv7f////////////// - /////////f39/+jm5f+Rgnf/bVhL/3FbTf9xWkz/e2ZZ/9LLx////////////0RERP9GRkb/XVFJ/3Bb - Tf9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//cFtN/25bTtdzXU+xc11P/3NdT/9zXU//c11P/3Nd - T/9zXU//cVxO/3BbTv9xW07/SkZE/0ZGRv9fUkv/dF5Q/7uxqv/+/v7//f39//T09P+5sKr/cV5Q/8S7 - tf///////////////////////////9PNyP9zX1H/cFtO/3BbTf9zXU//cFpM/6aYj//+/f3//f39/0ZG - Rv9GRkb/XlFJ/3BbTv9wW03/c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/21aTbVyXU99cVtN/XNd - T/9zXU//c11P/3NdT/9zXU//clxO/3FcTv9wW07/TklG/0ZGRv9aUEn/clxO/39rX//Sy8f//v7+//39 - /f/m4+L/iHht/4Z0av/q5+X//////////////////////87Hwv90XlD/cFtN/3BbTv9wW03/cFpM/6GS - if/8/Pz/6enp/0ZGRv9GRkb/ZVZM/3BbTf9wW07/cFtN/3NdT/9zXU//c11P/3NdT/9zXU//cVtN/XFd - Tn5yW09DcV1P7nNdT/9zXU//c11P/3NdT/9zXU//c11P/3JcTv9xW07/Vk1I/0ZGRv9QS0f/c11P/3Jc - Tv+AbF//saSc/9HKxf/c19T/qJuU/3BbTv+ilY3/9/b1/////////////////+rn5f+IdWn/cVpM/29a - TP9vWk3/cVxO/8K4sv//////xcXF/0ZGRv9GRkb/eGdc/3JcTv9wW03/cFtO/3BbTf9zXU//c11P/3Nd - T/9zXU//cV1P7nJbT0NtYVQVc11NxXNdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9yXE7/YFNL/0ZG - Rv9EQ0P/b1pN/3NdT/9yXE7/clxN/3RfUf95ZFf/eWRW/3BbTf9zXlH/raOb//j39/////////////// - ///RycX/jXtv/3tnWf9+a1//rKGZ/+ro5//p5uP/h4aF/0ZGRv9XV1f/l4d8/3FbTf9zXU//cFtN/3Bb - Tv9wW03/c11P/3NdT/9zXU//c11NxW1hVBUAAAAAc11PgHNdT/9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//cFtO/0RDQ/9GRkb/XVFK/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9vWkz/c19S/6qf - l//z8vH////////////+/v7/8O7s/+Db2P/n4+H/8/Ly/8fBvP96aF3/RkVE/0ZGRv+UlJT/sKSc/3Fb - TP9zXU//c11P/3BbTf9wW07/cFtN/3NdT/9zXU//c11PgAAAAAAAAAAAc19QM3FbT+dzXU//c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//c11P/1VNSP9GRkb/SEZF/21aTf9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//cFpM/3FcT/+YioH/49/c//7+/v///////////////////////f39/62imv9XTEb/RkZG/0ZG - Rv/e3t7/w7q0/3NdT/9zXU//c11P/3NdT/9wW03/cFtO/3BbTf9xW0/nc19QMwAAAAAAAAAAZmZmBXNd - Tp9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/2xZTf9EQ0P/RkZG/1RNR/9wW03/c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//c11P/3BbTf9vWUz/gW5i/760rv/w7u3//////////////////////766 - uP9GRkb/RkZG/3l4d//9/f3/zsbB/3ZgUv9zXU//c11P/3NdT/9zXU//cFtN/3BbTv9uWkykbW1tBwAA - AAAAAAAAAAAAAHJdUDxzXU/oc11P/3NdT/9yXE//clxO/3NdT/9zXU//c11P/3NdT/9cUUr/RkZG/0ZG - Rv9cUUr/cFtN/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9wW03/b1pN/3FcTv+NfHD/wbex/+vn - 5f/9/Pz/6Ojo/1dXV/9GRkb/UFBQ/+Hh4f/09PT/zsfC/3ZgU/9zXU//c11P/3NdT/9zXU//c11P/25a - TOloVktHOjo6DX9/fwIAAAAAAAAAAFVVVQNyXE6Mc11P/3NdT/9yXE//cVxO/3JcTv9zXU//c11P/3Nd - T/9yXE//UUtH/0ZGRv9GRkb/WlBJ/3BbTv9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//cFtN/3Bb - Tv9vWUz/dF5Q/4VyZv+TiID/UlFR/0ZGRv9FRUX/xMPC//Hx8f/x8PD/u7Gr/3ReUP9zXU//c11P/3Nd - T/9zXU//c11P/3FcTY0/Pz8QREREDzo6Og0AAAAAAAAAAAAAAABvX08gc1tPy3NdT/9yXE//clxP/3Fc - Tv9yXE7/c11P/3NdT/9zXU//cFtO/05JRv9GRkb/RkZG/09KR/9oV0z/c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3BbTf9wW07/blpN/1tQSf9EQ0P/RkZG/0NDQ/9wZF3/l4Z8/5+Qhv+Vhnz/fWtf/3Bb - TP9zXU//c11P/3NdT/9zXU//c1tPy29fTyB/f38COjo6DURERA8AAAAAAAAAAAAAAAAAAAAAcV1PSnFd - TelzXU//cVxO/3BbTv9xW07/c11P/3NdT/9zXU//c11P/3FcTv9TTEf/RkZG/0ZGRv9GRkb/UUtH/2JU - S/9tWk3/c11P/3NdT/9zXU//cVtO/2dWTP9YT0n/SEZF/0ZGRv9GRkb/R0ZF/2RVS/9yW03/cVtN/3Fb - Tf9xW03/b1pM/3BbTv9wW03/c11P/3NdT/9xXU3pcV1PSgAAAAAAAAAAf39/Ajo6Og0AAAAAAAAAAAAA - AAAAAAAAf39/AnJbTm9yW0/1clxO/3FcTv9wW07/cFtN/3NdT/9zXU//c11P/3NdT/9zXU//YlRL/0hG - Rf9GRkb/RkZG/0ZGRv9GRkb/RERD/0hGRf9IRkX/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9TTEj/bVlN/3Nd - T/9zXU//c11P/3NdT/9zXU//c11P/3BbTf9wW07/cFtN/3JbT/VyW05vf39/AgAAAAAAAAAAAAAAAH9/ - fwIAAAAAAAAAAAAAAAAAAAAAAAAAAH9fPwhzXU+AcV1N+XJcTv9xW07/cFtO/3FbTv9yXE7/c11P/3Nd - T/9zXU//c11P/3FcTv9gU0r/TUlG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9IR0b/Vk5I/2hX - TP9wW07/cVtO/3JcTv9zXU//c11P/3NdT/9zXU//c11P/3JcTv9xW07/bltM+W9aToVxVDgJAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzXEULc11PgHJbT/VyXE7/cVxO/3Bb - Tv9xXE7/clxO/3NdT/9zXU//c11P/3NdT/9zXU//clxO/25aTv9lVkz/X1JK/11RSv9fUkv/YlRL/2pY - TP9zXU//c11P/3JcTv9xXE7/cFtO/3FcTv9yXE7/c11P/3NdT/9zXU//c11P/3NdT/9xWk71blpNhFlM - PxQ/Pz8IAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf18/CHJb - Tm9xXU3pclxO/3FcTv9yXE//cVxO/3JcTv9zXU//c11P/3NdT/9zXU//c11P/3JcTv9xXE7/clxP/3Fc - Tv9yXE7/c11P/3NdT/9zXU//c11P/3NdT/9yXE7/cVxO/3JcT/9xXE7/clxO/3NdT/9zXU//c11P/3Fd - TelyW05vcVQ4CTMzMwVVVVUGMzMzBQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAH9/fwJxXU9Kc1xNzHNdT/5yXE//clxP/3JcT/9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//clxP/3JcT/9yXE//c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3JcT/9yXE//clxP/3Nd - T/9zXU/+c1xNzHFdT0p/f38CAAAAAAAAAABVVVUDVVVVA1VVVQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb19PIHJcToxxXU3pc11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3FdTelyXE6Mb19PIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZmZgVyXVA8c11On3Nd - T+hzXU/+c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3NdT/5zXU/oc11On3JdUDxmZmYFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAf1VVBnVbTDJzXU+AcltOxnNbTe9xW039c11P/3NdT/9zXU//c11P/3NdT/9zXU//c11P/3Nd - T/9zXU//c11P/3FbTf1zW03vcltOxnNdT4B1W0wyf1VVBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcllMFHJbT0NyXU99c11PsXFdT9VxXU/uc11P/nNd - T/9zXU//c11P/nFdT+5xXU/Vc11PsXJdT31yW09DcllMFAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//+AD//8AAP/+AAB/8QAA//gAAB/g - AAD/4AAAB8EAAP/AAAADgQAA/4AAAAEDAAD+AAAAAAcAAPwAAAAADwAA/AAAAAAfAAD4AAAAAB8AAPAA - AAAADwAA4AAAAAAHAADgAAAAAAcAAMAAAAAAAwAAwAAAAAADAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB - AACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB - AADAAAAAAAMAAMAAAAAAAwAA4AAAAAAHAADgAAAAAAcAAPAAAAAADwAA+AAAAAAfAAD8AAAAAD8AAPwA - AAAAPwAA/gAAAAB/AAD/gAAAAf8AAP/AAAAD/wAA/+AAAAf/AAD/+AAAH/8AAP/+AAB//wAA///gB/// - AAA= - - - \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/Forms/MainFormThreadButtonState.cs b/tmp/NTRDebuggerTool/Forms/MainFormThreadButtonState.cs deleted file mode 100644 index 5e49ebd..0000000 --- a/tmp/NTRDebuggerTool/Forms/MainFormThreadButtonState.cs +++ /dev/null @@ -1,91 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using NTRDebuggerTool.Objects; -using System; -using System.Threading; -namespace NTRDebuggerTool.Forms -{ - class MainFormThreadButtonState - { - private const uint BUTTON_STATES_START = 0x0010C0B5; - private const uint BUTTON_STATES_SIZE = 0x00000027; - - private const int Offset_Button = 0x23, Offset_Shoulder = 0x24, Offset_Stick = 0x26, Offset_Horiz = 0x00, Offset_Vert = 0x02; - - public ButtonState ButtonState; - public ShoulderState ShoulderState; - public StickState StickState; - public byte StickHoriz; - public byte StickVert; - private MainForm Form; - - public MainFormThreadButtonState(MainForm Form) - { - // TODO: Complete member initialization - this.Form = Form; - } - - internal void ThreadButtonState() - { - int LastSearchTime = Config.ButtonStateUpdateInterval; - while (true) - { - if (Form.NTRConnection.HardwarePID != null) - { - SearchCriteria Criteria = new SearchCriteria(); - Criteria.ProcessID = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Form.NTRConnection.HardwarePID), 0); - Criteria.DataType = DataTypeExact.Bytes1; - Criteria.StartAddress = BUTTON_STATES_START; - Criteria.Length = BUTTON_STATES_SIZE; - Criteria.SearchType = SearchTypeBase.Unknown; - Criteria.SearchValue = new byte[] { 0 }; - Criteria.Size = 1; - Criteria.HideSearch = true; - Form.NTRConnection.SearchCriteria.Add(Criteria); - - Form.NTRConnection.SendReadMemoryPacket(Criteria); - - ButtonState = (ButtonState)Criteria.AddressesFound[BUTTON_STATES_START + Offset_Button][0]; - ShoulderState = (ShoulderState)Criteria.AddressesFound[BUTTON_STATES_START + Offset_Shoulder][0]; - StickState = (StickState)Criteria.AddressesFound[BUTTON_STATES_START + Offset_Stick][0]; - StickHoriz = Criteria.AddressesFound[BUTTON_STATES_START + Offset_Horiz][0]; - StickVert = Criteria.AddressesFound[BUTTON_STATES_START + Offset_Vert][0]; - - LastSearchTime = Math.Max(LastSearchTime, (int)Criteria.Duration); - - Form.NTRConnection.SetCurrentOperationText2 = ButtonState.ToString() + "|" + ShoulderState.ToString() + "|" + StickState.ToString() + "|" + StickHoriz + "|" + StickVert + "|" + LastSearchTime; - } - - Thread.Sleep(LastSearchTime * 2); - } - } - } - - [Flags] - public enum ButtonState - { - A = 0x01, - B = 0x02, - Select = 0x04, - Start = 0x08, - DPAD_Right = 0x10, - DPAD_Left = 0x20, - DPAD_Up = 0x40, - DPAD_Down = 0x80 - } - - [Flags] - public enum ShoulderState - { - R = 0x01, - L = 0x02 - } - - [Flags] - public enum StickState - { - LStick_Right = 0x10, - LStick_Left = 0x20, - LStick_Up = 0x40, - LStick_Down = 0x80 - } -} diff --git a/tmp/NTRDebuggerTool/Forms/MainFormThreadEventDispatcher.cs b/tmp/NTRDebuggerTool/Forms/MainFormThreadEventDispatcher.cs deleted file mode 100644 index 2093454..0000000 --- a/tmp/NTRDebuggerTool/Forms/MainFormThreadEventDispatcher.cs +++ /dev/null @@ -1,387 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using NTRDebuggerTool.Objects; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using System.Windows.Forms; - -namespace NTRDebuggerTool.Forms -{ - class MainFormThreadEventDispatcher - { - internal bool DispatchConnect = false; - internal bool DispatchOpenProcess = false; - internal bool DispatchSearch = false; - internal bool DispatchConfig = false; - internal string DispatchPointerSearch = null; - public ConcurrentQueue RefreshValueAddresses = new ConcurrentQueue(), - RefreshValueReturn = new ConcurrentQueue(), - WriteAddress = new ConcurrentQueue(); - - internal string CurrentSelectedProcess = ""; - internal string CurrentMemoryRange = ""; - internal DataTypeExact CurrentSelectedDataType; - internal SearchTypeBase CurrentSelectedSearchType; - - internal string FoundPointerAddress = null; - - private MainForm Form; - private Regex HexRegex = new Regex("^[0-9A-F]+$", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private Regex ParserRegex = new Regex("\\(\\*(?
.+)\\)(?(?:\\[[0-9A-F]+\\])?)", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private Dictionary Pointers = new Dictionary(); - - internal MainFormThreadEventDispatcher(MainForm Form) - { - // TODO: Complete member initialization - this.Form = Form; - } - - internal void ThreadEventDispatcher() - { - while (true) - { - if (DispatchConnect) - { - DispatchConnect = false; - DoConnect(); - } - if (DispatchOpenProcess) - { - DispatchOpenProcess = false; - DoOpenProcess(); - } - if (DispatchSearch) - { - DispatchSearch = false; - DoSearch(); - } - if (DispatchConfig) - { - DispatchConfig = false; - DoConfig(); - } - if (DispatchPointerSearch != null) - { - string TempAddress = DispatchPointerSearch; - DispatchPointerSearch = null; - DoPointerSearch(TempAddress); - } - while (RefreshValueAddresses.Count > 0) - { - MemoryDispatch Row = new MemoryDispatch(); - RefreshValueAddresses.TryDequeue(out Row); - uint Address; - - if (HexRegex.IsMatch(Row.TextAddress)) - { - Address = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Row.TextAddress).Reverse().ToArray(), 0); ; - } - else - { - Match TopMatch = ParserRegex.Match(Row.TextAddress); - - if (!TopMatch.Success) - { - return; - } - - Address = ResolvePointer(TopMatch); - } - - if (Form.IsValidMemoryAddress(Address)) - { - Row.ResolvedAddress = Utilities.GetStringFromByteArray(BitConverter.GetBytes(Address).Reverse().ToArray()); - Row.Value = GetMemoryAtAddress(CurrentSelectedProcess, Address, Row.Type); - RefreshValueReturn.Enqueue(Row); - } - } - while (WriteAddress.Count > 0) - { - MemoryDispatch Row = new MemoryDispatch(); - WriteAddress.TryDequeue(out Row); - uint Address; - - if (HexRegex.IsMatch(Row.TextAddress)) - { - Address = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Row.TextAddress).Reverse().ToArray(), 0); ; - } - else - { - Match TopMatch = ParserRegex.Match(Row.TextAddress); - - if (!TopMatch.Success) - { - return; - } - - Address = ResolvePointer(TopMatch); - } - - if (Form.IsValidMemoryAddress(Address)) - { - Row.ResolvedAddress = Utilities.GetStringFromByteArray(BitConverter.GetBytes(Address).Reverse().ToArray()); - uint ProcessID = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(CurrentSelectedProcess.Split('|')[0]), 0); - Form.NTRConnection.SendWriteMemoryPacket(ProcessID, Address, Row.Value); - } - } - - Thread.Sleep(100); - } - } - - private void DoPointerSearch(string TempAddress) - { - Form.FormEnabled = false; - PointerScanDialog Dialog = new PointerScanDialog(Form, TempAddress, CurrentSelectedProcess); - Dialog.ShowDialog(); - FoundPointerAddress = Dialog.PointerFound; - Dialog.Dispose(); - Form.FormEnabled = true; - } - - private void DoConfig() - { - Form.FormEnabled = false; - ConfigDialog Dialog = new ConfigDialog(Form); - Dialog.ShowDialog(); - Dialog.Dispose(); - Form.FormEnabled = true; - } - - private void DoConnect() - { - if (Form.NTRConnection.IsConnected || Form.ButtonConnectDisconnect.Text == "Disconnect") - { - Form.NTRConnection.SetCurrentOperationText = "Disconnecting"; - Form.NTRConnection.Disconnect(); - Form.SetConnectedControls(false); - Form.SetProcessSelectedControls(false); - Form.SetConnectText = "Connect"; - Form.ControlEnabledButtonConnectDisconnect = true; - Form.NTRConnection.SetCurrentOperationText = ""; - } - else - { - Form.SetConnectionControls(false); - Form.NTRConnection.SetCurrentOperationText = "Connecting"; - Form.NTRConnection.IP = Form.IP.Text; - Form.NTRConnection.Port = short.Parse(Form.Port.Text); - - bool Connected = false; - - for (int i = 0; i < Config.ConnectTries && !Connected; ++i) - { - Connected = Form.NTRConnection.Connect(); - } - - if (Connected) - { - Form.SetConnectText = "Disconnect"; - Form.NTRConnection.SetCurrentOperationText = "Fetching Processes"; - Form.NTRConnection.SendListProcessesPacket(); - } - else - { - Form.SetConnectionControls(true); - Form.NTRConnection.SetCurrentOperationText = ""; - } - } - } - - private void DoOpenProcess() - { - Form.SetConnectedControls(false); - Form.NTRConnection.SetCurrentOperationText = "Fetching Memory Ranges"; - //Dummy search criteria to prevent operation collision - while (Form.NTRConnection.SearchCriteria.Count > 0) - { - Thread.Sleep(10); - } - Form.NTRConnection.SearchCriteria.Add(new SearchCriteria()); - Form.NTRConnection.SendReadMemoryAddressesPacket(CurrentSelectedProcess.Split('|')[0]); - while (!Form.NTRConnection.IsMemoryListUpdated && !Form.ControlEnabledButtonOpenProcess) - { - Thread.Sleep(10); - } - Form.NTRConnection.SearchCriteria.RemoveAt(0); - } - - private void DoSearch() - { - if (CurrentSelectedSearchType != SearchTypeBase.Same && CurrentSelectedSearchType != SearchTypeBase.Different && CurrentSelectedSearchType != SearchTypeBase.Unknown) - { - if (string.IsNullOrWhiteSpace(Form.SearchValue.Text)) - { - Form.NTRConnection.SetCurrentOperationText = "Invalid search criteria!"; - Form.SearchComplete = true; - if (Form.LastSearchCriteria == null) - { - Form.ControlEnabledSearchButton = Form.ControlEnabledDataType = Form.ControlEnabledMemoryRange = true; - } - return; - } - if (CurrentSelectedSearchType == SearchTypeBase.Range && string.IsNullOrWhiteSpace(Form.SearchValue2.Text)) - { - Form.NTRConnection.SetCurrentOperationText = "Invalid range criteria!"; - Form.SearchComplete = true; - if (Form.LastSearchCriteria == null) - { - Form.ControlEnabledSearchButton = Form.ControlEnabledDataType = Form.ControlEnabledMemoryRange = true; - } - return; - } - } - if (Form.LastSearchCriteria == null) - { - Form.LastSearchCriteria = new SearchCriteria(); - Form.LastSearchCriteria.ProcessID = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(CurrentSelectedProcess.Split('|')[0]), 0); - Form.LastSearchCriteria.DataType = this.CurrentSelectedDataType; - - if (CurrentMemoryRange.Equals("All")) - { - Form.LastSearchCriteria.StartAddress = Form.LastSearchCriteria.Length = uint.MaxValue; - } - else - { - Form.LastSearchCriteria.StartAddress = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Form.MemoryStart.Text).Reverse().ToArray(), 0); - Form.LastSearchCriteria.Length = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Form.MemorySize.Text).Reverse().ToArray(), 0); - } - } - Form.LastSearchCriteria.SearchType = this.CurrentSelectedSearchType; - - Form.NTRConnection.SetCurrentOperationText = "Searching Memory"; - - string Value1 = Form.SearchValue.Text; - - if (string.IsNullOrWhiteSpace(Value1)) - { - Value1 = "0"; - } - - Form.LastSearchCriteria.SearchValue = GetValueForDataType(CurrentSelectedDataType, Value1); - Form.LastSearchCriteria.Size = (uint)Form.LastSearchCriteria.SearchValue.Length; - if (CurrentSelectedSearchType == SearchTypeBase.Range) - { - Form.LastSearchCriteria.SearchValue2 = GetValueForDataType(CurrentSelectedDataType, Form.SearchValue2.Text); - } - - if (Form.LastSearchCriteria.FirstSearch && CurrentMemoryRange.Equals("All") && Form.LastSearchCriteria.SearchType != SearchTypeBase.Range && Form.LastSearchCriteria.SearchValue.All(x => x.Equals(0))) - { - Form.FormEnabled = false; - DialogResult DialogResult = MessageBox.Show("You're about to search for value 0 (or functional equivalent) across all memory ranges. This operation will take a long time and may cause issues. Are you sure you want to search for this value?", "Warning", MessageBoxButtons.YesNo); - Form.FormEnabled = true; - if (DialogResult != DialogResult.Yes) - { - Form.LastSearchCriteria = null; - Form.SearchComplete = true; - Form.ControlEnabledSearchButton = Form.ControlEnabledDataType = Form.ControlEnabledMemoryRange = true; - return; - } - } - - Form.NTRConnection.SearchCriteria.Add(Form.LastSearchCriteria); - - Form.NTRConnection.SendReadMemoryPacket(Form.LastSearchCriteria); - - Form.SearchComplete = true; - } - - private byte[] GetValueForDataType(DataTypeExact CurrentSelectedDataType, string Value) - { - switch (CurrentSelectedDataType) - { - case DataTypeExact.Bytes1: //1 Byte - return new byte[] { (byte)uint.Parse(Value) }; - case DataTypeExact.Bytes2: //2 Bytes - return BitConverter.GetBytes(ushort.Parse(Value)); - case DataTypeExact.Bytes4: //4 Bytes - return BitConverter.GetBytes(uint.Parse(Value)); - case DataTypeExact.Bytes8: //8 Bytes - return BitConverter.GetBytes(ulong.Parse(Value)); - case DataTypeExact.Float: //Float - return BitConverter.GetBytes(float.Parse(Value)); - case DataTypeExact.Double: //Double - return BitConverter.GetBytes(double.Parse(Value)); - case DataTypeExact.Raw: //Raw Bytes - return Utilities.GetByteArrayFromByteString(Value); - default: //Text - return System.Text.Encoding.Default.GetBytes(Value); - } - } - - private uint ResolvePointer(Match Match) - { - string AddressString = Match.Groups["Address"].Value; - string OffsetString = Match.Groups["Offset"].Value; - - - uint Address; - - Match RecurseMatch = ParserRegex.Match(AddressString); - - if (RecurseMatch.Success) - { - Address = ResolvePointer(RecurseMatch); - } - else - { - uint Pointer = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(AddressString).Reverse().ToArray(), 0); - if (!Pointers.ContainsKey(Pointer)) - { - byte[] Data = GetMemoryAtAddress(CurrentSelectedProcess, AddressString, DataTypeExact.Bytes4); - - Address = BitConverter.ToUInt32(Data, 0); - Pointers[Pointer] = Address; - } - else if (!Form.IsValidMemoryAddress(Pointer)) - { - return 0; - } - else - { - Address = Pointers[Pointer]; - } - } - - if (Address != 0 && !string.IsNullOrWhiteSpace(OffsetString)) - { - OffsetString = OffsetString.Replace("[", "").Replace("]", ""); - Address += BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(OffsetString.PadLeft(8, '0')).Reverse().ToArray(), 0); - } - - return Address; - } - - internal byte[] GetMemoryAtAddress(string ProcessID, string Address, DataTypeExact DataType) - { - return GetMemoryAtAddress(BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(ProcessID), 0), BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Address).Reverse().ToArray(), 0), DataType); - } - - internal byte[] GetMemoryAtAddress(uint ProcessID, string Address, DataTypeExact DataType) - { - return GetMemoryAtAddress(ProcessID, BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(Address).Reverse().ToArray(), 0), DataType); - } - - internal byte[] GetMemoryAtAddress(string ProcessID, uint Address, DataTypeExact DataType) - { - return GetMemoryAtAddress(BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(ProcessID), 0), Address, DataType); - } - - internal byte[] GetMemoryAtAddress(uint ProcessID, uint Address, DataTypeExact DataType) - { - SearchCriteria Criteria = new SearchCriteria(); - Criteria.ProcessID = ProcessID; - Criteria.DataType = DataType; - Criteria.StartAddress = Address; - Criteria.Length = Criteria.Size = Form.GetSearchMemorySize(DataType); - Criteria.SearchType = SearchTypeBase.Unknown; - Criteria.SearchValue = new byte[] { 0 }; - Form.NTRConnection.SearchCriteria.Add(Criteria); - Form.NTRConnection.SendReadMemoryPacket(Criteria); - return Criteria.AddressesFound.Values.First(); - } - } -} diff --git a/tmp/NTRDebuggerTool/Forms/PointerScanDialog.Designer.cs b/tmp/NTRDebuggerTool/Forms/PointerScanDialog.Designer.cs deleted file mode 100644 index 6733242..0000000 --- a/tmp/NTRDebuggerTool/Forms/PointerScanDialog.Designer.cs +++ /dev/null @@ -1,183 +0,0 @@ -namespace NTRDebuggerTool.Forms -{ - partial class PointerScanDialog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.TextAddress = new System.Windows.Forms.TextBox(); - this.LabelAddress = new System.Windows.Forms.Label(); - this.TextMaxOffset = new System.Windows.Forms.TextBox(); - this.LabelMaxOffset = new System.Windows.Forms.Label(); - this.ResultsDataGrid = new System.Windows.Forms.DataGridView(); - this.AddressColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.OffsetColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.CancelButton = new System.Windows.Forms.Button(); - this.SearchButton = new System.Windows.Forms.Button(); - this.CheckFullSearch = new System.Windows.Forms.CheckBox(); - ((System.ComponentModel.ISupportInitialize)(this.ResultsDataGrid)).BeginInit(); - this.SuspendLayout(); - // - // TextAddress - // - this.TextAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.TextAddress.Location = new System.Drawing.Point(63, 9); - this.TextAddress.Name = "TextAddress"; - this.TextAddress.ReadOnly = true; - this.TextAddress.Size = new System.Drawing.Size(65, 20); - this.TextAddress.TabIndex = 28; - // - // LabelAddress - // - this.LabelAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelAddress.Location = new System.Drawing.Point(12, 9); - this.LabelAddress.Name = "LabelAddress"; - this.LabelAddress.Size = new System.Drawing.Size(45, 23); - this.LabelAddress.TabIndex = 29; - this.LabelAddress.Text = "Address"; - this.LabelAddress.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // TextMaxOffset - // - this.TextMaxOffset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.TextMaxOffset.Location = new System.Drawing.Point(142, 9); - this.TextMaxOffset.Name = "TextMaxOffset"; - this.TextMaxOffset.Size = new System.Drawing.Size(65, 20); - this.TextMaxOffset.TabIndex = 30; - // - // LabelMaxOffset - // - this.LabelMaxOffset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.LabelMaxOffset.Location = new System.Drawing.Point(213, 9); - this.LabelMaxOffset.Name = "LabelMaxOffset"; - this.LabelMaxOffset.Size = new System.Drawing.Size(59, 23); - this.LabelMaxOffset.TabIndex = 31; - this.LabelMaxOffset.Text = "Max Offset"; - this.LabelMaxOffset.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // ResultsDataGrid - // - this.ResultsDataGrid.AllowUserToAddRows = false; - this.ResultsDataGrid.AllowUserToDeleteRows = false; - this.ResultsDataGrid.AllowUserToResizeRows = false; - this.ResultsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.ResultsDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.AddressColumn, - this.OffsetColumn}); - this.ResultsDataGrid.Location = new System.Drawing.Point(12, 35); - this.ResultsDataGrid.Name = "ResultsDataGrid"; - this.ResultsDataGrid.ReadOnly = true; - this.ResultsDataGrid.RowHeadersVisible = false; - this.ResultsDataGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; - this.ResultsDataGrid.Size = new System.Drawing.Size(260, 146); - this.ResultsDataGrid.TabIndex = 32; - this.ResultsDataGrid.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.ResultsDataGrid_CellDoubleClick); - // - // AddressColumn - // - this.AddressColumn.HeaderText = "Address"; - this.AddressColumn.Name = "AddressColumn"; - this.AddressColumn.ReadOnly = true; - // - // OffsetColumn - // - this.OffsetColumn.HeaderText = "Offset"; - this.OffsetColumn.Name = "OffsetColumn"; - this.OffsetColumn.ReadOnly = true; - // - // CancelButton - // - this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.CancelButton.Location = new System.Drawing.Point(15, 187); - this.CancelButton.Name = "CancelButton"; - this.CancelButton.Size = new System.Drawing.Size(75, 23); - this.CancelButton.TabIndex = 33; - this.CancelButton.Text = "Cancel"; - this.CancelButton.UseVisualStyleBackColor = true; - this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); - // - // SearchButton - // - this.SearchButton.Location = new System.Drawing.Point(197, 187); - this.SearchButton.Name = "SearchButton"; - this.SearchButton.Size = new System.Drawing.Size(75, 23); - this.SearchButton.TabIndex = 34; - this.SearchButton.Text = "Search"; - this.SearchButton.UseVisualStyleBackColor = true; - this.SearchButton.Click += new System.EventHandler(this.SearchButton_Click); - // - // CheckFullSearch - // - this.CheckFullSearch.AutoSize = true; - this.CheckFullSearch.Location = new System.Drawing.Point(97, 192); - this.CheckFullSearch.Name = "CheckFullSearch"; - this.CheckFullSearch.Size = new System.Drawing.Size(79, 17); - this.CheckFullSearch.TabIndex = 35; - this.CheckFullSearch.Text = "Full Search"; - this.CheckFullSearch.UseVisualStyleBackColor = true; - // - // PointerScanDialog - // - this.AcceptButton = this.SearchButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(284, 222); - this.ControlBox = false; - this.Controls.Add(this.CheckFullSearch); - this.Controls.Add(this.SearchButton); - this.Controls.Add(this.CancelButton); - this.Controls.Add(this.ResultsDataGrid); - this.Controls.Add(this.LabelMaxOffset); - this.Controls.Add(this.TextMaxOffset); - this.Controls.Add(this.LabelAddress); - this.Controls.Add(this.TextAddress); - this.MaximumSize = new System.Drawing.Size(300, 260); - this.MinimumSize = new System.Drawing.Size(300, 260); - this.Name = "PointerScanDialog"; - this.ShowIcon = false; - this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Pointer Scan"; - ((System.ComponentModel.ISupportInitialize)(this.ResultsDataGrid)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - internal System.Windows.Forms.TextBox TextAddress; - private System.Windows.Forms.Label LabelAddress; - internal System.Windows.Forms.TextBox TextMaxOffset; - private System.Windows.Forms.Label LabelMaxOffset; - private System.Windows.Forms.DataGridView ResultsDataGrid; - private System.Windows.Forms.DataGridViewTextBoxColumn AddressColumn; - private System.Windows.Forms.DataGridViewTextBoxColumn OffsetColumn; - private System.Windows.Forms.Button CancelButton; - private System.Windows.Forms.Button SearchButton; - private System.Windows.Forms.CheckBox CheckFullSearch; - } -} \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/Forms/PointerScanDialog.cs b/tmp/NTRDebuggerTool/Forms/PointerScanDialog.cs deleted file mode 100644 index 68980dc..0000000 --- a/tmp/NTRDebuggerTool/Forms/PointerScanDialog.cs +++ /dev/null @@ -1,68 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using NTRDebuggerTool.Objects; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; - -namespace NTRDebuggerTool.Forms -{ - public partial class PointerScanDialog : Form - { - MainForm MainForm; - - internal string PointerFound = null; - internal string ProcessID; - - public PointerScanDialog(MainForm MainForm, string Address, string ProcessID) - { - InitializeComponent(); - TextAddress.Text = Address; - TextMaxOffset.Text = "1000"; - this.MainForm = MainForm; - this.ProcessID = ProcessID; - } - - private void ResultsDataGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - PointerFound = "(*" + (string)ResultsDataGrid[0, e.RowIndex].Value + ")[" + (string)ResultsDataGrid[1, e.RowIndex].Value + "]"; - this.Close(); - } - - private void CancelButton_Click(object sender, EventArgs e) - { - this.Close(); - } - - private void SearchButton_Click(object sender, EventArgs e) - { - uint Pointer = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(TextAddress.Text).Reverse().ToArray(), 0); - SearchCriteria Criteria = new SearchCriteria(); - Criteria.ProcessID = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(ProcessID), 0); - Criteria.DataType = DataTypeExact.Bytes4; - if (CheckFullSearch.Checked) - { - Criteria.StartAddress = Criteria.Length = uint.MaxValue; - Criteria.Length = 4; - } - else - { - KeyValuePair KVP = MainForm.GetAddressSpaceForAddress(Pointer).Value; - Criteria.StartAddress = KVP.Key; - Criteria.Length = KVP.Value; - } - Criteria.Size = 4; - Criteria.SearchType = SearchTypeBase.Range; - Criteria.SearchValue = BitConverter.GetBytes(Pointer - BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(TextMaxOffset.Text.PadLeft(8, '0')).Reverse().ToArray(), 0)); - Criteria.SearchValue2 = BitConverter.GetBytes(Pointer); - MainForm.NTRConnection.SearchCriteria.Add(Criteria); - MainForm.NTRConnection.SendReadMemoryPacket(Criteria); - foreach (var a in Criteria.AddressesFound.OrderByDescending(x => BitConverter.ToUInt32(x.Value, 0)).ThenBy(x => x.Key)) - { - int RowIndex = ResultsDataGrid.Rows.Add(); - ResultsDataGrid[0, RowIndex].Value = Utilities.GetStringFromByteArray(BitConverter.GetBytes(a.Key).Reverse().ToArray()); - ResultsDataGrid[1, RowIndex].Value = Utilities.GetStringFromByteArray(BitConverter.GetBytes(Pointer - BitConverter.ToUInt32(a.Value, 0)).Reverse().ToArray()).TrimStart('0'); - } - } - } -} diff --git a/tmp/NTRDebuggerTool/Forms/PointerScanDialog.resx b/tmp/NTRDebuggerTool/Forms/PointerScanDialog.resx deleted file mode 100644 index 53e918b..0000000 --- a/tmp/NTRDebuggerTool/Forms/PointerScanDialog.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - True - - \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/NTRDebuggerTool.csproj b/tmp/NTRDebuggerTool/NTRDebuggerTool.csproj deleted file mode 100644 index c0911b7..0000000 --- a/tmp/NTRDebuggerTool/NTRDebuggerTool.csproj +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Debug - AnyCPU - {86AF1318-9584-4CDE-93BC-C2F0DCF958C5} - WinExe - Properties - NTRDebuggerTool - NTRDebuggerTool - v4.0 - 512 - false - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - NTRDebuggerTool.Program - 65001 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - - - - false - - - x86 - pdbonly - true - bin\Release\ - prompt - 4 - true - false - - - - - - - - - - - - - Resources\log4net.dll - False - - - - - - - - Form - - - ConfigDialog.cs - - - - - Form - - - MainForm.cs - - - - - Form - - - PointerScanDialog.cs - - - - - - - - - - - - - - - ConfigDialog.cs - - - MainForm.cs - - - PointerScanDialog.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - Designer - - - - - - - - False - Microsoft .NET Framework 4.5 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - - - - - - - - - - \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/Objects/GateSharkCode.cs b/tmp/NTRDebuggerTool/Objects/GateSharkCode.cs deleted file mode 100644 index 5389854..0000000 --- a/tmp/NTRDebuggerTool/Objects/GateSharkCode.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace NTRDebuggerTool.Objects -{ - class GateSharkCode - { - GateSharkCodeOperation operation; - - internal uint loadedValue; - internal bool returnToTopLevel = false, isInCType = false; - - public GateSharkCode() { } - - public void ParseCode(string code) - { - operation = new GateSharkCodeOperation(); - operation.operationType = OperationType.TopLevelOperation; - operation.ParseCode(code); - } - - private class GateSharkCodeOperation - { - private List operations = new List(); - internal OperationType operationType; - - private uint leftCode, rightCode; - - public string ParseCode(string code) - { - string[] codeLines = code.Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < codeLines.Length; ++i) - { - string[] lineParts = codeLines[i].Split(' '); - - uint leftCode = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(lineParts[0]), 0); - uint rightCode = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(lineParts[1]), 0); - - OperationType opType = (OperationType)(leftCode & 0xF0000000); - if (opType == OperationType.DTypeTest) - { - opType = (OperationType)(leftCode & 0xFF000000); - } - - GateSharkCodeOperation operation = new GateSharkCodeOperation(); - operation.operationType = opType; - operation.leftCode = leftCode; - operation.rightCode = rightCode; - - switch (opType) - { - case OperationType.ConditionalGreaterThan4Byte: - case OperationType.ConditionalLessThan4Byte: - case OperationType.ConditionalEqual4Byte: - case OperationType.ConditionalNotEqual4Byte: - case OperationType.ConditionalGreaterThan2Byte: - case OperationType.ConditionalLessThan2Byte: - case OperationType.ConditionalEqual2Byte: - case OperationType.ConditionalNotEqual2Byte: - case OperationType.ButtonStateRequire: - break; - case OperationType.WriteRange: - break; - } - } - return null; - } - } - - #region Pulled from http://gbatemp.net/threads/i-need-help-understanding-these-d-code-lines-please.417985/#post-6151997 - - private enum OperationType : uint - { - Write4Byte = 0x00000000, - Write2Byte = 0x10000000, - Write1Byte = 0x20000000, - ConditionalGreaterThan4Byte = 0x30000000, - ConditionalLessThan4Byte = 0x40000000, - ConditionalEqual4Byte = 0x50000000, - ConditionalNotEqual4Byte = 0x60000000, - ConditionalGreaterThan2Byte = 0x70000000, - ConditionalLessThan2Byte = 0x80000000, - ConditionalEqual2Byte = 0x90000000, - ConditionalNotEqual2Byte = 0xA0000000, - LoadOffset = 0xB0000000, - WriteRange = 0xC0000000, - DTypeTest = 0xD0000000, - EndConditional = 0xD0000000, - EndRepeat = 0xD1000000, - ResetState = 0xD2000000, - LoadPointer = 0xD3000000, - AddToLoadedPointer = 0xD4000000, - SetLoadedPointer = 0xD5000000, - SetAndInc4Byte = 0xD6000000, - SetAndInc2Byte = 0xD7000000, - SetAndInc1Byte = 0xD8000000, - LoadValue4Byte = 0xD9000000, - LoadValue2Byte = 0xDA000000, - LoadValue1Byte = 0xDB000000, - Unknown24Byte = 0xDC000000, - ButtonStateRequire = 0xDD000000, - WriteRegion = 0xE0000000, - UnusedFCode = 0xF0000000, - TopLevelOperation = 0xFFFFFFFF - } - - [Flags] - private enum GateSharkButtonState - { - A = 0x00000001, - B = 0x00000002, - Select = 0x00000004, - Start = 0x00000008, - Right = 0x00000010, - Left = 0x00000020, - Up = 0x00000040, - Down = 0x00000080, - R = 0x00000100, - L = 0x00000200, - X = 0x00000400, - Y = 0x00000800, - } - - #endregion - } -} diff --git a/tmp/NTRDebuggerTool/Objects/MemoryDispatch.cs b/tmp/NTRDebuggerTool/Objects/MemoryDispatch.cs deleted file mode 100644 index 6ee0f6a..0000000 --- a/tmp/NTRDebuggerTool/Objects/MemoryDispatch.cs +++ /dev/null @@ -1,12 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; - -namespace NTRDebuggerTool.Objects -{ - public struct MemoryDispatch - { - public int Row; - public DataTypeExact Type; - public string TextAddress, ResolvedAddress; - public byte[] Value; - } -} diff --git a/tmp/NTRDebuggerTool/Objects/Saving/SaveCode.cs b/tmp/NTRDebuggerTool/Objects/Saving/SaveCode.cs deleted file mode 100644 index bf0c770..0000000 --- a/tmp/NTRDebuggerTool/Objects/Saving/SaveCode.cs +++ /dev/null @@ -1,28 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using System; - -namespace NTRDebuggerTool.Objects.Saving -{ - public class SaveCode - { - public DataTypeExact type; - public String address; - - public SaveCode() - { - type = DataTypeExact.Raw; - address = null; - } - - public SaveCode(DataTypeExact type, String address) - { - this.type = type; - this.address = address; - } - - public override string ToString() - { - return type + ": " + address; - } - } -} diff --git a/tmp/NTRDebuggerTool/Objects/Saving/SaveManager.cs b/tmp/NTRDebuggerTool/Objects/Saving/SaveManager.cs deleted file mode 100644 index cf06db5..0000000 --- a/tmp/NTRDebuggerTool/Objects/Saving/SaveManager.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Windows.Forms; - -namespace NTRDebuggerTool.Objects.Saving -{ - public class SaveManager - { - private static readonly log4net.ILog LOGGER = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - public String titleId; - public List codes; - - public void Init() - { - titleId = null; - codes = new List(); - } - - public override string ToString() - { - return titleId + ",[" + codes.ToString() + "]"; - } - - public static void SaveToXml(string filePath, SaveManager sourceObj) - { - if (sourceObj.titleId == null || sourceObj.codes.Count == 0) - { - return; - } - try - { - using (StreamWriter writer = new StreamWriter(filePath)) - { - System.Xml.Serialization.XmlSerializer xmlSerializer = - new System.Xml.Serialization.XmlSerializer(sourceObj.GetType()); - xmlSerializer.Serialize(writer, sourceObj); - } - } - catch (Exception ex) - { - LOGGER.Error("Exception saving codes [" + sourceObj + "] to XML file", ex); - MessageBox.Show(ex.Message); - } - } - - public static SaveManager LoadFromXml(string filePath) - { - try - { - using (StreamReader reader = new StreamReader(filePath)) - { - System.Xml.Serialization.XmlSerializer xmlSerializer = - new System.Xml.Serialization.XmlSerializer(typeof(SaveManager)); - return (SaveManager)xmlSerializer.Deserialize(reader); - } - } - catch (Exception ex) - { - LOGGER.Warn("Exception loading codes from XML file " + filePath, ex); - } - return new SaveManager(); - } - } -} \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/Objects/SearchCriteria.cs b/tmp/NTRDebuggerTool/Objects/SearchCriteria.cs deleted file mode 100644 index c50786a..0000000 --- a/tmp/NTRDebuggerTool/Objects/SearchCriteria.cs +++ /dev/null @@ -1,25 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using System.Collections.Generic; - -namespace NTRDebuggerTool.Objects -{ - public class SearchCriteria - { - public uint Duration; - public uint ProcessID; - public uint StartAddress, Length; - public uint Size; - public SearchTypeBase SearchType; - public DataTypeExact DataType; - public byte[] SearchValue; - public byte[] SearchValue2; - - public bool SearchComplete = false; - public bool AllSearchesComplete = false; - - public bool FirstSearch = true; - public bool HideSearch = false; - - public Dictionary AddressesFound = new Dictionary(); - } -} diff --git a/tmp/NTRDebuggerTool/Program.cs b/tmp/NTRDebuggerTool/Program.cs deleted file mode 100644 index 58ffd18..0000000 --- a/tmp/NTRDebuggerTool/Program.cs +++ /dev/null @@ -1,85 +0,0 @@ -using NTRDebuggerTool.Forms; -using NTRDebuggerTool.Remote; -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Reflection; -using System.Windows.Forms; - -namespace NTRDebuggerTool -{ - static class Program - { - static Program() - { - AppDomain.CurrentDomain.AssemblyResolve += (sender, bargs) => - { - String dllName = new AssemblyName(bargs.Name).Name + ".dll"; - var assem = Assembly.GetExecutingAssembly(); - String resourceName = assem.GetManifestResourceNames().FirstOrDefault(rn => rn.EndsWith(dllName)); - if (resourceName == null) return null; // Not found, maybe another handler will find it - using (var stream = assem.GetManifestResourceStream(resourceName)) - { - Byte[] assemblyData = new Byte[stream.Length]; - stream.Read(assemblyData, 0, assemblyData.Length); - return Assembly.Load(assemblyData); - } - }; - } - - public const bool DEBUG = false; - - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main(string[] args) - { - try - { - if (DEBUG || (args.Length > 0 && args[0].Equals("-c"))) - { - ConsoleHelper.EnableConsole(); - } - try - { - File.Open(Path.GetTempPath() + "3dsreleases.xml", FileMode.Open).Close(); - } - catch (FileNotFoundException ex) - { - try - { - using (WebClient client = new WebClient()) - { - client.DownloadFile("http://3dsdb.com/xml.php", Path.GetTempPath() + "3dsreleases.xml"); - } - } - catch (Exception e) - { - //log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType).Error(null, ex); - //log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType).Error(null, e); - } - } - - //Debug code - if (!DEBUG) - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm(new NTRRemoteConnection())); - } - else - { - Debug.Execute(); - } - } - catch (Exception ex) - { - //log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType).Error(null, ex); - MessageBox.Show("An exception has occurred. Check the log file at " + System.IO.Path.GetTempPath() + System.IO.Path.DirectorySeparatorChar + "NTRDebuggerTool-Log.txt"); - Application.Exit(); - } - } - } -} diff --git a/tmp/NTRDebuggerTool/Properties/AssemblyInfo.cs b/tmp/NTRDebuggerTool/Properties/AssemblyInfo.cs deleted file mode 100644 index 9d488f5..0000000 --- a/tmp/NTRDebuggerTool/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("NTRDebuggerTool")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NTRDebuggerTool")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: ComVisible(false)] -[assembly: Guid("290cd39f-c191-4212-9985-0584c9200acc")] -[assembly: AssemblyVersion("0.8.6.2")] -[assembly: AssemblyFileVersion("0.8.6.2")] diff --git a/tmp/NTRDebuggerTool/Properties/Resources.Designer.cs b/tmp/NTRDebuggerTool/Properties/Resources.Designer.cs deleted file mode 100644 index 5187a67..0000000 --- a/tmp/NTRDebuggerTool/Properties/Resources.Designer.cs +++ /dev/null @@ -1,73 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NTRDebuggerTool.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NTRDebuggerTool.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap cog2 { - get { - object obj = ResourceManager.GetObject("cog2", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} diff --git a/tmp/NTRDebuggerTool/Properties/Resources.resx b/tmp/NTRDebuggerTool/Properties/Resources.resx deleted file mode 100644 index ca80b5c..0000000 --- a/tmp/NTRDebuggerTool/Properties/Resources.resx +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\cog2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/tmp/NTRDebuggerTool/Properties/Settings.Designer.cs b/tmp/NTRDebuggerTool/Properties/Settings.Designer.cs deleted file mode 100644 index e8bc796..0000000 --- a/tmp/NTRDebuggerTool/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NTRDebuggerTool.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/tmp/NTRDebuggerTool/Properties/Settings.settings b/tmp/NTRDebuggerTool/Properties/Settings.settings deleted file mode 100644 index 3964565..0000000 --- a/tmp/NTRDebuggerTool/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/tmp/NTRDebuggerTool/Remote/NTRPacketReceiverThread.cs b/tmp/NTRDebuggerTool/Remote/NTRPacketReceiverThread.cs deleted file mode 100644 index 728b67d..0000000 --- a/tmp/NTRDebuggerTool/Remote/NTRPacketReceiverThread.cs +++ /dev/null @@ -1,479 +0,0 @@ -using NTRDebuggerTool.Forms.FormEnums; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Xml; - -namespace NTRDebuggerTool.Remote -{ - class NTRPacketReceiverThread - { - private static readonly log4net.ILog LOGGER = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - private NTRRemoteConnection NTRConnection; - - private uint DataRead = 0; - - internal NTRPacketReceiverThread(NTRRemoteConnection NTRConnection) - { - this.NTRConnection = NTRConnection; - } - - #region Receiving Packets - - internal void ThreadReceivePackets() - { - byte[] Buffer = new byte[84]; - uint[] Arguments = new uint[16]; - uint Magic, Sequence, Type, Command; - - while (true) - { - try - { - Array.Clear(Buffer, 0, Buffer.Length); - int PacketSize = ReadBasePacket(Buffer, true); - if (PacketSize == 0) - { - break; - } - if (PacketSize < Buffer.Length && ShouldSkipPacket(Buffer)) - { - continue; - } - int t = 0; - Magic = BitConverter.ToUInt32(Buffer, t); - Sequence = BitConverter.ToUInt32(Buffer, t += 4); - Type = BitConverter.ToUInt32(Buffer, t += 4); - Command = BitConverter.ToUInt32(Buffer, t += 4); - for (int i = 0; i < Arguments.Length; i++) - { - Arguments[i] = BitConverter.ToUInt32(Buffer, t += 4); - } - uint ExtraDataLength = BitConverter.ToUInt32(Buffer, t += 4); - - if (Magic != 0x12345678) - { - break; - } - - if (ExtraDataLength > 0) - { - ReadExtraData(Command, Sequence, ExtraDataLength); - } - - if (Type == PacketType.General && Command == PacketCommand.Heartbeat) - { - this.NTRConnection.CanSendHeartbeat = true; - } - } - catch (Exception e) - { - LOGGER.Error(null, e); - break; - } - } - - this.NTRConnection.Disconnect(); - } - - private bool ShouldSkipPacket(byte[] Buffer) - { - if (System.Text.Encoding.Default.GetString(Buffer).Equals("finished")) //Finshed writing memory - { - return true; - } - return false; - } - - int ReadBasePacket(byte[] Buffer) - { - return ReadBasePacket(Buffer, false); - } - - int ReadBasePacket(byte[] Buffer, bool MainLoop) - { - int Read = 0; - int Position = this.NTRConnection.Client.GetStream().Read(Buffer, 0, Buffer.Length); - if (Position == 0) - { - return 0; - } - if (MainLoop) - { - if (ShouldSkipPacket(Buffer)) - { - return Read; - } - } - while (Position < Buffer.Length) - { - if (this.NTRConnection.ProgressReadMax > 0) - { - this.NTRConnection.ProgressRead = (uint)Position; - } - Read = this.NTRConnection.Client.GetStream().Read(Buffer, Position, Buffer.Length - Position); - if (Read == 0) - { - return 0; - } - Position += Read; - DataRead = (uint)Position; - } - DataRead = (uint)Position; - return Position; - } - - private void ReadExtraData(uint Command, uint Sequence, uint DataLength) - { - if (Sequence == this.NTRConnection.LastListProcessesSequence + 1000) - { - ReadProcessesPacket(DataLength); - } - else if (Sequence == this.NTRConnection.LastListMemoryRegionsSequence + 1000) - { - ReadAddressesPacket(DataLength); - } - else if (Sequence == this.NTRConnection.LastReadMemorySequence) //For some reason, not +1000? - { - ReadMemoryPacket(DataLength); - } - else - { - switch (Command) - { - default: - ReadBasePacket(new byte[DataLength]); - break; - } - } - } - - private void ReadProcessesPacket(uint DataLength) - { - this.NTRConnection.Processes.Clear(); - byte[] Buffer = new byte[DataLength]; - ReadBasePacket(Buffer); - string BufferText = System.Text.Encoding.Default.GetString(Buffer); - BufferText = BufferText.Replace("rtRecvSocket failed: 00000000", ""); - //Line format: - //pid: 0x00000029, pname: ro, tid: 0004013000003702, kpobj: fff7b5f8 - //Split on comma, then split KV on `: `, trim both key and value - foreach (string Line in BufferText.Split('\n')) - { - if (!Line.StartsWith("pid")) - { - continue; - } - string[] KVStrings = Line.Split(','); - string ProcessID = KVStrings[0].Split(new String[] { ": " }, StringSplitOptions.None)[1].Trim().Substring(2); - string ProcessName = KVStrings[1].Split(new String[] { ": " }, StringSplitOptions.None)[1].Trim(); - string TitleID = KVStrings[2].Split(new String[] { ": " }, StringSplitOptions.None)[1].Trim(); - XmlNode Node = null; - if (ProcessName.Equals("hid")) - { - NTRConnection.HardwarePID = ProcessID; - } - - if (NTRConnection.ReleasesDocument != null) - { - Node = NTRConnection.ReleasesDocument.DocumentElement.SelectSingleNode("/releases/release[translate(./titleid, 'ABCDEF', 'abcdef') = '" + TitleID.ToLower() + "']/name"); - } - - if (Node != null) - { - this.NTRConnection.Processes.Add(ProcessID + "|" + Node.InnerText); - } - else - { - this.NTRConnection.Processes.Add(ProcessID + "|" + ProcessName + "," + TitleID); - } - } - - if (this.NTRConnection.Processes.Count > 0) - { - //Bubble processes we ID'd to the top - List TempProcesses = this.NTRConnection.Processes.FindAll(x => x.Contains(',')); - this.NTRConnection.Processes.RemoveAll(x => TempProcesses.Contains(x)); - foreach (string Process in TempProcesses) - { - this.NTRConnection.Processes.Add(Process); - } - - this.NTRConnection.IsProcessListUpdated = true; - } - } - - private void ReadAddressesPacket(uint DataLength) - { - Dictionary AddressSpaces = new Dictionary(); - byte[] Buffer = new byte[DataLength]; - ReadBasePacket(Buffer); - string BufferText = System.Text.Encoding.Default.GetString(Buffer); - BufferText = BufferText.Replace("rtRecvSocket failed: 00000000", ""); - //Line format: - //00100000 - 0093cfff , size: 0083d000 - //Split on comma, then split on ` - ` for address start and `: ` for size - foreach (string Line in BufferText.Split('\n')) - { - if (!Line.Contains("size")) - { - continue; - } - string[] Parts = Line.Split(new String[] { " , " }, StringSplitOptions.None); - string StartString = Parts[0].Split(new String[] { " - " }, StringSplitOptions.None)[0].Trim().PadLeft(8, '0'); - string SizeString = Parts[1].Split(new String[] { ": " }, StringSplitOptions.None)[1].Trim().PadLeft(8, '0'); - uint Start = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(StartString).Reverse().ToArray(), 0); - uint Size = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(SizeString).Reverse().ToArray(), 0); - - AddressSpaces.Add(Start, Size); - } - - if (AddressSpaces.Count > 0) - { - this.NTRConnection.AddressSpaces = new Dictionary(AddressSpaces); - - this.NTRConnection.IsMemoryListUpdated = true; - } - } - - private void ReadMemoryPacket(uint DataLength) - { - this.NTRConnection.ProgressReadMax = this.NTRConnection.ProgressScanMax = DataLength; - if (DataLength < NTRConnection.SearchCriteria[0].Size) - { - NTRConnection.SearchCriteria[0].SearchComplete = true; - return; - } - - byte[] Buffer = new byte[DataLength]; - byte[] TemporaryBuffer = new byte[NTRConnection.SearchCriteria[0].Size]; - - DataRead = 0; - - Thread MemoryScanThread = new Thread(delegate() - { - uint RealAddress; - for (uint i = 0; i <= DataLength - NTRConnection.SearchCriteria[0].Size; ++i) - { - if (DataRead < i + NTRConnection.SearchCriteria[0].Size) - { - --i; - Thread.Sleep(50); - continue; - } - this.NTRConnection.ProgressScan = i; - RealAddress = (uint)(NTRConnection.SearchCriteria[0].StartAddress + i); - if (NTRConnection.SearchCriteria[0].FirstSearch || NTRConnection.SearchCriteria[0].AddressesFound.ContainsKey(RealAddress)) - { - Array.Copy(Buffer, i, TemporaryBuffer, 0, TemporaryBuffer.Length); - if (CheckCriteria(RealAddress, TemporaryBuffer)) - { - NTRConnection.SearchCriteria[0].AddressesFound.Remove(RealAddress); - NTRConnection.SearchCriteria[0].AddressesFound.Add(RealAddress, (byte[])TemporaryBuffer.Clone()); - } - else - { - NTRConnection.SearchCriteria[0].AddressesFound.Remove(RealAddress); - } - } - } - }); - - MemoryScanThread.Start(); - - ReadBasePacket(Buffer); - - MemoryScanThread.Join(); - - DataRead = 0; - - this.NTRConnection.SetCurrentOperationText = "Scanning Read Memory"; - - NTRConnection.SearchCriteria[0].SearchComplete = true; - this.NTRConnection.ProgressReadMax = this.NTRConnection.ProgressScanMax = this.NTRConnection.ProgressRead = this.NTRConnection.ProgressScan = 0; - } - - #endregion - - #region ReadMemoryPacket Helpers - - private bool CheckCriteria(uint RealAddress, byte[] RemoteValue) - { - switch (NTRConnection.SearchCriteria[0].SearchType) - { - case SearchTypeBase.Exact: - return Enumerable.SequenceEqual(NTRConnection.SearchCriteria[0].SearchValue, RemoteValue); - case SearchTypeBase.Range: - IComparable valc = GetValueFromByteArray(RemoteValue); - IComparable vall = GetValueFromByteArray(NTRConnection.SearchCriteria[0].SearchValue); - IComparable valh = GetValueFromByteArray(NTRConnection.SearchCriteria[0].SearchValue2); - if (vall.CompareTo(valh) > 0) - { - IComparable tmp = vall; - vall = valh; - valh = tmp; - } - return vall.CompareTo(valc) <= 0 && valc.CompareTo(valh) <= 0; - case SearchTypeBase.IncreasedBy: - if (!NTRConnection.SearchCriteria[0].AddressesFound.ContainsKey(RealAddress)) - { - return false; - } - return IsIncreasedBy(RealAddress, RemoteValue); - return GetValueFromByteArray(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress]).CompareTo(GetValueFromByteArray(RemoteValue)) == BitConverter.ToUInt32(NTRConnection.SearchCriteria[0].SearchValue, 0); - case SearchTypeBase.DecreasedBy: - if (!NTRConnection.SearchCriteria[0].AddressesFound.ContainsKey(RealAddress)) - { - return false; - } - return IsDecreasedBy(RealAddress, RemoteValue); - case SearchTypeBase.Increased: - if (!NTRConnection.SearchCriteria[0].AddressesFound.ContainsKey(RealAddress)) - { - return false; - } - return GetValueFromByteArray(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress]).CompareTo(GetValueFromByteArray(RemoteValue)) < 0; - case SearchTypeBase.Decreased: - if (!NTRConnection.SearchCriteria[0].AddressesFound.ContainsKey(RealAddress)) - { - return false; - } - return GetValueFromByteArray(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress]).CompareTo(GetValueFromByteArray(RemoteValue)) > 0; - case SearchTypeBase.Same: - if (!NTRConnection.SearchCriteria[0].AddressesFound.ContainsKey(RealAddress)) - { - return false; - } - return GetValueFromByteArray(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress]).CompareTo(GetValueFromByteArray(RemoteValue)) == 0; - case SearchTypeBase.Different: - if (!NTRConnection.SearchCriteria[0].AddressesFound.ContainsKey(RealAddress)) - { - return false; - } - return GetValueFromByteArray(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress]).CompareTo(GetValueFromByteArray(RemoteValue)) != 0; - case SearchTypeBase.Unknown: - return true; - default: - throw new InvalidOperationException("Invalid search type " + NTRConnection.SearchCriteria[0].SearchType.ToString() + " passed to NTRPacketReceiverThread.CheckCriteria"); - } - } - - private IComparable GetValueFromByteArray(byte[] Value) - { - switch (NTRConnection.SearchCriteria[0].DataType) - { - case DataTypeExact.Bytes1: - return Value[0]; - case DataTypeExact.Bytes2: - return BitConverter.ToUInt16(Value, 0); - case DataTypeExact.Bytes4: - return BitConverter.ToUInt32(Value, 0); - case DataTypeExact.Bytes8: - return BitConverter.ToUInt64(Value, 0); - case DataTypeExact.Float: - return BitConverter.ToSingle(Value, 0); - case DataTypeExact.Double: - return BitConverter.ToDouble(Value, 0); - default: - throw new InvalidOperationException("Invalid data type " + NTRConnection.SearchCriteria[0].DataType.ToString() + " passed to NTRPacketReceiverThread.GetValueFromByteArray"); - } - } - - private bool IsIncreasedBy(uint RealAddress, byte[] RemoteValue) - { - checked - { - switch (NTRConnection.SearchCriteria[0].DataType) - { - case DataTypeExact.Bytes1: - return NTRConnection.SearchCriteria[0].AddressesFound[RealAddress][0] == - RemoteValue[0] - NTRConnection.SearchCriteria[0].SearchValue[0]; - case DataTypeExact.Bytes2: - return BitConverter.ToUInt16(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0) == - BitConverter.ToUInt16(RemoteValue, 0) - BitConverter.ToUInt16(NTRConnection.SearchCriteria[0].SearchValue, 0); - case DataTypeExact.Bytes4: - return BitConverter.ToUInt32(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0) == - BitConverter.ToUInt32(RemoteValue, 0) - BitConverter.ToUInt32(NTRConnection.SearchCriteria[0].SearchValue, 0); - case DataTypeExact.Bytes8: - return BitConverter.ToUInt64(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0) == - BitConverter.ToUInt64(RemoteValue, 0) - BitConverter.ToUInt64(NTRConnection.SearchCriteria[0].SearchValue, 0); - case DataTypeExact.Float: - return IsLessThan(BitConverter.ToSingle(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0), - BitConverter.ToSingle(RemoteValue, 0) + BitConverter.ToSingle(NTRConnection.SearchCriteria[0].SearchValue, 0)); - case DataTypeExact.Double: - return IsLessThan(BitConverter.ToDouble(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0), - BitConverter.ToDouble(RemoteValue, 0) + BitConverter.ToDouble(NTRConnection.SearchCriteria[0].SearchValue, 0)); - default: - throw new InvalidOperationException("Invalid data type " + NTRConnection.SearchCriteria[0].DataType.ToString() + " passed to NTRPacketReceiverThread.GetValueFromByteArray"); - } - } - } - - private bool IsDecreasedBy(uint RealAddress, byte[] RemoteValue) - { - checked - { - switch (NTRConnection.SearchCriteria[0].DataType) - { - case DataTypeExact.Bytes1: - return NTRConnection.SearchCriteria[0].AddressesFound[RealAddress][0] == - RemoteValue[0] + NTRConnection.SearchCriteria[0].SearchValue[0]; - case DataTypeExact.Bytes2: - return BitConverter.ToUInt16(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0) == - BitConverter.ToUInt16(RemoteValue, 0) + BitConverter.ToUInt16(NTRConnection.SearchCriteria[0].SearchValue, 0); - case DataTypeExact.Bytes4: - return BitConverter.ToUInt32(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0) == - BitConverter.ToUInt32(RemoteValue, 0) + BitConverter.ToUInt32(NTRConnection.SearchCriteria[0].SearchValue, 0); - case DataTypeExact.Bytes8: - return BitConverter.ToUInt64(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0) == - BitConverter.ToUInt64(RemoteValue, 0) + BitConverter.ToUInt64(NTRConnection.SearchCriteria[0].SearchValue, 0); - case DataTypeExact.Float: - return IsGreaterThan(BitConverter.ToSingle(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0), - BitConverter.ToSingle(RemoteValue, 0) + BitConverter.ToSingle(NTRConnection.SearchCriteria[0].SearchValue, 0)); - case DataTypeExact.Double: - return IsGreaterThan(BitConverter.ToDouble(NTRConnection.SearchCriteria[0].AddressesFound[RealAddress], 0), - BitConverter.ToDouble(RemoteValue, 0) + BitConverter.ToDouble(NTRConnection.SearchCriteria[0].SearchValue, 0)); - default: - throw new InvalidOperationException("Invalid data type " + NTRConnection.SearchCriteria[0].DataType.ToString() + " passed to NTRPacketReceiverThread.GetValueFromByteArray"); - } - } - } - - #endregion - - #region Handle comparison of precision numbers (float, double) - - private bool IsLessThan(float Left, float Right) - { - checked - { - return Left < Right + float.Epsilon; - } - } - private bool IsGreaterThan(float Left, float Right) - { - checked - { - return Left + float.Epsilon > Right; - } - } - private bool IsLessThan(double Left, double Right) - { - checked - { - return Left < Right + double.Epsilon; - } - } - private bool IsGreaterThan(double Left, double Right) - { - checked - { - return Left + double.Epsilon > Right; - } - } - - #endregion - } -} diff --git a/tmp/NTRDebuggerTool/Remote/NTRRemoteConnection.cs b/tmp/NTRDebuggerTool/Remote/NTRRemoteConnection.cs deleted file mode 100644 index 73e875b..0000000 --- a/tmp/NTRDebuggerTool/Remote/NTRRemoteConnection.cs +++ /dev/null @@ -1,384 +0,0 @@ -using NTRDebuggerTool.Objects; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net.Sockets; -using System.Threading; -using System.Xml; - -namespace NTRDebuggerTool.Remote -{ - public class NTRRemoteConnection - { - private static readonly log4net.ILog LOGGER = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - #region Members - - public string HardwarePID = null; - - public String IP { get; set; } - public Int16 Port { get; set; } - - public Dictionary AddressSpaces; - - public uint ProgressRead = 0; - public uint ProgressReadMax = 0; - - public uint ProgressScan = 0; - public uint ProgressScanMax = 0; - - internal TcpClient Client; - - private uint Sequence = 0u; - - private object SendLock = new object(); - private object ReceiveLock = new object(); - public bool LockControls = false; - public bool IsConnected = false; - public bool IsProcessListUpdated = false; - public bool IsMemoryListUpdated = false; - - private long LastHeartbeat = 0; - - internal uint LastListProcessesSequence = 0u; - internal uint LastListMemoryRegionsSequence = 0u; - internal uint LastReadMemorySequence = 0u; - - private Thread PacketThread = null; - internal bool CanSendHeartbeat = true; - public List Processes = new List(); - - public string SetCurrentOperationText = ""; - public string SetCurrentOperationText2 = ""; - private NTRPacketReceiverThread PacketReceiverThread; - - internal XmlDocument ReleasesDocument; - public List SearchCriteria = new List(); - private Stopwatch SearchTimerStopwatch = new Stopwatch(); - - #endregion - - #region Constructor - - public NTRRemoteConnection() - { - this.PacketReceiverThread = new NTRPacketReceiverThread(this); - try - { - this.ReleasesDocument = new XmlDocument(); - ReleasesDocument.Load(File.OpenRead(Path.GetTempPath() + "3dsreleases.xml")); - } - catch (Exception e) - { - LOGGER.Error(null, e); - this.ReleasesDocument = null; - } - } - - #endregion - - #region Connection Management - - public bool Connect() - { - if (Client != null) - { - bool Disconnected = false; - try - { - if (Client.Connected) - { - if (!SendHeartbeatPacket(true)) - { - Disconnected = true; - } - } - else - { - Disconnected = true; - } - } - catch (Exception e) - { - LOGGER.Error(null, e); - Disconnected = true; - } - if (Disconnected) - { - Disconnect(); - } - } - if (Client == null) - { - try - { - Client = new TcpClient(); - Client.NoDelay = true; - IAsyncResult res = Client.BeginConnect(IP, Port, null, null); - if (!res.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(Config.ConnectTimeout))) - { - Client.Close(); - Client = null; - throw new Exception("Connect timeout"); - } - Client.EndConnect(res); - PacketThread = new Thread(new ThreadStart(this.PacketReceiverThread.ThreadReceivePackets)); - PacketThread.Name = "ReadPacketsThread"; - PacketThread.Start(); - IsConnected = true; - CanSendHeartbeat = true; - SendHeartbeatPacket(true); - } - catch (Exception e) - { - LOGGER.Error(null, e); - return false; - } - } - return true; - } - - public void Disconnect() - { - try - { - if (Client != null) - { - Client.Close(); - } - if (PacketThread != null) - { - PacketThread.Abort(); - } - } - catch (Exception e) - { - LOGGER.Error(null, e); - } - Client = null; - IsConnected = false; - HardwarePID = null; - } - - #endregion - - #region Sending Packets - - public void SendWriteMemoryPacket(uint ProcessID, uint Address, byte Value) - { - SendWriteMemoryPacket(ProcessID, Address, new byte[] { Value }); - } - - public void SendWriteMemoryPacket(uint ProcessID, uint Address, ushort Value) - { - SendWriteMemoryPacket(ProcessID, Address, BitConverter.GetBytes(Value)); - } - - public void SendWriteMemoryPacket(uint ProcessID, uint Address, uint Value) - { - SendWriteMemoryPacket(ProcessID, Address, BitConverter.GetBytes(Value)); - } - - public void SendWriteMemoryPacket(uint ProcessID, uint Address, ulong Value) - { - SendWriteMemoryPacket(ProcessID, Address, BitConverter.GetBytes(Value)); - } - - public void SendWriteMemoryPacket(uint ProcessID, uint Address, float Value) - { - SendWriteMemoryPacket(ProcessID, Address, BitConverter.GetBytes(Value)); - } - - public void SendWriteMemoryPacket(uint ProcessID, uint Address, double Value) - { - SendWriteMemoryPacket(ProcessID, Address, BitConverter.GetBytes(Value)); - } - - public void SendWriteMemoryPacket(uint ProcessID, uint Address, byte[] Values) - { - this.SendPacket(PacketType.GeneralMemory, PacketCommand.Write, new uint[] { BitConverter.ToUInt32(BitConverter.GetBytes(ProcessID).Reverse().ToArray(), 0), Address, (uint)Values.Length }, Values); - } - - public void SendReadMemoryPacket(SearchCriteria NewSearchCriteria) - { - if (!NewSearchCriteria.HideSearch) - { - this.LockControls = true; - } - while (SearchCriteria[0] != NewSearchCriteria) - { - Thread.Sleep(10); - } - SearchTimerStopwatch.Start(); - SendReadMemoryPacketPre(); - SearchTimerStopwatch.Stop(); - NewSearchCriteria.Duration = (uint)SearchTimerStopwatch.ElapsedMilliseconds; - SearchTimerStopwatch.Reset(); - if (!NewSearchCriteria.HideSearch) - { - this.LockControls = false; - } - } - - private void SendReadMemoryPacketPre() - { - SearchCriteria[0].AllSearchesComplete = false; - if (SearchCriteria[0].AddressesFound.Count > 0 && (SearchCriteria[0].AddressesFound.Count < 200 || SearchCriteria[0].StartAddress == uint.MaxValue)) - { - uint TempAddress = SearchCriteria[0].StartAddress; - uint TempLength = SearchCriteria[0].Length; - SearchCriteria[0].Length = (uint)SearchCriteria[0].AddressesFound[SearchCriteria[0].AddressesFound.Keys.First()].Length; - //Clone the list to an array to prevent concurrent modification - foreach (uint Address in new List(SearchCriteria[0].AddressesFound.Keys)) - { - SearchCriteria[0].SearchComplete = false; - SearchCriteria[0].StartAddress = Address; - SendReadMemoryPacket(); - } - SearchCriteria[0].Length = TempLength; - SearchCriteria[0].StartAddress = TempAddress; - } - else if (SearchCriteria[0].StartAddress == uint.MaxValue) - { - foreach (uint ActualAddressSpace in AddressSpaces.Keys) - { - SearchCriteria[0].StartAddress = ActualAddressSpace; - SearchCriteria[0].Length = AddressSpaces[ActualAddressSpace]; - SearchCriteria[0].SearchComplete = false; - SendReadMemoryPacket(); - } - SearchCriteria[0].StartAddress = uint.MaxValue; - SearchCriteria[0].Length = uint.MaxValue; - } - else - { - SearchCriteria[0].SearchComplete = false; - SendReadMemoryPacket(); - } - SearchCriteria[0].AllSearchesComplete = SearchCriteria[0].SearchComplete = true; - SearchCriteria[0].FirstSearch = false; - SearchCriteria.RemoveAt(0); - } - - private void SendReadMemoryPacket() - { - if (!SearchCriteria[0].HideSearch) - { - SetCurrentOperationText = "Searching Memory " + Utilities.GetStringFromByteArray(BitConverter.GetBytes(SearchCriteria[0].StartAddress).Reverse().ToArray()) + " - " + Utilities.GetStringFromByteArray(BitConverter.GetBytes(SearchCriteria[0].StartAddress + SearchCriteria[0].Length).Reverse().ToArray()); - } - - this.SendPacket(PacketType.General, PacketCommand.Read, new uint[] { BitConverter.ToUInt32(BitConverter.GetBytes(SearchCriteria[0].ProcessID).Reverse().ToArray(), 0), SearchCriteria[0].StartAddress, SearchCriteria[0].Length }); - while (SearchCriteria[0].SearchComplete != true) - { - Thread.Sleep(100); - } - if (!SearchCriteria[0].HideSearch) - { - SetCurrentOperationText = ""; - } - } - public void SendListProcessesPacket() - { - this.SendPacket(PacketType.General, PacketCommand.ListProcesses, null); - } - - public void SendReadMemoryAddressesPacket(string ProcessID) - { - uint ActualProcessID = BitConverter.ToUInt32(Utilities.GetByteArrayFromByteString(ProcessID).Reverse().ToArray(), 0); - this.SendPacket(PacketType.General, PacketCommand.ListAddresses, new uint[1] { ActualProcessID }); - } - - public void sendReloadPacket() - { - this.SendPacket(PacketType.General, PacketCommand.Reload, null); - } - - public void SendHelloPacket() - { - this.SendPacket(PacketType.General, PacketCommand.Hello, null); - } - - public bool SendHeartbeatPacket() - { - return SendHeartbeatPacket(false); - } - - public bool SendHeartbeatPacket(bool IsConnecting) - { - if (IsConnecting || this.Client != null) - { - if (IsConnecting || (this.Client != null && this.Client.Connected)) - { - if (CanSendHeartbeat && LastHeartbeat < (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - 30000) - { - CanSendHeartbeat = false; - LastHeartbeat = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - try - { - SendPacket(PacketType.General, PacketCommand.Heartbeat, null); - return true; - } - catch (Exception e) - { - LOGGER.Error(null, e); - } - } - } - } - return false; - } - - private void SendPacket(uint Type, uint Command, uint[] Arguments) - { - SendPacket(Type, Command, Arguments, new byte[0]); - } - - private void SendPacket(uint Type, uint Command, uint[] Arguments, byte[] AdditionalData) - { - lock (this.SendLock) - { - int num = 0; - byte[] array = new byte[84]; - Array.Clear(array, 0, 84); //Force to zero - BitConverter.GetBytes(0x12345678).CopyTo(array, num); - BitConverter.GetBytes(this.Sequence += 1000u).CopyTo(array, num += 4); - SetPacketSequence(Type, Command); - BitConverter.GetBytes(Type).CopyTo(array, num += 4); - BitConverter.GetBytes(Command).CopyTo(array, num += 4); - if (Arguments != null) - { - for (int i = 0; i < 16 && i < Arguments.Length; i++) - { - BitConverter.GetBytes(Arguments[i]).CopyTo(array, num += 4); - } - } - - BitConverter.GetBytes(AdditionalData.Length).CopyTo(array, array.Length - 4); - this.Client.GetStream().Write(array, 0, array.Length); - if (AdditionalData.Length > 0u) - { - this.Client.GetStream().Write(AdditionalData, 0, AdditionalData.Length); - } - } - } - - private void SetPacketSequence(uint Type, uint Command) - { - if (Type == PacketType.General && Command == PacketCommand.ListProcesses) - { - LastListProcessesSequence = Sequence; - } - else if (Type == PacketType.General && Command == PacketCommand.ListAddresses) - { - LastListMemoryRegionsSequence = Sequence; - } - else if (Type == PacketType.General && Command == PacketCommand.Read) - { - LastReadMemorySequence = Sequence; - } - } - - #endregion - } -} diff --git a/tmp/NTRDebuggerTool/Remote/PacketCommand.cs b/tmp/NTRDebuggerTool/Remote/PacketCommand.cs deleted file mode 100644 index f0127fb..0000000 --- a/tmp/NTRDebuggerTool/Remote/PacketCommand.cs +++ /dev/null @@ -1,17 +0,0 @@ - -namespace NTRDebuggerTool.Remote -{ - static class PacketCommand - { - //General - public const uint Heartbeat = 0u; - public const uint Hello = 3u; - public const uint Reload = 4u; - public const uint ListProcesses = 5u; - - //Memory - public const uint ListAddresses = 8u; - public const uint Read = 9u; - public const uint Write = 10u; - } -} diff --git a/tmp/NTRDebuggerTool/Remote/PacketType.cs b/tmp/NTRDebuggerTool/Remote/PacketType.cs deleted file mode 100644 index 958d122..0000000 --- a/tmp/NTRDebuggerTool/Remote/PacketType.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace NTRDebuggerTool.Remote -{ - static class PacketType - { - public const uint General = 0u; - public const uint GeneralMemory = 1u; - } -} diff --git a/tmp/NTRDebuggerTool/Resources/cog2.png b/tmp/NTRDebuggerTool/Resources/cog2.png deleted file mode 100644 index e510e526ae811d54288b3dae979a82f54d787b44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 430 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

EqQ?82~?sv~9{kOxfP5%$l|-yd2-U%yBI9 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 cML6BO;4u1%aJu=mVm#KEVY;?* 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 diff --git a/tmp/NTRDebuggerTool/Utilities.cs b/tmp/NTRDebuggerTool/Utilities.cs deleted file mode 100644 index 909e57b..0000000 --- a/tmp/NTRDebuggerTool/Utilities.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Linq; - -namespace NTRDebuggerTool -{ - static class Utilities - { - public static byte[] GetByteArrayFromByteString(string Text) - { - return Enumerable.Range(0, Text.Length) - .Where(x => x % 2 == 0) - .Select(x => Convert.ToByte(Text.Substring(x, 2), 16)) - .ToArray(); - } - - public static string GetStringFromByteArray(byte[] Buffer) - { - return BitConverter.ToString(Buffer).Replace("-", ""); - } - - } -} diff --git a/tmp/NTRDebuggerTool/packages.config b/tmp/NTRDebuggerTool/packages.config deleted file mode 100644 index 8c1f1bf..0000000 --- a/tmp/NTRDebuggerTool/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/tmp/README.md b/tmp/README.md deleted file mode 100644 index 035331a..0000000 --- a/tmp/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# NTRRemoteDebugger -Tool to interface with NTR CFW's remote debugging. - -# Features - -* Nice GUI for searching for memory addresses and modifying them. -* No messing about with files or other external resources. -* Allows searching for byte, short, int, long, float, double, list of bytes, and text strings. -* Subsequent searches will narrow search results by only requesting the memory addresses needed, speeding up things significantly. -* Ability to "lock" memory addresses to a given value. This means that they are set automatically based on a configured value. -* Can convert AR3DS codes to work with the tool. -* Works on mono and via wine. Thanks to u/Melon__Bread for verifying mono support (and MonoDevelop compile support) and u/MattKimura for verifying wine support. - -# Untested - -* Search for float, double, and raw bytes. - -# Notes - -* Editing items in the bottom-right grid (the 'Values' grid) requires double clicking. This is strange behavior for the checkbox and dropdown cells. -* The first half of the progress bar at the bottom is for receiving memory values from the 3DS. The second half is for searching for the value. -* The progress bar does not work for narrowing search results, just be patient. It's about 1/3rd of a second per result check for me. -* NTR's performance seems to degrade over time if the connection gets interrupted at all. I find that after about 10 interrupted connections, I have to reboot my 3DS to get NTR's Debugger to start responding properly again. Apparently running [NTR 3.3 fork](https://github.com/Shadowtrance/BootNTR) from Shadowtrance with the 3.2 ntr.bin (same repo) is better for stability and also works on 10.6.