Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Изменение значения в памяти дрогого процесса


Автор: chikistbuch 24.12.2009, 22:57
Люди добрые, подскажите пожалуйста. Есть сторонее приложение и мне нужно в его памяти изменить значение переменной ('006B9710'). Этот код (взял с DRKB, статья "поиск в памяти процесса") вроде бы как находит нужное значение, но как сохранить изменённое значение в памяти процесса???

Только пожалуйста не пишите какой я лузер и что всё написано не правильно, дайте пожалуйста дельный совет. 

WriteProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead) у меня не получается

Зарание огромное спасибо!!!!

Код

procedure se;
var

ProcessHandle: THandle;
Mbi: TMemoryBasicInformation;
Addr: DWord;
Value: DWord;
val:char;
I: Cardinal;
Buf: PChar;
BytesRead: DWord;
begin

val:='8';
Value := 9;
//
// Открываем процесс
//
ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or
PROCESS_VM_OPERATION, false, ProcessID);
if ProcessHandle <> 0 then
try
Addr := 0;
//
// Перечисляем все регионы виртуальной памяти процесса
//
while VirtualQueryEx(ProcessHandle, Pointer(Addr), Mbi, SizeOf(Mbi)) <> 0 do
begin

  // Uncomment чтобы увидеть список регионов, найденых в адресном пространстве
  // form1.Memo1.Lines.Add('region: ' + IntToHex(Integer(Mbi.BaseAddress), 8) +
  //   ' size: ' + IntToStr(Mbi.RegionSize));
  //
  // Если региону выделена память, и регион не является "сторожевым" (как вершина стека),
  // то читаем этот регион
  //
  if (Mbi.State = MEM_COMMIT) and not ((Mbi.Protect and PAGE_GUARD) = PAGE_GUARD) then
  begin
   //
   // Это демонстрационная программа, поэтому здесь выделяется буфер под весь регион.
   // Регион может быть достаточно большим, поэтому лучше читать его блоками для экономии
   // памяти. Но здесь для простоты алгоритма вся оптимизация похерена.
   //
   GetMem(Buf, Mbi.RegionSize);
   try
    //
    // Читаем весь регион в выделенный буфер
    //
    if ReadProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf,
      Mbi.RegionSize, BytesRead) then
    begin
     //
     // Ищем значение типа DWORD в буфере
     //
     for I := 0 to BytesRead - SizeOf(Value) do
     begin
      if PDWord(@Buf[I])^ = Value then begin
       // Найдено, выводим
       form1.Memo1.Lines.Add('Value ' + IntToStr(Value) + ' found at ' +IntToHex(Integer(Cardinal(Mbi.BaseAddress) + I), 8));

       if IntToHex(Integer(Cardinal(Mbi.BaseAddress)+I),8)='006B9710' then begin
       form1.Caption:=inttostr(PDWord(@Buf[I])^);
       PDWord(@Buf[I])^:=8;
       form1.Caption:=form1.Caption+'  good  ';

       if WriteProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead) then
       form1.Caption:=form1.Caption+' OK  '
      else form1.Caption:=form1.Caption+' BAD  ';


      end;
       end;
     end;
    end
    else
     form1.Memo1.Lines.Add('Failed to read process memory ' + IntToStr(GetLastError));
   finally
    FreeMem(Buf);
   end;
  end;
  // Вычисляем адрес следуюшего региона
  Addr := Addr + Mbi.RegionSize;
end;

finally
CloseHandle(ProcessHandle);
end
else
WriteLn('Failed to open process');

end;


Автор: kami 25.12.2009, 03:07
Цитата(chikistbuch @  24.12.2009,  22:57 Найти цитируемый пост)
дайте пожалуйста дельный совет. 

Пожалуйста.
В справке к http://msdn.microsoft.com/en-us/library/ms681674(VS.85).aspx указано, что для работы этой функции должны быть указаны PROCESS_VM_WRITE and PROCESS_VM_OPERATION. При открытии процесса у Вас в коде пропущен флаг PROCESS_VM_WRITE, т.е. должно быть
Код

ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, false, ProcessID);



Цитата(chikistbuch @  24.12.2009,  22:57 Найти цитируемый пост)
WriteProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead) у меня не получается

На будущее - не бывает просто "не получается", Windows обязательно скажет почему не получается. В данном случае - если операция не удалась, то на вопрос "почему" ответит GetLastError.

Автор: chikistbuch 25.12.2009, 12:39
kami, СПАСИБО!!! Буду пробовать

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