1

这是我的 Form1 代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace ReadMemory
{
    public partial class Form1 : Form
    {
        List<int> memoryAddresses = new List<int>();

        public Form1()
        {
            InitializeComponent();


            Process proc = Process.GetCurrentProcess();
            IntPtr startOffset = proc.MainModule.BaseAddress;
            IntPtr endOffset = IntPtr.Add(startOffset, proc.MainModule.ModuleMemorySize);
            for (int i = 0; i < startOffset.ToInt64(); i++)
            {
                memoryAddresses.Add(startOffset[i]
            }

        }

        private void modelsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }
}

我试图从头到尾扫描所有内存地址并将它们添加到列表中。但是我在线上遇到错误:

memoryAddresses.Add(startOffset[i]

错误 3 无法将带有 [] 的索引应用于“System.IntPtr”类型的表达式

第二件事是在循环中做: startOffset.ToInt64() 可以吗?或者我应该做 ToInt32() ?

4

2 回答 2

3

这不是 Windows 的工作方式。它是一个虚拟内存需求分页操作系统,每个进程获得 2 GB 内存。对于 32 位进程,它从 0x0001000 开始,到 0x7fffffff 结束。大多数进程从 0x00400000(EXE 的默认起始地址)开始使用 VM。Windows 始终使用 VM 空间的末尾来跟踪进程中的线程等基本内容。中间有很多空间,用于加载 DLL 并为堆分配内存。

看到分配需要 VirtualQueryEx(),你不能用 Process 类来做。您的代码否则无效, IntPtr 不是数组。通过 SysInternals 的 VMMap 实用程序深入了解进程使用虚拟内存空间的方式。同一作者编写了“Windows Internals”一书,这是一本了解 Windows 内部工作原理的重要书籍。

于 2013-10-05T13:13:41.827 回答
1

值只是一个IntPtr数字,它不是您可以通过索引访问的数组。现在你从零循环到startOffset,但我认为你想从到startOffset循环endOffset

由于内存地址可以是 32 位或 64 位,具体取决于您运行代码的平台,您需要一个long( Int64) 来处理这两种类型的指针:

List<long> memoryAddresses = new List<long>();

使用ToInt64将指针值转为整数是正确的。内存地址将只是您在循环中使用的变量。

for (long i = startOffset.ToInt64(); i < endOffset.ToInt64(); i++) {
  memoryAddresses.Add(i);
}

注意:当您为进程内存中的每个字节添加列表项时,列表将是进程内存大小的八倍。您的进程中可能没有足够的内存来执行此操作。

于 2013-10-05T13:08:24.850 回答