2013-10-05 3 views
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()?

+0

Возможный дубликат [Добавить смещение в IntPtr] (http://stackoverflow.com/questions/1866236/add-offset-to-intptr) – BartoszKP

ответ

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); 
} 

Примечание: Как вы добавляете элемент в список для каждого байта в памяти процесса, список будет в восемь раз превышает размер памяти процесса. Вероятно, вам не хватит памяти для вашего процесса.

+0

Гуффа, но делать это таким образом, это не просто его подсчет? Я имею в виду первый адрес startOffset: 2162888, а следующий в списке - 2162889, а 2162889 - следующий адрес памяти? Или я просто пересчитал с самого начала и до конца? –

+0

вам не нужно долго, вы можете просто использовать IntPtr, потому что цель IntPtr - обрабатывать ячейки памяти. IntPtr - 64 бит на x64 и 32 бит на x86 – Console

+0

@DoronMuzar: Да, цикл просто проходит через числа, которые первоначально поступали из адресов памяти. – Guffa

3

Это просто не то, как работает Windows. Это операционная система, требующая виртуальной памяти, каждый процесс получает 2 гигабайта памяти. Начало начинается с 0x0001000 и заканчивается на 0x7fffffff для 32-битного процесса. Большинство процессов начинают потреблять VM на 0x00400000, начальном адресе по умолчанию для EXE. Конец пространства VM всегда используется Windows, чтобы отслеживать важные вещи, такие как потоки в процессе. Много места между ними, используется для загрузки DLL и распределения памяти для кучи.

Для определения распределения требуется VirtualQueryEx(), вы не можете сделать это с помощью класса Process. Ваш код в противном случае недействителен, IntPtr не является массивом. Получите представление о том, как процесс использует пространство виртуальной памяти с помощью утилиты VMMap SysInternals. Эти же авторы писали книгу «Windows Internals», важную книгу, чтобы понять, как работает Windows внутри.

Смежные вопросы