2015-06-18 3 views
2

Я хочу найти путь к каждому запущенному процессу в окнах. Я попытался использовать модуль psutil, но он не показывает мне все пути. Он не может найти множество путей процессов из-за ошибки: „psutil.AccessDenied“Найти путь каждого работающего процесса в Python

c = wmi.WMI() 
for process in c.Win32_Process(): 
     p = psutil.Process(int(process.ProcessId)) 
     try: 
      path = p.exe() 
     except: 
      path = "-" 

Есть еще один способ, чтобы получить путь процесса?

+0

Вы пытались запустить это под Администратором? – cdarke

+0

да я пробовал ..... – Hila

ответ

5

В качестве администратора вы можете получить доступ к PROCESS_QUERY_LIMITED_INFORMATION (0x1000) для данного процесса, если вы не можете получить PROCESS_QUERY_INFORMATION (0x400). QueryFullProcessImageNameW требует ограниченного доступа. Однако даже это не будет работать во всех случаях. Например, дескриптор безопасности на csrss.exe предоставляет только доступ к учетной записи SYSTEM, а не администраторам. Другим примером является service.exe, который работает на уровне целостности (S-1-16-16384), а токен администратора - только на уровне целостности High (S-1-16-12288).

Обычно вы не можете открыть ручку для таких процессов. Но как администратор у вас есть почти всемогущий SeDebugPrivilege. Если вы включите эту привилегию, Windows AccessCheck неожиданно станет вашим лучшим другом (но даже лучшие друзья имеют свои ограничения).

Ниже приведен код ctypes для включения и отключения привилегии в токене доступа к текущему процессу. Вначале привилегия должна присутствовать в токене, поэтому обязательно используйте ее с помощью учетной записи администратора или администратора с повышенными правами при использовании UAC.

from ctypes import * 
from ctypes.wintypes import * 

kernel32 = WinDLL('kernel32', use_last_error=True) 
advapi32 = WinDLL('advapi32', use_last_error=True) 

SE_PRIVILEGE_ENABLED = 0x00000002 
TOKEN_ALL_ACCESS = 0x000F0000 | 0x01FF 

class LUID(Structure): 
    _fields_ = (('LowPart', DWORD), 
       ('HighPart', LONG)) 

class LUID_AND_ATTRIBUTES(Structure): 
    _fields_ = (('Luid',  LUID), 
       ('Attributes', DWORD)) 

class TOKEN_PRIVILEGES(Structure): 
    _fields_ = (('PrivilegeCount', DWORD), 
       ('Privileges', LUID_AND_ATTRIBUTES * 1)) 
    def __init__(self, PrivilegeCount=1, *args): 
     super(TOKEN_PRIVILEGES, self).__init__(PrivilegeCount, *args) 

PDWORD = POINTER(DWORD) 
PHANDLE = POINTER(HANDLE) 
PLUID = POINTER(LUID) 
PTOKEN_PRIVILEGES = POINTER(TOKEN_PRIVILEGES) 

def errcheck_bool(result, func, args): 
    if not result: 
     raise WinError(get_last_error()) 
    return args 

kernel32.CloseHandle.argtypes = (HANDLE,) 

kernel32.GetCurrentProcess.errcheck = errcheck_bool 
kernel32.GetCurrentProcess.restype = HANDLE 

# https://msdn.microsoft.com/en-us/library/aa379295 
advapi32.OpenProcessToken.errcheck = errcheck_bool 
advapi32.OpenProcessToken.argtypes = (
    HANDLE, # _In_ ProcessHandle 
    DWORD, # _In_ DesiredAccess 
    PHANDLE) # _Out_ TokenHandle 

# https://msdn.microsoft.com/en-us/library/aa379180 
advapi32.LookupPrivilegeValueW.errcheck = errcheck_bool 
advapi32.LookupPrivilegeValueW.argtypes = (
    LPCWSTR, # _In_opt_ lpSystemName 
    LPCWSTR, # _In_  lpName 
    PLUID) # _Out_ lpLuid 

# https://msdn.microsoft.com/en-us/library/aa375202 
advapi32.AdjustTokenPrivileges.errcheck = errcheck_bool 
advapi32.AdjustTokenPrivileges.argtypes = (
    HANDLE,   # _In_  TokenHandle 
    BOOL,    # _In_  DisableAllPrivileges 
    PTOKEN_PRIVILEGES, # _In_opt_ NewState 
    DWORD,    # _In_  BufferLength 
    PTOKEN_PRIVILEGES, # _Out_opt_ PreviousState 
    PDWORD)   # _Out_opt_ ReturnLength 

def enable_privilege(privilege): 
    hToken = HANDLE() 
    luid = LUID() 
    advapi32.LookupPrivilegeValueW(None, privilege, byref(luid)) 
    try: 
     advapi32.OpenProcessToken(kernel32.GetCurrentProcess(), 
            TOKEN_ALL_ACCESS, 
            byref(hToken)) 
     tp = TOKEN_PRIVILEGES() 
     tp.Privileges[0].Luid = luid 
     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED 
     advapi32.AdjustTokenPrivileges(hToken, False, 
             byref(tp), 
             sizeof(tp), 
             None, None) 
    finally: 
     if hToken: 
      kernel32.CloseHandle(hToken) 

def disable_privilege(privilege): 
    hToken = HANDLE() 
    luid = LUID() 
    advapi32.LookupPrivilegeValueW(None, privilege, byref(luid)) 
    try: 
     advapi32.OpenProcessToken(kernel32.GetCurrentProcess(), 
            TOKEN_ALL_ACCESS, 
            byref(hToken)) 
     tp = TOKEN_PRIVILEGES() 
     tp.Privileges[0].Luid = luid 
     tp.Privileges[0].Attributes = 0 
     advapi32.AdjustTokenPrivileges(hToken, False, 
             byref(tp), 
             sizeof(tp), 
             None, None) 
    finally: 
     if hToken: 
      kernel32.CloseHandle(hToken) 

Тест:

if __name__ == '__main__': 
    import psutil 
    system_process_names = {'smss.exe', 
          'csrss.exe', 
          'wininit.exe', 
          'winlogon.exe', 
          'services.exe', 
          'lsass.exe', 
          'lsm.exe'} 
    system_processes = [] 

    print('SeDebugPrivilege Enabled') 
    enable_privilege('SeDebugPrivilege')  
    for proc in psutil.process_iter(): 
     try: 
      name = proc.name().lower() 
      path = proc.exe() 
     except psutil.AccessDenied: 
      print('{:04d} ACCESS_DENIED'.format(proc.pid)) 
      continue 
     if name in system_process_names: 
      system_process_names.remove(name) 
      system_processes.append(proc) 
      print('{:04d} {}'.format(proc.pid, path)) 
    assert not system_process_names 

    print('\nSeDebugPrivilege Disabled') 
    disable_privilege('SeDebugPrivilege') 
    for proc in system_processes: 
     try: 
      path = psutil.Process(proc.pid).exe() # avoid cache 
     except psutil.AccessDenied: 
      path = 'ACCESS DENIED' 
     print('{:04d} {}'.format(proc.pid, path)) 

Выход

SeDebugPrivilege Enabled 
0000 ACCESS_DENIED 
0004 ACCESS_DENIED 
0256 C:\Windows\System32\smss.exe 
0404 C:\Windows\System32\csrss.exe 
0492 C:\Windows\System32\wininit.exe 
0540 C:\Windows\System32\winlogon.exe 
0588 C:\Windows\System32\services.exe 
0596 C:\Windows\System32\lsass.exe 
0604 C:\Windows\System32\lsm.exe 
4704 ACCESS_DENIED 

SeDebugPrivilege Disabled 
0256 ACCESS DENIED 
0404 ACCESS DENIED 
0492 ACCESS DENIED 
0540 ACCESS DENIED 
0588 ACCESS DENIED 
0596 ACCESS DENIED 
0604 ACCESS DENIED 

Это понятно, чтобы быть отказано в доступе к Idle (0) и системы (4) процессов. Однако интересно, что доступ был отключен PID 4704 даже отладчику. Это audiodg.exe, который является защищенным процессом, как описано в белой бумаге «Защищенные процессы», доступной для загрузки на Windows Hardware Dev Center Archive. Защищенные процессы позволяют запрашивать ограниченную информацию, такую ​​как путь к изображению. Давайте быстро проверим, что это так:

>>> kernel32.OpenProcess(0x1000, 0, 4704) 
304 
>>> path = (c_wchar * 260)() 
>>> size = c_uint(260) 
>>> kernel32.QueryFullProcessImageNameW(304, 0, path, byref(size)) 
1 
>>> path.value 
'C:\\Windows\\System32\\audiodg.exe' 
Смежные вопросы