Форум: "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.038 c