Всем привет!
Столкнулся с такой проблемой.. (Win7-x32, пишу на ассемблере FASM)
Мне нужно получить дескрипторы (Handle) всех активных процессов, чтобы просмотреть их токены OpenProcessToken(). Для этого делаю Snapshot, и в цикле Process32Next() получаю PID процессов, которые далее передаю в OpenProcess().
Проблема в том, что Process32Next() отрабатывает исправно (смотрел в отладчике) и на каждой итерации в OpenProcess() передаётся валидный PID. При ошибке она должна возвращать нуль, но в регистре EAX я всегда получаю одинаковое значение 0x9C, хотя в отладчике пишет "ErrorSuccess". Пробовал через тот-же OpenProcess() получить дескриптор своего процесса, но тогда опять Success, а в EAX всегда 44h. Просмотрел таблицу статусных кодов на MSDN для этих значений, и там указано:
В описании OpenProcess() говорится, что для доступа к сис.процессам нужна привилегия SE_DEBUG, которую я получил (смотрел в ProcessHacker для своего процесса). Подозреваю, что дело в "Уровнях целостности процессов" (Integrity Level), который ввели начиная с Висты. Данная функция возвращает ОК только с тремя флагами: SYNCHRONIZE, PROCESS_TERMINATE, и PROCESS_QUERY_LIMITED_INFORMATION - в остальных случаях получаем ошибку доступа(5).
Но тогда почему она не возвращает валидный хэндл для моего-же процесса?, ведь уровень должен это позволять. Кто-нибудь в курсе, почему такая проблема с OpenProcess(). Или может есть иной вариант получить хэндлы всех активных процессов? Вот мой код, который запускаю от админа, и результат его работы:
Столкнулся с такой проблемой.. (Win7-x32, пишу на ассемблере FASM)
Мне нужно получить дескрипторы (Handle) всех активных процессов, чтобы просмотреть их токены OpenProcessToken(). Для этого делаю Snapshot, и в цикле Process32Next() получаю PID процессов, которые далее передаю в OpenProcess().
Проблема в том, что Process32Next() отрабатывает исправно (смотрел в отладчике) и на каждой итерации в OpenProcess() передаётся валидный PID. При ошибке она должна возвращать нуль, но в регистре EAX я всегда получаю одинаковое значение 0x9C, хотя в отладчике пишет "ErrorSuccess". Пробовал через тот-же OpenProcess() получить дескриптор своего процесса, но тогда опять Success, а в EAX всегда 44h. Просмотрел таблицу статусных кодов на MSDN для этих значений, и там указано:
#define ERROR_TOO_MANY_NAMES 0x44 (68L)Первый вообще бред какой-то, а второй более похож на правду..
//
// MessageId: ERROR_TOO_MANY_NAMES
// The name limit for the local computer network adapter card was exceeded.
// (Превышено ограничение на имя карты сетевого адаптера локального компьютера)
#define ERROR_SIGNAL_REFUSED 0x9c (156L)
//
// MessageId: ERROR_SIGNAL_REFUSED
// The recipient process has refused the signal.
// (Процесс-получатель отказался от сигнала)
В описании OpenProcess() говорится, что для доступа к сис.процессам нужна привилегия SE_DEBUG, которую я получил (смотрел в ProcessHacker для своего процесса). Подозреваю, что дело в "Уровнях целостности процессов" (Integrity Level), который ввели начиная с Висты. Данная функция возвращает ОК только с тремя флагами: SYNCHRONIZE, PROCESS_TERMINATE, и PROCESS_QUERY_LIMITED_INFORMATION - в остальных случаях получаем ошибку доступа(5).
Но тогда почему она не возвращает валидный хэндл для моего-же процесса?, ведь уровень должен это позволять. Кто-нибудь в курсе, почему такая проблема с OpenProcess(). Или может есть иной вариант получить хэндлы всех активных процессов? Вот мой код, который запускаю от админа, и результат его работы:
format pe console include 'win32ax.inc' entry start ;//---------- .data pe32 PROCESSENTRY32 ;//---- Структура "TOKEN_PRIVILEGES" align 16 newState: PrivilegeCount dd 1 Luid1 dq 0 Attribute1 dd SE_PRIVILEGE_ENABLED errMes rb 64 sidStr rb 64 Name rb 128 DomainName rb 128 cbName dd 128 cbDomainName dd 128 peUse dd 0 align 16 hToken dd 0 hSnap dd 0 pcbBytesNeeded dd 0 align 16 buff db 0 ;//---------- .code start: invoke SetConsoleTitle,<'*** Session info ***',0> ;//----- Запрашиваю уровень целостности своего процесса ---------- invoke OpenProcessToken,-1,TOKEN_QUERY,hToken invoke GetTokenInformation,[hToken],\ TokenIntegrityLevel,\ buff,32,pcbBytesNeeded mov esi,dword[buff] push esi invoke ConvertSidToStringSid,esi,sidStr pop esi invoke LookupAccountSid,0,esi,\ Name,cbName,\ DomainName,cbDomainName,peUse invoke CharToOem,Name,Name invoke CharToOem,DomainName,DomainName cinvoke printf,<10,' Integrity Level.....: %s (%s, %s)',0>,\ dword[sidStr],DomainName,Name invoke CloseHandle,[hToken] ;//----- Попытка получить хэндл своего процесса ------------ invoke GetCurrentProcessId push eax invoke OpenProcess, PROCESS_TERMINATE, FALSE, eax pop ebx ;//<--- EBX = PID push eax ;//<--- EAX = Handle cinvoke printf,<10,' Current Process Hndl: 0x%x. PID: %d',10,0>,eax,ebx pop eax invoke CloseHandle,eax ;//----- Выставляю привилегию "SeDebug" в своём токене! invoke GetCurrentProcess invoke OpenProcessToken,eax,\ TOKEN_QUERY + TOKEN_ADJUST_PRIVILEGES,hToken invoke LookupPrivilegeValue,0,<'SeDebugPrivilege',0>,Luid1 invoke AdjustTokenPrivileges,[hToken],0,newState,0,0,0 or eax,eax jnz @f cinvoke printf,<10,' SeDebugPrivilege error!',0> jmp @exit @@: invoke CloseHandle,[hToken] ;//------------------------------------------ cinvoke printf,<10,23 dup(' '),'PID Hndl LastError',\ 10,23 dup(' '),'---- ----- -------------------',10,0> ;//----- Обход всех активных процессов invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0 mov [hSnap],eax invoke Process32First,[hSnap],pe32 @next: invoke Process32Next,[hSnap],pe32 ;// EAX=0: ошибка or eax,eax je @stop mov eax,[pe32.th32ProcessID] invoke OpenProcess, PROCESS_QUERY_LIMITED_INFORMATION, 0, eax or eax,eax je @fuck push eax eax ;//<---- EAX должен быть хэндл, но всегда получаю 0x9C mov esi,pe32 add esi,PROCESSENTRY32.szExeFile cinvoke printf,<' %-20s %4d %04x',0>, esi, [pe32.th32ProcessID], eax pop eax call GetError pop eax invoke CloseHandle,eax @fuck: jmp @next @stop: invoke CloseHandle,[hSnap] @exit: cinvoke _getch ;// клавиша cinvoke exit,0 ;// выход! ;//**** Расшифровка сообщений об ошибке *************************** GetError: invoke GetLastError invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,eax,0,errMes,128,0 invoke CharToOem,errMes,errMes cinvoke printf,<' %s',0>,errMes ret ;//**************************************************************** section '.idata' import data readable library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll',\ user32,'user32.dll',advapi32,'advapi32.dll' include 'api\msvcrt.inc' include 'api\kernel32.inc' include 'api\user32.inc' include 'api\advapi32.inc' include 'equates\advapi32.inc'
К сообщению приложены файлы: