Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用带偏移量的基指针读取进程内存_C#_Process - Fatal编程技术网

C# 使用带偏移量的基指针读取进程内存

C# 使用带偏移量的基指针读取进程内存,c#,process,C#,Process,我已经在网上搜索了好几个小时,我一辈子都无法理解为什么下面的代码不起作用 为进程提取的基址似乎是错误的。如果我将结束地址直接硬编码到ReadMemory,我会得到所需的值(这样我就知道我有正确的过程和所有内容) 我还没有发布MemoryHandler类,因为它已经正常工作了 这可能与我使用64位windows有关吗?游戏是32位的(安装在“ProgramFiles(x86)”文件夹中) 编辑:基址是对的,我关于指针的代码逻辑是错的,请参阅下面的完整答案。因此,David关于基址不能是奇数的评论让

我已经在网上搜索了好几个小时,我一辈子都无法理解为什么下面的代码不起作用

为进程提取的基址似乎是错误的。如果我将结束地址直接硬编码到
ReadMemory
,我会得到所需的值(这样我就知道我有正确的过程和所有内容)

我还没有发布
MemoryHandler
类,因为它已经正常工作了

这可能与我使用64位windows有关吗?游戏是32位的(安装在“ProgramFiles(x86)”文件夹中)


编辑:基址是对的,我关于指针的代码逻辑是错的,请参阅下面的完整答案。

因此,David关于基址不能是奇数的评论让我认为,也许我从作弊引擎得到的数字实际上不是基址。结果证明是正确的。我的代码实际上是在提取正确的基址。我之前发布的数字(9460301)实际上是存储在内存中的基址位置的数字(而不是地址本身)

无论如何,上面的代码获取基址并添加第一个偏移量,然后添加下一个偏移量,然后读取该地址上的内存。这是错误的,多级指针不是这样工作的。对于每个级别,您必须读取内存并查看存储在地址中的内容。您找到的值将是您的下一个地址,并应用下一个偏移量,依此类推

正确的代码是:

public partial class MainForm : Form
{

    Process myProcess = Process.GetProcessesByName("ffxiv").FirstOrDefault();

    public MainForm()
    {
        InitializeComponent();
    }

    private void startButton_Click(object sender, EventArgs e)
    {
        int bytesRead;

        IntPtr baseAddress = myProcess.MainModule.BaseAddress;
        Console.WriteLine("Base Address: " + baseAddress);

        IntPtr firstAddress = IntPtr.Add(baseAddress, 0xF8BEFC);
        IntPtr firstAddressValue = (IntPtr)BitConverter.ToInt32(MemoryHandler.ReadMemory(myProcess, firstAddress, 4, out bytesRead), 0);
        IntPtr finalAddr = IntPtr.Add(firstAddressValue, 0x1690);
        Console.WriteLine("Final Address: " + finalAddr.ToString("X"));

        byte[] memoryOutput = MemoryHandler.ReadMemory(myProcess, finalAddr, 4, out bytesRead);

        int value = BitConverter.ToInt32(memoryOutput, 0);
        Console.WriteLine("Read Value: " + value);
    }
}
我想知道,如何使这个非特定于32位windows?我不太喜欢Int32()函数和随后的IntPtr转换,因此我想知道是否有任何方法可以直接从字节[]转换为IntPtr。我尝试了封送副本等,但无法使其工作


再次非常感谢

你从基址中得到了什么样的值?你如何知道“正确”的值是什么?斯科特,我知道什么是正确的地址(因此,我得到的是错误的)是通过使用作弊引擎。例如,这就是我如何找到这个游戏中指向HP的基本指针的原因。它告诉我ffxiv.exe应该有什么地址,它与我的C#代码给我的地址不同。然而,最有力的证据是,读取内存的最终输出并没有提供我的hp(如果我将作弊引擎中找到的最低级别地址直接硬编码到上面的读取内存函数中,我会得到正确的值)。您的代码返回什么值?正确的值是多少?在Process Explorer中检查正确的值。这并不重要,因为低级地址是动态的,但在dec中我应该得到9460301(通过作弊引擎验证),但我得到1220000。这些数字自然只适用于前面提到的进程的当前实例(重启时,这些数字会改变)。模块的基址不会是奇数!
public partial class MainForm : Form
{

    Process myProcess = Process.GetProcessesByName("ffxiv").FirstOrDefault();

    public MainForm()
    {
        InitializeComponent();
    }

    private void startButton_Click(object sender, EventArgs e)
    {
        int bytesRead;

        IntPtr baseAddress = myProcess.MainModule.BaseAddress;
        Console.WriteLine("Base Address: " + baseAddress);

        IntPtr firstAddress = IntPtr.Add(baseAddress, 0xF8BEFC);
        IntPtr firstAddressValue = (IntPtr)BitConverter.ToInt32(MemoryHandler.ReadMemory(myProcess, firstAddress, 4, out bytesRead), 0);
        IntPtr finalAddr = IntPtr.Add(firstAddressValue, 0x1690);
        Console.WriteLine("Final Address: " + finalAddr.ToString("X"));

        byte[] memoryOutput = MemoryHandler.ReadMemory(myProcess, finalAddr, 4, out bytesRead);

        int value = BitConverter.ToInt32(memoryOutput, 0);
        Console.WriteLine("Read Value: " + value);
    }
}