Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > NtQuerySystemInformation()


Автор: Royan 14.5.2004, 22:27
Кто - нибудь пользовался этой функцией? Я было нашел на форуме сообщение от Шедона, с примером но он не работает, самое печальное, что там даже параметры структуры SYSTEM_PROCESS_INFORMATION не совпадают с теми, что задокументированы в msdn'е, то бишь
Код
typedef struct _SYSTEM_PROCESS_INFORMATION {
   ULONG NextEntryOffset;
   BYTE Reserved1[52];
   PVOID Reserved2[3];
   HANDLE UniqueProcessId;
   PVOID Reserved3;
   ULONG HandleCount;
   BYTE Reserved4[4];
   PVOID Reserved5[11];
   SIZE_T PeakPagefileUsage;
   SIZE_T PrivatePageCount;
   LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION;

Что означают Reserved1...6 я не понимаю

На самом деле мне всего лишь нужно перечислить все текущие процессы (найти их уникальные ID, и получить название самих процессов)

Вот мой код:
Код
typedef NTSYSAPI (NTAPI *pfnNtQuerySystemInformation)(
 SYSTEM_INFORMATION_CLASS SystemInformationClass,
 PVOID SystemInformation,
 ULONG SystemInformationLength,
 PULONG ReturnLength
 );


 pfnNtQuerySystemInformation NTProcAdd;

 hMod = LoadLibrary("ntdll.dll");


 if (hMod != NULL){
   //Здесь NTProcAdd определенно получает какой-то адрес
   NTProcAdd = (pfnNtQuerySystemInformation) GetProcAddress(hMod, "NtQuerySystemInformation");
 }

 SYSTEM_PROCESS_INFORMATION struct_sysProcInfo;
 ULONG SystemInformationLength = 1048576;//Один Мб
 ULONG ReturnLength;

 ULONG status = ((pfnNtQuerySystemInformation)(PROC) NTProcAdd)
   (SystemProcessInformation,
   &struct_sysProcInfo,
   SystemInformationLength,
   &ReturnLength);//По какой-то причине в ReturnLength валится совершенно неподдъемное число

Автор: shedon 14.5.2004, 22:51
что именно у тебя не работает ?

Автор: Royan 14.5.2004, 23:05
Несмотря на то что найден обходной путь, я приведу его в самом низу, все-таки надо разобряться с чем тут проблема...
У меня в коде с NtQuerySystemInformation() неправильно проходит инициализация struct_sysProcInfo после вызоваNtQuerySystemInformation() , а именно


- struct_sysProcInfo {...} _SYSTEM_PROCESS_INFORMATION
NextEntryOffset 3435973836 unsigned long
+ Reserved1 0x0012dfd4 "ММ...ММ" unsigned char [52]
+ Reserved2 0x0012e008 void * [3]
UniqueProcessId 0xcccccccc void *
Reserved3 0xcccccccc void *
HandleCount 3435973836 unsigned long
+ Reserved4 0x0012e020 "ММММ...МММ" unsigned char [4]
+ Reserved5 0x0012e024 void * [11]
PeakPagefileUsage 3435973836 unsigned long
PrivatePageCount 3435973836 unsigned long
+ Reserved6 0x0012e058 {-3689348814741910324} _LARGE_INTEGER [6]

Подозрительные значения сразу же видны

вот цикл перебора процессов, который я использую:
Цитата
DWORD dwProcessId = GetCurrentProcessId();
 
if(SystemProcessInformation == 5){

   
if(SystemInformationLength > 20000){
      pSysProcInfo = (SYSTEM_PROCESS_INFORMATION*)&struct_sysProcInfo;
     
while(1){
       
// если идентификатор процесса равен идентификатору нашего процесса
       
if(pSysProcInfo->UniqueProcessId == (HANDLE)dwProcessId){
         
if(pSysProcInfo->NextEntryOffset == 0){
            pSysProcInfoLast->NextEntryOffset = 0;
          }
else{
            pSysProcInfoLast->NextEntryOffset += pSysProcInfo->NextEntryOffset;
          }
        }
       
if(pSysProcInfo->NextEntryOffset == 0)
         
break;
        pSysProcInfoLast = pSysProcInfo;
        // это последняя строка которая выполняется после нее новая итерация и из нее  все вылетает в космос
        pSysProcInfo = (SYSTEM_PROCESS_INFORMATION *)((PCHAR)pSysProcInfo + pSysProcInfo->NextEntryOffset);
      }
    }
  }

и он валиться на втором же шаге

А вот работающий код перечисляющий процессы:
Цитата
  HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  PROCESSENTRY32* processInfo=
new PROCESSENTRY32;
  processInfo->dwSize=
sizeof(PROCESSENTRY32);
 
int index=0;
 
while(Process32Next(hSnapShot,processInfo)!=FALSE)
  {
    std::cout<<std::endl<<"***********************************************";   
    std::cout<<std::endl<<"\t\t\t"<<++index;
    std::cout<<std::endl<<"***********************************************";   
    std::cout<<std::endl<<"Parent Process ID: "<<processInfo->th32ParentProcessID;
    std::cout<<std::endl<<"Process ID: "<<processInfo->th32ProcessID;
    std::cout<<std::endl<<"Name: "<<processInfo->szExeFile;
    std::cout<<std::endl<<"Current Threads: "<<processInfo->cntThreads;
    std::cout<<std::endl<<"Current Usage: "<<processInfo->cntUsage;
    std::cout<<std::endl<<"Flags: "<<processInfo->dwFlags;
    std::cout<<std::endl<<"Size: "<<processInfo->dwSize;
    std::cout<<std::endl<<"Primary Class Base: "<<processInfo->pcPriClassBase;
    std::cout<<std::endl<<"Default Heap ID: "<<processInfo->th32DefaultHeapID;
    std::cout<<std::endl<<"Module ID: "<<processInfo->th32ModuleID;
  }
  CloseHandle(hSnapShot);
  std::cout<<std::endl;
  std::cout<<std::endl<<"***********************************************";
  std::cout<<std::endl<<std::endl;

Автор: shedon 15.5.2004, 13:17
Всё работает...
Цитата
вот цикл перебора процессов, который я использую:
Цитата
DWORD dwProcessId = GetCurrentProcessId();
  if(SystemProcessInformation == 5){

    if(SystemInformationLength > 20000){
      pSysProcInfo = (SYSTEM_PROCESS_INFORMATION*)&struct_sysProcInfo;
      while(1){
        // если идентификатор процесса равен идентификатору нашего процесса
        if(pSysProcInfo->UniqueProcessId == (HANDLE)dwProcessId){
          if(pSysProcInfo->NextEntryOffset == 0){
            pSysProcInfoLast->NextEntryOffset = 0;
          }else{
            pSysProcInfoLast->NextEntryOffset += pSysProcInfo->NextEntryOffset;
          }
        }
        if(pSysProcInfo->NextEntryOffset == 0)
          break;
        pSysProcInfoLast = pSysProcInfo;
        // это последняя строка которая выполняется после нее новая итерация и из нее  все вылетает в космос
        pSysProcInfo = (SYSTEM_PROCESS_INFORMATION *)((PCHAR)pSysProcInfo + pSysProcInfo->NextEntryOffset);
      }
    }
  }

Я не давал такого кода, если собрать всё, что ядовал, то всё рабортает....

Автор: Royan 15.5.2004, 22:32
Вот этот код я откопал (без моих изменений), и проблема здесь в том, что например поля "NextOffest" структура SYSTEM_PROCESS_INFORMATION не содержит.
Цитата

NTAPI Hook_NtQuerySystemInformation(
                                    LONG type,                   
// тип информации
                                   
PVOID SystemInformation,      // указатель на буфер
                                   
LONG SystemInformationLength, // размер буфера в байтах
                                   
PLONG ReturnLength            // указатель на 32-битное число
                                   
)
{
  SYSTEM_PROCESS_INFORMATION *pinfo, *pinfo_last;

 
// вызываем оригинальную функцию
 
((PFNNtQuerySystemInformation)(PROC) g_NtQuerySystemInformation)
    (type, SystemInformation, SystemInformationLength, ReturnLength);

 
// если получается информация о процессах
 
if(type == 5)
  {
   
if(SystemInformationLength > 20000)
    {
      pinfo = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
     
for(;;)
      {
       
// если идентификатор процесса равен идентификатору нашего процесса
       
if(pinfo->ProcessID == progProcessId)
        {
         
if(pinfo->NextOffest == 0)
          {
            pinfo_last->NextOffest = 0;
          }
         
else
         
{
            pinfo_last->NextOffest += pinfo->NextOffest;
          }
        }
       
if(pinfo->NextOffest == 0) break;
        pinfo_last = pinfo;
        pinfo = (SYSTEM_PROCESS_INFORMATION*)((
char *)pinfo + pinfo->NextOffest);
      }
    }
  }
}


И также непонятно, что у содержится в заголовке "..\CmnHdr.h" Вот ссылка на топик, в котором ты отправил этот код: http://forum.vingrad.ru/index.php?showtopic=21557

Автор: shedon 15.5.2004, 22:46
Извиняюсь, вот добавил хедер.
http://forum.vingrad.ru/index.php?act=ST&f=1&t=21557&st=0#entry146225

Автор: shedon 17.5.2004, 20:51
Royan, ну как заработоло ?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)