diff --git a/Memory/Memory.csproj b/Memory/Memory.csproj
index c662c14..a0bf854 100644
--- a/Memory/Memory.csproj
+++ b/Memory/Memory.csproj
@@ -13,7 +13,7 @@
Read and Write to process memory. Make PC cheat trainers easily!
icon.png
LICENSE
- 1.2.21
+ 1.2.22
x64;x86
app.manifest
@@ -34,10 +34,6 @@
true
-
-
-
-
@@ -51,4 +47,8 @@
+
+
+
+
diff --git a/Memory/Methods/AoB.cs b/Memory/Methods/AoB.cs
new file mode 100644
index 0000000..f608b93
--- /dev/null
+++ b/Memory/Methods/AoB.cs
@@ -0,0 +1,319 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using static Memory.Imps;
+
+namespace Memory
+{
+ public partial class Mem
+ {
+ ///
+ /// Array of byte scan.
+ ///
+ /// array of bytes to search for, OR your ini code label.
+ /// Include writable addresses in scan
+ /// Include executable addresses in scan
+ /// ini file (OPTIONAL)
+ /// IEnumerable of all addresses found.
+ public Task> AoBScan(string search, bool writable = false, bool executable = true, string file = "")
+ {
+ return AoBScan(0, long.MaxValue, search, writable, executable, file);
+ }
+
+ ///
+ /// Array of byte scan.
+ ///
+ /// array of bytes to search for, OR your ini code label.
+ /// Include readable addresses in scan
+ /// Include writable addresses in scan
+ /// Include executable addresses in scan
+ /// ini file (OPTIONAL)
+ /// IEnumerable of all addresses found.
+ public Task> AoBScan(string search, bool readable, bool writable, bool executable, string file = "")
+ {
+ return AoBScan(0, long.MaxValue, search, readable, writable, executable, file);
+ }
+
+
+ ///
+ /// Array of Byte scan.
+ ///
+ /// Your starting address.
+ /// ending address
+ /// array of bytes to search for, OR your ini code label.
+ /// ini file (OPTIONAL)
+ /// Include writable addresses in scan
+ /// Include executable addresses in scan
+ /// IEnumerable of all addresses found.
+ public Task> AoBScan(long start, long end, string search, bool writable = false, bool executable = true, string file = "")
+ {
+ // Not including read only memory was scan behavior prior.
+ return AoBScan(start, end, search, false, writable, executable, file);
+ }
+
+ ///
+ /// Array of Byte scan.
+ ///
+ /// Your starting address.
+ /// ending address
+ /// array of bytes to search for, OR your ini code label.
+ /// ini file (OPTIONAL)
+ /// Include readable addresses in scan
+ /// Include writable addresses in scan
+ /// Include executable addresses in scan
+ /// IEnumerable of all addresses found.
+ public Task> AoBScan(long start, long end, string search, bool readable, bool writable, bool executable, string file = "")
+ {
+ return Task.Run(() =>
+ {
+ var memRegionList = new List();
+
+ string memCode = LoadCode(search, file);
+
+ string[] stringByteArray = memCode.Split(' ');
+
+ byte[] aobPattern = new byte[stringByteArray.Length];
+ byte[] mask = new byte[stringByteArray.Length];
+
+ for (var i = 0; i < stringByteArray.Length; i++)
+ {
+ string ba = stringByteArray[i];
+
+ if (ba == "??" || (ba.Length == 1 && ba == "?"))
+ {
+ mask[i] = 0x00;
+ stringByteArray[i] = "0x00";
+ }
+ else if (Char.IsLetterOrDigit(ba[0]) && ba[1] == '?')
+ {
+ mask[i] = 0xF0;
+ stringByteArray[i] = ba[0] + "0";
+ }
+ else if (Char.IsLetterOrDigit(ba[1]) && ba[0] == '?')
+ {
+ mask[i] = 0x0F;
+ stringByteArray[i] = "0" + ba[1];
+ }
+ else
+ mask[i] = 0xFF;
+ }
+
+
+ for (int i = 0; i < stringByteArray.Length; i++)
+ aobPattern[i] = (byte)(Convert.ToByte(stringByteArray[i], 16) & mask[i]);
+
+ SYSTEM_INFO sys_info = new SYSTEM_INFO();
+ GetSystemInfo(out sys_info);
+
+ UIntPtr proc_min_address = sys_info.minimumApplicationAddress;
+ UIntPtr proc_max_address = sys_info.maximumApplicationAddress;
+
+ if (start < (long)proc_min_address.ToUInt64())
+ start = (long)proc_min_address.ToUInt64();
+
+ if (end > (long)proc_max_address.ToUInt64())
+ end = (long)proc_max_address.ToUInt64();
+
+ Debug.WriteLine("[DEBUG] memory scan starting... (start:0x" + start.ToString(MSize()) + " end:0x" + end.ToString(MSize()) + " time:" + DateTime.Now.ToString("h:mm:ss tt") + ")");
+ UIntPtr currentBaseAddress = new UIntPtr((ulong)start);
+
+ MEMORY_BASIC_INFORMATION memInfo = new MEMORY_BASIC_INFORMATION();
+
+ //Debug.WriteLine("[DEBUG] start:0x" + start.ToString("X8") + " curBase:0x" + currentBaseAddress.ToUInt64().ToString("X8") + " end:0x" + end.ToString("X8") + " size:0x" + memInfo.RegionSize.ToString("X8") + " vAloc:" + VirtualQueryEx(mProc.Handle, currentBaseAddress, out memInfo).ToUInt64().ToString());
+
+ while (VirtualQueryEx(mProc.Handle, currentBaseAddress, out memInfo).ToUInt64() != 0 &&
+ currentBaseAddress.ToUInt64() < (ulong)end &&
+ currentBaseAddress.ToUInt64() + (ulong)memInfo.RegionSize >
+ currentBaseAddress.ToUInt64())
+ {
+ bool isValid = memInfo.State == MEM_COMMIT;
+ isValid &= memInfo.BaseAddress.ToUInt64() < (ulong)proc_max_address.ToUInt64();
+ isValid &= ((memInfo.Protect & PAGE_GUARD) == 0);
+ isValid &= ((memInfo.Protect & PAGE_NOACCESS) == 0);
+ isValid &= (memInfo.Type == MEM_PRIVATE) || (memInfo.Type == MEM_IMAGE);
+
+ if (isValid)
+ {
+ bool isReadable = (memInfo.Protect & PAGE_READONLY) > 0;
+
+ bool isWritable = ((memInfo.Protect & PAGE_READWRITE) > 0) ||
+ ((memInfo.Protect & PAGE_WRITECOPY) > 0) ||
+ ((memInfo.Protect & PAGE_EXECUTE_READWRITE) > 0) ||
+ ((memInfo.Protect & PAGE_EXECUTE_WRITECOPY) > 0);
+
+ bool isExecutable = ((memInfo.Protect & PAGE_EXECUTE) > 0) ||
+ ((memInfo.Protect & PAGE_EXECUTE_READ) > 0) ||
+ ((memInfo.Protect & PAGE_EXECUTE_READWRITE) > 0) ||
+ ((memInfo.Protect & PAGE_EXECUTE_WRITECOPY) > 0);
+
+ isReadable &= readable;
+ isWritable &= writable;
+ isExecutable &= executable;
+
+ isValid &= isReadable || isWritable || isExecutable;
+ }
+
+ if (!isValid)
+ {
+ currentBaseAddress = new UIntPtr(memInfo.BaseAddress.ToUInt64() + (ulong)memInfo.RegionSize);
+ continue;
+ }
+
+ MemoryRegionResult memRegion = new MemoryRegionResult
+ {
+ CurrentBaseAddress = currentBaseAddress,
+ RegionSize = memInfo.RegionSize,
+ RegionBase = memInfo.BaseAddress
+ };
+
+ currentBaseAddress = new UIntPtr(memInfo.BaseAddress.ToUInt64() + (ulong)memInfo.RegionSize);
+
+ //Console.WriteLine("SCAN start:" + memRegion.RegionBase.ToString() + " end:" + currentBaseAddress.ToString());
+
+ if (memRegionList.Count > 0)
+ {
+ var previousRegion = memRegionList[memRegionList.Count - 1];
+
+ if ((long)previousRegion.RegionBase + previousRegion.RegionSize == (long)memInfo.BaseAddress)
+ {
+ memRegionList[memRegionList.Count - 1] = new MemoryRegionResult
+ {
+ CurrentBaseAddress = previousRegion.CurrentBaseAddress,
+ RegionBase = previousRegion.RegionBase,
+ RegionSize = previousRegion.RegionSize + memInfo.RegionSize
+ };
+
+ continue;
+ }
+ }
+
+ memRegionList.Add(memRegion);
+ }
+
+ ConcurrentBag bagResult = new ConcurrentBag();
+
+ Parallel.ForEach(memRegionList,
+ (item, parallelLoopState, index) =>
+ {
+ long[] compareResults = CompareScan(item, aobPattern, mask);
+
+ foreach (long result in compareResults)
+ bagResult.Add(result);
+ });
+
+ Debug.WriteLine("[DEBUG] memory scan completed. (time:" + DateTime.Now.ToString("h:mm:ss tt") + ")");
+
+ return bagResult.ToList().OrderBy(c => c).AsEnumerable();
+ });
+ }
+
+ ///
+ /// Array of bytes scan
+ ///
+ /// Starting address or ini label
+ /// ending address
+ /// array of bytes to search for or your ini code label
+ /// ini file
+ /// First address found
+ public async Task AoBScan(string code, long end, string search, string file = "")
+ {
+ long start = (long)GetCode(code, file).ToUInt64();
+
+ return (await AoBScan(start, end, search, true, true, true, file)).FirstOrDefault();
+ }
+
+ private long[] CompareScan(MemoryRegionResult item, byte[] aobPattern, byte[] mask)
+ {
+ if (mask.Length != aobPattern.Length)
+ throw new ArgumentException($"{nameof(aobPattern)}.Length != {nameof(mask)}.Length");
+
+ IntPtr buffer = Marshal.AllocHGlobal((int)item.RegionSize);
+
+ ReadProcessMemory(mProc.Handle, item.CurrentBaseAddress, buffer, (UIntPtr)item.RegionSize, out ulong bytesRead);
+
+ int result = 0 - aobPattern.Length;
+ List ret = new List();
+ unsafe
+ {
+ do
+ {
+
+ result = FindPattern((byte*)buffer.ToPointer(), (int)bytesRead, aobPattern, mask, result + aobPattern.Length);
+
+ if (result >= 0)
+ ret.Add((long)item.CurrentBaseAddress + result);
+
+ } while (result != -1);
+ }
+
+ Marshal.FreeHGlobal(buffer);
+
+ return ret.ToArray();
+ }
+
+ private int FindPattern(byte[] body, byte[] pattern, byte[] masks, int start = 0)
+ {
+ int foundIndex = -1;
+
+ if (body.Length <= 0 || pattern.Length <= 0 || start > body.Length - pattern.Length ||
+ pattern.Length > body.Length) return foundIndex;
+
+ for (int index = start; index <= body.Length - pattern.Length; index++)
+ {
+ if (((body[index] & masks[0]) == (pattern[0] & masks[0])))
+ {
+ var match = true;
+ for (int index2 = 1; index2 <= pattern.Length - 1; index2++)
+ {
+ if ((body[index + index2] & masks[index2]) == (pattern[index2] & masks[index2])) continue;
+ match = false;
+ break;
+
+ }
+
+ if (!match) continue;
+
+ foundIndex = index;
+ break;
+ }
+ }
+
+ return foundIndex;
+ }
+
+ private unsafe int FindPattern(byte* body, int bodyLength, byte[] pattern, byte[] masks, int start = 0)
+ {
+ int foundIndex = -1;
+
+ if (bodyLength <= 0 || pattern.Length <= 0 || start > bodyLength - pattern.Length ||
+ pattern.Length > bodyLength) return foundIndex;
+
+ for (int index = start; index <= bodyLength - pattern.Length; index++)
+ {
+ if (((body[index] & masks[0]) == (pattern[0] & masks[0])))
+ {
+ var match = true;
+ for (int index2 = 1; index2 <= pattern.Length - 1; index2++)
+ {
+ if ((body[index + index2] & masks[index2]) == (pattern[index2] & masks[index2])) continue;
+ match = false;
+ break;
+
+ }
+
+ if (!match) continue;
+
+ foundIndex = index;
+ break;
+ }
+ }
+
+ return foundIndex;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Memory/Methods/Read.cs b/Memory/Methods/Read.cs
new file mode 100644
index 0000000..f1b01d2
--- /dev/null
+++ b/Memory/Methods/Read.cs
@@ -0,0 +1,369 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using static Memory.Imps;
+
+namespace Memory
+{
+ public partial class Mem
+ {
+ ///
+ /// Cut a string that goes on for too long or one that is possibly merged with another string.
+ ///
+ /// The string you want to cut.
+ ///
+ public string CutString(string str)
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (char c in str)
+ {
+ if (c >= ' ' && c <= '~')
+ sb.Append(c);
+ else
+ break;
+ }
+ return sb.ToString();
+ }
+
+ ///
+ /// Reads up to `length ` bytes from an address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// The maximum bytes to read.
+ /// path and name of ini file.
+ /// The bytes read or null
+ public byte[] ReadBytes(string code, long length, string file = "")
+ {
+ byte[] memory = new byte[length];
+ UIntPtr theCode = GetCode(code, file);
+
+ if (!ReadProcessMemory(mProc.Handle, theCode, memory, (UIntPtr)length, IntPtr.Zero))
+ return null;
+
+ return memory;
+ }
+
+ ///
+ /// Read a float value from an address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and name of ini file. (OPTIONAL)
+ /// Round the value to 2 decimal places
+ ///
+ public float ReadFloat(string code, string file = "", bool round = true)
+ {
+ byte[] memory = new byte[4];
+
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+ try
+ {
+ if (ReadProcessMemory(mProc.Handle, theCode, memory, (UIntPtr)4, IntPtr.Zero))
+ {
+ float address = BitConverter.ToSingle(memory, 0);
+ float returnValue = (float)address;
+ if (round)
+ returnValue = (float)Math.Round(address, 2);
+ return returnValue;
+ }
+ else
+ return 0;
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
+ ///
+ /// Read a string value from an address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and name of ini file. (OPTIONAL)
+ /// length of bytes to read (OPTIONAL)
+ /// terminate string at null char
+ /// System.Text.Encoding.UTF8 (DEFAULT). Other options: ascii, unicode, utf32, utf7
+ ///
+ public string ReadString(string code, string file = "", int length = 32, bool zeroTerminated = true, System.Text.Encoding stringEncoding = null)
+ {
+ if (stringEncoding == null)
+ stringEncoding = System.Text.Encoding.UTF8;
+
+ byte[] memoryNormal = new byte[length];
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+
+ if (ReadProcessMemory(mProc.Handle, theCode, memoryNormal, (UIntPtr)length, IntPtr.Zero))
+ return (zeroTerminated) ? stringEncoding.GetString(memoryNormal).Split('\0')[0] : stringEncoding.GetString(memoryNormal);
+ else
+ return "";
+ }
+
+ ///
+ /// Read a double value
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and name of ini file. (OPTIONAL)
+ /// Round the value to 2 decimal places
+ ///
+ public double ReadDouble(string code, string file = "", bool round = true)
+ {
+ byte[] memory = new byte[8];
+
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+ try
+ {
+ if (ReadProcessMemory(mProc.Handle, theCode, memory, (UIntPtr)8, IntPtr.Zero))
+ {
+ double address = BitConverter.ToDouble(memory, 0);
+ double returnValue = (double)address;
+ if (round)
+ returnValue = (double)Math.Round(address, 2);
+ return returnValue;
+ }
+ else
+ return 0;
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
+ public int ReadUIntPtr(UIntPtr code)
+ {
+ byte[] memory = new byte[4];
+ if (ReadProcessMemory(mProc.Handle, code, memory, (UIntPtr)4, IntPtr.Zero))
+ return BitConverter.ToInt32(memory, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Read an integer from an address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and name of ini file. (OPTIONAL)
+ ///
+ public int ReadInt(string code, string file = "")
+ {
+ byte[] memory = new byte[4];
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+ if (ReadProcessMemory(mProc.Handle, theCode, memory, (UIntPtr)4, IntPtr.Zero))
+ return BitConverter.ToInt32(memory, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Read a long value from an address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and name of ini file. (OPTIONAL)
+ ///
+ public long ReadLong(string code, string file = "")
+ {
+ byte[] memory = new byte[16];
+ UIntPtr theCode;
+
+ theCode = GetCode(code, file);
+
+ if (ReadProcessMemory(mProc.Handle, theCode, memory, (UIntPtr)8, IntPtr.Zero))
+ return BitConverter.ToInt64(memory, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Read a UInt value from address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and name of ini file. (OPTIONAL)
+ ///
+ public UInt32 ReadUInt(string code, string file = "")
+ {
+ byte[] memory = new byte[4];
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+
+ if (ReadProcessMemory(mProc.Handle, theCode, memory, (UIntPtr)4, IntPtr.Zero))
+ return BitConverter.ToUInt32(memory, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Reads a 2 byte value from an address and moves the address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// Quantity to move.
+ /// path and name of ini file (OPTIONAL)
+ ///
+ public int Read2ByteMove(string code, int moveQty, string file = "")
+ {
+ byte[] memory = new byte[4];
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+
+ UIntPtr newCode = UIntPtr.Add(theCode, moveQty);
+
+ if (ReadProcessMemory(mProc.Handle, newCode, memory, (UIntPtr)2, IntPtr.Zero))
+ return BitConverter.ToInt32(memory, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Reads an integer value from address and moves the address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// Quantity to move.
+ /// path and name of ini file (OPTIONAL)
+ ///
+ public int ReadIntMove(string code, int moveQty, string file = "")
+ {
+ byte[] memory = new byte[4];
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+
+ UIntPtr newCode = UIntPtr.Add(theCode, moveQty);
+
+ if (ReadProcessMemory(mProc.Handle, newCode, memory, (UIntPtr)4, IntPtr.Zero))
+ return BitConverter.ToInt32(memory, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Get UInt and move to another address by moveQty. Use in a for loop.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// Quantity to move.
+ /// path and name of ini file (OPTIONAL)
+ ///
+ public ulong ReadUIntMove(string code, int moveQty, string file = "")
+ {
+ byte[] memory = new byte[8];
+ UIntPtr theCode;
+ theCode = GetCode(code, file, 8);
+
+ UIntPtr newCode = UIntPtr.Add(theCode, moveQty);
+
+ if (ReadProcessMemory(mProc.Handle, newCode, memory, (UIntPtr)8, IntPtr.Zero))
+ return BitConverter.ToUInt64(memory, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Read a 2 byte value from an address. Returns an integer.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and file name to ini file. (OPTIONAL)
+ ///
+ public int Read2Byte(string code, string file = "")
+ {
+ byte[] memoryTiny = new byte[4];
+
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+
+ if (ReadProcessMemory(mProc.Handle, theCode, memoryTiny, (UIntPtr)2, IntPtr.Zero))
+ return BitConverter.ToInt32(memoryTiny, 0);
+ else
+ return 0;
+ }
+
+ ///
+ /// Read 1 byte from address.
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and file name of ini file. (OPTIONAL)
+ ///
+ public int ReadByte(string code, string file = "")
+ {
+ byte[] memoryTiny = new byte[1];
+
+ UIntPtr theCode = GetCode(code, file);
+
+ if (ReadProcessMemory(mProc.Handle, theCode, memoryTiny, (UIntPtr)1, IntPtr.Zero))
+ return memoryTiny[0];
+
+ return 0;
+ }
+
+ ///
+ /// Reads a byte from memory and splits it into bits
+ ///
+ /// address, module + pointer + offset, module + offset OR label in .ini file.
+ /// path and file name of ini file. (OPTIONAL)
+ /// Array of 8 booleans representing each bit of the byte read
+ public bool[] ReadBits(string code, string file = "")
+ {
+ byte[] buf = new byte[1];
+
+ UIntPtr theCode = GetCode(code, file);
+
+ bool[] ret = new bool[8];
+
+ if (!ReadProcessMemory(mProc.Handle, theCode, buf, (UIntPtr)1, IntPtr.Zero))
+ return ret;
+
+
+ if (!BitConverter.IsLittleEndian)
+ throw new Exception("Should be little endian");
+
+ for (var i = 0; i < 8; i++)
+ ret[i] = Convert.ToBoolean(buf[0] & (1 << i));
+
+ return ret;
+
+ }
+
+ public int ReadPByte(UIntPtr address, string code, string file = "")
+ {
+ byte[] memory = new byte[4];
+ if (ReadProcessMemory(mProc.Handle, address + LoadIntCode(code, file), memory, (UIntPtr)1, IntPtr.Zero))
+ return BitConverter.ToInt32(memory, 0);
+ else
+ return 0;
+ }
+
+ public float ReadPFloat(UIntPtr address, string code, string file = "")
+ {
+ byte[] memory = new byte[4];
+ if (ReadProcessMemory(mProc.Handle, address + LoadIntCode(code, file), memory, (UIntPtr)4, IntPtr.Zero))
+ {
+ float spawn = BitConverter.ToSingle(memory, 0);
+ return (float)Math.Round(spawn, 2);
+ }
+ else
+ return 0;
+ }
+
+ public int ReadPInt(UIntPtr address, string code, string file = "")
+ {
+ byte[] memory = new byte[4];
+ if (ReadProcessMemory(mProc.Handle, address + LoadIntCode(code, file), memory, (UIntPtr)4, IntPtr.Zero))
+ return BitConverter.ToInt32(memory, 0);
+ else
+ return 0;
+ }
+
+ public string ReadPString(UIntPtr address, string code, string file = "")
+ {
+ byte[] memoryNormal = new byte[32];
+ if (ReadProcessMemory(mProc.Handle, address + LoadIntCode(code, file), memoryNormal, (UIntPtr)32, IntPtr.Zero))
+ return CutString(System.Text.Encoding.ASCII.GetString(memoryNormal));
+ else
+ return "";
+ }
+ }
+}
diff --git a/Memory/Methods/Write.cs b/Memory/Methods/Write.cs
new file mode 100644
index 0000000..49124ef
--- /dev/null
+++ b/Memory/Methods/Write.cs
@@ -0,0 +1,284 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using static Memory.Imps;
+
+namespace Memory
+{
+ public partial class Mem
+ {
+ Dictionary FreezeTokenSrcs = new Dictionary();
+
+ ///
+ /// Freeze a value to an address.
+ ///
+ /// Your address
+ /// byte, 2bytes, bytes, float, int, string, double or long.
+ /// Value to freeze
+ /// ini file to read address from (OPTIONAL)
+ public void FreezeValue(string address, string type, string value, string file = "")
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+
+ lock (FreezeTokenSrcs)
+ {
+ if (FreezeTokenSrcs.ContainsKey(address))
+ {
+ Debug.WriteLine("Changing Freezing Address " + address + " Value " + value);
+ try
+ {
+ FreezeTokenSrcs[address].Cancel();
+ FreezeTokenSrcs.Remove(address);
+ }
+ catch
+ {
+ Debug.WriteLine("ERROR: Avoided a crash. Address " + address + " was not frozen.");
+ }
+ }
+ else
+ Debug.WriteLine("Adding Freezing Address " + address + " Value " + value);
+
+ FreezeTokenSrcs.Add(address, cts);
+ }
+
+ Task.Factory.StartNew(() =>
+ {
+ while (!cts.Token.IsCancellationRequested)
+ {
+ WriteMemory(address, type, value, file);
+ Thread.Sleep(25);
+ }
+ },
+ cts.Token);
+ }
+
+ ///
+ /// Unfreeze a frozen value at an address
+ ///
+ /// address where frozen value is stored
+ public void UnfreezeValue(string address)
+ {
+ Debug.WriteLine("Un-Freezing Address " + address);
+ try
+ {
+ lock (FreezeTokenSrcs)
+ {
+ FreezeTokenSrcs[address].Cancel();
+ FreezeTokenSrcs.Remove(address);
+ }
+ }
+ catch
+ {
+ Debug.WriteLine("ERROR: Address " + address + " was not frozen.");
+ }
+ }
+
+ ///
+ ///Write to memory address. See https://github.com/erfg12/memory.dll/wiki/writeMemory() for more information.
+ ///
+ ///address, module + pointer + offset, module + offset OR label in .ini file.
+ ///byte, 2bytes, bytes, float, int, string, double or long.
+ ///value to write to address.
+ ///path and name of .ini file (OPTIONAL)
+ ///System.Text.Encoding.UTF8 (DEFAULT). Other options: ascii, unicode, utf32, utf7
+ ///If building a trainer on an emulator (Ex: RPCS3) you'll want to set this to false
+ public bool WriteMemory(string code, string type, string write, string file = "", System.Text.Encoding stringEncoding = null, bool RemoveWriteProtection = true)
+ {
+ byte[] memory = new byte[4];
+ int size = 4;
+
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+
+ if (type.ToLower() == "float")
+ {
+ write = Convert.ToString(float.Parse(write, CultureInfo.InvariantCulture));
+ memory = BitConverter.GetBytes(Convert.ToSingle(write));
+ size = 4;
+ }
+ else if (type.ToLower() == "int")
+ {
+ memory = BitConverter.GetBytes(Convert.ToInt32(write));
+ size = 4;
+ }
+ else if (type.ToLower() == "byte")
+ {
+ memory = new byte[1];
+ memory[0] = Convert.ToByte(write, 16);
+ size = 1;
+ }
+ else if (type.ToLower() == "2bytes")
+ {
+ memory = new byte[2];
+ memory[0] = (byte)(Convert.ToInt32(write) % 256);
+ memory[1] = (byte)(Convert.ToInt32(write) / 256);
+ size = 2;
+ }
+ else if (type.ToLower() == "bytes")
+ {
+ if (write.Contains(",") || write.Contains(" ")) //check if it's a proper array
+ {
+ string[] stringBytes;
+ if (write.Contains(","))
+ stringBytes = write.Split(',');
+ else
+ stringBytes = write.Split(' ');
+ //Debug.WriteLine("write:" + write + " stringBytes:" + stringBytes);
+
+ int c = stringBytes.Count();
+ memory = new byte[c];
+ for (int i = 0; i < c; i++)
+ {
+ memory[i] = Convert.ToByte(stringBytes[i], 16);
+ }
+ size = stringBytes.Count();
+ }
+ else //wasnt array, only 1 byte
+ {
+ memory = new byte[1];
+ memory[0] = Convert.ToByte(write, 16);
+ size = 1;
+ }
+ }
+ else if (type.ToLower() == "double")
+ {
+ memory = BitConverter.GetBytes(Convert.ToDouble(write));
+ size = 8;
+ }
+ else if (type.ToLower() == "long")
+ {
+ memory = BitConverter.GetBytes(Convert.ToInt64(write));
+ size = 8;
+ }
+ else if (type.ToLower() == "string")
+ {
+ if (stringEncoding == null)
+ memory = System.Text.Encoding.UTF8.GetBytes(write);
+ else
+ memory = stringEncoding.GetBytes(write);
+ size = memory.Length;
+ }
+
+ //Debug.Write("DEBUG: Writing bytes [TYPE:" + type + " ADDR:" + theCode + "] " + String.Join(",", memory) + Environment.NewLine);
+ MemoryProtection OldMemProt = 0x00;
+ bool WriteProcMem = false;
+ if (RemoveWriteProtection)
+ ChangeProtection(code, MemoryProtection.ExecuteReadWrite, out OldMemProt); // change protection
+ WriteProcMem = WriteProcessMemory(mProc.Handle, theCode, memory, (UIntPtr)size, IntPtr.Zero);
+ if (RemoveWriteProtection)
+ ChangeProtection(code, OldMemProt, out _); // restore
+ return WriteProcMem;
+ }
+
+ ///
+ /// Write to address and move by moveQty. Good for byte arrays. See https://github.com/erfg12/memory.dll/wiki/Writing-a-Byte-Array for more information.
+ ///
+ ///address, module + pointer + offset, module + offset OR label in .ini file.
+ ///byte, bytes, float, int, string or long.
+ /// byte to write
+ /// quantity to move
+ /// path and name of .ini file (OPTIONAL)
+ /// milliseconds to sleep between each byte
+ ///
+ public bool WriteMove(string code, string type, string write, int MoveQty, string file = "", int SlowDown = 0)
+ {
+ byte[] memory = new byte[4];
+ int size = 4;
+
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+
+ if (type == "float")
+ {
+ memory = new byte[write.Length];
+ memory = BitConverter.GetBytes(Convert.ToSingle(write));
+ size = write.Length;
+ }
+ else if (type == "int")
+ {
+ memory = BitConverter.GetBytes(Convert.ToInt32(write));
+ size = 4;
+ }
+ else if (type == "double")
+ {
+ memory = BitConverter.GetBytes(Convert.ToDouble(write));
+ size = 8;
+ }
+ else if (type == "long")
+ {
+ memory = BitConverter.GetBytes(Convert.ToInt64(write));
+ size = 8;
+ }
+ else if (type == "byte")
+ {
+ memory = new byte[1];
+ memory[0] = Convert.ToByte(write, 16);
+ size = 1;
+ }
+ else if (type == "string")
+ {
+ memory = new byte[write.Length];
+ memory = System.Text.Encoding.UTF8.GetBytes(write);
+ size = write.Length;
+ }
+
+ UIntPtr newCode = UIntPtr.Add(theCode, MoveQty);
+
+ //Debug.Write("DEBUG: Writing bytes [TYPE:" + type + " ADDR:[O]" + theCode + " [N]" + newCode + " MQTY:" + MoveQty + "] " + String.Join(",", memory) + Environment.NewLine);
+ Thread.Sleep(SlowDown);
+ return WriteProcessMemory(mProc.Handle, newCode, memory, (UIntPtr)size, IntPtr.Zero);
+ }
+
+ ///
+ /// Write byte array to addresses.
+ ///
+ /// address to write to
+ /// byte array to write
+ /// path and name of ini file. (OPTIONAL)
+ public void WriteBytes(string code, byte[] write, string file = "")
+ {
+ UIntPtr theCode;
+ theCode = GetCode(code, file);
+ WriteProcessMemory(mProc.Handle, theCode, write, (UIntPtr)write.Length, IntPtr.Zero);
+ }
+
+ ///
+ /// Takes an array of 8 booleans and writes to a single byte
+ ///
+ /// address to write to
+ /// Array of 8 booleans to write
+ /// path and name of ini file. (OPTIONAL)
+ public void WriteBits(string code, bool[] bits, string file = "")
+ {
+ if (bits.Length != 8)
+ throw new ArgumentException("Not enough bits for a whole byte", nameof(bits));
+
+ byte[] buf = new byte[1];
+
+ UIntPtr theCode = GetCode(code, file);
+
+ for (var i = 0; i < 8; i++)
+ {
+ if (bits[i])
+ buf[0] |= (byte)(1 << i);
+ }
+
+ WriteProcessMemory(mProc.Handle, theCode, buf, (UIntPtr)1, IntPtr.Zero);
+ }
+
+ ///
+ /// Write byte array to address
+ ///
+ /// Address to write to
+ /// Byte array to write to
+ public void WriteBytes(UIntPtr address, byte[] write)
+ {
+ WriteProcessMemory(mProc.Handle, address, write, (UIntPtr)write.Length, out IntPtr bytesRead);
+ }
+ }
+}
diff --git a/Memory/README.txt b/Memory/README.txt
index 2e55a72..395eeda 100644
--- a/Memory/README.txt
+++ b/Memory/README.txt
@@ -1,4 +1,4 @@
-Thank you for choosing Memory.dll! Created by NeWaGe and hollow87 at New Age Software.
+Thank you for choosing Memory.dll!
BEFORE YOU START
diff --git a/Memory/Structures/Imports.cs b/Memory/Structures/Imports.cs
new file mode 100644
index 0000000..b46050f
--- /dev/null
+++ b/Memory/Structures/Imports.cs
@@ -0,0 +1,354 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Memory
+{
+ public class Imps
+ {
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr OpenProcess(
+ UInt32 dwDesiredAccess,
+ bool bInheritHandle,
+ Int32 dwProcessId
+ );
+
+#if WINXP
+#else
+ [DllImport("kernel32.dll", EntryPoint = "VirtualQueryEx")]
+ public static extern UIntPtr Native_VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress,
+ out MEMORY_BASIC_INFORMATION32 lpBuffer, UIntPtr dwLength);
+
+ [DllImport("kernel32.dll", EntryPoint = "VirtualQueryEx")]
+ public static extern UIntPtr Native_VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress,
+ out MEMORY_BASIC_INFORMATION64 lpBuffer, UIntPtr dwLength);
+
+ [DllImport("kernel32.dll")]
+ static extern uint GetLastError();
+
+
+
+ [DllImport("kernel32.dll")]
+ public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
+#endif
+
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
+ [DllImport("kernel32.dll")]
+ public static extern uint SuspendThread(IntPtr hThread);
+ [DllImport("kernel32.dll")]
+ public static extern int ResumeThread(IntPtr hThread);
+
+ [DllImport("dbghelp.dll")]
+ static extern bool MiniDumpWriteDump(
+ IntPtr hProcess,
+ Int32 ProcessId,
+ IntPtr hFile,
+ MINIDUMP_TYPE DumpType,
+ IntPtr ExceptionParam,
+ IntPtr UserStreamParam,
+ IntPtr CallackParam);
+
+ [DllImport("user32.dll", SetLastError = true)]
+ public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
+ public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool WriteProcessMemory(
+ IntPtr hProcess,
+ UIntPtr lpBaseAddress,
+ string lpBuffer,
+ UIntPtr nSize,
+ out IntPtr lpNumberOfBytesWritten
+ );
+
+ [DllImport("kernel32.dll")]
+ public static extern int GetProcessId(IntPtr handle);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ public static extern uint GetPrivateProfileString(
+ string lpAppName,
+ string lpKeyName,
+ string lpDefault,
+ StringBuilder lpReturnedString,
+ uint nSize,
+ string lpFileName);
+
+ [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
+ public static extern bool VirtualFreeEx(
+ IntPtr hProcess,
+ UIntPtr lpAddress,
+ UIntPtr dwSize,
+ uint dwFreeType
+ );
+
+ [DllImport("psapi.dll")]
+ static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In][MarshalAs(UnmanagedType.U4)] int nSize);
+ [DllImport("psapi.dll", SetLastError = true)]
+ public static extern bool EnumProcessModules(IntPtr hProcess,
+ [Out] IntPtr lphModule,
+ uint cb,
+ [MarshalAs(UnmanagedType.U4)] out uint lpcbNeeded);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [Out] byte[] lpBuffer, UIntPtr nSize, IntPtr lpNumberOfBytesRead);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [Out] byte[] lpBuffer, UIntPtr nSize, out ulong lpNumberOfBytesRead);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [Out] IntPtr lpBuffer, UIntPtr nSize, out ulong lpNumberOfBytesRead);
+
+ [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
+ public static extern UIntPtr VirtualAllocEx(
+ IntPtr hProcess,
+ UIntPtr lpAddress,
+ uint dwSize,
+ uint flAllocationType,
+ uint flProtect
+ );
+
+ [DllImport("kernel32.dll")]
+ public static extern bool VirtualProtectEx(IntPtr hProcess, UIntPtr lpAddress,
+ IntPtr dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
+ public static extern UIntPtr GetProcAddress(
+ IntPtr hModule,
+ string procName
+ );
+
+ [DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
+ private static extern bool _CloseHandle(IntPtr hObject);
+
+ [DllImport("kernel32.dll")]
+ public static extern Int32 CloseHandle(
+ IntPtr hObject
+ );
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+ public static extern IntPtr GetModuleHandle(
+ string lpModuleName
+ );
+
+ [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
+ internal static extern Int32 WaitForSingleObject(
+ IntPtr handle,
+ Int32 milliseconds
+ );
+
+ [DllImport("kernel32.dll")]
+ public static extern bool WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, IntPtr lpNumberOfBytesWritten);
+
+ // Added to avoid casting to UIntPtr
+ [DllImport("kernel32.dll")]
+ public static extern bool WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out IntPtr lpNumberOfBytesWritten);
+
+ [DllImport("kernel32")]
+ public static extern IntPtr CreateRemoteThread(
+ IntPtr hProcess,
+ IntPtr lpThreadAttributes,
+ uint dwStackSize,
+ UIntPtr lpStartAddress, // raw Pointer into remote process
+ UIntPtr lpParameter,
+ uint dwCreationFlags,
+ out IntPtr lpThreadId
+ );
+
+ [DllImport("kernel32")]
+ public static extern bool IsWow64Process(IntPtr hProcess, out bool lpSystemInfo);
+
+ [DllImport("user32.dll")]
+ public static extern bool SetForegroundWindow(IntPtr hWnd);
+
+ [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
+ public static extern IntPtr CreateToolhelp32Snapshot([In] UInt32 dwFlags, [In] UInt32 th32ProcessID);
+
+ [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
+ static extern bool Process32First([In] IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
+ [DllImport("kernel32.dll")]
+ public static extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
+ [DllImport("kernel32.dll")]
+ public static extern bool Module32Next(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
+
+ [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
+ static extern bool Process32Next([In] IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
+
+ // privileges
+ public const int PROCESS_CREATE_THREAD = 0x0002;
+ public const int PROCESS_QUERY_INFORMATION = 0x0400;
+ public const int PROCESS_VM_OPERATION = 0x0008;
+ public const int PROCESS_VM_WRITE = 0x0020;
+ public const int PROCESS_VM_READ = 0x0010;
+
+ // used for memory allocation
+ public const uint MEM_FREE = 0x10000;
+ public const uint MEM_COMMIT = 0x00001000;
+ public const uint MEM_RESERVE = 0x00002000;
+
+ public const uint PAGE_READONLY = 0x02;
+ public const uint PAGE_READWRITE = 0x04;
+ public const uint PAGE_WRITECOPY = 0x08;
+ public const uint PAGE_EXECUTE_READWRITE = 0x40;
+ public const uint PAGE_EXECUTE_WRITECOPY = 0x80;
+ public const uint PAGE_EXECUTE = 0x10;
+ public const uint PAGE_EXECUTE_READ = 0x20;
+
+ public const uint PAGE_GUARD = 0x100;
+ public const uint PAGE_NOACCESS = 0x01;
+
+ public const uint MEM_PRIVATE = 0x20000;
+ public const uint MEM_IMAGE = 0x1000000;
+
+ internal enum MINIDUMP_TYPE
+ {
+ MiniDumpNormal = 0x00000000,
+ MiniDumpWithDataSegs = 0x00000001,
+ MiniDumpWithFullMemory = 0x00000002,
+ MiniDumpWithHandleData = 0x00000004,
+ MiniDumpFilterMemory = 0x00000008,
+ MiniDumpScanMemory = 0x00000010,
+ MiniDumpWithUnloadedModules = 0x00000020,
+ MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
+ MiniDumpFilterModulePaths = 0x00000080,
+ MiniDumpWithProcessThreadData = 0x00000100,
+ MiniDumpWithPrivateReadWriteMemory = 0x00000200,
+ MiniDumpWithoutOptionalData = 0x00000400,
+ MiniDumpWithFullMemoryInfo = 0x00000800,
+ MiniDumpWithThreadInfo = 0x00001000,
+ MiniDumpWithCodeSegs = 0x00002000
+ }
+
+ public struct SYSTEM_INFO
+ {
+ public ushort processorArchitecture;
+ ushort reserved;
+ public uint pageSize;
+ public UIntPtr minimumApplicationAddress;
+ public UIntPtr maximumApplicationAddress;
+ public IntPtr activeProcessorMask;
+ public uint numberOfProcessors;
+ public uint processorType;
+ public uint allocationGranularity;
+ public ushort processorLevel;
+ public ushort processorRevision;
+ }
+
+ public struct MEMORY_BASIC_INFORMATION32
+ {
+ public UIntPtr BaseAddress;
+ public UIntPtr AllocationBase;
+ public uint AllocationProtect;
+ public uint RegionSize;
+ public uint State;
+ public uint Protect;
+ public uint Type;
+ }
+
+ public struct MEMORY_BASIC_INFORMATION64
+ {
+ public UIntPtr BaseAddress;
+ public UIntPtr AllocationBase;
+ public uint AllocationProtect;
+ public uint __alignment1;
+ public ulong RegionSize;
+ public uint State;
+ public uint Protect;
+ public uint Type;
+ public uint __alignment2;
+ }
+
+ public struct MEMORY_BASIC_INFORMATION
+ {
+ public UIntPtr BaseAddress;
+ public UIntPtr AllocationBase;
+ public uint AllocationProtect;
+ public long RegionSize;
+ public uint State;
+ public uint Protect;
+ public uint Type;
+ }
+
+ private enum SnapshotFlags : uint
+ {
+ HeapList = 0x00000001,
+ Process = 0x00000002,
+ Thread = 0x00000004,
+ Module = 0x00000008,
+ Module32 = 0x00000010,
+ Inherit = 0x80000000,
+ All = 0x0000001F,
+ NoHeaps = 0x40000000
+ }
+
+ [Flags]
+ public enum ThreadAccess : int
+ {
+ TERMINATE = (0x0001),
+ SUSPEND_RESUME = (0x0002),
+ GET_CONTEXT = (0x0008),
+ SET_CONTEXT = (0x0010),
+ SET_INFORMATION = (0x0020),
+ QUERY_INFORMATION = (0x0040),
+ SET_THREAD_TOKEN = (0x0080),
+ IMPERSONATE = (0x0100),
+ DIRECT_IMPERSONATION = (0x0200)
+ }
+
+ [Flags]
+ public enum MemoryProtection : uint
+ {
+ Execute = 0x10,
+ ExecuteRead = 0x20,
+ ExecuteReadWrite = 0x40,
+ ExecuteWriteCopy = 0x80,
+ NoAccess = 0x01,
+ ReadOnly = 0x02,
+ ReadWrite = 0x04,
+ WriteCopy = 0x08,
+ GuardModifierflag = 0x100,
+ NoCacheModifierflag = 0x200,
+ WriteCombineModifierflag = 0x400
+ }
+
+ //inner struct used only internally
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ private struct PROCESSENTRY32
+ {
+ const int MAX_PATH = 260;
+ internal UInt32 dwSize;
+ internal UInt32 cntUsage;
+ internal UInt32 th32ProcessID;
+ internal IntPtr th32DefaultHeapID;
+ internal UInt32 th32ModuleID;
+ internal UInt32 cntThreads;
+ internal UInt32 th32ParentProcessID;
+ internal Int32 pcPriClassBase;
+ internal UInt32 dwFlags;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
+ internal string szExeFile;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
+ public struct MODULEENTRY32
+ {
+ internal uint dwSize;
+ internal uint th32ModuleID;
+ internal uint th32ProcessID;
+ internal uint GlblcntUsage;
+ internal uint ProccntUsage;
+ internal IntPtr modBaseAddr;
+ internal uint modBaseSize;
+ internal IntPtr hModule;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
+ internal string szModule;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
+ internal string szExePath;
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/Memory/MemoryRegionResult.cs b/Memory/Structures/MemoryRegionResult.cs
similarity index 83%
rename from Memory/MemoryRegionResult.cs
rename to Memory/Structures/MemoryRegionResult.cs
index 1d04e25..e137a2a 100644
--- a/Memory/MemoryRegionResult.cs
+++ b/Memory/Structures/MemoryRegionResult.cs
@@ -6,6 +6,9 @@
namespace Memory
{
+ ///
+ /// AoB scan information.
+ ///
struct MemoryRegionResult
{
public UIntPtr CurrentBaseAddress { get; set; }
diff --git a/Memory/Structures/Process.cs b/Memory/Structures/Process.cs
new file mode 100644
index 0000000..a20f6f9
--- /dev/null
+++ b/Memory/Structures/Process.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+
+namespace Memory
+{
+ ///
+ /// Information about the opened process.
+ ///
+ public class Proc
+ {
+ public Process Process { get; set; }
+ public IntPtr Handle { get; set; }
+ public bool Is64Bit { get; set; }
+ public Dictionary Modules { get; set; }
+ public ProcessModule MainModule { get; set; }
+ }
+}
diff --git a/Memory/memory.cs b/Memory/memory.cs
index 83303f2..05da64d 100644
--- a/Memory/memory.cs
+++ b/Memory/memory.cs
@@ -6,50 +6,27 @@
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
-using System.Threading;
using System.Globalization;
-//using System.Windows.Forms;
using System.Security.Principal;
using System.Threading.Tasks;
-using System.Collections.Concurrent;
-using System.Reflection;
using System.ComponentModel;
+using static Memory.Imps;
namespace Memory
{
///
/// Memory.dll class. Full documentation at https://github.com/erfg12/memory.dll/wiki
///
- public class Mem
+ public partial class Mem
{
- #region DllImports
- [DllImport("kernel32.dll")]
- public static extern IntPtr OpenProcess(
- UInt32 dwDesiredAccess,
- bool bInheritHandle,
- Int32 dwProcessId
- );
+ public Proc mProc = new Proc();
-#if WINXP
-#else
- [DllImport("kernel32.dll", EntryPoint = "VirtualQueryEx")]
- public static extern UIntPtr Native_VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress,
- out MEMORY_BASIC_INFORMATION32 lpBuffer, UIntPtr dwLength);
-
- [DllImport("kernel32.dll", EntryPoint = "VirtualQueryEx")]
- public static extern UIntPtr Native_VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress,
- out MEMORY_BASIC_INFORMATION64 lpBuffer, UIntPtr dwLength);
-
- [DllImport("kernel32.dll")]
- static extern uint GetLastError();
-
- public UIntPtr VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress,
- out MEMORY_BASIC_INFORMATION lpBuffer)
+ public UIntPtr VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer)
{
UIntPtr retVal;
// TODO: Need to change this to only check once.
- if (Is64Bit || IntPtr.Size == 8)
+ if (mProc.Is64Bit || IntPtr.Size == 8)
{
// 64 bit
MEMORY_BASIC_INFORMATION64 tmp64 = new MEMORY_BASIC_INFORMATION64();
@@ -65,7 +42,6 @@ public UIntPtr VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress,
return retVal;
}
-
MEMORY_BASIC_INFORMATION32 tmp32 = new MEMORY_BASIC_INFORMATION32();
retVal = Native_VirtualQueryEx(hProcess, lpAddress, out tmp32, new UIntPtr((uint)Marshal.SizeOf(tmp32)));
@@ -81,333 +57,11 @@ public UIntPtr VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress,
return retVal;
}
- [DllImport("kernel32.dll")]
- static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
-#endif
-
- [DllImport("kernel32.dll")]
- static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
- [DllImport("kernel32.dll")]
- static extern uint SuspendThread(IntPtr hThread);
- [DllImport("kernel32.dll")]
- static extern int ResumeThread(IntPtr hThread);
-
- [DllImport("dbghelp.dll")]
- static extern bool MiniDumpWriteDump(
- IntPtr hProcess,
- Int32 ProcessId,
- IntPtr hFile,
- MINIDUMP_TYPE DumpType,
- IntPtr ExceptionParam,
- IntPtr UserStreamParam,
- IntPtr CallackParam);
-
- [DllImport("user32.dll", SetLastError = true)]
- static extern int GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
- public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
-
- [DllImport("kernel32.dll")]
- static extern bool WriteProcessMemory(
- IntPtr hProcess,
- UIntPtr lpBaseAddress,
- string lpBuffer,
- UIntPtr nSize,
- out IntPtr lpNumberOfBytesWritten
- );
-
- [DllImport("kernel32.dll")]
- static extern int GetProcessId(IntPtr handle);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
- static extern uint GetPrivateProfileString(
- string lpAppName,
- string lpKeyName,
- string lpDefault,
- StringBuilder lpReturnedString,
- uint nSize,
- string lpFileName);
-
- [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
- static extern bool VirtualFreeEx(
- IntPtr hProcess,
- UIntPtr lpAddress,
- UIntPtr dwSize,
- uint dwFreeType
- );
-
- [DllImport("psapi.dll")]
- static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In][MarshalAs(UnmanagedType.U4)] int nSize);
- [DllImport("psapi.dll", SetLastError = true)]
- public static extern bool EnumProcessModules(IntPtr hProcess,
- [Out] IntPtr lphModule,
- uint cb,
- [MarshalAs(UnmanagedType.U4)] out uint lpcbNeeded);
-
- [DllImport("kernel32.dll")]
- private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [Out] byte[] lpBuffer, UIntPtr nSize, IntPtr lpNumberOfBytesRead);
-
- [DllImport("kernel32.dll")]
- private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [Out] byte[] lpBuffer, UIntPtr nSize, out ulong lpNumberOfBytesRead);
-
- [DllImport("kernel32.dll")]
- private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [Out] IntPtr lpBuffer, UIntPtr nSize, out ulong lpNumberOfBytesRead);
-
- [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
- static extern UIntPtr VirtualAllocEx(
- IntPtr hProcess,
- UIntPtr lpAddress,
- uint dwSize,
- uint flAllocationType,
- uint flProtect
- );
-
- [DllImport("kernel32.dll")]
- static extern bool VirtualProtectEx(IntPtr hProcess, UIntPtr lpAddress,
- IntPtr dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
- public static extern UIntPtr GetProcAddress(
- IntPtr hModule,
- string procName
- );
-
- [DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
- private static extern bool _CloseHandle(IntPtr hObject);
-
- [DllImport("kernel32.dll")]
- public static extern Int32 CloseHandle(
- IntPtr hObject
- );
-
- [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
- public static extern IntPtr GetModuleHandle(
- string lpModuleName
- );
-
- [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
- internal static extern Int32 WaitForSingleObject(
- IntPtr handle,
- Int32 milliseconds
- );
-
- [DllImport("kernel32.dll")]
- private static extern bool WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, IntPtr lpNumberOfBytesWritten);
-
- // Added to avoid casting to UIntPtr
- [DllImport("kernel32.dll")]
- private static extern bool WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out IntPtr lpNumberOfBytesWritten);
-
- [DllImport("kernel32")]
- public static extern IntPtr CreateRemoteThread(
- IntPtr hProcess,
- IntPtr lpThreadAttributes,
- uint dwStackSize,
- UIntPtr lpStartAddress, // raw Pointer into remote process
- UIntPtr lpParameter,
- uint dwCreationFlags,
- out IntPtr lpThreadId
- );
-
- [DllImport("kernel32")]
- public static extern bool IsWow64Process(IntPtr hProcess, out bool lpSystemInfo);
-
- [DllImport("user32.dll")]
- static extern bool SetForegroundWindow(IntPtr hWnd);
-
- private enum SnapshotFlags : uint
- {
- HeapList = 0x00000001,
- Process = 0x00000002,
- Thread = 0x00000004,
- Module = 0x00000008,
- Module32 = 0x00000010,
- Inherit = 0x80000000,
- All = 0x0000001F,
- NoHeaps = 0x40000000
- }
- //inner struct used only internally
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
- private struct PROCESSENTRY32
- {
- const int MAX_PATH = 260;
- internal UInt32 dwSize;
- internal UInt32 cntUsage;
- internal UInt32 th32ProcessID;
- internal IntPtr th32DefaultHeapID;
- internal UInt32 th32ModuleID;
- internal UInt32 cntThreads;
- internal UInt32 th32ParentProcessID;
- internal Int32 pcPriClassBase;
- internal UInt32 dwFlags;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
- internal string szExeFile;
- }
-
- [StructLayout(LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
- public struct MODULEENTRY32
- {
- internal uint dwSize;
- internal uint th32ModuleID;
- internal uint th32ProcessID;
- internal uint GlblcntUsage;
- internal uint ProccntUsage;
- internal IntPtr modBaseAddr;
- internal uint modBaseSize;
- internal IntPtr hModule;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
- internal string szModule;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
- internal string szExePath;
- }
-
- [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
- static extern IntPtr CreateToolhelp32Snapshot([In] UInt32 dwFlags, [In] UInt32 th32ProcessID);
-
- [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
- static extern bool Process32First([In] IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
- [DllImport("kernel32.dll")]
- static extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
- [DllImport("kernel32.dll")]
- static extern bool Module32Next(IntPtr hSnapshot, ref MODULEENTRY32 lpme);
-
- [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
- static extern bool Process32Next([In] IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
-
- // privileges
- const int PROCESS_CREATE_THREAD = 0x0002;
- const int PROCESS_QUERY_INFORMATION = 0x0400;
- const int PROCESS_VM_OPERATION = 0x0008;
- const int PROCESS_VM_WRITE = 0x0020;
- const int PROCESS_VM_READ = 0x0010;
-
- // used for memory allocation
- const uint MEM_FREE = 0x10000;
- const uint MEM_COMMIT = 0x00001000;
- const uint MEM_RESERVE = 0x00002000;
-
- private const uint PAGE_READONLY = 0x02;
- const uint PAGE_READWRITE = 0x04;
- const uint PAGE_WRITECOPY = 0x08;
- private const uint PAGE_EXECUTE_READWRITE = 0x40;
- private const uint PAGE_EXECUTE_WRITECOPY = 0x80;
- private const uint PAGE_EXECUTE = 0x10;
- private const uint PAGE_EXECUTE_READ = 0x20;
-
- private const uint PAGE_GUARD = 0x100;
- private const uint PAGE_NOACCESS = 0x01;
-
- private uint MEM_PRIVATE = 0x20000;
- private uint MEM_IMAGE = 0x1000000;
-
- #endregion
-
- ///
- /// The process handle that was opened. (Use OpenProcess function to populate this variable)
- ///
- public IntPtr pHandle;
- Dictionary FreezeTokenSrcs = new Dictionary();
- public Process theProc = null;
-
- internal enum MINIDUMP_TYPE
- {
- MiniDumpNormal = 0x00000000,
- MiniDumpWithDataSegs = 0x00000001,
- MiniDumpWithFullMemory = 0x00000002,
- MiniDumpWithHandleData = 0x00000004,
- MiniDumpFilterMemory = 0x00000008,
- MiniDumpScanMemory = 0x00000010,
- MiniDumpWithUnloadedModules = 0x00000020,
- MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
- MiniDumpFilterModulePaths = 0x00000080,
- MiniDumpWithProcessThreadData = 0x00000100,
- MiniDumpWithPrivateReadWriteMemory = 0x00000200,
- MiniDumpWithoutOptionalData = 0x00000400,
- MiniDumpWithFullMemoryInfo = 0x00000800,
- MiniDumpWithThreadInfo = 0x00001000,
- MiniDumpWithCodeSegs = 0x00002000
- }
-
- bool IsDigitsOnly(string str)
- {
- foreach (char c in str)
- {
- if (c < '0' || c > '9')
- return false;
- }
- return true;
- }
-
- ///
- /// Freeze a value to an address.
- ///
- /// Your address
- /// byte, 2bytes, bytes, float, int, string, double or long.
- /// Value to freeze
- /// ini file to read address from (OPTIONAL)
- public void FreezeValue(string address, string type, string value, string file = "")
- {
- CancellationTokenSource cts = new CancellationTokenSource();
-
- lock (FreezeTokenSrcs)
- {
- if (FreezeTokenSrcs.ContainsKey(address))
- {
- Debug.WriteLine("Changing Freezing Address " + address + " Value " + value);
- try
- {
- FreezeTokenSrcs[address].Cancel();
- FreezeTokenSrcs.Remove(address);
- }
- catch
- {
- Debug.WriteLine("ERROR: Avoided a crash. Address " + address + " was not frozen.");
- }
- }
- else
- Debug.WriteLine("Adding Freezing Address " + address + " Value " + value);
-
- FreezeTokenSrcs.Add(address, cts);
- }
-
- Task.Factory.StartNew(() =>
- {
- while (!cts.Token.IsCancellationRequested)
- {
- WriteMemory(address, type, value, file);
- Thread.Sleep(25);
- }
- },
- cts.Token);
- }
-
- ///
- /// Unfreeze a frozen value at an address
- ///
- /// address where frozen value is stored
- public void UnfreezeValue(string address)
- {
- Debug.WriteLine("Un-Freezing Address " + address);
- try
- {
- lock (FreezeTokenSrcs)
- {
- FreezeTokenSrcs[address].Cancel();
- FreezeTokenSrcs.Remove(address);
- }
- }
- catch
- {
- Debug.WriteLine("ERROR: Address " + address + " was not frozen.");
- }
- }
-
///
/// Open the PC game process with all security and access rights.
///
/// Use process name or process ID here.
- ///
+ /// Process opened successfully or failed.
public bool OpenProcess(int pid)
{
if (!IsAdmin())
@@ -422,44 +76,44 @@ public bool OpenProcess(int pid)
}
- if (theProc != null && theProc.Id == pid)
+ if (mProc.Process != null && mProc.Process.Id == pid)
return true;
try
{
- theProc = Process.GetProcessById(pid);
+ mProc.Process = System.Diagnostics.Process.GetProcessById(pid);
- if (theProc != null && !theProc.Responding)
+ if (mProc.Process != null && !mProc.Process.Responding)
{
Debug.WriteLine("ERROR: OpenProcess: Process is not responding or null.");
return false;
}
- pHandle = OpenProcess(0x1F0FFF, true, pid);
+ mProc.Handle = Imps.OpenProcess(0x1F0FFF, true, pid);
- try {
- Process.EnterDebugMode();
+ try {
+ System.Diagnostics.Process.EnterDebugMode();
} catch (Win32Exception) {
//Debug.WriteLine("WARNING: You are not running with raised privileges! Visit https://github.com/erfg12/memory.dll/wiki/Administrative-Privileges");
}
- if (pHandle == IntPtr.Zero)
+ if (mProc.Handle == IntPtr.Zero)
{
var eCode = Marshal.GetLastWin32Error();
Debug.WriteLine("ERROR: OpenProcess has failed opening a handle to the target process (GetLastWin32ErrorCode: " + eCode + ")");
- Process.LeaveDebugMode();
- theProc = null;
+ System.Diagnostics.Process.LeaveDebugMode();
+ mProc = null;
return false;
}
// Lets set the process to 64bit or not here (cuts down on api calls)
- Is64Bit = Environment.Is64BitOperatingSystem && (IsWow64Process(pHandle, out bool retVal) && !retVal);
+ mProc.Is64Bit = Environment.Is64BitOperatingSystem && (IsWow64Process(mProc.Handle, out bool retVal) && !retVal);
- mainModule = theProc.MainModule;
+ mProc.MainModule = mProc.Process.MainModule;
GetModules();
- Debug.WriteLine("Process #" + theProc + " is now open.");
+ Debug.WriteLine("Process #" + mProc.Process + " is now open.");
return true;
}
@@ -501,43 +155,32 @@ public bool IsAdmin()
}
}
- ///
- /// Check if opened process is 64bit. Used primarily for getCode().
- ///
- /// True if 64bit false if 32bit.
- private bool _is64Bit;
- public bool Is64Bit
- {
- get { return _is64Bit; }
- private set { _is64Bit = value; }
- }
-
///
/// Builds the process modules dictionary (names with addresses).
///
public void GetModules()
{
- if (theProc == null)
+ if (mProc.Process == null)
return;
- if (_is64Bit && IntPtr.Size != 8)
+ if (mProc.Is64Bit && IntPtr.Size != 8)
{
Debug.WriteLine("WARNING: Game is x64, but your Trainer is x86! You will be missing some modules, change your Trainer's Solution Platform.");
}
- else if (!_is64Bit && IntPtr.Size == 8)
+ else if (!mProc.Is64Bit && IntPtr.Size == 8)
{
Debug.WriteLine("WARNING: Game is x86, but your Trainer is x64! You will be missing some modules, change your Trainer's Solution Platform.");
}
- modules.Clear();
+ mProc.Modules.Clear();
- foreach (ProcessModule Module in theProc.Modules)
+ foreach (ProcessModule Module in mProc.Process.Modules)
{
- if (!string.IsNullOrEmpty(Module.ModuleName) && !modules.ContainsKey(Module.ModuleName))
- modules.Add(Module.ModuleName, Module.BaseAddress);
+ if (!string.IsNullOrEmpty(Module.ModuleName) && !mProc.Modules.ContainsKey(Module.ModuleName))
+ mProc.Modules.Add(Module.ModuleName, Module.BaseAddress);
}
- Debug.WriteLine("Found " + modules.Count() + " process modules.");
+ Debug.WriteLine("Found " + mProc.Modules.Count() + " process modules.");
}
public void SetFocus()
@@ -545,7 +188,7 @@ public void SetFocus()
//int style = GetWindowLong(procs.MainWindowHandle, -16);
//if ((style & 0x20000000) == 0x20000000) //minimized
// SendMessage(procs.Handle, 0x0112, (IntPtr)0xF120, IntPtr.Zero);
- SetForegroundWindow(theProc.MainWindowHandle);
+ SetForegroundWindow(mProc.Process.MainWindowHandle);
}
///
@@ -562,7 +205,7 @@ public int GetProcIdFromName(string name) //new 1.0.2 function
if (name.ToLower().Contains(".bin")) // test
name = name.Replace(".bin", "");
- foreach (Process theprocess in processlist)
+ foreach (System.Diagnostics.Process theprocess in processlist)
{
if (theprocess.ProcessName.Equals(name, StringComparison.CurrentCultureIgnoreCase)) //find (name).exe in the process list (use task manager to find the name)
return theprocess.Id;
@@ -613,11 +256,6 @@ private int LoadIntCode(string name, string path)
}
}
- ///
- /// Dictionary with our opened process module names with addresses.
- ///
- public Dictionary modules = new Dictionary();
-
///
/// Make a named pipe (if not already made) and call to a remote function.
///
@@ -639,617 +277,22 @@ public void ThreadStartClient(string func, string name)
sw.WriteLine(func);
}
}
- }
-
- private ProcessModule mainModule;
-
- ///
- /// Cut a string that goes on for too long or one that is possibly merged with another string.
- ///
- /// The string you want to cut.
- ///
- public string CutString(string str)
- {
- StringBuilder sb = new StringBuilder();
- foreach (char c in str)
- {
- if (c >= ' ' && c <= '~')
- sb.Append(c);
- else
- break;
- }
- return sb.ToString();
- }
-
- ///
- /// Clean up a string that has bad characters in it.
- ///
- /// The string you want to sanitize.
- ///
- public string SanitizeString(string str)
- {
- StringBuilder sb = new StringBuilder();
- foreach (char c in str)
- {
- if (c >= ' ' && c <= '~')
- sb.Append(c);
- }
- return sb.ToString();
- }
+ }
#region protection
- [Flags]
- public enum MemoryProtection : uint
- {
- Execute = 0x10,
- ExecuteRead = 0x20,
- ExecuteReadWrite = 0x40,
- ExecuteWriteCopy = 0x80,
- NoAccess = 0x01,
- ReadOnly = 0x02,
- ReadWrite = 0x04,
- WriteCopy = 0x08,
- GuardModifierflag = 0x100,
- NoCacheModifierflag = 0x200,
- WriteCombineModifierflag = 0x400
- }
public bool ChangeProtection(string code, MemoryProtection newProtection, out MemoryProtection oldProtection, string file = "")
{
UIntPtr theCode = GetCode(code, file);
if (theCode == UIntPtr.Zero
- || pHandle == IntPtr.Zero)
+ || mProc.Handle == IntPtr.Zero)
{
oldProtection = default;
return false;
}
- return VirtualProtectEx(pHandle, theCode, (IntPtr)(Is64Bit ? 8 : 4), newProtection, out oldProtection);
- }
- #endregion
-
- #region readMemory
- ///
- /// Reads up to `length ` bytes from an address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// The maximum bytes to read.
- /// path and name of ini file.
- /// The bytes read or null
- public byte[] ReadBytes(string code, long length, string file = "")
- {
- byte[] memory = new byte[length];
- UIntPtr theCode = GetCode(code, file);
-
- if (!ReadProcessMemory(pHandle, theCode, memory, (UIntPtr)length, IntPtr.Zero))
- return null;
-
- return memory;
- }
-
- ///
- /// Read a float value from an address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and name of ini file. (OPTIONAL)
- /// Round the value to 2 decimal places
- ///
- public float ReadFloat(string code, string file = "", bool round = true)
- {
- byte[] memory = new byte[4];
-
- UIntPtr theCode;
- theCode = GetCode(code, file);
- try
- {
- if (ReadProcessMemory(pHandle, theCode, memory, (UIntPtr)4, IntPtr.Zero))
- {
- float address = BitConverter.ToSingle(memory, 0);
- float returnValue = (float)address;
- if (round)
- returnValue = (float)Math.Round(address, 2);
- return returnValue;
- }
- else
- return 0;
- }
- catch
- {
- return 0;
- }
- }
-
- ///
- /// Read a string value from an address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and name of ini file. (OPTIONAL)
- /// length of bytes to read (OPTIONAL)
- /// terminate string at null char
- /// System.Text.Encoding.UTF8 (DEFAULT). Other options: ascii, unicode, utf32, utf7
- ///
- public string ReadString(string code, string file = "", int length = 32, bool zeroTerminated = true, System.Text.Encoding stringEncoding = null)
- {
- if (stringEncoding == null)
- stringEncoding = System.Text.Encoding.UTF8;
-
- byte[] memoryNormal = new byte[length];
- UIntPtr theCode;
- theCode = GetCode(code, file);
-
- if (ReadProcessMemory(pHandle, theCode, memoryNormal, (UIntPtr)length, IntPtr.Zero))
- return (zeroTerminated) ? stringEncoding.GetString(memoryNormal).Split('\0')[0] : stringEncoding.GetString(memoryNormal);
- else
- return "";
- }
-
- ///
- /// Read a double value
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and name of ini file. (OPTIONAL)
- /// Round the value to 2 decimal places
- ///
- public double ReadDouble(string code, string file = "", bool round = true)
- {
- byte[] memory = new byte[8];
-
- UIntPtr theCode;
- theCode = GetCode(code, file);
- try
- {
- if (ReadProcessMemory(pHandle, theCode, memory, (UIntPtr)8, IntPtr.Zero))
- {
- double address = BitConverter.ToDouble(memory, 0);
- double returnValue = (double)address;
- if (round)
- returnValue = (double)Math.Round(address, 2);
- return returnValue;
- }
- else
- return 0;
- }
- catch
- {
- return 0;
- }
- }
-
- public int ReadUIntPtr(UIntPtr code)
- {
- byte[] memory = new byte[4];
- if (ReadProcessMemory(pHandle, code, memory, (UIntPtr)4, IntPtr.Zero))
- return BitConverter.ToInt32(memory, 0);
- else
- return 0;
- }
-
- ///
- /// Read an integer from an address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and name of ini file. (OPTIONAL)
- ///
- public int ReadInt(string code, string file = "")
- {
- byte[] memory = new byte[4];
- UIntPtr theCode;
- theCode = GetCode(code, file);
- if (ReadProcessMemory(pHandle, theCode, memory, (UIntPtr)4, IntPtr.Zero))
- return BitConverter.ToInt32(memory, 0);
- else
- return 0;
- }
-
- ///
- /// Read a long value from an address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and name of ini file. (OPTIONAL)
- ///
- public long ReadLong(string code, string file = "")
- {
- byte[] memory = new byte[16];
- UIntPtr theCode;
-
- theCode = GetCode(code, file);
-
- if (ReadProcessMemory(pHandle, theCode, memory, (UIntPtr)8, IntPtr.Zero))
- return BitConverter.ToInt64(memory, 0);
- else
- return 0;
- }
-
- ///
- /// Read a UInt value from address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and name of ini file. (OPTIONAL)
- ///
- public UInt32 ReadUInt(string code, string file = "")
- {
- byte[] memory = new byte[4];
- UIntPtr theCode;
- theCode = GetCode(code, file);
-
- if (ReadProcessMemory(pHandle, theCode, memory, (UIntPtr)4, IntPtr.Zero))
- return BitConverter.ToUInt32(memory, 0);
- else
- return 0;
- }
-
- ///
- /// Reads a 2 byte value from an address and moves the address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// Quantity to move.
- /// path and name of ini file (OPTIONAL)
- ///
- public int Read2ByteMove(string code, int moveQty, string file = "")
- {
- byte[] memory = new byte[4];
- UIntPtr theCode;
- theCode = GetCode(code, file);
-
- UIntPtr newCode = UIntPtr.Add(theCode, moveQty);
-
- if (ReadProcessMemory(pHandle, newCode, memory, (UIntPtr)2, IntPtr.Zero))
- return BitConverter.ToInt32(memory, 0);
- else
- return 0;
- }
-
- ///
- /// Reads an integer value from address and moves the address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// Quantity to move.
- /// path and name of ini file (OPTIONAL)
- ///
- public int ReadIntMove(string code, int moveQty, string file = "")
- {
- byte[] memory = new byte[4];
- UIntPtr theCode;
- theCode = GetCode(code, file);
-
- UIntPtr newCode = UIntPtr.Add(theCode, moveQty);
-
- if (ReadProcessMemory(pHandle, newCode, memory, (UIntPtr)4, IntPtr.Zero))
- return BitConverter.ToInt32(memory, 0);
- else
- return 0;
- }
-
- ///
- /// Get UInt and move to another address by moveQty. Use in a for loop.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// Quantity to move.
- /// path and name of ini file (OPTIONAL)
- ///
- public ulong ReadUIntMove(string code, int moveQty, string file = "")
- {
- byte[] memory = new byte[8];
- UIntPtr theCode;
- theCode = GetCode(code, file, 8);
-
- UIntPtr newCode = UIntPtr.Add(theCode, moveQty);
-
- if (ReadProcessMemory(pHandle, newCode, memory, (UIntPtr)8, IntPtr.Zero))
- return BitConverter.ToUInt64(memory, 0);
- else
- return 0;
- }
-
- ///
- /// Read a 2 byte value from an address. Returns an integer.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and file name to ini file. (OPTIONAL)
- ///
- public int Read2Byte(string code, string file = "")
- {
- byte[] memoryTiny = new byte[4];
-
- UIntPtr theCode;
- theCode = GetCode(code, file);
-
- if (ReadProcessMemory(pHandle, theCode, memoryTiny, (UIntPtr)2, IntPtr.Zero))
- return BitConverter.ToInt32(memoryTiny, 0);
- else
- return 0;
- }
-
- ///
- /// Read 1 byte from address.
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and file name of ini file. (OPTIONAL)
- ///
- public int ReadByte(string code, string file = "")
- {
- byte[] memoryTiny = new byte[1];
-
- UIntPtr theCode = GetCode(code, file);
-
- if (ReadProcessMemory(pHandle, theCode, memoryTiny, (UIntPtr) 1, IntPtr.Zero))
- return memoryTiny[0];
-
- return 0;
- }
-
- ///
- /// Reads a byte from memory and splits it into bits
- ///
- /// address, module + pointer + offset, module + offset OR label in .ini file.
- /// path and file name of ini file. (OPTIONAL)
- /// Array of 8 booleans representing each bit of the byte read
- public bool[] ReadBits(string code, string file = "")
- {
- byte[] buf = new byte[1];
-
- UIntPtr theCode = GetCode(code, file);
-
- bool[] ret = new bool[8];
-
- if (!ReadProcessMemory(pHandle, theCode, buf, (UIntPtr) 1, IntPtr.Zero))
- return ret;
-
-
- if (!BitConverter.IsLittleEndian)
- throw new Exception("Should be little endian");
-
- for (var i = 0; i < 8; i++)
- ret[i] = Convert.ToBoolean(buf[0] & (1 << i));
-
- return ret;
-
- }
-
- public int ReadPByte(UIntPtr address, string code, string file = "")
- {
- byte[] memory = new byte[4];
- if (ReadProcessMemory(pHandle, address + LoadIntCode(code, file), memory, (UIntPtr)1, IntPtr.Zero))
- return BitConverter.ToInt32(memory, 0);
- else
- return 0;
- }
-
- public float ReadPFloat(UIntPtr address, string code, string file = "")
- {
- byte[] memory = new byte[4];
- if (ReadProcessMemory(pHandle, address + LoadIntCode(code, file), memory, (UIntPtr)4, IntPtr.Zero))
- {
- float spawn = BitConverter.ToSingle(memory, 0);
- return (float)Math.Round(spawn, 2);
- }
- else
- return 0;
- }
-
- public int ReadPInt(UIntPtr address, string code, string file = "")
- {
- byte[] memory = new byte[4];
- if (ReadProcessMemory(pHandle, address + LoadIntCode(code, file), memory, (UIntPtr)4, IntPtr.Zero))
- return BitConverter.ToInt32(memory, 0);
- else
- return 0;
- }
-
- public string ReadPString(UIntPtr address, string code, string file = "")
- {
- byte[] memoryNormal = new byte[32];
- if (ReadProcessMemory(pHandle, address + LoadIntCode(code, file), memoryNormal, (UIntPtr)32, IntPtr.Zero))
- return CutString(System.Text.Encoding.ASCII.GetString(memoryNormal));
- else
- return "";
- }
- #endregion
-
- #region writeMemory
- ///
- ///Write to memory address. See https://github.com/erfg12/memory.dll/wiki/writeMemory() for more information.
- ///
- ///address, module + pointer + offset, module + offset OR label in .ini file.
- ///byte, 2bytes, bytes, float, int, string, double or long.
- ///value to write to address.
- ///path and name of .ini file (OPTIONAL)
- ///System.Text.Encoding.UTF8 (DEFAULT). Other options: ascii, unicode, utf32, utf7
- ///If building a trainer on an emulator (Ex: RPCS3) you'll want to set this to false
- public bool WriteMemory(string code, string type, string write, string file = "", System.Text.Encoding stringEncoding = null, bool RemoveWriteProtection = true)
- {
- byte[] memory = new byte[4];
- int size = 4;
-
- UIntPtr theCode;
- theCode = GetCode(code, file);
-
- if (type.ToLower() == "float")
- {
- write = Convert.ToString(float.Parse(write, CultureInfo.InvariantCulture));
- memory = BitConverter.GetBytes(Convert.ToSingle(write));
- size = 4;
- }
- else if (type.ToLower() == "int")
- {
- memory = BitConverter.GetBytes(Convert.ToInt32(write));
- size = 4;
- }
- else if (type.ToLower() == "byte")
- {
- memory = new byte[1];
- memory[0] = Convert.ToByte(write, 16);
- size = 1;
- }
- else if (type.ToLower() == "2bytes")
- {
- memory = new byte[2];
- memory[0] = (byte)(Convert.ToInt32(write) % 256);
- memory[1] = (byte)(Convert.ToInt32(write) / 256);
- size = 2;
- }
- else if (type.ToLower() == "bytes")
- {
- if (write.Contains(",") || write.Contains(" ")) //check if it's a proper array
- {
- string[] stringBytes;
- if (write.Contains(","))
- stringBytes = write.Split(',');
- else
- stringBytes = write.Split(' ');
- //Debug.WriteLine("write:" + write + " stringBytes:" + stringBytes);
-
- int c = stringBytes.Count();
- memory = new byte[c];
- for (int i = 0; i < c; i++)
- {
- memory[i] = Convert.ToByte(stringBytes[i], 16);
- }
- size = stringBytes.Count();
- }
- else //wasnt array, only 1 byte
- {
- memory = new byte[1];
- memory[0] = Convert.ToByte(write, 16);
- size = 1;
- }
- }
- else if (type.ToLower() == "double")
- {
- memory = BitConverter.GetBytes(Convert.ToDouble(write));
- size = 8;
- }
- else if (type.ToLower() == "long")
- {
- memory = BitConverter.GetBytes(Convert.ToInt64(write));
- size = 8;
- }
- else if (type.ToLower() == "string")
- {
- if (stringEncoding == null)
- memory = System.Text.Encoding.UTF8.GetBytes(write);
- else
- memory = stringEncoding.GetBytes(write);
- size = memory.Length;
- }
-
- //Debug.Write("DEBUG: Writing bytes [TYPE:" + type + " ADDR:" + theCode + "] " + String.Join(",", memory) + Environment.NewLine);
- MemoryProtection OldMemProt = 0x00;
- bool WriteProcMem = false;
- if (RemoveWriteProtection)
- ChangeProtection(code, MemoryProtection.ExecuteReadWrite, out OldMemProt); // change protection
- WriteProcMem = WriteProcessMemory(pHandle, theCode, memory, (UIntPtr)size, IntPtr.Zero);
- if (RemoveWriteProtection)
- ChangeProtection(code, OldMemProt, out _); // restore
- return WriteProcMem;
- }
-
- ///
- /// Write to address and move by moveQty. Good for byte arrays. See https://github.com/erfg12/memory.dll/wiki/Writing-a-Byte-Array for more information.
- ///
- ///address, module + pointer + offset, module + offset OR label in .ini file.
- ///byte, bytes, float, int, string or long.
- /// byte to write
- /// quantity to move
- /// path and name of .ini file (OPTIONAL)
- /// milliseconds to sleep between each byte
- ///
- public bool WriteMove(string code, string type, string write, int MoveQty, string file = "", int SlowDown = 0)
- {
- byte[] memory = new byte[4];
- int size = 4;
-
- UIntPtr theCode;
- theCode = GetCode(code, file);
-
- if (type == "float")
- {
- memory = new byte[write.Length];
- memory = BitConverter.GetBytes(Convert.ToSingle(write));
- size = write.Length;
- }
- else if (type == "int")
- {
- memory = BitConverter.GetBytes(Convert.ToInt32(write));
- size = 4;
- }
- else if (type == "double")
- {
- memory = BitConverter.GetBytes(Convert.ToDouble(write));
- size = 8;
- }
- else if (type == "long")
- {
- memory = BitConverter.GetBytes(Convert.ToInt64(write));
- size = 8;
- }
- else if (type == "byte")
- {
- memory = new byte[1];
- memory[0] = Convert.ToByte(write, 16);
- size = 1;
- }
- else if (type == "string")
- {
- memory = new byte[write.Length];
- memory = System.Text.Encoding.UTF8.GetBytes(write);
- size = write.Length;
- }
-
- UIntPtr newCode = UIntPtr.Add(theCode, MoveQty);
-
- //Debug.Write("DEBUG: Writing bytes [TYPE:" + type + " ADDR:[O]" + theCode + " [N]" + newCode + " MQTY:" + MoveQty + "] " + String.Join(",", memory) + Environment.NewLine);
- Thread.Sleep(SlowDown);
- return WriteProcessMemory(pHandle, newCode, memory, (UIntPtr)size, IntPtr.Zero);
- }
-
- ///
- /// Write byte array to addresses.
- ///
- /// address to write to
- /// byte array to write
- /// path and name of ini file. (OPTIONAL)
- public void WriteBytes(string code, byte[] write, string file = "")
- {
- UIntPtr theCode;
- theCode = GetCode(code, file);
- WriteProcessMemory(pHandle, theCode, write, (UIntPtr)write.Length, IntPtr.Zero);
- }
-
- ///
- /// Takes an array of 8 booleans and writes to a single byte
- ///
- /// address to write to
- /// Array of 8 booleans to write
- /// path and name of ini file. (OPTIONAL)
- public void WriteBits(string code, bool[] bits, string file = "")
- {
- if(bits.Length != 8)
- throw new ArgumentException("Not enough bits for a whole byte", nameof(bits));
-
- byte[] buf = new byte[1];
-
- UIntPtr theCode = GetCode(code, file);
-
- for (var i = 0; i < 8; i++)
- {
- if (bits[i])
- buf[0] |= (byte)(1 << i);
- }
-
- WriteProcessMemory(pHandle, theCode, buf, (UIntPtr) 1, IntPtr.Zero);
- }
-
- ///
- /// Write byte array to address
- ///
- /// Address to write to
- /// Byte array to write to
- public void WriteBytes(UIntPtr address, byte[] write)
- {
- WriteProcessMemory(pHandle, address, write, (UIntPtr)write.Length, out IntPtr bytesRead);
+ return VirtualProtectEx(mProc.Handle, theCode, (IntPtr)(mProc.Is64Bit ? 8 : 4), newProtection, out oldProtection);
}
-
#endregion
///
@@ -1262,7 +305,7 @@ public void WriteBytes(UIntPtr address, byte[] write)
public UIntPtr GetCode(string name, string path = "", int size = 8)
{
string theCode = "";
- if (Is64Bit)
+ if (mProc.Is64Bit)
{
//Debug.WriteLine("Changing to 64bit code...");
if (size == 8) size = 16; //change to 64bit
@@ -1320,7 +363,7 @@ public UIntPtr GetCode(string name, string path = "", int size = 8)
int[] offsets = offsetsList.ToArray();
if (theCode.Contains("base") || theCode.Contains("main"))
- ReadProcessMemory(pHandle, (UIntPtr)((int)mainModule.BaseAddress + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, (UIntPtr)((int)mProc.MainModule.BaseAddress + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
else if (!theCode.Contains("base") && !theCode.Contains("main") && theCode.Contains("+"))
{
string[] moduleName = theCode.Split('+');
@@ -1335,18 +378,18 @@ public UIntPtr GetCode(string name, string path = "", int size = 8)
{
try
{
- altModule = modules[moduleName[0]];
+ altModule = mProc.Modules[moduleName[0]];
}
catch
{
Debug.WriteLine("Module " + moduleName[0] + " was not found in module list!");
- Debug.WriteLine("Modules: " + string.Join(",", modules));
+ Debug.WriteLine("Modules: " + string.Join(",", mProc.Modules));
}
}
- ReadProcessMemory(pHandle, (UIntPtr)((int)altModule + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, (UIntPtr)((int)altModule + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
}
else
- ReadProcessMemory(pHandle, (UIntPtr)(offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, (UIntPtr)(offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
uint num1 = BitConverter.ToUInt32(memoryAddress, 0); //ToUInt64 causes arithmetic overflow.
@@ -1355,7 +398,7 @@ public UIntPtr GetCode(string name, string path = "", int size = 8)
for (int i = 1; i < offsets.Length; i++)
{
base1 = new UIntPtr(Convert.ToUInt32(num1 + offsets[i]));
- ReadProcessMemory(pHandle, base1, memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, base1, memoryAddress, (UIntPtr)size, IntPtr.Zero);
num1 = BitConverter.ToUInt32(memoryAddress, 0); //ToUInt64 causes arithmetic overflow.
}
return base1;
@@ -1366,7 +409,7 @@ public UIntPtr GetCode(string name, string path = "", int size = 8)
IntPtr altModule = IntPtr.Zero;
//Debug.WriteLine("newOffsets=" + newOffsets);
if (theCode.ToLower().Contains("base") || theCode.ToLower().Contains("main"))
- altModule = mainModule.BaseAddress;
+ altModule = mProc.MainModule.BaseAddress;
else if (!theCode.ToLower().Contains("base") && !theCode.ToLower().Contains("main") && theCode.Contains("+"))
{
string[] moduleName = theCode.Split('+');
@@ -1380,17 +423,17 @@ public UIntPtr GetCode(string name, string path = "", int size = 8)
{
try
{
- altModule = modules[moduleName[0]];
+ altModule = mProc.Modules[moduleName[0]];
}
catch
{
Debug.WriteLine("Module " + moduleName[0] + " was not found in module list!");
- Debug.WriteLine("Modules: " + string.Join(",", modules));
+ Debug.WriteLine("Modules: " + string.Join(",", mProc.Modules));
}
}
}
else
- altModule = modules[theCode.Split('+')[0]];
+ altModule = mProc.Modules[theCode.Split('+')[0]];
return (UIntPtr)((int)altModule + trueCode);
}
}
@@ -1448,7 +491,7 @@ public UIntPtr Get64BitCode(string name, string path = "", int size = 16)
Int64[] offsets = offsetsList.ToArray();
if (theCode.Contains("base") || theCode.Contains("main"))
- ReadProcessMemory(pHandle, (UIntPtr)((Int64)mainModule.BaseAddress + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, (UIntPtr)((Int64)mProc.MainModule.BaseAddress + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
else if (!theCode.Contains("base") && !theCode.Contains("main") && theCode.Contains("+"))
{
string[] moduleName = theCode.Split('+');
@@ -1459,18 +502,18 @@ public UIntPtr Get64BitCode(string name, string path = "", int size = 16)
{
try
{
- altModule = modules[moduleName[0]];
+ altModule = mProc.Modules[moduleName[0]];
}
catch
{
Debug.WriteLine("Module " + moduleName[0] + " was not found in module list!");
- Debug.WriteLine("Modules: " + string.Join(",", modules));
+ Debug.WriteLine("Modules: " + string.Join(",", mProc.Modules));
}
}
- ReadProcessMemory(pHandle, (UIntPtr)((Int64)altModule + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, (UIntPtr)((Int64)altModule + offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
}
else // no offsets
- ReadProcessMemory(pHandle, (UIntPtr)(offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, (UIntPtr)(offsets[0]), memoryAddress, (UIntPtr)size, IntPtr.Zero);
Int64 num1 = BitConverter.ToInt64(memoryAddress, 0);
@@ -1479,7 +522,7 @@ public UIntPtr Get64BitCode(string name, string path = "", int size = 16)
for (int i = 1; i < offsets.Length; i++)
{
base1 = new UIntPtr(Convert.ToUInt64(num1 + offsets[i]));
- ReadProcessMemory(pHandle, base1, memoryAddress, (UIntPtr)size, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, base1, memoryAddress, (UIntPtr)size, IntPtr.Zero);
num1 = BitConverter.ToInt64(memoryAddress, 0);
}
return base1;
@@ -1489,7 +532,7 @@ public UIntPtr Get64BitCode(string name, string path = "", int size = 16)
Int64 trueCode = Convert.ToInt64(newOffsets, 16);
IntPtr altModule = IntPtr.Zero;
if (theCode.Contains("base") || theCode.Contains("main"))
- altModule = mainModule.BaseAddress;
+ altModule = mProc.MainModule.BaseAddress;
else if (!theCode.Contains("base") && !theCode.Contains("main") && theCode.Contains("+"))
{
string[] moduleName = theCode.Split('+');
@@ -1503,17 +546,17 @@ public UIntPtr Get64BitCode(string name, string path = "", int size = 16)
{
try
{
- altModule = modules[moduleName[0]];
+ altModule = mProc.Modules[moduleName[0]];
}
catch
{
Debug.WriteLine("Module " + moduleName[0] + " was not found in module list!");
- Debug.WriteLine("Modules: " + string.Join(",", modules));
+ Debug.WriteLine("Modules: " + string.Join(",", mProc.Modules));
}
}
}
else
- altModule = modules[theCode.Split('+')[0]];
+ altModule = mProc.Modules[theCode.Split('+')[0]];
return (UIntPtr)((Int64)altModule + trueCode);
}
}
@@ -1523,11 +566,11 @@ public UIntPtr Get64BitCode(string name, string path = "", int size = 16)
///
public void CloseProcess()
{
- if (pHandle == null)
+ if (mProc.Handle == null)
return;
- CloseHandle(pHandle);
- theProc = null;
+ CloseHandle(mProc.Handle);
+ mProc = null;
}
///
@@ -1538,25 +581,25 @@ public bool InjectDll(String strDllName)
{
IntPtr bytesout;
- foreach (ProcessModule pm in theProc.Modules)
+ foreach (ProcessModule pm in mProc.Process.Modules)
{
if (pm.ModuleName.StartsWith("inject", StringComparison.InvariantCultureIgnoreCase))
return false;
}
- if (!theProc.Responding)
+ if (!mProc.Process.Responding)
return false;
int lenWrite = strDllName.Length + 1;
- UIntPtr allocMem = VirtualAllocEx(pHandle, (UIntPtr)null, (uint)lenWrite, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ UIntPtr allocMem = VirtualAllocEx(mProc.Handle, (UIntPtr)null, (uint)lenWrite, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- WriteProcessMemory(pHandle, allocMem, strDllName, (UIntPtr)lenWrite, out bytesout);
+ WriteProcessMemory(mProc.Handle, allocMem, strDllName, (UIntPtr)lenWrite, out bytesout);
UIntPtr injector = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (injector == null)
return false;
- IntPtr hThread = CreateRemoteThread(pHandle, (IntPtr)null, 0, injector, allocMem, 0, out bytesout);
+ IntPtr hThread = CreateRemoteThread(mProc.Handle, (IntPtr)null, 0, injector, allocMem, 0, out bytesout);
if (hThread == null)
return false;
@@ -1567,7 +610,7 @@ public bool InjectDll(String strDllName)
CloseHandle(hThread);
return false;
}
- VirtualFreeEx(pHandle, allocMem, (UIntPtr)0, 0x8000);
+ VirtualFreeEx(mProc.Handle, allocMem, (UIntPtr)0, 0x8000);
if (hThread != null)
CloseHandle(hThread);
@@ -1605,8 +648,7 @@ public UIntPtr CreateCodeCave(string code, byte[] newBytes, int replaceCount, in
for(var i = 0; i < 10 && caveAddress == UIntPtr.Zero; i++)
{
- caveAddress = VirtualAllocEx(pHandle, FindFreeBlockForRegion(prefered, (uint)size),
- (uint)size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ caveAddress = VirtualAllocEx(mProc.Handle, FindFreeBlockForRegion(prefered, (uint)size), (uint)size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (caveAddress == UIntPtr.Zero)
prefered = UIntPtr.Add(prefered, 0x10000);
@@ -1614,7 +656,7 @@ public UIntPtr CreateCodeCave(string code, byte[] newBytes, int replaceCount, in
// Failed to allocate memory around the address we wanted let windows handle it and hope for the best?
if (caveAddress == UIntPtr.Zero)
- caveAddress = VirtualAllocEx(pHandle, UIntPtr.Zero, (uint)size, MEM_COMMIT | MEM_RESERVE,
+ caveAddress = VirtualAllocEx(mProc.Handle, UIntPtr.Zero, (uint)size, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
int nopsNeeded = replaceCount > 5 ? replaceCount - 5 : 0;
@@ -1654,7 +696,7 @@ private UIntPtr FindFreeBlockForRegion(UIntPtr baseAddress, uint size)
GetSystemInfo(out SYSTEM_INFO si);
- if (Is64Bit)
+ if (mProc.Is64Bit)
{
if ((long)minAddress > (long)si.maximumApplicationAddress ||
(long)minAddress < (long)si.minimumApplicationAddress)
@@ -1675,7 +717,7 @@ private UIntPtr FindFreeBlockForRegion(UIntPtr baseAddress, uint size)
UIntPtr current = minAddress;
UIntPtr previous = current;
- while (VirtualQueryEx(pHandle, current, out mbi).ToUInt64() != 0)
+ while (VirtualQueryEx(mProc.Handle, current, out mbi).ToUInt64() != 0)
{
if ((long)mbi.BaseAddress > (long)maxAddress)
return UIntPtr.Zero; // No memory found, let windows handle
@@ -1751,23 +793,9 @@ private UIntPtr FindFreeBlockForRegion(UIntPtr baseAddress, uint size)
}
#endif
- [Flags]
- public enum ThreadAccess : int
- {
- TERMINATE = (0x0001),
- SUSPEND_RESUME = (0x0002),
- GET_CONTEXT = (0x0008),
- SET_CONTEXT = (0x0010),
- SET_INFORMATION = (0x0020),
- QUERY_INFORMATION = (0x0040),
- SET_THREAD_TOKEN = (0x0080),
- IMPERSONATE = (0x0100),
- DIRECT_IMPERSONATION = (0x0200)
- }
-
public static void SuspendProcess(int pid)
{
- var process = Process.GetProcessById(pid);
+ var process = System.Diagnostics.Process.GetProcessById(pid);
if (process.ProcessName == string.Empty)
return;
@@ -1785,7 +813,7 @@ public static void SuspendProcess(int pid)
public static void ResumeProcess(int pid)
{
- var process = Process.GetProcessById(pid);
+ var process = System.Diagnostics.Process.GetProcessById(pid);
if (process.ProcessName == string.Empty)
return;
@@ -1829,7 +857,7 @@ public byte[] FileToBytes(string path, bool dontDelete = false) {
public string MSize()
{
- if (Is64Bit)
+ if (mProc.Is64Bit)
return ("x16");
else
return ("x8");
@@ -1868,59 +896,6 @@ public static string ByteArrayToString(byte[] ba)
return hex.ToString();
}
-#if WINXP
-#else
-
- public struct SYSTEM_INFO
- {
- public ushort processorArchitecture;
- ushort reserved;
- public uint pageSize;
- public UIntPtr minimumApplicationAddress;
- public UIntPtr maximumApplicationAddress;
- public IntPtr activeProcessorMask;
- public uint numberOfProcessors;
- public uint processorType;
- public uint allocationGranularity;
- public ushort processorLevel;
- public ushort processorRevision;
- }
-
- public struct MEMORY_BASIC_INFORMATION32
- {
- public UIntPtr BaseAddress;
- public UIntPtr AllocationBase;
- public uint AllocationProtect;
- public uint RegionSize;
- public uint State;
- public uint Protect;
- public uint Type;
- }
-
- public struct MEMORY_BASIC_INFORMATION64
- {
- public UIntPtr BaseAddress;
- public UIntPtr AllocationBase;
- public uint AllocationProtect;
- public uint __alignment1;
- public ulong RegionSize;
- public uint State;
- public uint Protect;
- public uint Type;
- public uint __alignment2;
- }
-
- public struct MEMORY_BASIC_INFORMATION
- {
- public UIntPtr BaseAddress;
- public UIntPtr AllocationBase;
- public uint AllocationProtect;
- public long RegionSize;
- public uint State;
- public uint Protect;
- public uint Type;
- }
-
public ulong GetMinAddress()
{
SYSTEM_INFO SI;
@@ -1942,7 +917,7 @@ public bool DumpMemory(string file = "dump.dmp")
// saving the values as long ints so I won't have to do a lot of casts later
Int64 proc_min_address_l = (Int64)proc_min_address; //(Int64)procs.MainModule.BaseAddress;
- Int64 proc_max_address_l = (Int64)theProc.VirtualMemorySize64 + proc_min_address_l;
+ Int64 proc_max_address_l = (Int64)mProc.Process.VirtualMemorySize64 + proc_min_address_l;
//int arrLength = 0;
if (File.Exists(file))
@@ -1952,12 +927,12 @@ public bool DumpMemory(string file = "dump.dmp")
MEMORY_BASIC_INFORMATION memInfo = new MEMORY_BASIC_INFORMATION();
while (proc_min_address_l < proc_max_address_l)
{
- VirtualQueryEx(pHandle, proc_min_address, out memInfo);
+ VirtualQueryEx(mProc.Handle, proc_min_address, out memInfo);
byte[] buffer = new byte[(Int64)memInfo.RegionSize];
UIntPtr test = (UIntPtr)((Int64)memInfo.RegionSize);
UIntPtr test2 = (UIntPtr)((Int64)memInfo.BaseAddress);
- ReadProcessMemory(pHandle, test2, buffer, test, IntPtr.Zero);
+ ReadProcessMemory(mProc.Handle, test2, buffer, test, IntPtr.Zero);
AppendAllBytes(file, buffer); //due to memory limits, we have to dump it then store it in an array.
//arrLength += buffer.Length;
@@ -1971,310 +946,7 @@ public bool DumpMemory(string file = "dump.dmp")
return true;
}
- ///
- /// Array of byte scan.
- ///
- /// array of bytes to search for, OR your ini code label.
- /// Include writable addresses in scan
- /// Include executable addresses in scan
- /// ini file (OPTIONAL)
- /// IEnumerable of all addresses found.
- public Task> AoBScan(string search, bool writable = false, bool executable = true, string file = "")
- {
- return AoBScan(0, long.MaxValue, search, writable, executable, file);
- }
-
- ///
- /// Array of byte scan.
- ///
- /// array of bytes to search for, OR your ini code label.
- /// Include readable addresses in scan
- /// Include writable addresses in scan
- /// Include executable addresses in scan
- /// ini file (OPTIONAL)
- /// IEnumerable of all addresses found.
- public Task> AoBScan(string search, bool readable, bool writable, bool executable, string file = "")
- {
- return AoBScan(0, long.MaxValue, search, readable, writable, executable, file);
- }
-
-
- ///
- /// Array of Byte scan.
- ///
- /// Your starting address.
- /// ending address
- /// array of bytes to search for, OR your ini code label.
- /// ini file (OPTIONAL)
- /// Include writable addresses in scan
- /// Include executable addresses in scan
- /// IEnumerable of all addresses found.
- public Task> AoBScan(long start, long end, string search, bool writable = false, bool executable = true, string file = "")
- {
- // Not including read only memory was scan behavior prior.
- return AoBScan(start, end, search, false, writable, executable, file);
- }
-
- ///
- /// Array of Byte scan.
- ///
- /// Your starting address.
- /// ending address
- /// array of bytes to search for, OR your ini code label.
- /// ini file (OPTIONAL)
- /// Include readable addresses in scan
- /// Include writable addresses in scan
- /// Include executable addresses in scan
- /// IEnumerable of all addresses found.
- public Task> AoBScan(long start, long end, string search, bool readable, bool writable, bool executable, string file = "")
- {
- return Task.Run(() =>
- {
- var memRegionList = new List();
-
- string memCode = LoadCode(search, file);
-
- string[] stringByteArray = memCode.Split(' ');
-
- byte[] aobPattern = new byte[stringByteArray.Length];
- byte[] mask = new byte[stringByteArray.Length];
-
- for (var i = 0; i < stringByteArray.Length; i++)
- {
- string ba = stringByteArray[i];
-
- if (ba == "??" || (ba.Length == 1 && ba == "?"))
- {
- mask[i] = 0x00;
- stringByteArray[i] = "0x00";
- }
- else if (Char.IsLetterOrDigit(ba[0]) && ba[1] == '?')
- {
- mask[i] = 0xF0;
- stringByteArray[i] = ba[0] + "0";
- }
- else if (Char.IsLetterOrDigit(ba[1]) && ba[0] == '?')
- {
- mask[i] = 0x0F;
- stringByteArray[i] = "0" + ba[1];
- }
- else
- mask[i] = 0xFF;
- }
-
-
- for (int i = 0; i < stringByteArray.Length; i++)
- aobPattern[i] = (byte)(Convert.ToByte(stringByteArray[i], 16) & mask[i]);
-
- SYSTEM_INFO sys_info = new SYSTEM_INFO();
- GetSystemInfo(out sys_info);
-
- UIntPtr proc_min_address = sys_info.minimumApplicationAddress;
- UIntPtr proc_max_address = sys_info.maximumApplicationAddress;
-
- if (start < (long)proc_min_address.ToUInt64())
- start = (long)proc_min_address.ToUInt64();
-
- if (end > (long)proc_max_address.ToUInt64())
- end = (long)proc_max_address.ToUInt64();
-
- Debug.WriteLine("[DEBUG] memory scan starting... (start:0x" + start.ToString(MSize()) + " end:0x" + end.ToString(MSize()) + " time:" + DateTime.Now.ToString("h:mm:ss tt") + ")");
- UIntPtr currentBaseAddress = new UIntPtr((ulong)start);
-
- MEMORY_BASIC_INFORMATION memInfo = new MEMORY_BASIC_INFORMATION();
-
- //Debug.WriteLine("[DEBUG] start:0x" + start.ToString("X8") + " curBase:0x" + currentBaseAddress.ToUInt64().ToString("X8") + " end:0x" + end.ToString("X8") + " size:0x" + memInfo.RegionSize.ToString("X8") + " vAloc:" + VirtualQueryEx(pHandle, currentBaseAddress, out memInfo).ToUInt64().ToString());
-
- while (VirtualQueryEx(pHandle, currentBaseAddress, out memInfo).ToUInt64() != 0 &&
- currentBaseAddress.ToUInt64() < (ulong)end &&
- currentBaseAddress.ToUInt64() + (ulong)memInfo.RegionSize >
- currentBaseAddress.ToUInt64())
- {
- bool isValid = memInfo.State == MEM_COMMIT;
- isValid &= memInfo.BaseAddress.ToUInt64() < (ulong)proc_max_address.ToUInt64();
- isValid &= ((memInfo.Protect & PAGE_GUARD) == 0);
- isValid &= ((memInfo.Protect & PAGE_NOACCESS) == 0);
- isValid &= (memInfo.Type == MEM_PRIVATE) || (memInfo.Type == MEM_IMAGE);
-
- if (isValid)
- {
- bool isReadable = (memInfo.Protect & PAGE_READONLY) > 0;
-
- bool isWritable = ((memInfo.Protect & PAGE_READWRITE) > 0) ||
- ((memInfo.Protect & PAGE_WRITECOPY) > 0) ||
- ((memInfo.Protect & PAGE_EXECUTE_READWRITE) > 0) ||
- ((memInfo.Protect & PAGE_EXECUTE_WRITECOPY) > 0);
-
- bool isExecutable = ((memInfo.Protect & PAGE_EXECUTE) > 0) ||
- ((memInfo.Protect & PAGE_EXECUTE_READ) > 0) ||
- ((memInfo.Protect & PAGE_EXECUTE_READWRITE) > 0) ||
- ((memInfo.Protect & PAGE_EXECUTE_WRITECOPY) > 0);
-
- isReadable &= readable;
- isWritable &= writable;
- isExecutable &= executable;
-
- isValid &= isReadable || isWritable || isExecutable;
- }
-
- if (!isValid)
- {
- currentBaseAddress = new UIntPtr(memInfo.BaseAddress.ToUInt64() + (ulong)memInfo.RegionSize);
- continue;
- }
-
- MemoryRegionResult memRegion = new MemoryRegionResult
- {
- CurrentBaseAddress = currentBaseAddress,
- RegionSize = memInfo.RegionSize,
- RegionBase = memInfo.BaseAddress
- };
-
- currentBaseAddress = new UIntPtr(memInfo.BaseAddress.ToUInt64() + (ulong)memInfo.RegionSize);
-
- //Console.WriteLine("SCAN start:" + memRegion.RegionBase.ToString() + " end:" + currentBaseAddress.ToString());
-
- if (memRegionList.Count > 0)
- {
- var previousRegion = memRegionList[memRegionList.Count - 1];
-
- if ((long)previousRegion.RegionBase + previousRegion.RegionSize == (long)memInfo.BaseAddress)
- {
- memRegionList[memRegionList.Count - 1] = new MemoryRegionResult
- {
- CurrentBaseAddress = previousRegion.CurrentBaseAddress,
- RegionBase = previousRegion.RegionBase,
- RegionSize = previousRegion.RegionSize + memInfo.RegionSize
- };
-
- continue;
- }
- }
-
- memRegionList.Add(memRegion);
- }
-
- ConcurrentBag bagResult = new ConcurrentBag();
-
- Parallel.ForEach(memRegionList,
- (item, parallelLoopState, index) =>
- {
- long[] compareResults = CompareScan(item, aobPattern, mask);
-
- foreach (long result in compareResults)
- bagResult.Add(result);
- });
-
- Debug.WriteLine("[DEBUG] memory scan completed. (time:" + DateTime.Now.ToString("h:mm:ss tt") + ")");
-
- return bagResult.ToList().OrderBy(c => c).AsEnumerable();
- });
- }
-
- ///
- /// Array of bytes scan
- ///
- /// Starting address or ini label
- /// ending address
- /// array of bytes to search for or your ini code label
- /// ini file
- /// First address found
- public async Task AoBScan(string code, long end, string search, string file ="")
- {
- long start = (long)GetCode(code, file).ToUInt64();
-
- return (await AoBScan(start, end, search, true, true, true, file)).FirstOrDefault();
- }
-
- private long[] CompareScan(MemoryRegionResult item, byte[] aobPattern, byte[] mask)
- {
- if (mask.Length != aobPattern.Length)
- throw new ArgumentException($"{nameof(aobPattern)}.Length != {nameof(mask)}.Length");
-
- IntPtr buffer = Marshal.AllocHGlobal((int)item.RegionSize);
-
- ReadProcessMemory(pHandle, item.CurrentBaseAddress, buffer, (UIntPtr)item.RegionSize, out ulong bytesRead);
-
- int result = 0 - aobPattern.Length;
- List ret = new List();
- unsafe
- {
- do
- {
-
- result = FindPattern((byte*)buffer.ToPointer(), (int)bytesRead, aobPattern, mask, result + aobPattern.Length);
-
- if (result >= 0)
- ret.Add((long) item.CurrentBaseAddress + result);
-
- } while (result != -1);
- }
-
- Marshal.FreeHGlobal(buffer);
-
- return ret.ToArray();
- }
-
- private int FindPattern(byte[] body, byte[] pattern, byte[] masks, int start = 0)
- {
- int foundIndex = -1;
-
- if (body.Length <= 0 || pattern.Length <= 0 || start > body.Length - pattern.Length ||
- pattern.Length > body.Length) return foundIndex;
-
- for (int index = start; index <= body.Length - pattern.Length; index++)
- {
- if (((body[index] & masks[0]) == (pattern[0] & masks[0])))
- {
- var match = true;
- for (int index2 = 1; index2 <= pattern.Length - 1; index2++)
- {
- if ((body[index + index2] & masks[index2]) == (pattern[index2] & masks[index2])) continue;
- match = false;
- break;
-
- }
-
- if (!match) continue;
-
- foundIndex = index;
- break;
- }
- }
-
- return foundIndex;
- }
-
- private unsafe int FindPattern(byte* body, int bodyLength, byte[] pattern, byte[] masks, int start = 0)
- {
- int foundIndex = -1;
-
- if (bodyLength <= 0 || pattern.Length <= 0 || start > bodyLength - pattern.Length ||
- pattern.Length > bodyLength) return foundIndex;
-
- for (int index = start; index <= bodyLength - pattern.Length; index++)
- {
- if (((body[index] & masks[0]) == (pattern[0] & masks[0])))
- {
- var match = true;
- for (int index2 = 1; index2 <= pattern.Length - 1; index2++)
- {
- if ((body[index + index2] & masks[index2]) == (pattern[index2] & masks[index2])) continue;
- match = false;
- break;
-
- }
-
- if (!match) continue;
-
- foundIndex = index;
- break;
- }
- }
-
- return foundIndex;
- }
+
-#endif
}
}
diff --git a/Test/TestApp/MemoryTestApp.sln b/Test/TestApp/MemoryTestApp.sln
index 34d5665..b0f90c5 100644
--- a/Test/TestApp/MemoryTestApp.sln
+++ b/Test/TestApp/MemoryTestApp.sln
@@ -23,8 +23,8 @@ Global
{75D0CEA2-0444-4959-B797-91ADD7FD3A4A}.Release|Any CPU.Build.0 = Release|Any CPU
{75D0CEA2-0444-4959-B797-91ADD7FD3A4A}.Release|x64.ActiveCfg = Release|x64
{75D0CEA2-0444-4959-B797-91ADD7FD3A4A}.Release|x64.Build.0 = Release|x64
- {D506F6CE-1A4C-4655-809E-928893D45005}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D506F6CE-1A4C-4655-809E-928893D45005}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D506F6CE-1A4C-4655-809E-928893D45005}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {D506F6CE-1A4C-4655-809E-928893D45005}.Debug|Any CPU.Build.0 = Debug|x64
{D506F6CE-1A4C-4655-809E-928893D45005}.Debug|x64.ActiveCfg = Debug|Any CPU
{D506F6CE-1A4C-4655-809E-928893D45005}.Debug|x64.Build.0 = Debug|Any CPU
{D506F6CE-1A4C-4655-809E-928893D45005}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/Test/TestApp/MemoryTestApp/Classes/Processing.cs b/Test/TestApp/MemoryTestApp/Classes/Processing.cs
index 498e060..35c7c00 100644
--- a/Test/TestApp/MemoryTestApp/Classes/Processing.cs
+++ b/Test/TestApp/MemoryTestApp/Classes/Processing.cs
@@ -15,70 +15,45 @@ public partial class TrainerForm : Form
public bool ProcOpen = false;
///
- /// Process opening code. Generates a list of modules too.
+ /// After process opens, update UI. Generates a list of modules too.
///
- public void OpenTheProc()
+ public void ProcUIUpdate()
{
- ProcTypeBox.Invoke((MethodInvoker)delegate
- {
- if (String.Compare(ProcTypeBox.Text, "Name") == 0) // if combobox set to Name, use string
- ProcOpen = m.OpenProcess(ProcTextBox.Text);
- else // if combobox set to ID, use integer
- ProcOpen = m.OpenProcess(Convert.ToInt32(ProcTextBox.Text));
- });
-
if (ProcOpen) // if process opens successfully
{
- OpenProcessBtn.Invoke((MethodInvoker)delegate
- {
- OpenProcessBtn.Text = "Close Process";
- OpenProcessBtn.ForeColor = Color.Red;
- });
+ OpenProcessBtn.Text = "Close Process";
+ OpenProcessBtn.ForeColor = Color.Red;
- ModuleList.Invoke((MethodInvoker)delegate
- {
- if (ModuleList.Items.Count <= 0)
- GetModuleList();
- });
+ if (ModuleList.Items.Count <= 0)
+ GetModuleList();
}
else // on process open fail, show error message
{
//MessageBox.Show("ERROR: Process open failed!");
- ProcStatus.Invoke((MethodInvoker)delegate
- {
- ProcStatus.Text = "Closed";
- ProcStatus.ForeColor = Color.Red;
- });
- ModuleList.Invoke((MethodInvoker)delegate
- {
- if (ModuleList.Items.Count > 0)
- ModuleList.Items.Clear();
- });
+ ProcStatus.Text = "Closed";
+ ProcStatus.ForeColor = Color.Red;
+
+ if (ModuleList.Items.Count > 0)
+ ModuleList.Items.Clear();
StopWorker = true;
}
}
public void GetModuleList()
{
- ModuleList.Invoke((MethodInvoker)delegate
+ ModuleList.Items.Clear();
+ foreach (KeyValuePair kvp in m.mProc.Modules) // iterate through process module list
{
- ModuleList.Items.Clear();
- foreach (KeyValuePair kvp in m.modules) // iterate through process module list
- {
- string[] arr = new string[4];
- ListViewItem itm;
- arr[0] = "0x" + kvp.Value.ToString("x8");
- arr[1] = kvp.Key;
- itm = new ListViewItem(arr);
- ModuleList.Items.Add(itm);
- }
- });
+ string[] arr = new string[4];
+ ListViewItem itm;
+ arr[0] = "0x" + kvp.Value.ToString("x8");
+ arr[1] = kvp.Key;
+ itm = new ListViewItem(arr);
+ ModuleList.Items.Add(itm);
+ }
- ProcStatus.Invoke((MethodInvoker)delegate
- {
- ProcStatus.Text = "Open";
- ProcStatus.ForeColor = Color.Green;
- });
+ ProcStatus.Text = "Open";
+ ProcStatus.ForeColor = Color.Green;
}
///
diff --git a/Test/TestApp/MemoryTestApp/Forms/TrainerForm.Designer.cs b/Test/TestApp/MemoryTestApp/Forms/TrainerForm.Designer.cs
index fe58da2..9c8f1d1 100644
--- a/Test/TestApp/MemoryTestApp/Forms/TrainerForm.Designer.cs
+++ b/Test/TestApp/MemoryTestApp/Forms/TrainerForm.Designer.cs
@@ -91,6 +91,7 @@ private void InitializeComponent()
this.ProcTextBox.Size = new System.Drawing.Size(120, 20);
this.ProcTextBox.TabIndex = 0;
this.ProcTextBox.Text = "Xae\'s Quest";
+ this.ProcTextBox.TextChanged += new System.EventHandler(this.ProcTextBox_TextChanged);
//
// label1
//
@@ -601,8 +602,11 @@ private void InitializeComponent()
//
// BackgroundWork
//
+ this.BackgroundWork.WorkerReportsProgress = true;
this.BackgroundWork.WorkerSupportsCancellation = true;
this.BackgroundWork.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWork_DoWork);
+ this.BackgroundWork.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.BackgroundWork_ProgressChanged);
+ this.BackgroundWork.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWork_RunWorkerCompleted);
//
// TrainerForm
//
diff --git a/Test/TestApp/MemoryTestApp/Forms/TrainerForm.cs b/Test/TestApp/MemoryTestApp/Forms/TrainerForm.cs
index bcd2bfd..a32f7f9 100644
--- a/Test/TestApp/MemoryTestApp/Forms/TrainerForm.cs
+++ b/Test/TestApp/MemoryTestApp/Forms/TrainerForm.cs
@@ -30,6 +30,7 @@ public TrainerForm()
Mem m = new Mem(); // Declare m as our Memory.dll function reference variable.
bool StopWorker = false;
+ string ProcNameOrID;
private void TrainerForm_Shown(object sender, EventArgs e)
{
@@ -41,6 +42,8 @@ private void TrainerForm_Shown(object sender, EventArgs e)
private void OpenProcessBtn_Click(object sender, EventArgs e)
{
+ ProcNameOrID = ProcTextBox.Text;
+ // start BG worker if not already started
if (!BackgroundWork.IsBusy)
{
BackgroundWork.RunWorkerAsync();
@@ -102,18 +105,13 @@ private void BackgroundWork_DoWork(object sender, DoWorkEventArgs e)
// infinite loop that checks if the process is available and open, if not, modify the UI.
while (true)
{
- OpenTheProc();
- System.Threading.Thread.Sleep(1000);
- if (StopWorker)
- {
- StopWorker = false;
- OpenProcessBtn.Invoke((MethodInvoker)delegate
- {
- OpenProcessBtn.Text = "Close Process";
- OpenProcessBtn.ForeColor = Color.Red;
- });
- break;
- }
+ if (String.Compare(ProcTypeBox.Text, "Name") == 0) // if combobox set to Name, use string
+ ProcOpen = m.OpenProcess(ProcNameOrID);
+ else // if combobox set to ID, use integer
+ ProcOpen = m.OpenProcess(Convert.ToInt32(ProcNameOrID));
+
+ BackgroundWork.ReportProgress(0); // do UI thread stuff
+ Thread.Sleep(1000);
}
}
@@ -122,5 +120,25 @@ private void UpdateModulesButton_Click(object sender, EventArgs e)
if (ProcOpen)
GetModuleList();
}
+
+ private void BackgroundWork_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
+ {
+ if (StopWorker)
+ {
+ StopWorker = false;
+ OpenProcessBtn.Text = "Open Process";
+ OpenProcessBtn.ForeColor = Color.Black;
+ }
+ }
+
+ private void BackgroundWork_ProgressChanged(object sender, ProgressChangedEventArgs e)
+ {
+ ProcUIUpdate();
+ }
+
+ private void ProcTextBox_TextChanged(object sender, EventArgs e)
+ {
+ StopWorker = true; // stop worker if we're changing process name
+ }
}
}