Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Вниз

Адресное пространство процесса   Найти похожие ветки 

 
Nomolos   (2004-06-14 22:11) [0]

Нужно разбить виртуальную память процесса на страницы, делаю примерно так:

hProcess := OpenProcess(PROCESS_VM_READ, true, ProcessID);
VirtualQueryEx(hProcess, P, mbi, sizeof(mbi));

В 98м всё происходит, а под XP возвращает 0 (говорит, ошибка доступа). В чём ошибка, не знаете?


 
Игорь Шевченко ©   (2004-06-14 22:35) [1]

Наверное процесс не открывается...

>  В чём ошибка, не знаете?


В том, что не все процессы можно открыть


 
Nomolos   (2004-06-15 00:16) [2]

Но на хэндл не ругается, там обработка стоит, я её не писал здесь просто, да и ошибка больно уж специфическая... Вобщем, у меня крупное подозрение, что процесс всё-же открывается. А если и нет, как ещё можно дескриптор запросить?


 
RagE ©   (2004-06-15 11:13) [3]

Я решал немного не такую задачу, мне надо было сначала считать весь исполняемый код процесса а потом его заменить на другой. Так вот интересную вещь заметил, что фиг поймешь как оно работает. Тоже ругалось на ошибках прав доступа но вы не поверите. Чуть ли не методом перебора я получил работающий код.
А хендл процесса можно получить с помощью CreateProcess. Вот код который у меня заработал.
procedure TfMain.ExecuteEXE(FileName:TFileName;Key:string);
var SI:StartupInfo;
   ProcInfo:PROCESS_INFORMATION;
   Coder:TEXECoder;
   TmpStream:TMemoryStream;
   base,imageSize:Cardinal;
   Cont:CONTEXT;
begin
// Запускаем процесс в режиме останова
 ZeroMemory(@si,sizeof(si));
 si.cb:=SizeOf(si);
 if not CreateProcess(PChar(FileName),nil,nil,nil,false,CREATE_SUSPENDED,
     nil,nil,SI,ProcInfo) then
       begin
         ShowMessage("Не удалось запустить файл "+FileName);
         Exit;
       end;
//   GetThreadContext(ProcInfo.hThread,Cont);
// Декодируем
 Coder:=TEXECoder.Create;
 TmpStream:=TMemoryStream.Create;
 try
   //Read from memory to stream
   base:=Coder.GetImageBase(FileName); //Base Address from Header
   imageSize:=Coder.CalcImageSize(FileName); //CalcImageSize
   Self.ReadFromProcMemoryToStream(ProcInfo.hProcess,base,imageSize,TmpStream);
   // Decode
//TmpStream.SaveToFile("e:\123.memory");
   Coder.DecodeStreamToStream(TmpStream,TmpStream,Key);
//TmpStream.SaveToFile("e:\123.memory2");
   //Write from stream to memory
   Self.WriteFromStreamToProcMemory(ProcInfo.hProcess,base,TmpStream.Size,TmpStream);

//Self.ReadFromProcMemoryToStream(ProcInfo.hProcess,base,imageSize,TmpStream);
//TmpStream.SaveToFile("e:\123.memory3");

 finally
   Coder.Free;
   TmpStream.Free;
 end;
// Запускаем
//  SetThreadContext(ProcInfo.hThread,Cont);
 ResumeThread(ProcInfo.hThread);
 WaitForSingleObject(ProcInfo.hThread,INFINITE);
 WaitForSingleObject(ProcInfo.hProcess,INFINITE);
 CloseHandle(ProcInfo.hThread);
 CloseHandle(ProcInfo.hProcess);
end;
procedure TfMain.ReadFromProcMemoryToStream(ProcHandle:THandle;FromAddress,Count:Cardinal;var Stream:TMemoryStream);
var ReadCount:Cardinal;
begin
 Stream.SetSize(Count);
 Stream.Position:=0;
 ReadProcessMemory(ProcHandle,Ptr(FromAddress),Stream.Memory,Count,ReadCount);
//  ErrorShow;
end;

procedure TfMain.WriteFromStreamToProcMemory(ProcHandle:THandle;FromAddress,Count:Cardinal;Stream:TMemoryStream);
var WriteCount:Cardinal;
   Err:LongBool;
   oldprotect:Cardinal;
   AllocAddress:Pointer;
begin
 Stream.Position:=0;
//  if VirtualAllocEx(ProcHandle,Ptr(FromAddress),Count,MEM_COMMIT,PAGE_READWRITE)=nil then
//     ErrorShow;
//  ErrorShow;
 VirtualProtectEx(ProcHandle,Ptr(FromAddress),Count,PAGE_EXECUTE_WRITECOPY,Addr(oldprotect));
//  ErrorShow;
 Err:=WriteProcessMemory(ProcHandle,Ptr(FromAddress),Stream.Memory,Count,WriteCount);
//  ErrorShow;
//  VirtualProtectEx(ProcHandle,Ptr(FromAddress),Count,oldprotect,Addr(oldprotect));
//  ErrorShow;
end;

Я не убирал комментарии, чтобы было видно какие методы я еще пробовал. Вот так работает. Может это не то что нужно но может хоть чем то поможет


 
Игорь Шевченко ©   (2004-06-15 11:36) [4]


> Но на хэндл не ругается, там обработка стоит, я её не писал
> здесь просто, да и ошибка больно уж специфическая... Вобщем,
> у меня крупное подозрение, что процесс всё-же открывается


И на основе этих скудных сведений и своих беспочвенных подозрений ты предлагаешь поставить точный диагноз ?

Код (полный) и место возникновения ошибки в студию


 
Nomolos   (2004-06-15 23:11) [5]

2Игорь Шевченко:

Я не делаю никаких выводов, но, если я правильно понимаю, в случае, если OpenProcess не создаёт системной ошибки и возвращает описатель, отличный от INVALID_HANDLE_VALUE, то он, вероятно получен, другое дело - доступ. Я проверял, специально давал ему лже-PID, он ругается на неверный дескриптор. Но, если это действительно необходимо, привожу полный код:
var
 hProcess: THandle;
 P: Pointer;
 mbi: _MEMORY_BASIC_INFORMATION;
begin
 hProcess := OpenProcess(PROCESS_VM_READ, true, ProcessID);
 if hProcess = INVALID_HANDLE_VALUE then Exit;
 P := nil;
 while VirtualQueryEx(hProcess, P, mbi, sizeof(mbi)) <> 0 do begin
// делаем то, что нужно
   P := Pointer(DWORD(P) + mbi.RegionSize)
 end;
 DeleteObject(hProcess)
end;

В цикл он не входит, GetLastError выдаёт "Ошибку доступа". Я как-то слышал, что для полного доступа к объектам системы процесс программы должен иметь ряд привилегированных особенностей, в частности, процесс не имеет доступа к тем процессам, pid которых меньше его собственного. Если кто-нибудь знает подробнее, просьба описать детальнее.
Ещё смущает, что программа корректно работает под платформой Win98, хотя, в старых версиях контроль доступа был значительно ниже...

2RagE:

Благодарю за помощь, ещё не смотрел, но обязательно просмотрю.


 
BiN ©   (2004-06-16 00:35) [6]

>>Я не делаю никаких выводов, но, если я правильно понимаю, в случае, если OpenProcess не создаёт системной ошибки и возвращает описатель, отличный от INVALID_HANDLE_VALUE...

В случае неудачи функция возвращает не INVALID_HANDLE_VALUE, а ноль, так что выражаясь твоим языком, у меня крупное подозрение, что нужный тебе хэндл просто не возвращается.


 
RagE ©   (2004-06-16 09:40) [7]

2 Nomolos
 Осмелюсь предположить что вместо DeleteObject(hProcess) будет более корректно использовать CloseHandle.


 
RagE ©   (2004-06-16 09:41) [8]

2 Nomolos
 Осмелюсь предположить что вместо DeleteObject(hProcess) будет более корректно использовать CloseHandle.
 Да кстати может это и глупо но попробоуй использовать PROCESS?ALL_ACCESS кажется. Не только чтение.


 
clickmaker ©   (2004-06-16 10:30) [9]

DeleteObject вообще для объектов GDI


 
Nomolos   (2004-06-16 22:06) [10]

Насчёт DeleteObject я списал неправильно, у меня CloseHandle =) Хэндл далеко не нулевой, проблемы действительно, как заметил RagE, с доступом, буду в Delphi - попробую



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.035 c
1-1089749097
Mazer
2004-07-14 00:04
2004.08.01
Есть ли StringGrid с возможностями, наподобие DBGridEh?


14-1089616282
Сергей Стоянов
2004-07-12 11:11
2004.08.01
Разработка компьютерной системы для частной клиники


14-1090160087
4ainik
2004-07-18 18:14
2004.08.01
dcu


1-1089899316
Pontic
2004-07-15 17:48
2004.08.01
Блокирование управлением ХР


1-1090310634
888
2004-07-20 12:03
2004.08.01
progressbar.create





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский