这是我的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)
{
}
}
}
我尝试从开始到结束扫描所有内存地址,并将它们添加到List中。 但我收到了错误:
memoryAddresses.Add(startOffset[i]
错误3无法将带有[]的索引应用于类型为&#39; System.IntPtr&#39;
的表达式第二件事是在循环中做:startOffset.ToInt64()没关系?或者我应该做ToInt32()?
答案 0 :(得分:3)
这不是Windows的工作方式。它是一个虚拟内存需求分页操作系统,每个进程获得2 GB的内存。对于32位进程,它从0x0001000开始,到0x7fffffff结束。大多数进程在0x00400000(EXE的默认起始地址)开始消耗VM。 Windows始终使用VM空间的末尾来跟踪流程中的线程等基本内容。中间有很多空间,用于加载DLL并为堆分配内存。
查看分配需要VirtualQueryEx(),您无法使用Process类执行此操作。您的代码无效,IntPtr不是数组。通过SysInternals的VMMap实用程序深入了解进程使用虚拟内存空间的方式。同一作者撰写了“Windows Internals”一书,这本书是了解Windows如何在内部工作的必备书。
答案 1 :(得分:1)
IntPtr
值只是一个数字,它不是您可以通过索引访问的数组。现在你从0循环到startOffset
,但我认为你想从startOffset
循环到endOffset
。
由于内存地址可以是32位或64位,具体取决于您运行代码的平台,您需要long
(Int64
)来处理任何类型的指针:< / p>
List<long> memoryAddresses = new List<long>();
使用ToInt64
将指针值转换为整数是正确的。内存地址只是您在循环中使用的变量。
for (long i = startOffset.ToInt64(); i < endOffset.ToInt64(); i++) {
memoryAddresses.Add(i);
}
注意:当您为进程内存中的每个字节添加列表项时,该列表将是进程内存大小的八倍。你的过程可能没有足够的内存。