
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
Страницы: (3) 1 [2] 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Цитата Кстати пока отлаживал, псевдохендл не всегда отрабатывал(закономерности не понял), и NtQueryInformationProcess выкидывало с "неверный декриптор". Пришлось DublicateHandle все-таки оставить. Честно говоря, не сталкивался с проблемами из-за псевдохэндла, но раз так, то буду иметь в виду. PS: Закройте его тогда уж, хотя бы, dwProcessHandle в смысле... |
Сообщ.
#17
,
|
|
|
Цитата PS: Закройте его тогда уж, хотя бы, dwProcessHandle в смысле... Сорь ![]() |
Сообщ.
#18
,
|
|
|
Ну раз уж выкладывается решение для copy/paste`ого использования, то не плохо было бы включить в него и проверку настоящего родителя мы нашли или так "погулять вышедшего" ![]() |
Сообщ.
#19
,
|
|
|
Цитата Ну раз уж выкладывается решение для copy/paste`ого использования, то не плохо было бы включить в него и проверку настоящего родителя мы нашли или так "погулять вышедшего" Riply, поясни плиз. Не понял что ты имеешь ввиду под "настоящим родителем". Добавлено Это: Цитата P.S. Только проку от данной методики, как от козла молока. Процесса родителя уже может и не быть в помине, пока мы тут соизволяем его искать И полученный нами ID, можно выбрасывать на помойку. Гораздо лучше использовать NtQuerySystemInformation с параметром SystemProcessesAndThreadsInformation - можно обойтись одним "снимком". Правда и с CreateToolhelp32Snapshot можно, но придется запоминать ProcEntry`ы. P.S.S. >Да нет с TlHelp32 работал >Я люблю, когда появляються задачи по программированию.. >Но тут немного в невиддении насчет родителя.. Ой как "не вяжутся" эти три фразы (особенно учитывая, что в Help`е есть пример Забыла еще одну неприятную вещь: Может получиться так, что к моменту нашего поиска, родитель уже умрет, и будет создан другой процесс с такм же ID, как и у родителя. А вот чтобы не попасть впросак с этим, придется использовать NtQuerySystemInformation и сравнивать времена создания найденого нами родителя и наше. имеешь ввиду? Или более жесткая проверка на то что это именно IE? |
Сообщ.
#20
,
|
|
|
Цитата Rennigth @ Riply, поясни плиз. Не понял что ты имеешь ввиду под "настоящим родителем". Я хотела сказать, что у нас нет уверенности в том, что ID, с которым мы работаем, действительно ID нашего родителя, а не какого-то левого процесса. (случай с использованием старого значения ID, для нового процесса). Соответственно, как положительный ответ OwnerProcessIs_IExplore, так и отрицательный верны с некой долей вероятности. Проверять можно так: сравнить время нашего создания, с временем создания "родителя". И если родитель был создан позже нас, то кричать о подлоге ![]() |
Сообщ.
#21
,
|
|
|
Цитата Я хотела сказать, что у нас нет уверенности в том, что ID, с которым мы работаем, действительно ID нашего родителя, а не какого-то левого процесса. (случай с использованием старого значения ID, для нового процесса). Соответственно, как положительный ответ OwnerProcessIs_IExplore, так и отрицательный верны с некой долей вероятности. Проверять можно так: сравнить время нашего создания, с временем создания "родителя". И если родитель был создан позже нас, то кричать о подлоге Желание дамы - закон! ![]() ![]() ![]() uses ShlObj //Лень в ручную экспортировать //... const SYSTEM_PROCESSES_AND_THREADS_INFORMATION = 5; NT_STATUS_SUCCESS = DWord($00000000); NT_STATUS_ACCESS_DENIED = DWord($C0000022); NT_STATUS_INFO_LENGTH_MISMATCH = DWord($C0000004); CSIDL_PROGRAM_FILES = $0026; IExplorePath: string = '\Internet Explorer\IEXPLORE.EXE'; type PSYSTEM_THREAD_INFORMATION = ^_SYSTEM_THREAD_INFORMATION; _SYSTEM_THREAD_INFORMATION = packed record KernelTime: LARGE_INTEGER; UserTime: LARGE_INTEGER; CreateTime: LARGE_INTEGER; WaitTime: ULONG; StartAddress: Pointer; UniqueProcess: DWORD; UniqueThread: DWORD; Priority: Integer; BasePriority: Integer; ContextSwitchCount: ULONG; State: Longint; WaitReason: Longint; end; PSYSTEM_PROCESS_INFORMATION = ^_SYSTEM_PROCESS_INFORMATION; _SYSTEM_PROCESS_INFORMATION = packed record NextOffset: ULONG; ThreadCount: ULONG; Reserved1: array [0..5] of ULONG; CreateTime: FILETIME; UserTime: FILETIME; KernelTime: FILETIME; ModuleNameLength: WORD; ModuleNameMaxLength: WORD; ModuleName: PWideChar; BasePriority: ULONG; ProcessID: ULONG; InheritedFromUniqueProcessID: ULONG; HandleCount: ULONG; Reserved2 : array[0..1] of ULONG; PeakVirtualSize : ULONG; VirtualSize : ULONG; PageFaultCount : ULONG; PeakWorkingSetSize : ULONG; WorkingSetSize : ULONG; QuotaPeakPagedPoolUsage : ULONG; QuotaPagedPoolUsage : ULONG; QuotaPeakNonPagedPoolUsage : ULONG; QuotaNonPagedPoolUsage : ULONG; PageFileUsage : ULONG; PeakPageFileUsage : ULONG; PrivatePageCount : ULONG; ReadOperationCount : LARGE_INTEGER; WriteOperationCount : LARGE_INTEGER; OtherOperationCount : LARGE_INTEGER; ReadTransferCount : LARGE_INTEGER; WriteTransferCount : LARGE_INTEGER; OtherTransferCount : LARGE_INTEGER; ThreadInfo: array [0..0] of _SYSTEM_THREAD_INFORMATION; end; function ZwQuerySystemInformation(ASystemInformationClass: Cardinal; ASystemInformation: Pointer; ASystemInformationLength: Cardinal; AReturnLength: PCardinal): Cardinal; stdcall; external 'ntdll.dll'; function GetModuleFileNameExA(hProcess: THandle; hModule: HModule; lpFilename: PAnsiChar; nSize: DWORD): DWORD; stdcall; external 'PSAPI.dll'; function OwnerProcessIs_IExplore: Boolean; var pSI, pSITemp: PSYSTEM_PROCESS_INFORMATION; hParentProcess: THandle; dwParentProcessID, dwSelfProcessID: DWORD; lpFileName, lpPFPath: PAnsiChar; dwOffSet, dwSize: DWORD; ftSelfProcTime: FILETIME; begin Result := False; dwSelfProcessID := GetCurrentProcessId; dwSize := 0; dwParentProcessID := 0; if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION, nil, 0, @dwSize) <> NT_STATUS_INFO_LENGTH_MISMATCH then Exit; pSI := VirtualAlloc(nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); if Assigned(pSI) then try if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION, pSI, dwSize, @dwSize) = NT_STATUS_SUCCESS then begin pSITemp := pSI; repeat if pSITemp^.ProcessID = dwSelfProcessID then begin dwParentProcessID := pSITemp^.InheritedFromUniqueProcessID; ftSelfProcTime := pSITemp^.CreateTime; Break; end; dwOffSet := pSITemp^.NextOffset; pSITemp := Pointer(DWORD(pSITemp) + dwOffSet); until dwOffSet = 0; if dwParentProcessID > 0 then begin pSITemp := pSI; repeat if pSITemp^.ProcessID = dwParentProcessID then begin if CompareFileTime(ftSelfProcTime, pSITemp^.CreateTime) > 0 then begin hParentProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, dwParentProcessID); try if hParentProcess > 0 then begin lpFileName := GetMemory(MAX_PATH); try ZeroMemory(lpFileName, MAX_PATH); lpPFPath := GetMemory(MAX_PATH); try ZeroMemory(lpPFPath, MAX_PATH); if SHGetSpecialFolderPath(0, lpPFPath, CSIDL_PROGRAM_FILES, False) and (GetModuleFileNameExA(hParentProcess, 0, lpFileName, MAX_PATH) > 0) then Result := lpPFPath + IExplorePath = lpFileName; finally FreeMemory(lpPFPath); end; finally FreeMemory(lpFileName); end; end; finally CloseHandle(hParentProcess); end; end; Break; end; dwOffSet := pSITemp^.NextOffset; pSITemp := Pointer(DWORD(pSITemp) + dwOffSet); until dwOffSet = 0; end; end; finally VirtualFree(pSI, 0, MEM_RELEASE); end; end; Добавлено Кстати вопросик, чем отличаеютя в структуре SYSTEM_PROCESS_INFORMATION времена CreateTime, UserTime, KernelTime? |
![]() |
Сообщ.
#22
,
|
|
Что значит чем отличаются. UserTime + KernelTime = общее время работы процесса.
|
Сообщ.
#23
,
|
|
|
Цитата Кстати вопросик, чем отличаеютя в структуре SYSTEM_PROCESS_INFORMATION времена CreateTime, UserTime, KernelTime? Соответственно время создания процесса, время, которое его потоки выполнялись в пользовательском режиме и режиме ядра. Здесь описано: http://msdn2.microsoft.com/en-us/library/ms683223.aspx |
Сообщ.
#24
,
|
|
|
Цитата Что значит чем отличаются. UserTime + KernelTime = общее время работы процесса. Логично... ![]() ![]() Добавлено Цитата Соответственно время создания процесса, время, которое его потоки выполнялись в пользовательском режиме и режиме ядра. Здесь описано: http://msdn2.microsoft.com/en-us/library/ms683223.aspx О спс, почитаем... |
Сообщ.
#25
,
|
|
|
Rouse_
Кстати, ExitTime - CreationTime не равно UserTime + KernelTime. Когда все потоки процесса простаивают, UserTime и KernelTime не меняется. В этом случае UserTime + KernelTime будет меньше. И наоборот, если у процесса несколько потоков и все они работают безперебойно, UserTime + KernelTime может быть больше чем ExitTime - CreationTime, так как вроде бы UserTime и KernelTime суммируются по всем потокам процесса. |
![]() |
Сообщ.
#26
,
|
|
Rose, ну это то понятно
![]() ![]() Цитата Rose @ так как вроде бы UserTime и KernelTime суммируются по всем потокам процесса. Конечно, но т.к. система псевдомногопоточная, т.е. в единый квант времени выполняется только что-то одно, то ExitTime - CreationTime никогда не будет меньше чем UserTime + KernelTime ![]() |
Сообщ.
#27
,
|
|
|
Цитата Конечно, но т.к. система псевдомногопоточная, т.е. в единый квант времени выполняется только что-то одно, то ExitTime - CreationTime никогда не будет меньше чем UserTime + KernelTime Логично, но это верно только для однопроцессорной системы. На многопроцессорной UserTime + KernelTime уже может и превышать ![]() Кстати, мне тоже интересно, как система следит за тем, в каком режиме (user или kernel) выолняется поток? |
![]() |
Сообщ.
#28
,
|
|
Цитата Rose @ На многопроцессорной UserTime + KernelTime уже может и превышать Истину глаголишь ![]() Цитата Rose @ Кстати, мне тоже интересно, как система следит за тем, в каком режиме (user или kernel) выолняется поток? Вычисляется в KeUpdateRunTime() Грубо говоря выглядит примерно так: ![]() ![]() push ebx ; we will destroy ebx inc dword ptr [eax]+PcPrcbData+PbInterruptCount mov ebx, [eax]+PcPrcbData+PbCurrentThread ; (ebx)->current thread mov ecx, ThApcState+AsProcess[ebx] ; (ecx)->current thread's process test dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK jne Kutp20 ; if ne, user mode test byte ptr [ebp]+TsSegCs, MODE_MASK ; test if prev mode was kernel jne Kutp20 ; if ne, user mode ; ; Update the total time spent in kernel mode ; mov edx, 0 ; set kernel mode inc dword ptr [eax].PcPrcbData.PbKernelTime cmp byte ptr [esp+8], DISPATCH_LEVEL jc short Kutp4 ; OldIrql<2, then kernel ja short Kutp3 ; OldIrql>2, then interrupt |
Сообщ.
#29
,
|
|
|
Ага, осталось только выяснить где и когда вызывается KeUpdateRunTime? Надо полагать, по прерыванию от таймера?
|
![]() |
Сообщ.
#30
,
|
|
Она вызывается из KeUpdateSystemTime который дергается каждый раз при срабатывании прерывания системного таймера (тамже увеличивается и знаение возвращаемое GetTiCkCount и много чего еще)
![]() |