首页 > 解决方案 > C# 多级指针最后一次计算错误

问题描述

我目前正在尝试在使用 Cheat Engine 找到的基本指针上实现 C# 中的内存读取。我 100% 确定我找到了正确的指针和偏移量,因为它们在 Cheat-Engine 中工作得很好,即使在重新启动之间也是如此。

我现在在 C# 中实现它,单级点没有任何问题,但由于某种原因,我无法让我的最后一个多级指针工作。

一切都很顺利,直到它必须添加的最后一个值,然后它返回一些“随机”的东西给我,这些是我找到的指针,我可以看到它在 Cheat Engine 中工作。

在此处输入图像描述

这是我在 C# 中的实现:

public static int ReadFromPointer(int address, int[] offsets)
{
    Console.WriteLine("----------");
    Console.WriteLine("Address: " + address);
    int ptr = ReadPointer(address);
    Console.WriteLine($"Pointer returned as int: {ptr}, hex: {ptr:X}");
    foreach (var offset in offsets)
    {
        Console.WriteLine($"Adding offset: {offset:X} to Pointer: {ptr:X}");
        ptr = ReadPointer(ptr + offset);
        Console.WriteLine($"Pointer returned as int: {ptr}, hex: {ptr:X}");
    }
    Console.WriteLine("----------");
    return ptr;
}

private static int ReadPointer(int adress)
{
    int ptrNext;
    int bytesRead = 0;
    byte[] _Value = new byte[4];
    ReadProcessMemory((IntPtr)ProcessHandle, (IntPtr)adress, _Value, IntPtr.Size, ref bytesRead);
    ptrNext = BitConverter.ToInt32(_Value, 0);
    return ptrNext;
}

我使用以下方法调用它:

var valueToFind = ProcessHelper.ReadFromPointer((int)baseAddress + 0x00C45A5C, new []{ 0xEC, 0x1C, 0x178, 0x74, 0x458 });

现在是“随机”部分,除了最后一个指针必须将 0x458 添加到指针 1E138F80 时,每个指针都正确添加,这应该返回 1E1393D8,但最终返回“41C00000” 在此处输入图像描述

我不确定这是否是由于我的最后一个指针不再是 4 个字节,或者是否由于某种方式发生了将其混淆的转换。这里的任何帮助将不胜感激!

标签: c#cheat-engine

解决方案


您的问题是,在添加最后一个偏移量后,您将再次取消引用它,就好像该地址指向您尝试获取地址的变量一样。实际上,此时地址是变量的地址,而不是指向它的指针。添加最后一个偏移量后,您应该停止并打印该变量。

我很确定改变:

foreach (var offset in offsets)

for (var i = 0; i < offsets.Length; ++i)

和改变

ptr = ReadPointer(ptr + offset);

ptr = ReadPointer(ptr + offset[i]);

会修复它。

在此 for 循环结束后打印,它应该打印正确的地址。

如果失败,我已经为您准备了替换功能:

public static IntPtr FindDMAAddy(IntPtr hProc, IntPtr ptr, int[] offsets)
{
    var buffer = new byte[IntPtr.Size];

    foreach (int i in offsets)
    {
        ReadProcessMemory(hProc, ptr, buffer, buffer.Length, out var read);

        ptr = (IntPtr.Size == 4)
        ? IntPtr.Add(new IntPtr(BitConverter.ToInt32(buffer, 0)), i)
        : ptr = IntPtr.Add(new IntPtr(BitConverter.ToInt64(buffer, 0)), i);
    }
    return ptr;
}

推荐阅读