1

首先,我知道这看起来像是重复的,但我查看了其他问题但找不到解决方案,所以请听我说完。

我有一个函数可以将相对虚拟地址转换为动态内存地址,也就是读取多级指针(如下所示)。我使用具有所有访问权限的远程进程的有效句柄、指向进程基地址(4194304 或 0x400000)的指针、rva(29128148 或 0x1BC75D4)和偏移量({ 20, 48, 12 } , { 0x14, 0x30, 0xC })。将基地址添加到 rva 的行返回正确的 33322452 或 0x1FC75D4(通过作弊引擎验证)。循环的第一次迭代使用上述地址调用 RPM(),对 BitConverter.ToInt32() 的调用返回 -134118400 或 0xF8018400,这也是正确的。dynamicMemoryAddress 的新值是通过添加该地址和第一个偏移量 (0x14) 来设置的,它产生一个值为 -134118380 或 0xF8018414 的 IntPtr。

但是,当在第二次迭代中使用新值 dynamicMemoryAddress (0xF8018414) 调用 RPM() 时,该函数将返回失败状态。调用 GetLastError() 返回 998 或 ERROR_NOACCESS(对内存位置的访问无效。)。在作弊引擎中,我浏览到 0xF8018414 并且它具有正确的值,并且页面保护值是 PAGE_READ_WRITE 所以我不明白为什么第一个调用成功但第二个调用失败,即使我似乎有足够的访问权限。

出于调试目的,我在调用 RPM() 之前立即插入了对 VirtualQueryEx() 的调用,第一次迭代成功并且 MemoryBasicInformation 结构正确填充,在第二次迭代中,该结构完全为空。

我已经在这个问题上停留了 2 天,现在我束手无策,非常感谢任何帮助。我在 x64 windows 7 上运行,但如果相关,所有相关进程都是 x86。

private static IntPtr ConvertRVAToDMA(RemoteProcess rProcess, IntPtr baseAddress, IntPtr relativeVirtualAddress, Int32[] offsets)
        {
            Process.EnterDebugMode();
            byte[] buffer = new byte[Marshal.SizeOf(new IntPtr())];
            int tmpNewBaseAddress;
            IntPtr bytesRead = new IntPtr();

            IntPtr dynamicMemoryAddress = new IntPtr(baseAddress.ToInt32() + relativeVirtualAddress.ToInt32());

            try
            {
                for (int i = 0; i < (offsets.Length); i++)
                {
                    if (!WinApis.ReadProcessMemory(rProcess.Handle, dynamicMemoryAddress, buffer, Marshal.SizeOf(new IntPtr()), out bytesRead))
                    {
                        dynamicMemoryAddress = IntPtr.Zero;
                        break;
                    }

                    tmpNewBaseAddress = BitConverter.ToInt32(buffer, 0);
                    if (tmpNewBaseAddress == 0)
                    {
                        dynamicMemoryAddress = IntPtr.Zero;
                        break;
                    }

                    dynamicMemoryAddress = IntPtr.Add((IntPtr)tmpNewBaseAddress, offsets[i]);
                }
            }
            catch (Exception ex)
            {
                dynamicMemoryAddress = IntPtr.Zero;
            }
            Process.LeaveDebugMode();
            return dynamicMemoryAddress;
        }
4

0 回答 0