⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 processinfo.cpp

📁 Windows via C++ Code (December 1, 2007),关于如何在window下学习C++编程的代码资源
💻 CPP
📖 第 1 页 / 共 3 页
字号:

///////////////////////////////////////////////////////////////////////////////


PVOID GetModulePreferredBaseAddr(DWORD dwProcessId, PVOID pvModuleRemote) {

   PVOID pvModulePreferredBaseAddr = NULL;
   IMAGE_DOS_HEADER idh;
   IMAGE_NT_HEADERS inth;

   // Read the remote module's DOS header
   Toolhelp32ReadProcessMemory(dwProcessId, 
      pvModuleRemote, &idh, sizeof(idh), NULL);

   // Verify the DOS image header
   if (idh.e_magic == IMAGE_DOS_SIGNATURE) {
      // Read the remote module's NT header
      Toolhelp32ReadProcessMemory(dwProcessId, 
         (PBYTE) pvModuleRemote + idh.e_lfanew, &inth, sizeof(inth), NULL);

      // Verify the NT image header
      if (inth.Signature == IMAGE_NT_SIGNATURE) {
         // This is valid NT header, get the image's preferred base address
         pvModulePreferredBaseAddr = (PVOID) inth.OptionalHeader.ImageBase;
      }
   }
   return(pvModulePreferredBaseAddr);
}


///////////////////////////////////////////////////////////////////////////////



/* 
   from  http://msdn.microsoft.com/msdnmag/issues/02/06/debug/
         Escape from DLL Hell with Custom Debugging and 
         Instrumentation Tools and Utilities

   The PEB (Process Environment Block) is an undocumented structure 
   which varies from version to version of Windows.
   However, WinDbg 
   (from http://www.microsoft.com/whdc/devtools/debugging/default.mspx) 
   provides a command that list the "documented" fields of a structure. 
      dt nt!_PEB 
      dt nt!_RTL_USER_PROCESS_PARAMETERS
*/

typedef struct
{
   DWORD Filler[4];
   DWORD InfoBlockAddress;
} __PEB;

typedef struct
{
   DWORD Filler[17];
   DWORD wszCmdLineAddress;
} __INFOBLOCK;



// NtQueryInformationProcess is declared in winternl.h
typedef NTSTATUS (CALLBACK *PFN_NTQUERYINFORMATIONPROCESS)(
   HANDLE ProcessHandle, 
   PROCESSINFOCLASS ProcessInformationClass,
   PVOID ProcessInformation,
   ULONG ProcessInformationLength,
   PULONG ReturnLength OPTIONAL
   );


NTSTATUS _NtQueryInformationProcess(
    HANDLE hProcess,
    PROCESSINFOCLASS pic,
    PVOID pPI,
    ULONG cbSize,
    PULONG pLength
    ) {
    
   HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll"));
   if (hNtDll == NULL) {
      return(-1);
   }

   NTSTATUS lStatus = -1;  // error by default.

   // Note that function name is not UNICODE
   PFN_NTQUERYINFORMATIONPROCESS pfnNtQIP = 
      (PFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(
         hNtDll, "NtQueryInformationProcess");
   if (pfnNtQIP != NULL) {
      lStatus = pfnNtQIP(hProcess, pic, pPI, cbSize, pLength);
   }   
   
   FreeLibrary(hNtDll);
   return(lStatus);
}


BOOL GetProcessCmdLine(HANDLE hProcess, LPTSTR szCmdLine, DWORD Size) {

   // Sanity checks
   if ((hProcess == NULL) || (szCmdLine == NULL) || (Size == 0))
      return(FALSE);

   // 0. Get the Process Environment Block address
   int   iReturn = 1;
   DWORD dwSize;
   SIZE_T size;

   PROCESS_BASIC_INFORMATION  pbi;
   // The PEB was supposed to always be at address 0x7ffdf000 in XP...
   // ... but, here is the "right" way to get it now in Vista.
   iReturn =
      _NtQueryInformationProcess(
         hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &dwSize);

   // NtQueryInformationProcess returns a negative value if it fails
   if (iReturn >= 0) {
      // 1. Find the Process Environment Block
      __PEB PEB;
	  size = dwSize;
      if (!ReadProcessMemory(hProcess, pbi.PebBaseAddress, &PEB, 
         sizeof(PEB), &size)) {
         // Call GetLastError() if you need to know why
         return(FALSE);
      }

      // 2. From this PEB, get the address of the block containing 
      // a pointer to the CmdLine
      __INFOBLOCK Block;
      if (!ReadProcessMemory(hProcess, (LPVOID)PEB.InfoBlockAddress, 
         &Block, sizeof(Block), &size)) {
         // Call GetLastError() if you need to know why
         return(FALSE);
      }

      // 3. Get the CmdLine
      wchar_t wszCmdLine[MAX_PATH+1];
      if (!ReadProcessMemory(hProcess, (LPVOID)Block.wszCmdLineAddress, 
         wszCmdLine, MAX_PATH*sizeof(wchar_t), &size)) {
         // Call GetLastError() if you need to know why
         return(FALSE);
      }

      // 4. Skip the application pathname
      //    it can be empty, "c:\...\app.exe" or c:\...\app.exe
      wchar_t* pPos = wszCmdLine;
      if (*pPos != L'\0') {
         if (*pPos == L'"') {
         // Find the next " character
            pPos = wcschr(&pPos[1], L'"');
         } else {
         // Find the next SPACE character
            pPos = wcschr(&pPos[1], L' ');
         }

         // Skip it
         if (pPos != NULL)
            pPos++;
      }

      // Copy it back
      if (pPos != NULL) {
         if (*pPos != L'\0') {
#ifdef UNICODE
            // Both strings are in UNICODE.
            _tcscpy_s(szCmdLine, Size, pPos);   
#else
            // from UNICODE to ANSI
            MultiByteToWideChar(CP_ACP, 0, szCmdLine, Size, 
               pPos, wcslen(pPos)); 
#endif
         }
         else
            szCmdLine[0] = TEXT('\0');
      }
      else
         szCmdLine[0] = TEXT('\0');
   }
   else {
      return(FALSE);
   }

   return(TRUE);
}


BOOL GetProcessCmdLine(DWORD PID, LPTSTR szCmdLine, DWORD Size) {

   // Sanity checks
   if ((PID <= 0) || (szCmdLine == NULL))
      return(FALSE);

   // Check if we can get information for this process
   HANDLE hProcess = 
      OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
   if (hProcess == NULL)
      return(FALSE);

   BOOL bReturn = GetProcessCmdLine(hProcess, szCmdLine, Size);

   // Don't forget to release the process handle
   CloseHandle(hProcess);

   return(bReturn);
}


BOOL GetProcessOwner(HANDLE hProcess, LPTSTR szOwner, size_t cchSize) {

   // Sanity checks
   if ((szOwner == NULL) || (cchSize == 0))
      return(FALSE);

   // Default value
   szOwner[0] = TEXT('\0');

   // Gget process token
   HANDLE hToken = NULL;
   CToolhelp::EnablePrivilege(SE_TCB_NAME, TRUE);
   if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
      CToolhelp::EnablePrivilege(SE_TCB_NAME, FALSE);
      return(FALSE);
   }

   // Obtain the size of the user information in the token.
   DWORD cbti = 0;
   GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti);

   // Call should have failed due to zero-length buffer.
   if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
      // Allocate buffer for user information in the token.
      PTOKEN_USER ptiUser = 
         (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, cbti);
      if (ptiUser != NULL) {
         // Retrieve the user information from the token.
         if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti)) {
            SID_NAME_USE   snu;
            TCHAR          szUser[MAX_PATH];
            DWORD          chUser = MAX_PATH;
            PDWORD         pcchUser = &chUser;
            TCHAR          szDomain[MAX_PATH];
            DWORD          chDomain = MAX_PATH;
            PDWORD         pcchDomain = &chDomain;

            // Retrieve user name and domain name based on user's SID.
            if (
                  LookupAccountSid(
                     NULL,
                     ptiUser->User.Sid,
                     szUser,
                     pcchUser,
                     szDomain,
                     pcchDomain,
                     &snu
                     )
               ) {
               // build the owner string as \\DomainName\UserName
               _tcscpy_s(szOwner, cchSize, TEXT("\\\\"));
               _tcscat_s(szOwner, cchSize, szDomain);
               _tcscat_s(szOwner, cchSize, TEXT("\\"));
               _tcscat_s(szOwner, cchSize, szUser);
            }
         }

         // Don't forget to free memory buffer
         HeapFree(GetProcessHeap(), 0, ptiUser);
      }
   }

   // Don't forget to free process token
   CloseHandle(hToken);

   // Restore privileges
   CToolhelp::EnablePrivilege(SE_TCB_NAME, TRUE);

   return(TRUE);
}


BOOL GetProcessOwner(DWORD PID, LPTSTR szOwner, DWORD cchSize) {

   // Sanity checks
   if ((PID <= 0) || (szOwner == NULL))
      return(FALSE);

   // Check if we can get information for this process
   HANDLE hProcess = 
      OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, PID);
   if (hProcess == NULL)
      return(FALSE);

   BOOL bReturn = GetProcessOwner(hProcess, szOwner, cchSize);

   // Don't forget to release the process handle
   CloseHandle(hProcess);

   return(bReturn);
}


VOID FormatSizeInKB(DWORD dwSize, DWORD nCharacters, 
   LPTSTR szSize, size_t cchSize) {
   
   TCHAR szFormattedSize[64];
   if (StrFormatKBSize(dwSize, szFormattedSize, 
      _countof(szFormattedSize)) == NULL) {
      StringCchPrintf(szFormattedSize, _countof(szFormattedSize), TEXT("%8u"), dwSize); 
   }

   // Format to the right nCharacter width if needed.
   if (_tcslen(szFormattedSize) < nCharacters) {
      DWORD current = 0;
      for(current = 0; 
         current < (nCharacters - _tcslen(szFormattedSize)); 
         current++) {
         szSize[current] = TEXT(' ');
      }
      szSize[current] = TEXT('\0');      

      _tcscat_s(szSize, cchSize - current, szFormattedSize);
   }
}

VOID ShowProcessInfo(HWND hwnd, DWORD dwProcessID) {

   SetWindowText(hwnd, TEXT(""));   // Clear the output box

   CToolhelp th(TH32CS_SNAPALL, dwProcessID);

   // Show Process details
   PROCESSENTRY32 pe = { sizeof(pe) };
   BOOL fOk = th.ProcessFirst(&pe);
   for (; fOk; fOk = th.ProcessNext(&pe)) {
      if (pe.th32ProcessID == dwProcessID) {
         TCHAR szCmdLine[1024];
         if (GetProcessCmdLine(dwProcessID, szCmdLine, _countof(szCmdLine))) {
            AddText(hwnd, 
               TEXT("Command line: %s %s\r\n"), pe.szExeFile, szCmdLine);
         } else {
            AddText(hwnd, TEXT("Filename: %s\r\n"), pe.szExeFile);
         }
         AddText(hwnd, TEXT("   PID=%08X, ParentPID=%08X, ")
            TEXT("PriorityClass=%d, Threads=%d, Heaps=%d\r\n"),
            pe.th32ProcessID, pe.th32ParentProcessID, 
            pe.pcPriClassBase, pe.cntThreads,
            th.HowManyHeaps());
         TCHAR szOwner[MAX_PATH+1];
         if (GetProcessOwner(dwProcessID, szOwner, MAX_PATH)) {
            AddText(hwnd, TEXT("Owner: %s\r\n"), szOwner);
         }

         break;   // No need to continue looping
      }
   }


   // Show Modules in the Process
   // Number of characters to display an address
   AddText(hwnd, TEXT("\r\nModules Information:\r\n")
      TEXT("  Usage  %-*s(%-*s)  %10s  Module\r\n"),
      s_cchAddress, TEXT("BaseAddr"),
      s_cchAddress, TEXT("ImagAddr"), TEXT("Size"));

   MODULEENTRY32 me = { sizeof(me) };
   fOk = th.ModuleFirst(&me);
   for (; fOk; fOk = th.ModuleNext(&me)) {
      if (me.ProccntUsage == 65535) {
         // Module was implicitly loaded and cannot be unloaded
         AddText(hwnd, TEXT("  Fixed"));
      } else {
         AddText(hwnd, TEXT("  %5d"), me.ProccntUsage);
      }

      // Try to format the size in kb.
      TCHAR szFormattedSize[64];
      if (StrFormatKBSize(me.modBaseSize, szFormattedSize, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -