05.05.2000 Недокументированные функции WindozeNT/2000 [ULTRAS/MATRiX]

В этой статье описывается часть недокументированных функций WindowsNT/2000

 NtQueryInformationProcess

 NtQueryInformationProcess копирует информацию процесса указанного типа в 
 буфер

 
  NTSYSAPI

  NTSTATUS

  NTAPI

  NtQuerySystemInformation(

      IN HANDLE ProcessHandle,

      IN PROCESSINFOCLASS InformationClass,

      OUT PVOID ProcessInformation, // pointer to buffer

      IN ULONG ProcessInformationLength, // buffer size in bytes

      OUT PULONG ReturnLength OPTIONAL // number of bytes written to 
                                          the buffer

      );


  ProcessHandle - хэндл процесса
  InformationClass - информационный тип
  ProcessInformation - указатель на буфер
  ProcessInformationLength - буферный размер в байтах
  ReturnLength - число байтов записываемых в буферу

  Первый аргумент - открытый хендл к процессу, этот хендл должна 
  иметь PROCESS_QUERY_INFORMATION доступ. 
  Чтобы получить хендл, мы должны использовать функцию OpenProcess:

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwProcessID); 

  Второй аргумент - тип требуемой информации, имеются много параметров 
  для этого аргумента, но мы будем использовать 
  ProcessBasicInformation, он равен 0.

  Поэтому, если второй аргумент - ProcessBasicInformation, третий 
  аргумент обязательно должен быть указатель на структуру 
  PROCESS_BASIC_INFORMATION:

 Typedef struct
 {
  DWORD ExitStatus; // получает статус завершения процесса
  DWORD PebBaseAddress; // получает адрес блока окружающей 
                           среды процесса
  DWORD AffinityMask; // получает маску близости процесса
  DWORD BasePriority; // получает класс приоритета процесса
  ULONG UniqueProcessId; // получает идентификатор процесса
  ULONG InheritedFromUniqueProcessId; // получает родительский 
                                        идентификатор процесса
 } PROCESS_BASIC_INFORMATION; 


  Последний элемент в этой структуре - InheritedFromUniqueProcessId, 
  это - то, что нам нжно:

 DWORD dwParentPID;
 LONG status;
 PROCESS_BASIC_INFORMATION pbi;

 status = NtQueryInformationProcess( hProcess,
 ProcessBasicInformation,
 (PVOID)&pbi,
 sizeof(PROCESS_BASIC_INFORMATION),
 NULL );

 
 if (!status)
 dwParentPID = pbi.InheritedFromUniqueProcessId; 


  InternalGetWindowText

  Функция InternalGetWindowText аналог функций GetWindowText, 
  но работает наша функция на много быстрее.

  Еще одна недокументированная функция WindowsNT/2000.

  InternalGetWindowText:

  BOOL InternalGetWindowText (
  HWND hWnd, // обращается к окну или контролю с текстом
  LPWSTR lpString, // указатель на буфер для текста (UNICODE!!!)
  int nMaxCount, // максимальный значение знаков, чтобы копировать
  ); 


  Microsoft не обеспечивает нас символами экспорта в User32.lib для 
  этой функции, так что мы должны загрузить их, динамически используя 
  Функции GetModuleHandle и GetProcAddress:

  typedef BOOL (WINAPI *PROCINTERNALGETWINDOWTEXT)(HWND,LPWSTR,int);

  PROCINTERNALGETWINDOWTEXT InternalGetWindowText;

  HMODULE hUser32 = GetModuleHandle("user32");

  InternalGetWindowText = (PROCINTERNALGETWINDOWTEXT)
  GetProcAddress(hUser32,"InternalGetWindowText"); 


  Admin privileges!

  Определяем если процесс запущен с административными привилегиями в 
  WindowsNT/2000

  Сначала, мы должны получить handle к текущему символу процесса, вызывая 
  функцию OpenProcessToken:
  HANDLE hAccessToken;

  OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hAccessToken); 

  После этого нам надо получить символический хендл, мы должны 
  получить информацию

  BYTE InfoBuffer[1024];
  DWORD dwInfoBufferSize;

  GetTokenInformation( hAccessToken,
  TokenGroups,
  InfoBuffer,
  1024,
  &dwInfoBufferSize);  

  теперь нам надо получить идентификатор безопасности (SiD) для 
  Local Admin, который мы будем искать через 
  группы всех символов (не забудте вызывать функцию FreeSid, 
  чтобы освободить память):

  PSID psidAdministrators;
  SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;

  AllocateAndInitializeSid( &siaNtAuthority,
				2,
				SECURITY_BUILTIN_DOMAIN_RID,
				DOMAIN_ALIAS_RID_ADMINS,
				0,0,0,0,0,0,
				&psidAdministrators)

  И заключительный шаг - поиск LOCAL Admin (SiD) в группах всех 
  символов:

  PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer;

   for(UINT i = 0; i < ptgGroups->GroupCount; i ++)
   {
     if( EqualSid(psidAdministrators,ptgGroups->Groups[i].Sid) )
     {
        // Этот процесс имеет admin привилегии!
        break;
    }
   }
        
 
   ULTRAS[MATRiX]
 What`s my age again

  [email protected] 
 www.coderz.net/ultras 
 www.coderz.net/matrix

 Статья для журнала Top Device