打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
AdjustTokenPrivileges失败的解决方法

在整理代码,遍历进程时,当然有些进程会枚举不到信息.
但是没有枚举到的进程太多了. 这一般都是访问权限低造成的.
尝试用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
  • 1

以管理员身份运行程序的MS例程

// @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[]);
  • 1

#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
  • 1

实验工程下载点

编译环境:vs2015update3 + win10x64
src_fix_AdjustTokenPrivileges_failed.zip

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
三个给进程提权的方法 (c/cpp)
关机有关的函数
主函数参数argc和argv测试
Cocoa入门-使用Objective-C
iOS开发UI篇
利用C++编写Windows服务程序的一般框架
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服