3

私は何時間もウェブ全体を検索しましたが、以下のコードが機能しない理由を一生理解できません。

プロセス用に取得されたベース アドレスが間違っているようです。エンドアドレスを に直接ハードコードするとReadMemory、必要な値が得られます (したがって、正しいプロセスとすべてがあることがわかります)。

MemoryHandlerクラスは正常に機能しているため、投稿していません

私が64ビットのWindowsを使用しているという事実と何か関係があるのでしょうか? ゲームは 32 ビットです (「Program Files (x86)」フォルダーにインストールされます)。

public partial class MainForm : Form
{

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

    public MainForm()
    {
        InitializeComponent();
    }

    private void startButton_Click(object sender, EventArgs e)
    {
        IntPtr baseAddress = myProcess.MainModule.BaseAddress;
        Console.WriteLine("Base Address: " + baseAddress.ToString("X"));

        IntPtr newAddr = IntPtr.Add(baseAddress, 0xF8BEFC);
        IntPtr finalAddr = IntPtr.Add(newAddr, 0x1690);

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

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

編集:ベースアドレスは正しかった、ポインタに関する私のコードロジックは間違っていた、以下の完全な回答を参照してください。

4

1 に答える 1

0

だから、ベースアドレスは奇数にはなり得ないというDavidのコメントは、おそらく私がCheat Engineから持っていた数字は実際にはベースアドレスではなかったのではないかと思いました. それは正しいことが判明しました。実際、私のコードは正しいベース アドレスを取得していました。以前に投稿した番号 (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 キャストがあまり好きではないので、byte[] から IntPtr に直接移動する方法があるかどうかを調べたいと思います。マーシャルコピーなども試しましたが、うまくいきませんでした。

ありがとうございました!

于 2013-11-08T02:49:24.543 に答える