Advertisement
Sombody101

Memory Management

Aug 11th, 2023
1,310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.72 KB | None | 0 0
  1. using System.Diagnostics;
  2. using System.Runtime.InteropServices;
  3. using System.Text;
  4.  
  5. namespace MemoryManagement;
  6.  
  7. public class MemoryManagement
  8. {
  9.     // Unsed
  10.     private const int PROCESS_CREATE_THREAD = 2;
  11.     private const int PROCESS_QUERY_INFORMATION = 1024;
  12.     private const int PROCESS_VM_OPERATION = 8;
  13.     private const int PROCESS_VM_WRITE = 32;
  14.     private const int PROCESS_VM_READ = 16;
  15.     private const uint MEM_COMMIT = 4096u;
  16.     private const uint MEM_RESERVE = 8192u;
  17.     private const uint PAGE_READWRITE = 4u;
  18.     //
  19.  
  20.     /// <summary>
  21.     /// The handle of the attached process
  22.     /// </summary>
  23.     public static nint ProcessHandle { get => pHandle; }
  24.     private static nint pHandle;
  25.  
  26.     /// <summary>
  27.     /// The DLL
  28.     /// </summary>
  29.     private ProcessModule? mainModule;
  30.  
  31.     /// <summary>
  32.     /// The current attached process (Null when not attached)
  33.     /// </summary>
  34.     public Process? AttachedProcess { get => procs; }
  35.     private Process? procs = null;
  36.  
  37.     public Dictionary<string, nint> Modules { get; private set; } = new();
  38.  
  39.     // Private imports
  40.     [DllImport("kernel32.dll")]
  41.     private static extern bool WriteProcessMemory(nint hProcess, nint lpBaseAddress, string lpBuffer, nuint nSize, out nint lpNumberOfBytesWritten);
  42.  
  43.     [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
  44.     private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize, string lpFileName);
  45.  
  46.     [DllImport("kernel32.dll")]
  47.     private static extern bool ReadProcessMemory(nint hProcess, nuint lpBaseAddress, [Out] byte[] lpBuffer, nuint nSize, nint lpNumberOfBytesRead);
  48.  
  49.     [DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
  50.     private static extern bool _CloseHandle(nint hObject);
  51.  
  52.     [DllImport("kernel32.dll")]
  53.     private static extern bool WriteProcessMemory(nint hProcess, nuint lpBaseAddress, byte[] lpBuffer, nuint nSize, nint lpNumberOfBytesWritten);
  54.     //
  55.  
  56.     // Public imports
  57.     [DllImport("kernel32.dll")]
  58.     public static extern int CloseHandle(nint hObject);
  59.  
  60.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  61.     public static extern nint GetModuleHandle(string lpModuleName);
  62.  
  63.     [DllImport("kernel32.dll")]
  64.     public static extern nint OpenProcess(uint dwDesiredAccess, int bInheritHandle, int dwProcessId);
  65.     //
  66.  
  67.     /// <summary>
  68.     /// Attaches to the process
  69.     /// </summary>
  70.     /// <param name="procID"></param>
  71.     /// <returns></returns>
  72.     public bool OpenGameProcess(int procID)
  73.     {
  74.         if (procID is not 0)
  75.         {
  76.             procs = Process.GetProcessById(procID);
  77.             if (!procs.Responding)
  78.                 return false;
  79.             else
  80.             {
  81.                 pHandle = OpenProcess(2035711u, 1, procID);
  82.                 mainModule = procs.MainModule;
  83.                 RefreshModules();
  84.                 return true;
  85.             }
  86.         }
  87.         return false;
  88.     }
  89.  
  90.     /// <summary>
  91.     /// Refreshes the Modules dictionary
  92.     /// </summary>
  93.     public void RefreshModules()
  94.     {
  95.         if (procs is not null)
  96.         {
  97.             Modules.Clear();
  98.             foreach (ProcessModule processModule in procs.Modules)
  99.                 if (processModule.ModuleName is not "" &&
  100.                     processModule.ModuleName is not null &&
  101.                     !Modules.ContainsKey(processModule.ModuleName))
  102.                     if (processModule.ModuleName is not null)
  103.                         Modules.Add(processModule.ModuleName, processModule.BaseAddress);
  104.         }
  105.     }
  106.  
  107.     /// <summary>
  108.     /// Gets the ID of a process via its string name
  109.     /// </summary>
  110.     /// <param name="name"></param>
  111.     /// <returns></returns>
  112.     public int GetProcIDFromName(string name)
  113.     {
  114.         Process? process = Process.GetProcessesByName(name).FirstOrDefault();
  115.         return process?.Id ?? 0;
  116.     }
  117.  
  118.     /// <summary>
  119.     /// Closes the attached process
  120.     /// </summary>
  121.     public void CloseProcess()
  122.         => _ = CloseHandle(pHandle);
  123.  
  124.     /// <summary>
  125.     /// .INI file loader
  126.     /// </summary>
  127.     /// <param name="name"></param>
  128.     /// <param name="file"></param>
  129.     /// <returns></returns>
  130.     public string LoadCode(string name, string file)
  131.     {
  132.         StringBuilder stringBuilder = new(1024);
  133.         if (file is not "")
  134.             _ = GetPrivateProfileString("codes", name, "", stringBuilder, (uint)file.Length, file);
  135.         else
  136.             _ = stringBuilder.Append(name);
  137.  
  138.         return stringBuilder.ToString();
  139.     }
  140.  
  141.     /// <summary>
  142.     /// Read a string from the attached process
  143.     /// </summary>
  144.     /// <param name="code"></param>
  145.     /// <param name="file"></param>
  146.     /// <returns></returns>
  147.     public string ReadString(string code, string file = "")
  148.     {
  149.         _ = getCode(code, file, 4);
  150.  
  151.         byte[] array = new byte[10];
  152.         return ReadProcessMemory(pHandle,
  153.             !LoadCode(code, file).Contains(',') ?
  154.                 loadUIntPtrCode(code, file) :
  155.                 getCode(code, file, 4), array,
  156.             (nuint)10uL, nint.Zero) ? Encoding.UTF8.GetString(array) : "";
  157.     }
  158.  
  159.     /// <summary>
  160.     /// Write data to a specific address of the attached process
  161.     /// </summary>
  162.     /// <param name="code"></param>
  163.     /// <param name="type"></param>
  164.     /// <param name="write"></param>
  165.     /// <param name="file"></param>
  166.     /// <returns></returns>
  167.     public bool WriteMemory(string code, string type, string write, string file = "")
  168.     {
  169.         byte[] lpBuffer = new byte[4];
  170.         int num = 4;
  171.         nuint lpBaseAddress = !LoadCode(code, file).Contains(',') ? loadUIntPtrCode(code, file) : getCode(code, file, 4);
  172.  
  173.         switch (type)
  174.         {
  175.             case "float":
  176.                 lpBuffer = BitConverter.GetBytes(Convert.ToSingle(write));
  177.                 break;
  178.             case "int":
  179.                 lpBuffer = BitConverter.GetBytes(Convert.ToInt32(write));
  180.                 break;
  181.             case "byte":
  182.                 lpBuffer = BitConverter.GetBytes(Convert.ToInt32(write));
  183.                 num = 1;
  184.                 break;
  185.             case "string":
  186.                 lpBuffer = Encoding.UTF8.GetBytes(write);
  187.                 num = write.Length;
  188.                 break;
  189.         }
  190.  
  191.         return WriteProcessMemory(pHandle, lpBaseAddress, lpBuffer, (nuint)(ulong)(long)num, nint.Zero);
  192.     }
  193.  
  194.     private nuint loadUIntPtrCode(string name, string path = "")
  195.     {
  196.         string text = LoadCode(name, path);
  197.  
  198.         if (string.IsNullOrEmpty(text))
  199.             return nuint.Zero;
  200.  
  201.         string value = text[(text.IndexOf('+') + 1)..];
  202.  
  203.         if (string.IsNullOrEmpty(value))
  204.             return nuint.Zero;
  205.  
  206.         int num = Convert.ToInt32(value, 16);
  207.  
  208.         nuint uIntPtr = nuint.Zero;
  209.  
  210.         if (text.Contains("base") || text.Contains("main"))
  211.             uIntPtr = (nuint)mainModule.BaseAddress + (nuint)num;
  212.         else if (!text.Contains("base") && !text.Contains("main") && text.Contains('+'))
  213.         {
  214.             string[] array = text.Split('+');
  215.  
  216.             if (Modules.Count is 0 || !Modules.ContainsKey(array[0]))
  217.                 RefreshModules();
  218.  
  219.             Debug.WriteLine("module=" + array[0]);
  220.             uIntPtr = (nuint)Modules[array[0]] + (nuint)num;
  221.         }
  222.         else
  223.             uIntPtr = (nuint)num;
  224.  
  225.         return uIntPtr;
  226.     }
  227.  
  228.     private nuint getCode(string name, string path, int size = 4)
  229.     {
  230.         string text = LoadCode(name, path);
  231.  
  232.         if (string.IsNullOrEmpty(text))
  233.             return nuint.Zero;
  234.  
  235.         string[] elements = text.Split('+', ',');
  236.         int[] offsets = new int[elements.Length];
  237.  
  238.         for (int i = 0; i < elements.Length; i++)
  239.             offsets[i] = Convert.ToInt32(elements[i], 16);
  240.  
  241.         nuint baseAddress = nuint.Zero;
  242.  
  243.         if (text.Contains("base") || text.Contains("main"))
  244.             baseAddress = (nuint)mainModule.BaseAddress;
  245.         else if (!text.Contains("base") && !text.Contains("main") && text.Contains('+'))
  246.         {
  247.             string moduleName = elements[0];
  248.  
  249.             if (Modules.Count is 0 || !Modules.ContainsKey(moduleName))
  250.                 RefreshModules();
  251.  
  252.             baseAddress = (nuint)Modules[moduleName];
  253.         }
  254.  
  255.         byte[] buffer = new byte[size];
  256.  
  257.         uint resultValue = 0;
  258.         nuint resultAddress = baseAddress;
  259.  
  260.         for (int i = 0; i < offsets.Length; i++)
  261.         {
  262.             resultAddress += (nuint)offsets[i];
  263.             _ = ReadProcessMemory(pHandle, resultAddress, buffer, (nuint)size, nint.Zero);
  264.             resultValue = BitConverter.ToUInt32(buffer, 0);
  265.         }
  266.  
  267.         return new nuint(resultValue);
  268.     }
  269. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement