Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 296

/ вопрос открыт /

Всем привет!!!
Мой вопрос заключается в следующем:
Я пытаюсь слить из памяти в файл содержимое главного процесса чужого приложения. С доступом к памяти разобрался, но возникла проблема: я не знаю как определить размер памяти, которую занимет процесс.
Возможно ктото чемто подобным занимался и знает как можно получить количество байт, которые занимает процес в виртуальной памяти.

Приложение:
  1. var
  2. Form1: TForm1;
  3. OperaHandl:hwnd;
  4. ProcessHandle:THANDLE;
  5. ProcessID:DWORD;
  6. BytsR: Cardinal;
  7.  
  8. MyFile: File of byte;
  9. NumWritten:Integer;
  10.  
  11. procedure TForm1.Button1Click(Sender: TObject);
  12. var
  13. Buf:byte;
  14. begin
  15. Smeshenie:=0;
  16. OperaHandl:=FindWindow(nil,'Opera');
  17. if OperaHandl<>0 Then
  18.  
  19.  
  20. GetWindowThreadProcessId(OperaHandl,@ProcessId);
  21. if ProcessId<>0 Then
  22.  
  23. ProcessHandle:=OpenProcess(PROCESS_ALL_ACCESS,TRUE,ProcessId);
  24. if ProcessHandle<>null Then
  25.  
  26. AssignFile(MyFile,'Slitok.mydat');
  27. Rewrite(MyFile);
  28.  
  29.  
  30. ReadProcessMemory(ProcessHandle,Pointer(Smeshenie),@Buf,Cardinal(1),BytsR);
  31. BlockWrite(MyFile,Buf,BytsR,NumWritten);
  32.  
  33. End;
  34. End;
  35. End;
  36. end;


SOA Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 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™

min@y™ (статус: Доктор наук), 7 июня 2010, 15:05 [#1]:

Могу прислать пример, в котором целевой процесс дампится в TMemoryStream. А стрим можно потом сохранить в файло, если надо.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
SOA

SOA (статус: Посетитель), 7 июня 2010, 15:12 [#2]:

Большой наверно?
min@y™

min@y™ (статус: Доктор наук), 7 июня 2010, 15:23 [#3]:

Цитата (SOA):

Большой наверно?

Кто большой? Исходник? Щас померяю...
5,3 кб в архиве. А что?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
SOA

SOA (статус: Посетитель), 7 июня 2010, 15:24 [#4]:

Там хоть коменты есть?
Мне ведь всего то надо узнать число байт.
min@y™

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

SOA (статус: Посетитель), 7 июня 2010, 15:42 [#6]:

Почитаю.
bugmenot

bugmenot (статус: 3-ий класс), 7 июня 2010, 15:45 [#7]:

min@y™: клай его сюды, мне тоже интересно.
Я бы смешение инициализировал в базовый адрес ($40000000 же), а размер брал от GetProcessWorkingSetSize().
Что такое "главный процесс приложения"? Главный модуль?
виконання програми розпочинається з того самого мiсця, де призупинилося.

SOA

SOA (статус: Посетитель), 7 июня 2010, 15:45 [#8]:

Этж 4 ГИГА на винт сливать, а там чуть больше 40mb наверно.
SOA

SOA (статус: Посетитель), 7 июня 2010, 15:47 [#9]:

Главный процесс приложения это тот который порождает остальные и в его контексте если я все правильно понимаю работают все дочерние, ввиду чего если слить главный то сольешь и все остальные.
bugmenot

bugmenot (статус: 3-ий класс), 7 июня 2010, 15:54 [#10]:

VirtualQueryEx да, логично, working-set не обязан был непрерывным.

Нет, с дочерними _процессами_ предстоит ровно такая же операция. Похоже ты путаешь process и thread
виконання програми розпочинається з того самого мiсця, де призупинилося.

SOA

SOA (статус: Посетитель), 7 июня 2010, 15:58 [#11]:

$40000000 это верхняя граница области памяти отведенная для ОС да?
GetProcessWorkingSetSize можно попробывать взять минимальный размер, мне ведь данные нужны, а они вроде бы в первым сегментом поидее идут, такчто может получиться, хотя могу и ошибаться.
min@y™

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

SOA (статус: Посетитель), 7 июня 2010, 16:04 [#13]:

Тоесть получается что система не даст мне прочитать больше инфы чем есть в процессе так?
min@y™

min@y™ (статус: Доктор наук), 7 июня 2010, 16:07 [#14]:

Цитата (SOA):

Тоесть получается что система не даст мне прочитать больше инфы чем есть в процессе так?

Начинаешь по-немногу шарить... Это радует.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
SOA

SOA (статус: Посетитель), 7 июня 2010, 16:07 [#15]:

Просто я не знал что возвращает эта функция, так что сори 8)
SOA

SOA (статус: Посетитель), 7 июня 2010, 16:23 [#16]:

Люди так всетаки начинать то наверно надо $40000000, или же с 0 а?
Вадим К

Вадим К (статус: Академик), 7 июня 2010, 16:27 [#17]:

$40000000 - это такой адрес с которого "обычно" начинается размешаться код приложения. но "НЕ ОБЯЗАН!!!!"
А код операционной системы обычно начинается с 3 гига. Хотя может начинаться с 4гига (не с конца 4 гига, а с начала!).
Галочка "подтверждения прочтения" - вселенское зло.
SOA

SOA (статус: Посетитель), 7 июня 2010, 16:30 [#18]:

А какже тогда смещение на начало процесса то узнать?
bugmenot

bugmenot (статус: 3-ий класс), 7 июня 2010, 16:38 [#19]:

Прошу прощения, сыпанул нулей слишком щедро :) правильный _базовый_ адрес $400000
Именно это вернет GetModuleHandle(nil) см. http://msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx (непрозрачный тип HMODULE - суть адрес загрузки)
виконання програми розпочинається з того самого мiсця, де призупинилося.

SOA

SOA (статус: Посетитель), 7 июня 2010, 16:44 [#20]:

так ведь GetModuleHandle(nil) вернет Handle моего окна, если я не ошибаюсь.

Страницы: [1] [2] [Следующая »]

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:42
Выполнено за 0.03 сек.