-
Здравствуйте !
Допустим, мы хотим собственнолапно перебрать модули некого процесса
и написали для этого скелет нашей будущей ф-ии:function Process_EnumerateModulesTemplate(const hProcess: THANDLE): NTSTATUS;
var
BasicInfo: PROCESS_BASIC_INFORMATION;
pLoaderModule: PLDR_DATA_TABLE_ENTRY;
pLoaderData: PPEB_LDR_DATA;
pHeadEntry, pCurrentEntry: PLIST_ENTRY;
begin
Result := ZwQueryInformationProcess(hProcess, ProcessBasicInformation,
@BasicInfo, SizeOf(PROCESS_BASIC_INFORMATION), nil);
if NT_SUCCESS(Result) then
begin
Result := NtReadVirtualMemory(hProcess, @BasicInfo.PebBaseAddress.LdrData,
@pLoaderData, SizeOf(pLoaderData), nil);
if NT_SUCCESS(Result) then
begin
pHeadEntry := @pLoaderData.InLoadOrderModuleList;
Result := NtReadVirtualMemory(hProcess, @pLoaderData.InLoadOrderModuleList,
@pCurrentEntry, SizeOf(pCurrentEntry), nil);
if NT_SUCCESS(Result) then
while pCurrentEntry <> pHeadEntry do
begin
Result := NtReadVirtualMemory(hProcess, @PLDR_DATA_TABLE_ENTRY(pCurrentEntry).InLoadOrderLinks,
@pLoaderModule, SizeOf(pLoaderModule), nil);
if NT_SUCCESS(Result) then
begin
// Чавой-то вытворяем с pLoaderModule и идем дальше
pCurrentEntry := @pLoaderModule.InLoadOrderLinks.Flink;
end
else Break;
end;
end;
end;
end;
Вроде, наш "скелет" даже работает.
Но, меня смущает, что пока мы занимаемся перебором, данные могут изменится.
В результате мы получим черт знает что или застрянем в каком-нибудь бесконечном цикле.
Как можно обезопаситься от этого ?
P.S.
В "своем" процессе я использовала Peb.LoaderLock, а как быть в чужем ?
P.S.S.
Очень хочется избежать таких варварских приемов,
как усыпление всех нитей целевого процесса :) -
Сергей М. © (17.10.08 08:15) [1]
> как быть в чужем ?
Точно так же.
Внедряешь туда свой код, он выполняет блокировку peb'а и - вуаля ! - надобность в "удаленных" выкрутасах с peb'ом отпадает напрочь) -
> [1] Сергей М. © (17.10.08 08:15)
> Точно так же.
> Внедряешь туда свой код, он выполняет блокировку peb'а и - вуаля ! -
> надобность в "удаленных" выкрутасах с peb'ом отпадает напрочь)
Эт, конечно, так - и проще и возни меньше.
Но слишком уж тяжелая артиллерия применяется.
Можно еще воспользоваться RtlQueryProcessDebugInformation,
но она не со всеми процессами может работать.
А как поступает EnumProcessModules ? -
Сергей М. © (17.10.08 09:05) [3]
> как поступает EnumProcessModules ?
Тогда уж не psapi, а snapshot-функции из tlhelp следовало бы рассматривать ..
А EnumProcessModules - ради интереса оттрассировал вызов - поступает так же "тупо". -
> [3] Сергей М. © (17.10.08 09:05)
> Тогда уж не psapi, а snapshot-функции из tlhelp следовало бы рассматривать ..
Посмотрела. Работает через ту же RtlQueryProcessDebugInformation и, соответственно
спотыкается на тех же процессах, что и она.
> А EnumProcessModules - ради интереса оттрассировал вызов - поступает так же "тупо".
Спасибо. Но что-то здесь "не то" или я чего-то не понимаю.
Мне кажется, что не блокируя PEB, работать просто нельзя.
Может существуют способы попросить процесс: "слушай, залоч Loader на чуть-чуть, а ?" :) ? -
Сергей М. © (17.10.08 12:21) [5]
> спотыкается на тех же процессах, что и она
Уж не system-ли ? -
> Riply © (17.10.08 12:02) [4]
> Может существуют способы попросить процесс: "слушай, залоч
> Loader на чуть-чуть, а ?" :) ?
NTSTATUS NtSuspendProcess(HANDLE hProcess)
NTSTATUS NtResumeProcess(HANDLE hProcess) ?
--
Regards, LVT. -
> [5] Сергей М. © (17.10.08 12:21)
> Уж не system-ли ?
:) Если бы только на нем, я бы и не расстраивалась.
У меня спотыкается (ACCESS_DENIED) примерно на четырех (типа NOPDB.exe - "симантек" антивирус).
А вот наш "скелет" и EnumProcessModules на них отрабатываю нормально. -
Сергей М. © (17.10.08 12:57) [8]
> Riply © (17.10.08 12:36) [7]
> У меня спотыкается (ACCESS_DENIED)
Так м.б. твоему процессу следует сначала получить привелегии пользователя SYSTEM ? -
> [8] Сергей М. © (17.10.08 12:57)
> Так м.б. твоему процессу следует сначала получить привелегии пользователя SYSTEM ?
Видимо, так и сделаю.
И заодно попробую воспользоваться советом [6] Leonid Troyanovsky.