From 26067bd2265982ef23b5e252344187de4ba6fb03 Mon Sep 17 00:00:00 2001 From: Luaancz Date: Sat, 31 May 2014 09:53:44 +0200 Subject: [PATCH] Initial commit. --- .gitignore | 29 ++ AutoPoke.sln | 20 + AutoPoke/AutoPoke.csproj | 145 +++++++ AutoPoke/MainForm.Designer.cs | 505 ++++++++++++++++++++++ AutoPoke/MainForm.cs | 348 +++++++++++++++ AutoPoke/MainForm.resx | 144 ++++++ AutoPoke/PInvoke.cs | 66 +++ AutoPoke/PageInfo.cs | 13 + AutoPoke/ProcessListItem.cs | 24 + AutoPoke/Program.cs | 21 + AutoPoke/Properties/AssemblyInfo.cs | 36 ++ AutoPoke/Properties/Resources.Designer.cs | 63 +++ AutoPoke/Properties/Resources.resx | 117 +++++ AutoPoke/Properties/Settings.Designer.cs | 26 ++ AutoPoke/Properties/Settings.settings | 7 + AutoPoke/ScanResultInformation.cs | 18 + AutoPoke/SearchEngine.cs | 189 ++++++++ AutoPoke/SearchTypes/DecimalSearch.cs | 85 ++++ AutoPoke/SearchTypes/DoubleSearch.cs | 136 ++++++ AutoPoke/SearchTypes/Int16Search.cs | 131 ++++++ AutoPoke/SearchTypes/Int32DeltaSearch.cs | 135 ++++++ AutoPoke/SearchTypes/Int32Search.cs | 133 ++++++ AutoPoke/SearchTypes/SearchBase.cs | 68 +++ AutoPoke/SearchTypes/SingleSearch.cs | 136 ++++++ AutoPoke/app.config | 3 + 25 files changed, 2598 insertions(+) create mode 100644 .gitignore create mode 100644 AutoPoke.sln create mode 100644 AutoPoke/AutoPoke.csproj create mode 100644 AutoPoke/MainForm.Designer.cs create mode 100644 AutoPoke/MainForm.cs create mode 100644 AutoPoke/MainForm.resx create mode 100644 AutoPoke/PInvoke.cs create mode 100644 AutoPoke/PageInfo.cs create mode 100644 AutoPoke/ProcessListItem.cs create mode 100644 AutoPoke/Program.cs create mode 100644 AutoPoke/Properties/AssemblyInfo.cs create mode 100644 AutoPoke/Properties/Resources.Designer.cs create mode 100644 AutoPoke/Properties/Resources.resx create mode 100644 AutoPoke/Properties/Settings.Designer.cs create mode 100644 AutoPoke/Properties/Settings.settings create mode 100644 AutoPoke/ScanResultInformation.cs create mode 100644 AutoPoke/SearchEngine.cs create mode 100644 AutoPoke/SearchTypes/DecimalSearch.cs create mode 100644 AutoPoke/SearchTypes/DoubleSearch.cs create mode 100644 AutoPoke/SearchTypes/Int16Search.cs create mode 100644 AutoPoke/SearchTypes/Int32DeltaSearch.cs create mode 100644 AutoPoke/SearchTypes/Int32Search.cs create mode 100644 AutoPoke/SearchTypes/SearchBase.cs create mode 100644 AutoPoke/SearchTypes/SingleSearch.cs create mode 100644 AutoPoke/app.config diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0bc8230 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ + +#ignore thumbnails created by windows +Thumbs.db +#Ignore files build by Visual Studio +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +[Dd]ebug*/ +*.lib +*.sbr +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* diff --git a/AutoPoke.sln b/AutoPoke.sln new file mode 100644 index 0000000..2e4a654 --- /dev/null +++ b/AutoPoke.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoPoke", "AutoPoke\AutoPoke.csproj", "{6908C63E-E0F3-47E2-8CBE-AD65C2526783}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6908C63E-E0F3-47E2-8CBE-AD65C2526783}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6908C63E-E0F3-47E2-8CBE-AD65C2526783}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6908C63E-E0F3-47E2-8CBE-AD65C2526783}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6908C63E-E0F3-47E2-8CBE-AD65C2526783}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AutoPoke/AutoPoke.csproj b/AutoPoke/AutoPoke.csproj new file mode 100644 index 0000000..44cef60 --- /dev/null +++ b/AutoPoke/AutoPoke.csproj @@ -0,0 +1,145 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {6908C63E-E0F3-47E2-8CBE-AD65C2526783} + WinExe + Properties + Luaan.AutoPoke + AutoPoke + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + + + prompt + 4 + AllRules.ruleset + x86 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + Form + + + MainForm.cs + + + + + + + + + + + + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/AutoPoke/MainForm.Designer.cs b/AutoPoke/MainForm.Designer.cs new file mode 100644 index 0000000..dc9e57f --- /dev/null +++ b/AutoPoke/MainForm.Designer.cs @@ -0,0 +1,505 @@ +namespace Luaan.AutoPoke +{ + 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.ddlProcesses = new System.Windows.Forms.ComboBox(); + this.btnReloadProcesses = new System.Windows.Forms.Button(); + this.tbxSearchValue = new System.Windows.Forms.TextBox(); + this.btnSearch = new System.Windows.Forms.Button(); + this.btnAddToList = new System.Windows.Forms.Button(); + this.bwMemoryScan = new System.ComponentModel.BackgroundWorker(); + this.pbScanProgress = new System.Windows.Forms.ProgressBar(); + this.lvFound = new System.Windows.Forms.ListView(); + this.chTitle = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chAddress = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chMaintainValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chTypeName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.lblSearchText = new System.Windows.Forms.Label(); + this.tbxSetValue = new System.Windows.Forms.TextBox(); + this.btnSet = new System.Windows.Forms.Button(); + this.btnRemoveFromList = new System.Windows.Forms.Button(); + this.refreshTimer = new System.Windows.Forms.Timer(this.components); + this.lblMessage = new System.Windows.Forms.Label(); + this.cbxMaintainValue = new System.Windows.Forms.CheckBox(); + this.btnTest = new System.Windows.Forms.Button(); + this.lvSearches = new System.Windows.Forms.ListView(); + this.chSearchTitle = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chSearchValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chSearchType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chSearchLocations = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.gbNewSearch = new System.Windows.Forms.GroupBox(); + this.btnAddSearch = new System.Windows.Forms.Button(); + this.lblSearchType = new System.Windows.Forms.Label(); + this.ddlSearchType = new System.Windows.Forms.ComboBox(); + this.lblTitle = new System.Windows.Forms.Label(); + this.tbxTitle = new System.Windows.Forms.TextBox(); + this.btnSearchRemove = new System.Windows.Forms.Button(); + this.cbxPresumeAlignment = new System.Windows.Forms.CheckBox(); + this.tbxDelta = new System.Windows.Forms.TextBox(); + this.lblDelta = new System.Windows.Forms.Label(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.toolTipError = new System.Windows.Forms.ToolTip(this.components); + this.gbNewSearch.SuspendLayout(); + this.SuspendLayout(); + // + // ddlProcesses + // + this.ddlProcesses.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.ddlProcesses.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.ddlProcesses.FormattingEnabled = true; + this.ddlProcesses.Location = new System.Drawing.Point(12, 12); + this.ddlProcesses.Name = "ddlProcesses"; + this.ddlProcesses.Size = new System.Drawing.Size(674, 21); + this.ddlProcesses.TabIndex = 0; + // + // btnReloadProcesses + // + this.btnReloadProcesses.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnReloadProcesses.Location = new System.Drawing.Point(692, 11); + this.btnReloadProcesses.Name = "btnReloadProcesses"; + this.btnReloadProcesses.Size = new System.Drawing.Size(48, 23); + this.btnReloadProcesses.TabIndex = 1; + this.btnReloadProcesses.Text = "load"; + this.btnReloadProcesses.UseVisualStyleBackColor = true; + this.btnReloadProcesses.Click += new System.EventHandler(this.btnReloadProcesses_Click); + // + // tbxSearchValue + // + this.tbxSearchValue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.tbxSearchValue.Location = new System.Drawing.Point(12, 344); + this.tbxSearchValue.Name = "tbxSearchValue"; + this.tbxSearchValue.Size = new System.Drawing.Size(100, 20); + this.tbxSearchValue.TabIndex = 1; + this.toolTip.SetToolTip(this.tbxSearchValue, "Represents the value being searched."); + this.tbxSearchValue.KeyUp += new System.Windows.Forms.KeyEventHandler(this.tbxSearchValue_KeyUp); + // + // btnSearch + // + this.btnSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnSearch.Location = new System.Drawing.Point(181, 342); + this.btnSearch.Name = "btnSearch"; + this.btnSearch.Size = new System.Drawing.Size(56, 23); + this.btnSearch.TabIndex = 3; + this.btnSearch.Text = "search"; + this.btnSearch.UseVisualStyleBackColor = true; + this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click); + // + // btnAddToList + // + this.btnAddToList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnAddToList.Location = new System.Drawing.Point(266, 302); + this.btnAddToList.Name = "btnAddToList"; + this.btnAddToList.Size = new System.Drawing.Size(43, 23); + this.btnAddToList.TabIndex = 5; + this.btnAddToList.Text = "-->"; + this.btnAddToList.UseVisualStyleBackColor = true; + this.btnAddToList.Click += new System.EventHandler(this.btnAddToList_Click); + // + // bwMemoryScan + // + this.bwMemoryScan.WorkerReportsProgress = true; + // + // pbScanProgress + // + this.pbScanProgress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pbScanProgress.Location = new System.Drawing.Point(12, 427); + this.pbScanProgress.Name = "pbScanProgress"; + this.pbScanProgress.Size = new System.Drawing.Size(728, 23); + this.pbScanProgress.TabIndex = 6; + // + // lvFound + // + this.lvFound.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.lvFound.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.chTitle, + this.chValue, + this.chAddress, + this.chMaintainValue, + this.chTypeName}); + this.lvFound.FullRowSelect = true; + this.lvFound.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.lvFound.HideSelection = false; + this.lvFound.Location = new System.Drawing.Point(315, 39); + this.lvFound.MultiSelect = false; + this.lvFound.Name = "lvFound"; + this.lvFound.Size = new System.Drawing.Size(425, 354); + this.lvFound.TabIndex = 7; + this.lvFound.UseCompatibleStateImageBehavior = false; + this.lvFound.View = System.Windows.Forms.View.Details; + this.lvFound.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvFound_ItemSelectionChanged); + // + // chTitle + // + this.chTitle.Text = "Title"; + this.chTitle.Width = 104; + // + // chValue + // + this.chValue.Text = "Value"; + // + // chAddress + // + this.chAddress.Text = "Address"; + // + // chMaintainValue + // + this.chMaintainValue.Text = "Maintain"; + // + // chTypeName + // + this.chTypeName.Text = "Type"; + // + // lblSearchText + // + this.lblSearchText.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblSearchText.AutoSize = true; + this.lblSearchText.Location = new System.Drawing.Point(12, 328); + this.lblSearchText.Name = "lblSearchText"; + this.lblSearchText.Size = new System.Drawing.Size(73, 13); + this.lblSearchText.TabIndex = 8; + this.lblSearchText.Text = "Search value:"; + // + // tbxSetValue + // + this.tbxSetValue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.tbxSetValue.Location = new System.Drawing.Point(559, 401); + this.tbxSetValue.Name = "tbxSetValue"; + this.tbxSetValue.Size = new System.Drawing.Size(100, 20); + this.tbxSetValue.TabIndex = 9; + this.tbxSetValue.KeyUp += new System.Windows.Forms.KeyEventHandler(this.tbxSetValue_KeyUp); + // + // btnSet + // + this.btnSet.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnSet.Enabled = false; + this.btnSet.Location = new System.Drawing.Point(665, 399); + this.btnSet.Name = "btnSet"; + this.btnSet.Size = new System.Drawing.Size(75, 23); + this.btnSet.TabIndex = 10; + this.btnSet.Text = "set"; + this.btnSet.UseVisualStyleBackColor = true; + this.btnSet.Click += new System.EventHandler(this.btnSet_Click); + // + // btnRemoveFromList + // + this.btnRemoveFromList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnRemoveFromList.Enabled = false; + this.btnRemoveFromList.Location = new System.Drawing.Point(315, 399); + this.btnRemoveFromList.Name = "btnRemoveFromList"; + this.btnRemoveFromList.Size = new System.Drawing.Size(54, 23); + this.btnRemoveFromList.TabIndex = 11; + this.btnRemoveFromList.Text = "remove"; + this.btnRemoveFromList.UseVisualStyleBackColor = true; + this.btnRemoveFromList.Click += new System.EventHandler(this.btnRemoveFromList_Click); + // + // refreshTimer + // + this.refreshTimer.Enabled = true; + this.refreshTimer.Tick += new System.EventHandler(this.refreshTimer_Tick); + // + // lblMessage + // + this.lblMessage.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblMessage.AutoSize = true; + this.lblMessage.Location = new System.Drawing.Point(12, 404); + this.lblMessage.Name = "lblMessage"; + this.lblMessage.Size = new System.Drawing.Size(41, 13); + this.lblMessage.TabIndex = 14; + this.lblMessage.Text = "Ready."; + // + // cbxMaintainValue + // + this.cbxMaintainValue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.cbxMaintainValue.AutoSize = true; + this.cbxMaintainValue.Location = new System.Drawing.Point(487, 403); + this.cbxMaintainValue.Name = "cbxMaintainValue"; + this.cbxMaintainValue.Size = new System.Drawing.Size(66, 17); + this.cbxMaintainValue.TabIndex = 15; + this.cbxMaintainValue.Text = "Maintain"; + this.toolTip.SetToolTip(this.cbxMaintainValue, "If checked, the application will periodically reset the selected data item to the" + + " specified value."); + this.cbxMaintainValue.UseVisualStyleBackColor = true; + this.cbxMaintainValue.CheckedChanged += new System.EventHandler(this.cbxMaintainValue_CheckedChanged); + // + // btnTest + // + this.btnTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnTest.Location = new System.Drawing.Point(266, 342); + this.btnTest.Name = "btnTest"; + this.btnTest.Size = new System.Drawing.Size(43, 23); + this.btnTest.TabIndex = 17; + this.btnTest.Text = "Test"; + this.btnTest.UseVisualStyleBackColor = true; + this.btnTest.Click += new System.EventHandler(this.btnTest_Click); + // + // lvSearches + // + this.lvSearches.Activation = System.Windows.Forms.ItemActivation.OneClick; + this.lvSearches.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.lvSearches.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.chSearchTitle, + this.chSearchValue, + this.chSearchType, + this.chSearchLocations}); + this.lvSearches.FullRowSelect = true; + this.lvSearches.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.lvSearches.HideSelection = false; + this.lvSearches.Location = new System.Drawing.Point(12, 107); + this.lvSearches.MultiSelect = false; + this.lvSearches.Name = "lvSearches"; + this.lvSearches.Size = new System.Drawing.Size(297, 189); + this.lvSearches.TabIndex = 18; + this.lvSearches.UseCompatibleStateImageBehavior = false; + this.lvSearches.View = System.Windows.Forms.View.Details; + // + // chSearchTitle + // + this.chSearchTitle.Text = "Title"; + // + // chSearchValue + // + this.chSearchValue.Text = "Value"; + // + // chSearchType + // + this.chSearchType.Text = "Type"; + // + // chSearchLocations + // + this.chSearchLocations.Text = "Found"; + this.chSearchLocations.Width = 45; + // + // gbNewSearch + // + this.gbNewSearch.Controls.Add(this.btnAddSearch); + this.gbNewSearch.Controls.Add(this.lblSearchType); + this.gbNewSearch.Controls.Add(this.ddlSearchType); + this.gbNewSearch.Controls.Add(this.lblTitle); + this.gbNewSearch.Controls.Add(this.tbxTitle); + this.gbNewSearch.Location = new System.Drawing.Point(12, 39); + this.gbNewSearch.Name = "gbNewSearch"; + this.gbNewSearch.Size = new System.Drawing.Size(297, 62); + this.gbNewSearch.TabIndex = 0; + this.gbNewSearch.TabStop = false; + this.gbNewSearch.Text = "New search"; + // + // btnAddSearch + // + this.btnAddSearch.Location = new System.Drawing.Point(238, 30); + this.btnAddSearch.Name = "btnAddSearch"; + this.btnAddSearch.Size = new System.Drawing.Size(50, 23); + this.btnAddSearch.TabIndex = 19; + this.btnAddSearch.Text = "add"; + this.btnAddSearch.UseVisualStyleBackColor = true; + this.btnAddSearch.Click += new System.EventHandler(this.btnAddSearch_Click); + // + // lblSearchType + // + this.lblSearchType.AutoSize = true; + this.lblSearchType.Location = new System.Drawing.Point(129, 16); + this.lblSearchType.Name = "lblSearchType"; + this.lblSearchType.Size = new System.Drawing.Size(34, 13); + this.lblSearchType.TabIndex = 18; + this.lblSearchType.Text = "Type:"; + // + // ddlSearchType + // + this.ddlSearchType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.ddlSearchType.FormattingEnabled = true; + this.ddlSearchType.Items.AddRange(new object[] { + "Int32", + "Int16", + "ΔSingle", + "ΔDouble", + "ΔInt32"}); + this.ddlSearchType.Location = new System.Drawing.Point(132, 31); + this.ddlSearchType.Name = "ddlSearchType"; + this.ddlSearchType.Size = new System.Drawing.Size(100, 21); + this.ddlSearchType.TabIndex = 17; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Location = new System.Drawing.Point(6, 16); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(30, 13); + this.lblTitle.TabIndex = 15; + this.lblTitle.Text = "Title:"; + // + // tbxTitle + // + this.tbxTitle.Location = new System.Drawing.Point(9, 32); + this.tbxTitle.Name = "tbxTitle"; + this.tbxTitle.Size = new System.Drawing.Size(108, 20); + this.tbxTitle.TabIndex = 0; + this.tbxTitle.KeyUp += new System.Windows.Forms.KeyEventHandler(this.tbxTitle_KeyUp); + // + // btnSearchRemove + // + this.btnSearchRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnSearchRemove.Location = new System.Drawing.Point(12, 302); + this.btnSearchRemove.Name = "btnSearchRemove"; + this.btnSearchRemove.Size = new System.Drawing.Size(63, 23); + this.btnSearchRemove.TabIndex = 20; + this.btnSearchRemove.Text = "remove"; + this.btnSearchRemove.UseVisualStyleBackColor = true; + this.btnSearchRemove.Click += new System.EventHandler(this.btnSearchRemove_Click); + // + // cbxPresumeAlignment + // + this.cbxPresumeAlignment.AutoSize = true; + this.cbxPresumeAlignment.Checked = true; + this.cbxPresumeAlignment.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbxPresumeAlignment.Location = new System.Drawing.Point(12, 373); + this.cbxPresumeAlignment.Name = "cbxPresumeAlignment"; + this.cbxPresumeAlignment.Size = new System.Drawing.Size(115, 17); + this.cbxPresumeAlignment.TabIndex = 21; + this.cbxPresumeAlignment.Text = "Presume alignment"; + this.toolTip.SetToolTip(this.cbxPresumeAlignment, resources.GetString("cbxPresumeAlignment.ToolTip")); + this.cbxPresumeAlignment.UseVisualStyleBackColor = true; + // + // tbxDelta + // + this.tbxDelta.Location = new System.Drawing.Point(118, 344); + this.tbxDelta.Name = "tbxDelta"; + this.tbxDelta.Size = new System.Drawing.Size(57, 20); + this.tbxDelta.TabIndex = 2; + this.tbxDelta.Text = "1"; + this.toolTip.SetToolTip(this.tbxDelta, resources.GetString("tbxDelta.ToolTip")); + this.tbxDelta.KeyUp += new System.Windows.Forms.KeyEventHandler(this.tbxSearchValue_KeyUp); + // + // lblDelta + // + this.lblDelta.AutoSize = true; + this.lblDelta.Location = new System.Drawing.Point(115, 328); + this.lblDelta.Name = "lblDelta"; + this.lblDelta.Size = new System.Drawing.Size(35, 13); + this.lblDelta.TabIndex = 22; + this.lblDelta.Text = "Delta:"; + // + // toolTip + // + this.toolTip.AutomaticDelay = 100; + this.toolTip.AutoPopDelay = 0; + this.toolTip.InitialDelay = 100; + this.toolTip.ReshowDelay = 20; + // + // toolTipError + // + this.toolTipError.AutomaticDelay = 100; + this.toolTipError.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); + this.toolTipError.ForeColor = System.Drawing.Color.Black; + this.toolTipError.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Error; + this.toolTipError.ToolTipTitle = "Error"; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(752, 462); + this.Controls.Add(this.lblDelta); + this.Controls.Add(this.tbxDelta); + this.Controls.Add(this.cbxPresumeAlignment); + this.Controls.Add(this.btnSearchRemove); + this.Controls.Add(this.gbNewSearch); + this.Controls.Add(this.lvSearches); + this.Controls.Add(this.btnTest); + this.Controls.Add(this.cbxMaintainValue); + this.Controls.Add(this.lblMessage); + this.Controls.Add(this.btnRemoveFromList); + this.Controls.Add(this.btnSet); + this.Controls.Add(this.tbxSetValue); + this.Controls.Add(this.lblSearchText); + this.Controls.Add(this.lvFound); + this.Controls.Add(this.pbScanProgress); + this.Controls.Add(this.btnAddToList); + this.Controls.Add(this.btnSearch); + this.Controls.Add(this.tbxSearchValue); + this.Controls.Add(this.btnReloadProcesses); + this.Controls.Add(this.ddlProcesses); + this.Name = "MainForm"; + this.Text = "AutoPoke"; + this.gbNewSearch.ResumeLayout(false); + this.gbNewSearch.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ComboBox ddlProcesses; + private System.Windows.Forms.Button btnReloadProcesses; + private System.Windows.Forms.TextBox tbxSearchValue; + private System.Windows.Forms.Button btnSearch; + private System.Windows.Forms.Button btnAddToList; + private System.ComponentModel.BackgroundWorker bwMemoryScan; + private System.Windows.Forms.ProgressBar pbScanProgress; + private System.Windows.Forms.ListView lvFound; + private System.Windows.Forms.Label lblSearchText; + private System.Windows.Forms.TextBox tbxSetValue; + private System.Windows.Forms.Button btnSet; + private System.Windows.Forms.ColumnHeader chTitle; + private System.Windows.Forms.ColumnHeader chValue; + private System.Windows.Forms.Button btnRemoveFromList; + private System.Windows.Forms.ColumnHeader chAddress; + private System.Windows.Forms.Timer refreshTimer; + private System.Windows.Forms.Label lblMessage; + private System.Windows.Forms.ColumnHeader chMaintainValue; + private System.Windows.Forms.CheckBox cbxMaintainValue; + private System.Windows.Forms.ColumnHeader chTypeName; + private System.Windows.Forms.Button btnTest; + private System.Windows.Forms.ListView lvSearches; + private System.Windows.Forms.ColumnHeader chSearchTitle; + private System.Windows.Forms.ColumnHeader chSearchValue; + private System.Windows.Forms.ColumnHeader chSearchLocations; + private System.Windows.Forms.ColumnHeader chSearchType; + private System.Windows.Forms.GroupBox gbNewSearch; + private System.Windows.Forms.Label lblSearchType; + private System.Windows.Forms.ComboBox ddlSearchType; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.TextBox tbxTitle; + private System.Windows.Forms.Button btnSearchRemove; + private System.Windows.Forms.Button btnAddSearch; + private System.Windows.Forms.CheckBox cbxPresumeAlignment; + private System.Windows.Forms.TextBox tbxDelta; + private System.Windows.Forms.Label lblDelta; + private System.Windows.Forms.ToolTip toolTip; + private System.Windows.Forms.ToolTip toolTipError; + } +} + diff --git a/AutoPoke/MainForm.cs b/AutoPoke/MainForm.cs new file mode 100644 index 0000000..4652b36 --- /dev/null +++ b/AutoPoke/MainForm.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Threading; +using System.Media; +using Luaan.AutoPoke.SearchTypes; +using System.Reflection; +using System.Globalization; + +namespace Luaan.AutoPoke +{ + public partial class MainForm : Form + { + /// + /// Initializes a new instance of the class. + /// + public MainForm() + { + InitializeComponent(); + + bwMemoryScan.DoWork += new DoWorkEventHandler(bwMemoryScan_DoWork); + bwMemoryScan.ProgressChanged += new ProgressChangedEventHandler(bwMemoryScan_ProgressChanged); + + ddlSearchType.SelectedIndex = 0; + } + + void bwMemoryScan_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + pbScanProgress.Value = Math.Max(Math.Min(e.ProgressPercentage, 100), 0); + if (e.UserState != null) + lblMessage.Text = e.UserState as string; + else + lblMessage.Text = "Working..."; + } + + Dictionary processes; + + void bwMemoryScan_DoWork(object sender, DoWorkEventArgs e) + { + try + { + var search = e.Argument as SearchEngine; + + search.Search(); + + if (search.LocationCount == 0) + Invoke(new ThreadStart(() => { lvSearches.Items.Remove(lvSearches.SelectedItems[0]); })); + } + finally + { + Invoke(new ThreadStart(UpdateSearches)); + } + } + + void UpdateSearches() + { + if (lvSearches.SelectedItems.Count > 0) + { + var lvi = lvSearches.SelectedItems[0]; + var engine = lvi.Tag as SearchEngine; + + lvi.SubItems[1].Text = engine.SearchData.GetText(); + lvi.SubItems[3].Text = engine.LocationCount.ToString(); + } + + Cursor = Cursors.Default; + btnSearch.Enabled = true; + lvSearches.Enabled = true; + } + + string GetProcessName(Process p) + { + bool isDotNet = false; + + try + { + if (p.Modules.OfType().Any(i => i.ModuleName.ToLower() == "mscoree.dll")) + isDotNet = true; + } + catch {} + + return string.Format("{0} ({1})", p.MainWindowTitle, p.Id) + (isDotNet ? " - .NET" : string.Empty); + } + + private void btnReloadProcesses_Click(object sender, EventArgs e) + { + processes = Process.GetProcesses().Where(i => i.MainWindowHandle != IntPtr.Zero).ToDictionary(i => i.Id); + + ddlProcesses.DataSource = processes.Select(i => new ProcessListItem { Text = GetProcessName(i.Value), Id = i.Key }).ToList(); + } + + private void btnSearch_Click(object sender, EventArgs e) + { + if (bwMemoryScan.IsBusy) + { + toolTipError.Show("A search is alread underway. You have to wait for it to finish.", btnSearch, 1000); + + return; + } + + if (lvSearches.SelectedItems.Count == 0) + { + toolTipError.Show("You have to select a search item to search a value of.", lvSearches, 1000); + + return; + } + + var engine = lvSearches.SelectedItems[0].Tag as SearchEngine; + + SearchBase searchData; + + try + { + switch (engine.SearchType) + { + case "ΔSingle": searchData = new SingleSearch(tbxSearchValue.Text, float.Parse(tbxDelta.Text.Replace(",", "."), CultureInfo.InvariantCulture)); break; + case "ΔDouble": searchData = new DoubleSearch(tbxSearchValue.Text, double.Parse(tbxDelta.Text.Replace(",", "."), CultureInfo.InvariantCulture)); break; + case "ΔInt32": searchData = new Int32DeltaSearch(tbxSearchValue.Text, int.Parse(tbxDelta.Text)); break; + case "Int16": searchData = new Int16Search(tbxSearchValue.Text); break; + case "Int32": + default: + searchData = new Int32Search(tbxSearchValue.Text); break; + } + } + catch (Exception ex) + { + toolTipError.Show(ex.Message, tbxSearchValue, 2000); + + return; + } + + engine.SearchData = searchData; + engine.PresumeAlignment = cbxPresumeAlignment.Checked; + + btnSearch.Enabled = false; + + bwMemoryScan.RunWorkerAsync(engine); + + Cursor = Cursors.WaitCursor; + } + + private void btnAddToList_Click(object sender, EventArgs e) + { + if (lvSearches.SelectedItems.Count == 0) + { + toolTipError.Show("You have to select the search item you want to add to the data item list.", lvSearches, 1000); + + return; + } + + SearchEngine engine = lvSearches.SelectedItems[0].Tag as SearchEngine; + + ScanResultInformation sri = engine.GetResults(); + + var group = lvFound.Groups.OfType().Where(i => (int)i.Tag == sri.ParentProcess.Id).FirstOrDefault(); + + if (group == null) + lvFound.Groups.Add(group = new ListViewGroup(sri.ParentProcess.MainWindowTitle + " (" + sri.ParentProcess.Id.ToString() + ")") { Tag = sri.ParentProcess.Id }); + + ListViewItem lvi = new ListViewItem(); + lvi.Group = group; + lvi.Text = engine.Name; + lvi.SubItems.Add(sri.Value.ToString()); + lvi.SubItems.Add(string.Join(", ", sri.MemoryPointers.Select(i => "0x" + i.ToInt32().ToString("X8")).ToArray())); + lvi.SubItems.Add(sri.MaintainValue.ToString()); + lvi.SubItems.Add(sri.Value.TypeName); + + lvi.Tag = sri; + lvFound.Items.Add(lvi); + + lvSearches.Items.Remove(lvSearches.SelectedItems[0]); + } + + private void btnSet_Click(object sender, EventArgs e) + { + if (lvFound.SelectedItems.Count == 0) + { + toolTipError.Show("You have to select the data item you want to change the value of.", lvFound, 1000); + + return; + } + + ScanResultInformation sri = lvFound.SelectedItems[0].Tag as ScanResultInformation; + + if (sri.ParentProcess.HasExited) + { + lvFound.Items.Remove(lvFound.SelectedItems[0]); + return; + } + + try + { + sri.Value = sri.Value.ChangeValue(tbxSetValue.Text); + Write(sri); + } + catch (Exception ex) + { + toolTipError.Show(ex.Message, tbxSetValue, 2000); + } + } + + void Write(ScanResultInformation sri) + { + uint bytesWritten; + + foreach (var ptr in sri.MemoryPointers) + PInvoke.WriteProcessMemory(sri.ParentProcess.Handle.ToInt32(), ptr.ToInt32(), sri.Value.GetBytes(), (uint)sri.Value.Length, out bytesWritten); + } + + private void lvFound_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) + { + btnRemoveFromList.Enabled = btnSet.Enabled = cbxMaintainValue.Enabled = lvFound.SelectedItems.Count > 0; + + if (lvFound.SelectedItems.Count > 0) + { + cbxMaintainValue.Checked = (lvFound.SelectedItems[0].Tag as ScanResultInformation).MaintainValue; + } + } + + void RefreshValues() + { + for (int i = 0; i < lvFound.Items.Count; i++) + { + var item = lvFound.Items[i]; + var sri = item.Tag as ScanResultInformation; + + if (sri.ParentProcess.HasExited) + { + lvFound.Items.Remove(item); + i--; + continue; + } + + byte[] buf = new byte[sri.Value.Length]; + int bytesRead = 0; + + PInvoke.ReadProcessMemory(sri.ParentProcess.Handle, sri.MemoryPointers[0], buf, buf.Length, out bytesRead); + + var newValue = sri.Value.ChangeValue(buf); + + if (sri.MaintainValue && !sri.Value.Equals(newValue)) + { + Write(sri); + } + else + item.SubItems[1].Text = newValue.GetText(); + } + } + + private void tbxSearchValue_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + btnSearch.PerformClick(); + } + + private void tbxTitle_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + btnAddSearch.PerformClick(); + } + + private void btnRemoveFromList_Click(object sender, EventArgs e) + { + if (lvFound.SelectedItems.Count > 0) + lvFound.Items.Remove(lvFound.SelectedItems[0]); + else + toolTipError.Show("You have to select the data item you want to remove.", lvFound, 1000); + } + + private void refreshTimer_Tick(object sender, EventArgs e) + { + RefreshValues(); + } + + private void cbxMaintainValue_CheckedChanged(object sender, EventArgs e) + { + if (lvFound.SelectedItems.Count == 0) + { + toolTipError.Show("You have to select the data item you want to maintain value of.", lvFound, 1000); + + return; + } + + ScanResultInformation sri = lvFound.SelectedItems[0].Tag as ScanResultInformation; + sri.MaintainValue = cbxMaintainValue.Checked; + lvFound.SelectedItems[0].SubItems[3].Text = sri.MaintainValue.ToString(); + } + + private void btnTest_Click(object sender, EventArgs e) + { + + } + + private void btnAddSearch_Click(object sender, EventArgs e) + { + if (ddlProcesses.SelectedItem == null) + { + toolTipError.Show("You have to select a process from the dropdown control.", ddlProcesses, 1000); + + return; + } + + + SearchEngine engine = new SearchEngine(processes[((ProcessListItem)ddlProcesses.SelectedItem).Id], ddlSearchType.SelectedItem as string); + engine.ReportProgress += new ProgressChangedEventHandler((s, args) => { bwMemoryScan.ReportProgress(args.ProgressPercentage, args.UserState); }); + + var group = lvSearches.Groups.OfType().Where(i => (int)i.Tag == engine.Process.Id).FirstOrDefault(); + + if (group == null) + lvSearches.Groups.Add(group = new ListViewGroup(engine.Process.MainWindowTitle + " (" + engine.Process.Id.ToString() + ")") { Tag = engine.Process.Id }); + + ListViewItem lvi = new ListViewItem(); + lvi.Group = group; + lvi.Text = engine.Name = tbxTitle.Text; + lvi.SubItems.Add(string.Empty); + lvi.SubItems.Add(engine.SearchType); + lvi.SubItems.Add(string.Empty); + lvi.Tag = engine; + + lvSearches.Items.Add(lvi); + } + + private void btnSearchRemove_Click(object sender, EventArgs e) + { + if (lvSearches.SelectedItems.Count == 0) + { + toolTipError.Show("You have to select a search item to remove.", lvSearches, 1000); + + return; + } + + lvSearches.Items.Remove(lvSearches.SelectedItems[0]); + } + + private void tbxSetValue_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + btnSet.PerformClick(); + } + } +} diff --git a/AutoPoke/MainForm.resx b/AutoPoke/MainForm.resx new file mode 100644 index 0000000..aec50f4 --- /dev/null +++ b/AutoPoke/MainForm.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 276, 17 + + + 17, 17 + + + 156, 17 + + + If checked, the search engine expects the values to be aligned, eg. 32 bit integers will always be on addresses of a multiple of 4. +This is much faster than searching for unaligned data, but isn't always guaranteed to return all the search results. +If you can't find the value you are looking for, try unchecking this option. + + + Represents the allowed variation from the value being searched (ie. searching for 12 with a delta of 1 will return all values in the range of 11-13). +Only useable with types that start with Δ (delta) values (ΔSingle, ΔDouble, ΔInt32). + + + 366, 17 + + + 48 + + \ No newline at end of file diff --git a/AutoPoke/PInvoke.cs b/AutoPoke/PInvoke.cs new file mode 100644 index 0000000..932e254 --- /dev/null +++ b/AutoPoke/PInvoke.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +namespace Luaan.AutoPoke +{ + public class PInvoke + { + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool ReadProcessMemory( + IntPtr hProcess, + IntPtr lpBaseAddress, + [Out] byte[] lpBuffer, + int dwSize, + out int lpNumberOfBytesRead + ); + + [DllImport("kernel32.dll")] + public static extern int VirtualQueryEx(int hProcess, int lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, uint nSize, out uint lpNumberOfBytesWritten); + } + + public struct MEMORY_BASIC_INFORMATION + { + public uint BaseAddress; + public uint AllocationBase; + public AllocationProtectEnum AllocationProtect; + public uint RegionSize; + public StateEnum State; + public AllocationProtectEnum Protect; + public TypeEnum Type; + } + + public enum AllocationProtectEnum : uint + { + PAGE_EXECUTE = 0x00000010, + PAGE_EXECUTE_READ = 0x00000020, + PAGE_EXECUTE_READWRITE = 0x00000040, + PAGE_EXECUTE_WRITECOPY = 0x00000080, + PAGE_NOACCESS = 0x00000001, + PAGE_READONLY = 0x00000002, + PAGE_READWRITE = 0x00000004, + PAGE_WRITECOPY = 0x00000008, + PAGE_GUARD = 0x00000100, + PAGE_NOCACHE = 0x00000200, + PAGE_WRITECOMBINE = 0x00000400 + } + + public enum StateEnum : uint + { + MEM_COMMIT = 0x1000, + MEM_FREE = 0x10000, + MEM_RESERVE = 0x2000 + } + + public enum TypeEnum : uint + { + MEM_IMAGE = 0x1000000, + MEM_MAPPED = 0x40000, + MEM_PRIVATE = 0x20000 + } +} diff --git a/AutoPoke/PageInfo.cs b/AutoPoke/PageInfo.cs new file mode 100644 index 0000000..49bea13 --- /dev/null +++ b/AutoPoke/PageInfo.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Luaan.AutoPoke +{ + public class PageInfo + { + public long PageStart { get; set; } + public long PageEnd { get; set; } + } +} diff --git a/AutoPoke/ProcessListItem.cs b/AutoPoke/ProcessListItem.cs new file mode 100644 index 0000000..5b209aa --- /dev/null +++ b/AutoPoke/ProcessListItem.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Luaan.AutoPoke +{ + public class ProcessListItem + { + public int Id { get; set; } + public string Text { get; set; } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return Text; + } + } +} diff --git a/AutoPoke/Program.cs b/AutoPoke/Program.cs new file mode 100644 index 0000000..c20062a --- /dev/null +++ b/AutoPoke/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace Luaan.AutoPoke +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/AutoPoke/Properties/AssemblyInfo.cs b/AutoPoke/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fa73bb6 --- /dev/null +++ b/AutoPoke/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AutoPoke")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Luaan")] +[assembly: AssemblyProduct("AutoPoke")] +[assembly: AssemblyCopyright("Copyright © Luaan 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1dda8721-1c0e-42ae-bf7d-413215945167")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AutoPoke/Properties/Resources.Designer.cs b/AutoPoke/Properties/Resources.Designer.cs new file mode 100644 index 0000000..5831d55 --- /dev/null +++ b/AutoPoke/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18052 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Luaan.AutoPoke.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("Luaan.AutoPoke.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; + } + } + } +} diff --git a/AutoPoke/Properties/Resources.resx b/AutoPoke/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/AutoPoke/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AutoPoke/Properties/Settings.Designer.cs b/AutoPoke/Properties/Settings.Designer.cs new file mode 100644 index 0000000..aa6c1bd --- /dev/null +++ b/AutoPoke/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18052 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Luaan.AutoPoke.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.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/AutoPoke/Properties/Settings.settings b/AutoPoke/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/AutoPoke/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/AutoPoke/ScanResultInformation.cs b/AutoPoke/ScanResultInformation.cs new file mode 100644 index 0000000..01308f3 --- /dev/null +++ b/AutoPoke/ScanResultInformation.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics; +using Luaan.AutoPoke.SearchTypes; + +namespace Luaan.AutoPoke +{ + public class ScanResultInformation + { + public Process ParentProcess { get; set; } + public IntPtr[] MemoryPointers { get; set; } + + public SearchBase Value { get; set; } + public bool MaintainValue { get; set; } + } +} diff --git a/AutoPoke/SearchEngine.cs b/AutoPoke/SearchEngine.cs new file mode 100644 index 0000000..1c693d8 --- /dev/null +++ b/AutoPoke/SearchEngine.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics; +using Luaan.AutoPoke.SearchTypes; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Threading; +using System.Media; +using System.Threading.Tasks; + +namespace Luaan.AutoPoke +{ + public class SearchEngine + { + bool firstSearchDone = false; + Process lockedProcess; + List locations = new List(); + int lastLocationCount = 0; + + public int LocationCount { get { return this.locations.Count; } } + public Process Process { get { return this.lockedProcess; } } + public string SearchType { get; private set; } + public bool PresumeAlignment { get; set; } + + public ScanResultInformation GetResults() + { + ScanResultInformation sri = new ScanResultInformation(); + sri.ParentProcess = lockedProcess; + sri.MemoryPointers = locations.ToArray(); + sri.Value = SearchData; + + return sri; + } + + public SearchEngine(Process process, string searchType) + { + this.lockedProcess = process; + this.SearchType = searchType; + } + + public string Name { get; set; } + public SearchBase SearchData { get; set; } + + public event ProgressChangedEventHandler ReportProgress; + + public void Search() + { + if (firstSearchDone) + FilterSearch(); + else + InitialSearch(); + } + + List FindAllPages() + { + List pages = new List(); + + MEMORY_BASIC_INFORMATION m; + long MaxAddress = uint.MaxValue;// 0x7fffffffffffffffL; + long address = 0; + + do + { + int result = PInvoke.VirtualQueryEx(lockedProcess.Handle.ToInt32(), (int)address, out m, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))); + + if (m.RegionSize != 0) + pages.Add(new PageInfo { PageStart = (long)m.BaseAddress, PageEnd = (long)(m.BaseAddress + m.RegionSize - 1) }); + + if (address == (long)m.BaseAddress + m.RegionSize) + break; + + address = (long)m.BaseAddress + m.RegionSize; + } + while (address <= MaxAddress); + + return pages; + } + + void ScanPage(long start, long end, SearchBase searchData) + { + byte[] buf = new byte[Math.Max(Math.Min(unchecked(end - start), 65536), 0)]; + int bytesRead = 0; + long currentPtr = start; + + int alignment = PresumeAlignment ? searchData.Alignment : 1; + + while (currentPtr < end) + { + // Ignore handles over x86 + if (currentPtr + buf.Length > int.MaxValue) + break; + + if (PInvoke.ReadProcessMemory(lockedProcess.Handle, new IntPtr(currentPtr), buf, buf.Length, out bytesRead)) + { + for (int i = 0; i < bytesRead - searchData.Length; i += alignment) + { + bool ok = searchData.Find(buf, i); + + if (ok) + locations.Add(new IntPtr(currentPtr + i)); + } + } + + currentPtr += (long)(buf.Length - searchData.Length); + } + } + + public void OnReportProgress(int progress, object userState) + { + if (ReportProgress != null) + ReportProgress(this, new ProgressChangedEventArgs(progress, userState)); + } + + void InitialSearch() + { + Stopwatch sw = Stopwatch.StartNew(); + + locations.Clear(); + + // First search + var pages = FindAllPages(); + + long bytesCurrent = 0; + long bytesTotal = pages.Sum(i => i.PageEnd - i.PageStart); + + Parallel.ForEach(pages, page => + //pages.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism).WithDegreeOfParallelism(16).ForAll(page => + { + ScanPage(page.PageStart, page.PageEnd, SearchData); + + Interlocked.Add(ref bytesCurrent, page.PageEnd - page.PageStart); + + OnReportProgress((int)((bytesCurrent * 100) / bytesTotal), null); + }); + + sw.Stop(); + + SystemSounds.Beep.Play(); + OnReportProgress(100, string.Format("Found {0} occurences in {1:f2} s.", locations.Count, (float)sw.ElapsedMilliseconds / 1000f)); + + firstSearchDone = true; + } + + void FilterSearch() + { + OnReportProgress(0, null); + + byte[] buf = new byte[SearchData.Length]; + int bytesRead = 0; + + List oldLocations = locations; + locations = new List(); + + int lastPerc = 0; + + // Go through all the past occurences + for (int idx = 0; idx < oldLocations.Count; idx++) + { + IntPtr locPtr = oldLocations[idx]; + + if (PInvoke.ReadProcessMemory(lockedProcess.Handle, locPtr, buf, buf.Length, out bytesRead)) + { + bool ok = SearchData.Find(buf, 0); + + if (ok) + { + locations.Add(locPtr); + continue; + } + } + + int percComplete = (idx * 100) / oldLocations.Count; + + if (percComplete != lastPerc) + { + OnReportProgress(percComplete, null); + lastPerc = percComplete; + } + } + + SystemSounds.Beep.Play(); + OnReportProgress(100, string.Format("{0} occurences remaining.", locations.Count)); + + lastLocationCount = locations.Count; + } + } +} diff --git a/AutoPoke/SearchTypes/DecimalSearch.cs b/AutoPoke/SearchTypes/DecimalSearch.cs new file mode 100644 index 0000000..e98041d --- /dev/null +++ b/AutoPoke/SearchTypes/DecimalSearch.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Globalization; + +namespace Luaan.AutoPoke.SearchTypes +{ + public class DecimalSearch : SearchBase + { + decimal originalValue; + decimal delta; + byte[] searchBytes; + decimal decimalPoint = 1M; + + public DecimalSearch(string searchText, decimal delta) : base(searchText) + { + this.originalValue = decimal.Parse(searchText.Replace(",", "."), CultureInfo.InvariantCulture); + this.delta = delta; + } + + public DecimalSearch(byte[] bytes, decimal delta) : base(bytes) + { + this.searchBytes = (byte[])bytes.Clone(); + this.originalValue = BitConverter.ToInt32(this.searchBytes, 0); + this.delta = delta; + } + + public override int Alignment + { + get { return 4; } + } + + public override int Length + { + get { return 4; } + } + + public override string TypeName + { + get { return "Single"; } + } + + public override string GetText() + { + return this.originalValue.ToString(); + } + + public override byte[] GetBytes() + { + if (this.searchBytes != null) + return this.searchBytes; + else + return this.searchBytes = BitConverter.GetBytes((int)(originalValue * decimalPoint)); + } + + public override bool Find(byte[] buf, int offset) + { + if (buf.Length - offset < Length) + return false; + + var pomValue = BitConverter.ToInt32(buf, offset); + + return Math.Abs((pomValue * decimalPoint) - originalValue) < delta; + } + + public override SearchBase ChangeValue(string searchText) + { + return new DecimalSearch(searchText, delta); + } + + public override SearchBase ChangeValue(byte[] bytes) + { + return new DecimalSearch(bytes, delta); + } + + public override bool Equals(SearchBase other) + { + if (!(other is DecimalSearch)) + return false; + + return Math.Abs(originalValue - (other as DecimalSearch).originalValue) < delta; + } + } +} diff --git a/AutoPoke/SearchTypes/DoubleSearch.cs b/AutoPoke/SearchTypes/DoubleSearch.cs new file mode 100644 index 0000000..264a24f --- /dev/null +++ b/AutoPoke/SearchTypes/DoubleSearch.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Luaan.AutoPoke.SearchTypes +{ + public class DoubleSearch : SearchBase + { + double originalValue; + double delta; + byte[] searchBytes; + + /// + /// Initializes a new instance of the class. + /// + /// The search text. + /// The delta. + public DoubleSearch(string searchText, double delta) : base(searchText) + { + this.originalValue = double.Parse(searchText.Replace(",", "."), CultureInfo.InvariantCulture); + this.searchBytes = BitConverter.GetBytes(this.originalValue); + this.delta = delta; + } + + /// + /// Initializes a new instance of the class. + /// + /// The bytes. + /// The delta. + public DoubleSearch(byte[] bytes, double delta) : base(bytes) + { + this.searchBytes = (byte[])bytes.Clone(); + this.originalValue = BitConverter.ToDouble(this.searchBytes, 0); + this.delta = delta; + } + + /// + /// Gets the memory alignment of this type. + /// + public override int Alignment + { + get { return 4; } + } + + /// + /// Gets the length of this type (if applicable). + /// + public override int Length + { + get { return 8; } + } + + /// + /// Gets the name of the type. + /// + /// + /// The name of the type. + /// + public override string TypeName + { + get { return "ΔDouble"; } + } + + /// + /// Gets the textual representation of the search value. + /// + /// + public override string GetText() + { + return this.originalValue.ToString(); + } + + /// + /// Gets the in-memory byte representation of the search value. + /// + /// + public override byte[] GetBytes() + { + return this.searchBytes; + } + + /// + /// Tries to find the search value in the specified byte array, starting at the specified offset. + /// + /// The buf. + /// The offset. + /// + public override bool Find(byte[] buf, int offset) + { + if (buf.Length - offset < Length) + return false; + + var pomValue = BitConverter.ToDouble(buf, offset); + + return Math.Abs(pomValue - originalValue) <= delta; + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The search text. + /// + public override SearchBase ChangeValue(string searchText) + { + return new DoubleSearch(searchText, delta); + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The bytes. + /// + public override SearchBase ChangeValue(byte[] bytes) + { + return new DoubleSearch(bytes, delta); + } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// An object to compare with this object. + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public override bool Equals(SearchBase other) + { + if (!(other is DoubleSearch)) + return false; + + return Math.Abs(originalValue - (other as DoubleSearch).originalValue) <= delta; + } + } +} diff --git a/AutoPoke/SearchTypes/Int16Search.cs b/AutoPoke/SearchTypes/Int16Search.cs new file mode 100644 index 0000000..571ded9 --- /dev/null +++ b/AutoPoke/SearchTypes/Int16Search.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Luaan.AutoPoke.SearchTypes +{ + public class Int16Search : SearchBase + { + short originalValue; + byte[] searchBytes; + + /// + /// Initializes a new instance of the class. + /// + /// The search text. + public Int16Search(string searchText) : base(searchText) + { + this.originalValue = short.Parse(searchText); + this.searchBytes = BitConverter.GetBytes(this.originalValue); + } + + /// + /// Initializes a new instance of the class. + /// + /// The bytes. + public Int16Search(byte[] bytes) : base(bytes) + { + this.searchBytes = (byte[])bytes.Clone(); + this.originalValue = BitConverter.ToInt16(this.searchBytes, 0); + } + + /// + /// Gets the memory alignment of this type. + /// + public override int Alignment + { + get { return 2; } + } + + /// + /// Gets the length of this type (if applicable). + /// + public override int Length + { + get { return 2; } + } + + /// + /// Gets the name of the type. + /// + /// + /// The name of the type. + /// + public override string TypeName + { + get { return "Int16"; } + } + + /// + /// Gets the textual representation of the search value. + /// + /// + public override string GetText() + { + return this.originalValue.ToString(); + } + + /// + /// Gets the in-memory byte representation of the search value. + /// + /// + public override byte[] GetBytes() + { + return this.searchBytes; + } + + /// + /// Tries to find the search value in the specified byte array, starting at the specified offset. + /// + /// The buf. + /// The offset. + /// + public override bool Find(byte[] buf, int offset) + { + if (buf.Length - offset < 2) + return false; + + for (int j = 0; j < searchBytes.Length; j++) + if (buf[offset + j] != searchBytes[j]) + return false; + + return true; + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The search text. + /// + public override SearchBase ChangeValue(string searchText) + { + return new Int16Search(searchText); + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The bytes. + /// + public override SearchBase ChangeValue(byte[] bytes) + { + return new Int16Search(bytes); + } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// An object to compare with this object. + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public override bool Equals(SearchBase other) + { + if (!(other is Int16Search)) + return false; + + return originalValue == (other as Int16Search).originalValue; + } + } +} diff --git a/AutoPoke/SearchTypes/Int32DeltaSearch.cs b/AutoPoke/SearchTypes/Int32DeltaSearch.cs new file mode 100644 index 0000000..e19a394 --- /dev/null +++ b/AutoPoke/SearchTypes/Int32DeltaSearch.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +namespace Luaan.AutoPoke.SearchTypes +{ + public class Int32DeltaSearch : SearchBase + { + int originalValue; + int delta; + byte[] searchBytes; + + /// + /// Initializes a new instance of the class. + /// + /// The search text. + /// The delta. + public Int32DeltaSearch(string searchText, int delta) : base(searchText) + { + this.originalValue = int.Parse(searchText); + this.searchBytes = BitConverter.GetBytes(this.originalValue); + this.delta = delta; + } + + /// + /// Initializes a new instance of the class. + /// + /// The bytes. + /// The delta. + public Int32DeltaSearch(byte[] bytes, int delta) : base(bytes) + { + this.searchBytes = (byte[])bytes.Clone(); + this.originalValue = BitConverter.ToInt32(this.searchBytes, 0); + this.delta = delta; + } + + /// + /// Gets the memory alignment of this type. + /// + public override int Alignment + { + get { return 4; } + } + + /// + /// Gets the length of this type (if applicable). + /// + public override int Length + { + get { return 4; } + } + + /// + /// Gets the name of the type. + /// + /// + /// The name of the type. + /// + public override string TypeName + { + get { return "ΔInt32"; } + } + + /// + /// Gets the textual representation of the search value. + /// + /// + public override string GetText() + { + return this.originalValue.ToString(); + } + + /// + /// Gets the in-memory byte representation of the search value. + /// + /// + public override byte[] GetBytes() + { + return this.searchBytes; + } + + /// + /// Tries to find the search value in the specified byte array, starting at the specified offset. + /// + /// The buf. + /// The offset. + /// + public override bool Find(byte[] buf, int offset) + { + if (buf.Length - offset < Length) + return false; + + long pomValue = BitConverter.ToInt32(buf, offset); + + return Math.Abs(unchecked(pomValue - originalValue)) <= delta; + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The search text. + /// + public override SearchBase ChangeValue(string searchText) + { + return new Int32DeltaSearch(searchText, delta); + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The bytes. + /// + public override SearchBase ChangeValue(byte[] bytes) + { + return new Int32DeltaSearch(bytes, delta); + } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// An object to compare with this object. + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public override bool Equals(SearchBase other) + { + if (!(other is Int32DeltaSearch)) + return false; + + return Math.Abs(unchecked((long)originalValue - (other as Int32DeltaSearch).originalValue)) <= delta; + } + } +} diff --git a/AutoPoke/SearchTypes/Int32Search.cs b/AutoPoke/SearchTypes/Int32Search.cs new file mode 100644 index 0000000..9af651f --- /dev/null +++ b/AutoPoke/SearchTypes/Int32Search.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using System.Diagnostics; + +namespace Luaan.AutoPoke.SearchTypes +{ + public class Int32Search : SearchBase + { + int originalValue; + byte[] searchBytes; + + /// + /// Initializes a new instance of the class. + /// + /// The search text. + public Int32Search(string searchText) : base(searchText) + { + this.originalValue = int.Parse(searchText); + this.searchBytes = BitConverter.GetBytes(this.originalValue); + } + + /// + /// Initializes a new instance of the class. + /// + /// The bytes. + public Int32Search(byte[] bytes) : base(bytes) + { + this.searchBytes = (byte[])bytes.Clone(); + this.originalValue = BitConverter.ToInt32(this.searchBytes, 0); + } + + /// + /// Gets the memory alignment of this type. + /// + public override int Alignment + { + get { return 4; } + } + + /// + /// Gets the length of this type (if applicable). + /// + public override int Length + { + get { return 4; } + } + + /// + /// Gets the name of the type. + /// + /// + /// The name of the type. + /// + public override string TypeName + { + get { return "Int32"; } + } + + /// + /// Gets the textual representation of the search value. + /// + /// + public override string GetText() + { + return this.originalValue.ToString(); + } + + /// + /// Gets the in-memory byte representation of the search value. + /// + /// + public override byte[] GetBytes() + { + return this.searchBytes; + } + + /// + /// Tries to find the search value in the specified byte array, starting at the specified offset. + /// + /// The buf. + /// The offset. + /// + public override bool Find(byte[] buf, int offset) + { + if (buf.Length - offset < Length) + return false; + + for (int j = 0; j < searchBytes.Length; j++) + if (buf[offset + j] != searchBytes[j]) + return false; + + return true; + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The search text. + /// + public override SearchBase ChangeValue(string searchText) + { + return new Int32Search(searchText); + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The bytes. + /// + public override SearchBase ChangeValue(byte[] bytes) + { + return new Int32Search(bytes); + } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// An object to compare with this object. + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public override bool Equals(SearchBase other) + { + if (!(other is Int32Search)) + return false; + + return originalValue == (other as Int32Search).originalValue; + } + } +} diff --git a/AutoPoke/SearchTypes/SearchBase.cs b/AutoPoke/SearchTypes/SearchBase.cs new file mode 100644 index 0000000..f1a0f19 --- /dev/null +++ b/AutoPoke/SearchTypes/SearchBase.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Luaan.AutoPoke.SearchTypes +{ + public abstract class SearchBase : IEquatable + { + public SearchBase(string searchText) { } + public SearchBase(byte[] bytes) { } + + /// + /// Gets the memory alignment of this type. + /// + public abstract int Alignment { get; } + /// + /// Gets the length of this type (if applicable). + /// + public abstract int Length { get; } + /// + /// Gets the name of the type. + /// + /// + /// The name of the type. + /// + public abstract string TypeName { get; } + + /// + /// Gets the textual representation of the search value. + /// + /// + public abstract string GetText(); + /// + /// Gets the in-memory byte representation of the search value. + /// + /// + public abstract byte[] GetBytes(); + /// + /// Tries to find the search value in the specified byte array, starting at the specified offset. + /// + /// The buf. + /// The offset. + /// + public abstract bool Find(byte[] buf, int offset); + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The search text. + /// + public abstract SearchBase ChangeValue(string searchText); + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The bytes. + /// + public abstract SearchBase ChangeValue(byte[] bytes); + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// An object to compare with this object. + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public abstract bool Equals(SearchBase other); + } +} diff --git a/AutoPoke/SearchTypes/SingleSearch.cs b/AutoPoke/SearchTypes/SingleSearch.cs new file mode 100644 index 0000000..4b783b4 --- /dev/null +++ b/AutoPoke/SearchTypes/SingleSearch.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Luaan.AutoPoke.SearchTypes +{ + public class SingleSearch : SearchBase + { + float originalValue; + float delta; + byte[] searchBytes; + + /// + /// Initializes a new instance of the class. + /// + /// The search text. + /// The delta. + public SingleSearch(string searchText, float delta) : base(searchText) + { + this.originalValue = float.Parse(searchText.Replace(",", "."), CultureInfo.InvariantCulture); + this.searchBytes = BitConverter.GetBytes(this.originalValue); + this.delta = delta; + } + + /// + /// Initializes a new instance of the class. + /// + /// The bytes. + /// The delta. + public SingleSearch(byte[] bytes, float delta) : base(bytes) + { + this.searchBytes = (byte[])bytes.Clone(); + this.originalValue = BitConverter.ToSingle(this.searchBytes, 0); + this.delta = delta; + } + + /// + /// Gets the memory alignment of this type. + /// + public override int Alignment + { + get { return 4; } + } + + /// + /// Gets the length of this type (if applicable). + /// + public override int Length + { + get { return 4; } + } + + /// + /// Gets the name of the type. + /// + /// + /// The name of the type. + /// + public override string TypeName + { + get { return "ΔSingle"; } + } + + /// + /// Gets the textual representation of the search value. + /// + /// + public override string GetText() + { + return this.originalValue.ToString(); + } + + /// + /// Gets the in-memory byte representation of the search value. + /// + /// + public override byte[] GetBytes() + { + return this.searchBytes; + } + + /// + /// Tries to find the search value in the specified byte array, starting at the specified offset. + /// + /// The buf. + /// The offset. + /// + public override bool Find(byte[] buf, int offset) + { + if (buf.Length - offset < Length) + return false; + + var pomValue = BitConverter.ToSingle(buf, offset); + + return Math.Abs(pomValue - originalValue) <= delta; + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The search text. + /// + public override SearchBase ChangeValue(string searchText) + { + return new SingleSearch(searchText, delta); + } + + /// + /// Returns a new identical instance of the search class with a different search value. + /// + /// The bytes. + /// + public override SearchBase ChangeValue(byte[] bytes) + { + return new SingleSearch(bytes, delta); + } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// An object to compare with this object. + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public override bool Equals(SearchBase other) + { + if (!(other is SingleSearch)) + return false; + + return Math.Abs(originalValue - (other as SingleSearch).originalValue) <= delta; + } + } +} diff --git a/AutoPoke/app.config b/AutoPoke/app.config new file mode 100644 index 0000000..e365603 --- /dev/null +++ b/AutoPoke/app.config @@ -0,0 +1,3 @@ + + +