Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > ReadProcessMemory


Автор: NET_or_not_NET 22.5.2007, 13:45
Доброго дня!

У меня возникла проблема с ReadProcessMemory при работе с приложением написанном на C# & VS2005! 

Когда я использую эту функцию (например с игрой "Минер") то все ОК!!!! все читаеться, все работает! И не только с "минером", 
с другими приложениями тоже все ок! Но решил я посмотреть что твориться в пямяти в моем приложении...
 как  smile  -  функция возвращает false, GetLastError - 299 ("выполнена только часть функции"). 
Складываеться такое впечетление что работает со всеми прогами написанными где угодно 
только без участия CLR, .Net FrameWork! надеюсь я страшно заблуждаюсь! Народ ПОМОГИТЕ! наставте на путь истинный!
Пишу C# & VS2005


P.S. Написал самое простое: одну форму + одна кнопка + 2-ве переменные! и вот немогу добраться до памяти процесса!
В ЧЕМ я ОШИБСЯ????

P.S.S. пробывал OpenProcess со всеми флагами - 0!
          пробывал сам создавать CreateProcess , Process.Start   -  0!

P.S.S.S. BaseAddress главного модуля получаеться без проблем!

Автор: archeg 22.5.2007, 14:08
Дай плз пример кода, что именно ты делаешь.

Похоже что твое впечатление правильное:
Цитата(NET_or_not_NET @  22.5.2007,  13:45 Найти цитируемый пост)
Складываеться такое впечетление что работает со всеми прогами написанными где угодно 
только без участия CLR, .Net FrameWork!

Кажись всему виной AppDomain

Автор: NET_or_not_NET 22.5.2007, 14:32
Даю...

Код

[DllImport("kernel32.dll", SetLastError = true)]
        public extern static bool ReadProcessMemory(IntPtr hProcess, int lpBaseAddress,
           [In, Out] byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesRead);

---------------------------------------------------------------------------------------------

            p = Process.Start("winmine.exe"); // тут надо вместо минера приложение .NET

            //Process[] cur_p = Process.GetProcesses(".");
            //foreach (Process pp in cur_p)
            //{
            //    if (pp.ProcessName == "winmine")
            //    {
            //        p = pp;
            //        break;
            //    }
            //}

            ProcessModule pm = p.MainModule; // главный модуль

            //IntPtr o = OpenProcess(0x1F0FFF, 1, (uint)p.Id);  //0x1F0FFF - эквивалент PROCESS_ALL_ACCESS
                
            byte[] b = new byte[pm.ModuleMemorySize]; // выделям под память размером ModuleMemorySize

            IntPtr ptrBytesReaded; // потом вернет сколько байт прочитал

            retValue1 = ReadProcessMemory(p.Handle, pm.BaseAddress.ToInt32(), b, pm.ModuleMemorySize, out ptrBytesReaded);
            //pm.BaseAddress.ToInt32() - адресс откуда начинаю считывать
            //retValue2 = ReadProcessMemory(o, pm.BaseAddress.ToInt32(), b, pm.ModuleMemorySize, out ptrBytesReaded);

            int vsego = (int)ptrBytesReaded;

            int i = GetLastError();


Автор: tol05 22.5.2007, 18:12
Проблема в том, что в .Net, в отличие от "winmine.exe" есть сборщик мусора. Он запускается самопроизвольно и в своей работе не стесняется удалять и перемещать объекты в куче (а куча - это та память приложения, которую мы хотим знать). 
Если в процессе чтения памяти он запустится - результаты выполнения ReadProcessMemory() окажутся непредсказуемыми. smile

Автор: NET_or_not_NET 23.5.2007, 11:06
Доброго дня, tol05
а если это не ссылочнае значение а значимое и оно не в куче а в стеке?
И переменная глобальная? Как догда? тоже сборьщик грохнет?, или он грохнет при закрытии приложения?
если при закрытии, то значение в памяти? может прочитать адреес памяти для потока, а не для главного модуля?
конечно - если так можно?

Автор: tol05 23.5.2007, 11:39
Цитата(NET_or_not_NET @  23.5.2007,  11:06 Найти цитируемый пост)
если это не ссылочнае значение а значимое и оно не в куче а в стеке

сборщик работает в куче. Запускается недетерминированно (никто не знает когда, в начале, в конце).  Но это не важно, ведь если бы даже ты приноровился к какому-то режиму в одной сборке, то для другой мог бы быть другой режим, так? smile

Стек заполняется и очищается независимо от кучи. По мере прохода потоком выполнения кода.

Ссылочные переменные находятся в куче, неважно, локальные они, глобальные, экземплярные или статические.

Значимые - в стеке. Тоже неважно кому они принадлежат.

Одним словом, есть мнение, что от этой ф-ции в .Net лучше отказаться. Можно попробовать решить поставленную задачу через члены GC класса. Я имею в виду GC.GetTotalMemory например. 
Больше ничего, к сожалению, сказать не могу. smile

Автор: NET_or_not_NET 23.5.2007, 13:26
tol05, спаисбо!

буду пробывать через GC класс.....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)