在整理代码,遍历进程时,当然有些进程会枚举不到信息.
但是没有枚举到的进程太多了. 这一般都是访问权限低造成的.
尝试用AdjustTokenPrivileges调整访问权限,但是失败了.
BOOL addDebugToken(HANDLE TokenHandle, LPCSTR lpName, BOOL bAdd){ BOOL bRc = FALSE; DWORD ReturnLength = 0; struct _LUID Luid; struct _TOKEN_PRIVILEGES PreviousState; struct _TOKEN_PRIVILEGES NewState; ReturnLength = sizeof(PreviousState); bRc = LookupPrivilegeValueA(0, lpName, &Luid); if (bRc) { NewState.Privileges[0].Luid = Luid; NewState.PrivilegeCount = 1; NewState.Privileges[0].Attributes = 0; AdjustTokenPrivileges(TokenHandle, 0, &NewState, sizeof(NewState), &PreviousState, &ReturnLength); if (GetLastError()) { bRc = FALSE; // 这就错了, @err,hr看提示信息是没有取到全部信息之类的报错 } else { PreviousState.Privileges[0].Luid = Luid; PreviousState.PrivilegeCount = 1; PreviousState.Privileges[0].Attributes = (bAdd ? SE_PRIVILEGE_ENABLED/*2*/ : 0); AdjustTokenPrivileges(TokenHandle, 0, &PreviousState, ReturnLength, 0, 0); bRc = (GetLastError() == 0); } } return bRc;}
我当前是用管理员身份登录,这也不能提高访问权限。
那剩下的可能性就是程序要以管理员身份运行才行。
程序编译时,可以指定运行时请求管理员权限。
在MSDN上找了一段代码,可以将指定程序(包括自己)以管理员身份运行。
当以管理员身份登录&&程序是以管理员身份运行后,AdjustTokenPrivileges就成功了。
当使用快照取进程信息时,取不到的就剩下系统程序了.
我是在win10x64下用vs2015将测试工程编译成x64版本测试的,好使.
虽然系统程序取不到程序信息,也看一下,到底是哪些系统程序和他们之间的启动关系.
// 以管理员身份运行后,可以得到大部分进程信息,得不到的只有7,8个系统进程// 进程名称(进程ID) => 父进程名称(父进程ID)// System(4) => (0)// (488) 该进程win10x64自带的任务管理器,procexp64,PCHunter_free都没有列出来...// (2056) 该进程win10x64自带的任务管理器,procexp64,PCHunter_free都没有列出来...// smss.exe(388) => System(4)// csrss.exe(524) => (488)// wininit.exe(624) => (488)// services.exe(852) => wininit.exe(624)// SecurityHealthService.exe(4052) => services.exe(852)// Memory Compression(4284) => System(4)// csrss.exe(7424) => (2056)
PCHunter_free在我的win10x64上显示加载驱动失败,不知道是啥问题,报给作者了.
Win10发布版本1703Win10内部版本10.0.15063.413
// @fn RunAsAdmin// @brief 以管理员身份运行一个程序, 也许有提示.(在管理员登录后,是没有提示的)BOOL RunAsAdmin(/*IN*/ HWND hWnd, /*IN*/ LPTSTR lpFile, /*IN*/ LPTSTR lpParameters, /*OUT*/ DWORD& dwErrSn);// @fn TryToRunAsAdmin// @brief 如果不是runasAdmin,就尝试runasAdmin,启动新进程, 返回TRUE;// 如果程序已经是runasAdmin, 返回FALSE;BOOL TryToRunAsAdmin(int argc, char* argv[]);
#define RUN_AS_ADMIN "run_as_admin"
BOOL RunAsAdmin(/*IN*/ HWND hWnd, /*IN*/ LPTSTR lpFile, /*IN*/ LPTSTR lpParameters, /*OUT*/ DWORD& dwErrSn){ SHELLEXECUTEINFO sei; ZeroMemory(&sei, sizeof(sei)); sei.cbSize = sizeof(SHELLEXECUTEINFOW); sei.hwnd = hWnd; sei.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI; sei.lpVerb = TEXT("runas"); sei.lpFile = lpFile; sei.lpParameters = lpParameters; sei.nShow = SW_SHOWNORMAL; if (!ShellExecuteEx(&sei)) { printf("Error: ShellExecuteEx failed 0x%x\n", GetLastError()); return FALSE; } return TRUE;}BOOL TryToRunAsAdmin(int argc, char* argv[]){ USES_CONVERSION; DWORD dwErrSn = 0; std::wstring strCmdLine = A2W(GetCmdlineParam(argc, argv).c_str()); if ((argc <= 1) || (0 != strcmp(argv[argc - 1], RUN_AS_ADMIN))) { strCmdLine += L" "; strCmdLine += A2W(RUN_AS_ADMIN); RunAsAdmin(NULL, A2W(argv[0]), (WCHAR*)strCmdLine.c_str(), dwErrSn); return TRUE; } return FALSE;}
如果程序没有以runasAdmin运行,就尝试TryToRunAsAdmin.
如果程序已经以runasAdmin运行, 这时访问权限是足够的,走正常流程.
#include "stdafx.h"#include "helper\process\helper_process.h"int main(int argc, char* argv[]){ int iProcessCnt = 0; std::vector<TAG_PROCESS_INFO> vec; show_parameter(argc, argv); if (TryToRunAsAdmin(argc, argv)) { return 0; } // 当前用户是以Administrator用户登录 && 程序是以runasAdmin运行 // 执行addDebugToken()才会成功 if (isAdministrator()) { printf("current user is Administrator\n"); if (!addDebugToken()) { printf("FALSE = addDebugToken()\n"); } else { printf("ok : addDebugToken()\n"); } } else { printf("cur user isn't administrator\n"); return 0; } printf("if need continue, press any key; else close it\n"); getchar(); iProcessCnt = GetProcessList(vec); if (iProcessCnt > 0) { ShowConsoleInfo_ProcessList(vec); } printf("END\n"); getchar(); return 0;}
argv[0] = D:\mydir\helper\testcase\x64\Debug\testcase.exeargv[1] = run_as_admincurrent user is Administratorok : addDebugToken()if need continue, press any key; else close it...>>====================================================================szExeFile = Systemth32ParentProcessID = 0!th32ProcessID = 4cntThreads = 179pcPriClassBase = 8----------------------------------------------------------------------<<====================================================================...>>====================================================================szExeFile = TeamViewer_Service.exeth32ParentProcessID = 852th32ProcessID = 15720cntThreads = 20pcPriClassBase = 8---------------------------------------------------------------------- szModule = TeamViewer_Service.exe szExePath = C:\Program Files (x86)\TeamViewer\TeamViewer_Service.exe th32ProcessID = 15720 th32ModuleID = 1 hModule = 0xAA0000 modBaseAddr = 0xAA0000 modBaseSize = 0xA98000 GlblcntUsage = 65535 ProccntUsage = 65535 szModule = ntdll.dll szExePath = C:\Windows\SYSTEM32\ntdll.dll th32ProcessID = 15720 th32ModuleID = 1 hModule = 0x7FFD99290000 modBaseAddr = 0x7FFD99290000 modBaseSize = 0x1DB000 GlblcntUsage = 65535 ProccntUsage = 65535 szModule = wow64.dll szExePath = C:\Windows\System32\wow64.dll th32ProcessID = 15720 th32ModuleID = 1 hModule = 0x6A230000 modBaseAddr = 0x6A230000 modBaseSize = 0x51000 GlblcntUsage = 65535 ProccntUsage = 65535 szModule = wow64win.dll szExePath = C:\Windows\System32\wow64win.dll th32ProcessID = 15720 th32ModuleID = 1 hModule = 0x6A2A0000 modBaseAddr = 0x6A2A0000 modBaseSize = 0x73000 GlblcntUsage = 65535 ProccntUsage = 65535 szModule = wow64cpu.dll szExePath = C:\Windows\System32\wow64cpu.dll th32ProcessID = 15720 th32ModuleID = 1 hModule = 0x6A290000 modBaseAddr = 0x6A290000 modBaseSize = 0xA000 GlblcntUsage = 1 ProccntUsage = 1<<====================================================================...>>====================================================================process count = 1618 process 's module list is empty : th32ProcessID = 4 th32ProcessID = 388 th32ProcessID = 524 th32ProcessID = 624 th32ProcessID = 852 th32ProcessID = 4052 th32ProcessID = 4284 th32ProcessID = 23608<<====================================================================END
编译环境:vs2015update3 + win10x64
src_fix_AdjustTokenPrivileges_failed.zip
联系客服