我正在製作一個類似於作弊引擎的內存掃描器應用程序,但希望在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正確發現
將您的代碼添加到問題本身。不要將我們鏈接到可下載的二進制文件。 – Amy
「但由於某種原因,我無法在64位進程中找到它們」 - 以何種方式?你無法讀取內存,或找不到內存中的數據?這似乎不太可能與Boyer-Moore的部分有關...... –
我強烈懷疑你包含的絕大多數代碼都是不相關的。請減少到[mcve]。 –