0

我写了一个可以读写内存的内存编辑器类,但是我需要做的是扫描程序的内存,并找到包含我正在搜索的内存的内存地址列表。

这是内存编辑器类。

class MemoryEditor
{
    public const uint DELETE = 0x00010000;
    public const uint READ_CONTROL = 0x00020000;
    public const uint WRITE_DAC = 0x00040000;
    public const uint WRITE_OWNER = 0x00080000;
    public const uint SYNCHRONIZE = 0x00100000;
    public const uint END = 0xFFF;
    public const uint PROCESS_ALL_ACCESS = (DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | SYNCHRONIZE | END);

    public Process targetedProcess;

    [DllImport("kernel32.dll")]
    public static extern int OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);

    [DllImport("kernel32.dll")]
    public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesRead);

    [DllImport("kernel32.dll")]
    public static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesWritten);

    public Process targetProcess(string name, int index = 0)
    {
        return (targetedProcess = Process.GetProcessesByName(name)[index]);
    }

    public int getHandle(Process proc, uint access = PROCESS_ALL_ACCESS)
    {
        return OpenProcess(access, false, proc.Id);
    }

    public byte[] getBytesFromString(string str)
    {
        return Encoding.Unicode.GetBytes(str);
    }

    public string getStringFromBytes(byte[] byteArr)
    {
        return Encoding.Unicode.GetString(byteArr);
    }

    public int makeHex(string str)
    {
        return (int.Parse(str, System.Globalization.NumberStyles.HexNumber));
    }

    public byte[] ReadMemory(int address, int processSize)
    {
        byte[] buffer = new byte[processSize];
        ReadProcessMemory(getHandle(targetedProcess), address, buffer, processSize, 0);
        return buffer;
    }

    public List<int> GetAddress(byte[] memory, int index = 0)
    {
        List<int> buf = new List<int>();

        for (int i = 0; i < int.MaxValue; i++)
            if (ReadMemory(makeHex(i.ToString()), 1) == memory)
                buf.Add(i);

        return buf;
    }

    public void WriteMemory(int address, byte[] processBytes)
    {
        WriteProcessMemory(getHandle(targetedProcess), address, processBytes, processBytes.Length, 0);
    }

    public int GetObjectSize(object TestObject)
    {
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream();
        byte[] Array;
        bf.Serialize(ms, TestObject);
        Array = ms.ToArray();
        return Array.Length;
    }
}

这是尝试查找内存地址的功能

    public List<int> GetAddress(byte[] memory, int index = 0)
    {
        List<int> buf = new List<int>();

        for (int i = 0; i < int.MaxValue; i++)
            if (ReadMemory(makeHex(i.ToString()), 1) == memory)
                buf.Add(i);

        return buf;
    }

它滞后非常严重,我只针对记事本。当我在作弊引擎中扫描内存时,它会立即找到它,没有任何延迟。我的程序从 0 扫描到 int 的最大值,但 Cheat Engine 从 0 扫描到 long 的最大值,所以我不知道我做错了什么。

有什么办法可以有效地做到这一点?

4

1 回答 1

3

我马上看到了几个问题。

1.您一次只读取一个字节

ReadMemory(makeHex(i.ToString()), 1)

我不确定,但我会假设调用ReadProcessMemory需要执行系统调用,并且为每个字节执行此操作肯定会成为减速的一个来源。相反,您应该阅读一些大小的“块”,然后在您的进程中扫描该块。(一次做一页可能是最有效的。)

2.你到底为什么要来回转换字符串?!

public int makeHex(string str)
{
    return (int.Parse(str, System.Globalization.NumberStyles.HexNumber));
}

....

for (int i = 0; i < int.MaxValue; i++)
    if (ReadMemory(makeHex(i.ToString()), 1) == memory)

该循环的每次迭代,您都将转换i为字符串(默认值,十进制 - 不是十六进制),然后立即将其传递给makeHex将其(始终为十六进制)解析回整数的字符串。这有什么意义?只需传递整数!这些转换可能非常昂贵。

<pedantic>顺便说一句,“ makeHex”这个名字没有意义——它是十六进制开始的,然后是一个整数。</pedantic>

于 2013-08-01T04:40:30.767 回答