| 
| 
 | Вопрос # 4 296/ вопрос открыт / | 
 |  Всем привет!!!Мой вопрос заключается в следующем:
 Я пытаюсь слить из памяти в файл содержимое главного процесса чужого приложения. С доступом к памяти разобрался, но возникла проблема: я не знаю как определить размер памяти, которую занимет процесс.
 Возможно ктото чемто подобным занимался и знает как можно получить количество байт, которые занимает процес в виртуальной памяти.
 Приложение:Переключить в обычный режим var  Form1: TForm1;  OperaHandl:hwnd;  ProcessHandle:THANDLE;  ProcessID:DWORD;  BytsR: Cardinal;   MyFile: File of byte;  NumWritten:Integer; procedure TForm1.Button1Click(Sender: TObject);varBuf:byte;beginSmeshenie:=0;OperaHandl:=FindWindow(nil,'Opera');if OperaHandl<>0 Then    GetWindowThreadProcessId(OperaHandl,@ProcessId);  if ProcessId<>0 Then    ProcessHandle:=OpenProcess(PROCESS_ALL_ACCESS,TRUE,ProcessId);   if ProcessHandle<>null Then    AssignFile(MyFile,'Slitok.mydat');   Rewrite(MyFile);     ReadProcessMemory(ProcessHandle,Pointer(Smeshenie),@Buf,Cardinal(1),BytsR);   BlockWrite(MyFile,Buf,BytsR,NumWritten);    End;  End; End;end;
|  |   Вопрос задал: SOA (статус: Посетитель)Вопрос отправлен: 7 июня 2010, 14:55
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: min@y™ Короче, вот тебе исходники двух программ: первая - программа-цель (Target.dpr), её препарирует втора прога (MainApp.dpr), т.е. дампит в стрим, а затем ищет в нём ячейку памяти с заданным значением.К ответу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки ответа)
 
 
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 7 июня 2010, 16:11
 Оценка за ответ: 5
 Комментарий к оценке: За проги конечно спасибо, но мне бы помогла и одна функция VirtualQueryEx, собственно то что и явилось решением. |  
 Мини-форум вопросаВсего сообщений: 21; последнее сообщение — 7 июня 2010, 16:58; участников в обсуждении: 4. Страницы: [1] [2] [Следующая »]  
|   | min@y™ (статус: Доктор наук), 7 июня 2010, 15:05 [#1]:Могу прислать пример, в котором целевой процесс дампится в TMemoryStream. А стрим можно потом сохранить в файло, если надо. Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | SOA (статус: Посетитель), 7 июня 2010, 15:12 [#2]:Большой наверно? |  
|   | min@y™ (статус: Доктор наук), 7 июня 2010, 15:23 [#3]: Цитата (SOA): Большой наверно?  Кто большой? Исходник? Щас померяю...
 5,3 кб в архиве. А что?
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | SOA (статус: Посетитель), 7 июня 2010, 15:24 [#4]:Там хоть коменты есть? Мне ведь всего то надо узнать число байт.
 |  
|   | min@y™ (статус: Доктор наук), 7 июня 2010, 15:41 [#5]:Вот кусок: 
 procedure TMainForm.GetInfoButtonClick(Sender: TObject);
var
  MBI: MEMORY_BASIC_INFORMATION;
  Address, Readed: Cardinal;
  Buf: Pointer;
  Stream: TMemoryStream;
begin
  // Получение инфы о процессе - цели
  // 1) Получение хэндла окна
  FTargetWindow:= FindWindow(TargetWindowClassName, TargetWindowTitle);
  if FTargetWindow <> 0
    then TargetHWndPanel.Caption:= ' Target window hWnd:'#9#9' 0x' + IntToHex(FTargetWindow, 8)
    else TargetHWndPanel.Caption:= ' Target window hWnd:'#9#9' не найдено';
 
  // 2) Получение идентификатора процесса (PID) и идентификатора нити
  FTargetThreadId := GetWindowThreadProcessId(FTargetWindow, @FTargetProcessId);
  if FTargetProcessId <> 0
    then TargetProcessIDPanel.Caption:= ' Target window ProcessID:'#9' 0x' + IntToHex(FTargetProcessId, 8)
    else TargetProcessIDPanel.Caption:= ' Target window ProcessID:'#9' не найдено';
 
  if FTargetThreadId <> 0
    then TargetThreadIDPanel.Caption:= ' Target window ThreadID:'#9' 0x' + IntToHex(FTargetThreadId, 8)
    else TargetThreadIDPanel.Caption:= ' Target window ThreadID:'#9' не найдено';
 
  // 3) Получение хэндла области памяти и чтение этой памяти с поток
  FHandleWindow:= OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, FTargetProcessId);
  if FHandleWindow <> 0
    then try
           HandleWindowHWndPanel.Caption:= ' Handle window hWnd:'#9#9' 0x' + IntToHex(FHandleWindow, 8);
           Buf:= nil;
           Address:= 0;
           Stream:= TMemoryStream.Create;
 
           try
             while Address < $FFFFFFFF do
               begin
                 if VirtualQueryEx(FHandleWindow,
                                   Pointer(Address),
                                   MBI,
                                   SizeOf(MBI)) <> SizeOf(MBI)
                   then Break;
 
                 if MBI.State = MEM_COMMIT
                   then begin
                          ReAllocMem(Buf, MBI.RegionSize);
                          if not ReadProcessMemory(FHandleWindow,
                                                   MBI.BaseAddress,
                                                   Buf,
                                                   MBI.RegionSize,
                                                   Readed)
                            then Readed:= 0;
 
                          Stream.WriteBuffer(Buf^, Readed);
                        end;
 
                  Address:= DWORD(MBI.BaseAddress) + MBI.RegionSize;
               end; // while
             //Stream.SaveToFile('dump.bin');
             FindValueInStream(Cardinal(FTargetValue), Stream, ChangeProgress, AddFinded);
           finally
             Stream.Free;
           end;
 
         finally
           // Закрытие хэндла
           if FHandleWindow <> 0
             then CloseHandle(FHandleWindow);
         end
    else HandleWindowHWndPanel.Caption:= ' Handle window hWnd:'#9#9' не найдено';
end;Процесс дампится в стрим. Размер стрима после считывания - Stream.Size. Однако стоит помнить, что процессы во время работы могут клянчить динамическую память у системы, следовательно, их размер может меняться с течением времени. Дак что такой дамп - это слепок процесса в конкретный момент времени.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | SOA (статус: Посетитель), 7 июня 2010, 15:42 [#6]:Почитаю. |  
|   | bugmenot (статус: 3-ий класс), 7 июня 2010, 15:45 [#7]:min@y™: клай его сюды, мне тоже интересно. Я бы смешение инициализировал в базовый адрес ($40000000 же), а размер брал от GetProcessWorkingSetSize().
 Что такое "главный процесс приложения"? Главный модуль?
 виконання програми розпочинається з того самого мiсця, де призупинилося.
 
 |  
|   | SOA (статус: Посетитель), 7 июня 2010, 15:45 [#8]:Этж 4 ГИГА на винт сливать, а там чуть больше 40mb наверно. |  
|   | SOA (статус: Посетитель), 7 июня 2010, 15:47 [#9]:Главный процесс приложения это тот который порождает остальные и в его контексте если я все правильно понимаю работают все дочерние, ввиду чего если слить главный то сольешь и все остальные. |  
|   | bugmenot (статус: 3-ий класс), 7 июня 2010, 15:54 [#10]:VirtualQueryEx да, логично, working-set не обязан был непрерывным. 
 Нет, с дочерними _процессами_ предстоит ровно такая же операция. Похоже ты путаешь process и thread
 виконання програми розпочинається з того самого мiсця, де призупинилося.
 
 |  
|   | SOA (статус: Посетитель), 7 июня 2010, 15:58 [#11]:$40000000 это верхняя граница области памяти отведенная для ОС да? GetProcessWorkingSetSize можно попробывать взять минимальный размер, мне ведь данные нужны, а они вроде бы в первым сегментом поидее идут, такчто может получиться, хотя могу и ошибаться.
 |  
|   | min@y™ (статус: Доктор наук), 7 июня 2010, 16:01 [#12]: Цитата (SOA): Этж 4 ГИГА на винт сливать, а там чуть больше 40mb наверно.  Смотри внимательно на условие выхода из цикла.
 
 if VirtualQueryEx(FHandleWindow,
                  Pointer(Address),
                  MBI,
                  SizeOf(MBI)) <> SizeOf(MBI)
  then Break;Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | SOA (статус: Посетитель), 7 июня 2010, 16:04 [#13]:Тоесть получается что система не даст мне прочитать больше инфы чем есть в процессе так? |  
|   | min@y™ (статус: Доктор наук), 7 июня 2010, 16:07 [#14]: Цитата (SOA): Тоесть получается что система не даст мне прочитать больше инфы чем есть в процессе так?  Начинаешь по-немногу шарить... Это радует.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | SOA (статус: Посетитель), 7 июня 2010, 16:07 [#15]:Просто я не знал что возвращает эта функция, так что сори 8) |  
|   | SOA (статус: Посетитель), 7 июня 2010, 16:23 [#16]:Люди так всетаки начинать то наверно надо $40000000, или же с 0 а? |  
|   | Вадим К (статус: Академик), 7 июня 2010, 16:27 [#17]:$40000000 - это такой адрес с которого "обычно" начинается размешаться код приложения. но "НЕ ОБЯЗАН!!!!" А код операционной системы обычно начинается с 3 гига. Хотя может начинаться с 4гига (не с конца 4 гига, а с начала!).
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | SOA (статус: Посетитель), 7 июня 2010, 16:30 [#18]:А какже тогда смещение на начало процесса то узнать? |  
|   | bugmenot (статус: 3-ий класс), 7 июня 2010, 16:38 [#19]:Прошу прощения, сыпанул нулей слишком щедро  правильный _базовый_ адрес $400000 Именно это вернет GetModuleHandle(nil) см. http://msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx (непрозрачный тип HMODULE - суть адрес загрузки)
 виконання програми розпочинається з того самого мiсця, де призупинилося.
 
 |  
|   | SOA (статус: Посетитель), 7 июня 2010, 16:44 [#20]:так ведь GetModuleHandle(nil) вернет Handle моего окна, если я не ошибаюсь. |  Страницы: [1] [2] [Следующая »]  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |