Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.07.2013, 12:32   #1
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию Работа с памятью своего процесса

Здравствуйте. Есть желание поработать с памятью своего процесса.
В приведённом ниже коде я хочу получить блок памяти в переменную array of byte, но получаю run time error


Код:
var
  SysInfo:TSystemInfo;
  lpBuffer:TMemoryBasicInformation;
  dwLength:DWORD;
  readResult:boolean;
  Buf:array[0..99999] of byte;
begin
  GetSystemInfo(SysInfo);
  dwLength:=1;
  while (dwLength<>0) do begin
    dwLength:=VirtualQuery(SysInfo.lpMaximumApplicationAddress,lpBuffer,SizeOf(lpBuffer));
    SysInfo.lpMinimumApplicationAddress:=Pointer(longint(SysInfo.lpMinimumApplicationAddress)+lpBuffer.RegionSize);
    if (lpBuffer.State = MEM_COMMIT) and (lpBuffer.Protect = PAGE_READWRITE) then begin
      try
        ZeroMemory(@Buf, sizeof(Buf));
        move(lpBuffer.BaseAddress,Buf,lpBuffer.RegionSize); //Вот тут Run time error
      except
      end;
    end;
  end;
end;

Что я делаю не правильно?

Заранее благодарен
lollollollol вне форума Ответить с цитированием
Старый 01.07.2013, 15:22   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

у вы уверены что ваш регион вам доступен и доступен для записи?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.07.2013, 15:33   #3
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Но ведь я могу читать память своего процесса?
move(lpBuffer.BaseAddress,Buf,lpBuf fer.RegionSize);
Тут я пытаюсь скопировать lpBuffer.RegionSize байт в массив Buf начиная с адреса lpBuffer.BaseAddress, или чтото путаю?
lollollollol вне форума Ответить с цитированием
Старый 01.07.2013, 15:44   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Сообщение от lollollollol Посмотреть сообщение
Но ведь я могу читать память своего процесса?
move(lpBuffer.BaseAddress,Buf,lpBuf fer.RegionSize);
Тут я пытаюсь скопировать lpBuffer.RegionSize байт в массив Buf начиная с адреса lpBuffer.BaseAddress, или чтото путаю?
ваша память не является сразу зарезервированной всей, вы берете её по мере необходимости через VirtualAlloc если страницы, или через менагер кучи если просто память.
если страница не зарезервированна и не произведено выделение ей памяти, то будет AV.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.07.2013, 16:22   #5
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Цитата:
ваша память не является сразу зарезервированной всей, вы берете её по мере необходимости через VirtualAlloc
Но ведь я пытаюсь работать именно с памятью которую взял через VirtualAlloc
lpBuffer.BaseAddress - сюда значение записала VirtualAlloc
lpBuffer.RegionSize - и сюда размер она же записала


Подскажите пожалуйста алгоритм действий, а то я чтото совсем запутался.
Моя конечная цель - изменение памяти моего же процесса.
Т.е. например есть функция
Код:
MessageBox(0,'aoaoaoaoao','',0);
Я хочу в памяти найти и поменять 'aoaoaoaoao' на 'eeeeeeeeee'

По какому алгоритму стоит действовать?

Последний раз редактировалось lollollollol; 01.07.2013 в 16:26.
lollollollol вне форума Ответить с цитированием
Старый 01.07.2013, 17:06   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Сообщение от lollollollol Посмотреть сообщение
Но ведь я пытаюсь работать именно с памятью которую взял через VirtualAlloc
lpBuffer.BaseAddress - сюда значение записала VirtualAlloc
lpBuffer.RegionSize - и сюда размер она же записала


Подскажите пожалуйста алгоритм действий, а то я чтото совсем запутался.
Моя конечная цель - изменение памяти моего же процесса.
Т.е. например есть функция
Код:
MessageBox(0,'aoaoaoaoao','',0);
Я хочу в памяти найти и поменять 'aoaoaoaoao' на 'eeeeeeeeee'

По какому алгоритму стоит действовать?
не вижу никаких VirtualAlloc, вижу лишь VirtualQuery с запросом состояния памяти про адрес SysInfo.lpMaximumApplicationAddress .
в вашем случае проще текст вынести в константу, и её адрес уже можно легко получить.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.07.2013, 18:09   #7
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Невнимательность, сейчас буду исправляться
lollollollol вне форума Ответить с цитированием
Старый 01.07.2013, 18:11   #8
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Цитата:
Функция VirtualAlloc резервирует или предоставляет физическую память под указанными страницами в виртуальном адресном пространстве процесса. Память, выделяемая этой функцией, автоматически инициализируется нулями, кроме случая, когда указан флаг MEM_RESET.
Непойму, зачем мне резервировать память если на данном этапе я хочу прочитать уже существующую?
lollollollol вне форума Ответить с цитированием
Старый 01.07.2013, 19:07   #9
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Вот смотри, пытаюсь изсенить значение, код отрабатывает без ошибок, но и результата нет. сообщение не меняется.
А выносить в константу не вариант. Это просто как пример для обучения.



Код:
function Testsss:string;
begin
  result:='a';
end;

var
  SysInfo:TSystemInfo;
  lpBuffer:TMemoryBasicInformation;
  dwLength:DWORD;
  readResult:boolean;
  Buf:array[0..999999] of byte;
  IpBuf:char;
   numberWrite:cardinal;
begin
  GetSystemInfo(SysInfo);
  dwLength:=1;
  while (dwLength<>0) do begin
    dwLength:=VirtualQuery(SysInfo.lpMinimumApplicationAddress,lpBuffer,SizeOf(lpBuffer));
    SysInfo.lpMinimumApplicationAddress:=Pointer(longint(SysInfo.lpMinimumApplicationAddress)+lpBuffer.RegionSize);
    if (integer(SysInfo.lpMinimumApplicationAddress)>integer(SysInfo.lpMaximumApplicationAddress)) then Break;
    if (lpBuffer.State = MEM_COMMIT) and ((lpBuffer.Protect<>PAGE_NOACCESS)and(lpBuffer.Protect<>PAGE_NOACCESS)) then begin
      try
        ZeroMemory(@Buf, sizeof(Buf));
        ProcessHandle:=OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);
        readResult:=ReadProcessMemory(ProcessHandle,lpBuffer.BaseAddress, @Buf,lpBuffer.RegionSize, lpBuffer.RegionSize);
        CloseHandle(ProcessHandle);
        SetString(r,PChar(@Buf),lpBuffer.RegionSize);
        if (Pos(Testsss+'oa1',r)<>0) then begin
          r:=ReplaceSub(r,Testsss+'oa1','eeee');
          WriteProcessMemory(ProcessHandle, lpBuffer.BaseAddress, @r[1], lpBuffer.RegionSize, numberWrite);
        end;
      except
      end;
    end;
  end;
Примечание
if (Pos(Testsss+'oa1',r)<>0) then begin
r:=ReplaceSub(r,Testsss+'oa1','eeee ');
Сделал через Testsss так как подумал что прога может поменять значение которое будет искать

Временно сделал вместо move OpenProcess, с OpenProcess работает без ошибок, а вот move run time error создаёт.
С этим разберусь чуть позже, вначале хочу понять почему сообщение отображается без внесённых изменений

Последний раз редактировалось lollollollol; 01.07.2013 в 19:21.
lollollollol вне форума Ответить с цитированием
Старый 01.07.2013, 19:21   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
WriteProcessMemory
вы внутри себя, зачем это?
нужны лишь указатели.

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

а свое приложение менять проще создавая мап файл, где будут все адреса(поидее все).
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Delphi XE2 работа с памятью процесса YCA4 Win Api 2 18.02.2012 19:26
Работа с памятью mufesto Win Api 1 30.01.2012 15:13
Смертоубийство своего процесса Johnson Win Api 7 23.08.2011 19:29
Работа с памятью процесса JRcoker Win Api 10 18.07.2009 22:22
Работа с памятью запущенного процесса DeniCPP Общие вопросы C/C++ 2 09.04.2009 12:38