2017-06-01 236 views
1

我正在製作一個類似於作弊引擎的內存掃描器應用程序,但希望在c#中做一個測試項目...... 所以,我正在使用它使用使用Boyer-Moore的https://github.com/Adversities/Cheatool在64位進程中使用Boyer-Moore算法

過程檢測是在working..and 32個進程我能找到的字節陣列等`

60 8A DD BC 01 48 00 00 88 01 04 02 00 01 44 D0 30 60 8C DD 01 46 AD 1F 00 2A 12 10 00 00 29

`正確,如果我尋找使用博耶-摩爾方法他們...

,但由於某種原因,我不能在64個的進程找到它們。

如何更新dll庫中找到的方法以及我的應用程序以適應64位進程? 現在,作爲即時通訊很新的C#和試驗一樣,我起草了測試程序:測試應用程序的

代碼:

using System; 
using System.Diagnostics; 

using System.Linq; 

using System.Threading.Tasks; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 


using System.Threading; 

namespace MemTester 
{ 





    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.Title = "Memory Addres Tester [?] (PID: ?)"; 

      //Console.Write("Process to open => "); 
      //string process = Console.ReadLine(); 
      string process = " "; 
      int ppid = 0; 
      while (ppid == 0) 
      { 
       Console.Write("Process PID to open as int=> "); 
       string ppid2 = Console.ReadLine(); 
       if ((ppid2 == "") || (ppid2 == null) || (ppid2.Length < 2)) 
       { ppid2 = "0"; } 
       ppid = Convert.ToInt32(ppid2); 
      } 
      while (true) 
      { 
       Console.Write("Value to scan => "); 
       string aob = Console.ReadLine(); 
       if (aob == "exit") break; 

       MeMory(process, aob, ppid); 
      } 
     } 
     public abstract class Manager 
     { 
      [DllImport("KERNEL32.DLL", SetLastError = true)] 
      public static extern bool WriteProcessMemory(
       IntPtr process, IntPtr address, byte[] buffer, uint size, ref uint written); 

      [DllImport("KERNEL32.DLL")] 
      public static extern bool VirtualProtectEx(IntPtr process, IntPtr address, 
       uint size, uint access, out uint oldProtect); 

      [DllImport("KERNEL32.DLL")] 
      public static extern int CloseHandle(IntPtr objectHandle); 

      [DllImport("KERNEL32.DLL")] 
      public static extern IntPtr OpenProcess(uint access, bool inheritHandler, uint processId); 

      [Flags] 
      public enum Protection 
      { 
       PEReadWrite = 0x40, 
       PReadWrite = 0x04 
      } 

      [Flags] 
      public enum Access 
      { 
       Synchronize = 0x100000, 
       StandardRightsRequired = 0x000F0000, 
       AllAccess = StandardRightsRequired | Synchronize | 0xFFFF 
      } 
     } 
     public abstract class Reader 
     { 
      [StructLayout(LayoutKind.Sequential)] 
      public struct MEMORY_BASIC_INFORMATION 
      { 
       public IntPtr BaseAddress; 
       public IntPtr AllocationBase; 
       public uint AllocationProtect; 
       public uint RegionSize; 
       public uint State; 
       public uint Protect; 
       public uint Type; 
      } 

      [DllImport("KERNEL32.DLL")] 
      public static extern int VirtualQueryEx(IntPtr hProcess, 
       IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength); 

      [DllImport("KERNEL32.DLL", SetLastError = true)] 
      public static extern bool ReadProcessMemory(
       IntPtr process, IntPtr address, byte[] buffer, uint size, ref uint read); 

      public List<MEMORY_BASIC_INFORMATION> MemoryRegion = new List<MEMORY_BASIC_INFORMATION>(); 
     } 
     public class BoyerMoore : Reader 
     { 
      private IntPtr _processHandle; 

      public BoyerMoore(IntPtr processHandle) 
      { 
       _processHandle = processHandle; 
      } 

      private void MemInfo(bool unwritable) 
      { 
       IntPtr Addy = new IntPtr(); 

       while (true) 
       { 
        MEMORY_BASIC_INFORMATION memInfo = new MEMORY_BASIC_INFORMATION(); 

        int MemDump = VirtualQueryEx(_processHandle, Addy, out memInfo, Marshal.SizeOf(memInfo)); 

        if (MemDump == 0) break; 

        if ((memInfo.State & 0x1000) != 0) 
        { 
         if (unwritable && (memInfo.Protect & 0xCC) != 0) 
          MemoryRegion.Add(memInfo); 
         else 
          MemoryRegion.Add(memInfo); 
        } 

        Addy = new IntPtr(memInfo.BaseAddress.ToInt32() + (int)memInfo.RegionSize); 
       } 
      } 

      private void BoyerAlgo(IntPtr baseAddress, byte[] memoryBrick, byte[] pattern, ref List<IntPtr> addresses) 
      { 
       int offSet = 0; 
       while ((offSet = Array.IndexOf(memoryBrick, pattern[0], offSet)) != -1) 
       { 
        if (pattern.Length > 1) 
         for (int i = 1; i < pattern.Length; i++) 
         { 
          if (memoryBrick.Length <= offSet + pattern.Length 
           || pattern[i] != memoryBrick[offSet + i]) break; 

          if (i == pattern.Length - 1) 
           addresses.Add(new IntPtr((int)baseAddress + offSet)); 
         } 
        else addresses.Add(new IntPtr((int)baseAddress + offSet)); 
        offSet++; 
       } 
      } 

      private void BoyerAlgo(IntPtr baseAddress, byte[] memoryBrick, string pattern, ref List<IntPtr> addresses) 
      { 
       int offSet = 0; 
       string[] aob = pattern.Split(' '); 
       List<int> bytesPos = new List<int>(); 

       for (int i = 0; i < aob.Length; i++) 
        if (aob[i] != "??") 
         bytesPos.Add(i); 

       if (bytesPos.Count != 0) 
        while ((offSet = Array.IndexOf(memoryBrick, (byte)Convert.ToInt32(aob[bytesPos[0]], 16), offSet)) != -1) 
        { 
         if (bytesPos.Count > 1) 
          for (int i = 1; i < bytesPos.Count; i++) 
          { 
           if (memoryBrick.Length <= offSet + pattern.Length 
            || (byte)Convert.ToInt32(aob[bytesPos[i]], 16) 
            != memoryBrick[(offSet - bytesPos[0]) + bytesPos[i]]) break; 

           if (i == bytesPos.Count - 1) 
            if (aob[0] == "??") 
             addresses.Add(new IntPtr((int)baseAddress + (offSet - bytesPos[0]))); 
            else addresses.Add(new IntPtr((int)baseAddress + offSet)); 
          } 
         else 
          addresses.Add(new IntPtr((int)baseAddress + (offSet - bytesPos[0]))); 
         offSet++; 
        } 
       else 
        for (int i = 0; i < memoryBrick.Length; i++) 
         addresses.Add(new IntPtr((int)baseAddress + i)); 
      } 

      public CancellationTokenSource cancelToken { get; set; } = new CancellationTokenSource(); 

      public Task<IntPtr[]> AoByte(string pattern, bool unwritable = false) 
      { 
       if (!pattern.Contains("?")) 
       { 
        byte[] buff = pattern.Split(' ').Select(by => 
        (byte)Convert.ToInt32(by, 16)).ToArray(); 

        return Task.Run(() => { return GeneralScan(buff, unwritable); }, cancelToken.Token); 
       } 
       else return Task.Run(() => { return WCScan(pattern, unwritable); }, cancelToken.Token); 
      } 


      private IntPtr[] GeneralScan(byte[] buff, bool unwritable) 
      { 
       MemInfo(unwritable); 

       List<IntPtr> addresses = new List<IntPtr>(); 

       for (int i = 0; i < MemoryRegion.Count; i++) 
       { 
        uint read = 0; 
        byte[] wholeMemory = new byte[MemoryRegion[i].RegionSize]; 

        ReadProcessMemory(_processHandle, MemoryRegion[i].BaseAddress, wholeMemory, 
         MemoryRegion[i].RegionSize, ref read); 

        BoyerAlgo(MemoryRegion[i].BaseAddress, wholeMemory, buff, ref addresses); 
       } 
       return addresses.ToArray(); 
      } 

      private IntPtr[] WCScan(string pattern, bool unwritable) 
      { 
       MemInfo(unwritable); 

       List<IntPtr> addresses = new List<IntPtr>(); 

       for (int i = 0; i < MemoryRegion.Count; i++) 
       { 
        uint read = 0; 
        byte[] wholeMemory = new byte[MemoryRegion[i].RegionSize]; 

        ReadProcessMemory(_processHandle, MemoryRegion[i].BaseAddress, wholeMemory, 
         MemoryRegion[i].RegionSize, ref read); 

        BoyerAlgo(MemoryRegion[i].BaseAddress, wholeMemory, pattern, ref addresses); 
       } 
       return addresses.ToArray(); 
      } 
     } 

     public class MeMorybox : Manager 
     { 

      public BoyerMoore BoyerScan { get; set; } 


      IntPtr _processHandle; 

      public MeMorybox(Process process) 
      { 
       _processHandle = OpenProcess((uint)Access.AllAccess, false, (uint)process.Id); 


       BoyerScan = new BoyerMoore(_processHandle); 

      } 



      ~MeMorybox() 
      { 
       CloseHandle(_processHandle); 
      } 

     } 

     static void MeMory(string process, string aob, int ppid) 
     { 
      //Process[] processList = Process.GetProcessesByName(process); 
      Process p = Process.GetProcessById(ppid); ; 

      MeMorybox notepad = new MeMorybox(p); 

      Console.WriteLine("Hex value of pid:"+p.Id.ToString("x8")); 

      var addresses = notepad.BoyerScan.AoByte(aob).GetAwaiter().GetResult(); 

     Console.WriteLine(addresses.Length + " hits found for pid:"+ppid); 

     Console.WriteLine(); 
    } 
} 

閃存工藝測試.. 火狐.. < 32位過程> 鉻.. < 64位進程> 鏈接直接測試:https://apps.facebook.com/candycrushsoda

字節的數組,以搜尋作爲試驗:60? ?? ?? ?? ?? ?? ?? ?? 01 ?? ?? 00 01 44 ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 2A 12 10 00 00 29

它應該給1個結果

在Firefox

- Flashplayerplugin它工作得很好,

在鉻

- 包含模塊pepflashplayer.dll它的處理>中的一個沒有給出結果,因爲chrome是一個64位的進程。

爲了驗證我的雙用cheatengine檢查,在這兩種情況下,AOB正確發現

+5

將您的代碼添加到問題本身。不要將我們鏈接到可下載的二進制文件。 – Amy

+0

「但由於某種原因,我無法在64位進程中找到它們」 - 以何種方式?你無法讀取內存,或找不到內存中的數據?這似乎不太可能與Boyer-Moore的部分有關...... –

+0

我強烈懷疑你包含的絕大多數代碼都是不相關的。請減少到[mcve]。 –

回答

2

我想你的代碼對我來說,檢查一個64位進程時,它產生的上線算術溢出:

 Addy = new IntPtr(memInfo.BaseAddress.ToInt32() + (int) memInfo.RegionSize); 

(你可以嘗試一下,打開生成/高級... /檢查算術......在項目設置)

它看起來像VirtualQueryEx可以在MEMORY_BASIC_INFORMA填寫TION.BaseAddress與Int32.MaxValue()查詢64位進程時。

我認爲讓它與32位和64位進程兼容的最簡單方法就是隻針對64位體系結構並相應地編寫代碼,如果可以的話。 我建議你嘗試以下方法:

  1. 更改項目的目標平臺到x64
  2. 更新MEMORY_BASIC_INFORMATION,以便其映射到結構(底部一個在備註)的64位版本,而不是其他一。 https://msdn.microsoft.com/en-us/library/windows/desktop/aa366775(v=vs.85).aspx
  3. 的代碼更新後使用64位算術徘徊無論它使用BaseAddress或RegionSize(例如使它們的IntPtr並使用.ToInt64()而不是.ToInt32())
1

Right..so第i個只好用建設有任何的CPU,以 「寧可32位」 取消選中 然後

public class MeMorybox : Manager 
     { 

      public BoyerMoore BoyerScan { get; set; } 


      IntPtr _processHandle; 

      public MeMorybox(Process process) 
      { 
       _processHandle = OpenProcess((uint)Access.AllAccess, false, (uint)process.Id); 


       BoyerScan = new BoyerMoore(_processHandle); 

      } 

得到更新爲:

UIntPtr _processHandle; 

     public MeMorybox(Process process) 
     { 
      _processHandle = OpenProcess((uint)Access.AllAccess, false, (uint)process.Id); 


      BoyerScan = new BoyerMoore(_processHandle); 

     } 

我更新內存的基本信息...:

public struct _MEMORY_BASIC_INFORMATION64 
    { 
     public ulong BaseAddress; 
     public ulong AllocationBase; 
     public int AllocationProtect; 
     public int __alignment1; 
     public ulong RegionSize; 
     public int State; 
     public int Protect; 
     public int Type; 
     public int __alignment2; 
    } 

和更新_MEMORY_BASIC_INFORMATION應用以及進程句柄變爲## UIntPtr ##通代碼

還更新了變化:

[DllImport("KERNEL32.DLL")] 
     public static extern int VirtualQueryEx(UIntPtr hProcess, 
      UIntPtr lpAddress, out _MEMORY_BASIC_INFORMATION64 lpBuffer, int dwLength); 

     [DllImport("KERNEL32.DLL", SetLastError = true)] 
     public static extern bool ReadProcessMemory(
      UIntPtr process, ulong address, byte[] buffer, ulong size, ref uint read); 

     public List<_MEMORY_BASIC_INFORMATION64> MemoryRegion = new List<_MEMORY_BASIC_INFORMATION64>(); 

     [DllImport("KERNEL32.DLL", SetLastError = true)] 
     public static extern bool WriteProcessMemory(
      UIntPtr process, ulong address, byte[] buffer, uint size, ref uint written); 

     [DllImport("KERNEL32.DLL")] 
     public static extern bool VirtualProtectEx(UIntPtr process, ulong address, 
      uint size, uint access, out uint oldProtect); 

     [DllImport("KERNEL32.DLL")] 
     public static extern int CloseHandle(UIntPtr objectHandle); 

     [DllImport("KERNEL32.DLL")] 
     public static extern UIntPtr OpenProcess(uint access, bool inheritHandler, uint processId); 

     [Flags] 
     public enum Protection 
     { 
      PEReadWrite = 0x40, 
      PReadWrite = 0x04 
     } 

     [Flags] 
     public enum Access 
     { 
      Synchronize = 0x100000, 
      StandardRightsRequired = 0x000F0000, 
      AllAccess = StandardRightsRequired | Synchronize | 0xFFFF 
     } 

    so, now, compiled for any cpu, it finds adreses corectly for 32 bit and 64 bit proceses 
    many thanks to: 
    @Dirk 
    and 
    @Loonquawl 
相關問題