|
Вопрос # 4 296/ вопрос открыт / |
|
Всем привет!!!
Мой вопрос заключается в следующем:
Я пытаюсь слить из памяти в файл содержимое главного процесса чужого приложения. С доступом к памяти разобрался, но возникла проблема: я не знаю как определить размер памяти, которую занимет процесс.
Возможно ктото чемто подобным занимался и знает как можно получить количество байт, которые занимает процес в виртуальной памяти.
Приложение: Переключить в обычный режим- var
- Form1: TForm1;
- OperaHandl:hwnd;
- ProcessHandle:THANDLE;
- ProcessID:DWORD;
- BytsR: Cardinal;
-
- MyFile: File of byte;
- NumWritten:Integer;
-
- procedure TForm1.Button1Click(Sender: TObject);
- var
- Buf:byte;
- begin
- Smeshenie:=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] [Следующая »]
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|