Windows Vista/Windows 7权限:SeDebugPrivilege和OpenProcess

Kev*_*enK 25 c++ windows privileges uac openprocess

我能够找到的有关升级到我需要的适当权限的所有内容都与我当前的方法一致,但问题依然存在.我希望也许某人有一些Windows Vista/Windows 7内部体验可能会在只有黑暗的地方发光.我相信这会很长,但请耐心等待.

上下文

我正在开发一个需要访问当前机器上其他进程内存的应用程序.显然,这需要管理员权限.它还要求SeDebugPrivilege(不,它不是拼写错误SetDebugPrivilege),我相信自己要正确获取,尽管我怀疑是否有更多的特权是不必要的,因此我的问题的原因.到目前为止,Code已成功应用于所有版本的Windows XP,以及我的测试Vista 32位和Windows 7 64位环境.

处理

  • 程序将始终以管理员权限运行.在这篇文章中可以假设这一点.
  • 升级当前流程Access Token以包含SeDebugPrivilege权限.
  • 使用EnumProcesses该系统上创建当前PID列表
  • 使用OpenProcess具有PROCESS_ALL_ACCESS访问权限的句柄打开
  • 使用ReadProcessMemory读取其他进程的内存.

问题:

在开发和个人测试期间,一切都运行良好(包括Windows XP 32和64,Windows Vista 32和Windows 7 x64).但是,在同事的Windows Vista(32位)和Windows 7(64位)计算机上进行测试部署期间,似乎存在权限/权限问题,导致OpenProcess一般Access Denied错误失败.当以受限用户身份运行时(如预期的那样)以及以管理员身份明确运行(右键单击?以管理员身份运行以及从管理员级别命令提示符运行时)都会发生这种情况.

但是,在我的测试环境中,这个问题对我自己来说是不可再现的.我亲眼目睹了这个问题,所以我相信这个问题存在.我能够在实际环境和我的测试环境之间辨别的唯一区别是,在UAC提示符下使用域管理员帐户时发生了实际错误,而我的测试(无错误地工作)使用了本地管理员帐户. UAC提示.

看来虽然使用的凭据允许UAC"以管理员身份运行",但该流程仍未获得能够OpenProcess在另一个进程上运行的正确权限.我对Vista/Windows 7的内部结构不太熟悉,知道这可能是什么,我希望有人知道可能是什么原因.

踢球者

报告此错误的人,以及谁的环境可以定期重现此错误,有一个小应用程序,RunWithDebugEnabled其名称是一个小的引导程序,似乎升级其自己的权限,然后启动传递给它的可执行文件(从而继承升级的特权).使用此程序运行时,在UAC提示符下使用相同的域管理员凭据,程序可以正常工作,并且能够成功调用OpenProcess并按预期运行.

因此,这肯定是获取正确权限的问题,并且已知域管理员帐户应该能够访问正确权限的管理员帐户.(显然获得这个源代码会很棒,但如果可能的话,我不会在这里).

笔记

如上所述,失败OpenProcess尝试报告的错误是Access Denied.根据MSDN文档OpenProcess:

如果调用者启用了SeDebugPrivilege特权,则无论安全描述符的内容如何,​​都会授予所请求的访问权限.

这让我相信在这些条件下可能存在以下问题:(1)获取SeDebugPrivileges或(2)要求在任何MSDN文档中未提及的其他权限,以及域管理员帐户和本地管理员之间可能不同的权限帐户

示例代码:

void sample()
{
   /////////////////////////////////////////////////////////
   //   Note: Enabling SeDebugPrivilege adapted from sample
   //     MSDN @ http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx
   // Enable SeDebugPrivilege
   HANDLE hToken = NULL;
   TOKEN_PRIVILEGES tokenPriv;
   LUID luidDebug;
   if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE)
   {
      if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
      {
         tokenPriv.PrivilegeCount           = 1;
         tokenPriv.Privileges[0].Luid       = luidDebug;
         tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
         if(AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, 0, NULL, NULL) != FALSE)
         {
            // Always successful, even in the cases which lead to OpenProcess failure
            cout << "SUCCESSFULLY CHANGED TOKEN PRIVILEGES" << endl;
         }
         else
         {
            cout << "FAILED TO CHANGE TOKEN PRIVILEGES, CODE: " << GetLastError() << endl;
         }
      }
   }
   CloseHandle(hToken);
   // Enable SeDebugPrivilege
   /////////////////////////////////////////////////////////

   vector<DWORD> pidList = getPIDs();  // Method that simply enumerates all current process IDs

   /////////////////////////////////////////////////////////
   // Attempt to open processes
   for(int i = 0; i < pidList.size(); ++i)
   {
      HANDLE hProcess = NULL;
      hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pidList[i]);
      if(hProcess == NULL)
      {
         // Error is occurring here under the given conditions
         cout << "Error opening process PID(" << pidList[i] << "): " << GetLastError() << endl;
      }
      CloseHandle(hProcess);
   }
   // Attempt to open processes
   /////////////////////////////////////////////////////////
}
Run Code Online (Sandbox Code Playgroud)




谢谢!

如果有人在上述条件下对Windows Vista和Windows 7上正确打开另一个进程(假设可执行文件已正确"以管理员身份运行")可能缺少的可能权限,权限,权限等有所了解,非常感谢.

如果我不是绝对难过,我就不会在这里,但我希望这个团队的经验和知识能够再次闪耀.我感谢你花时间阅读这一面墙.感谢作为使Stack Overflow对所有人都如此有用的人的类型!

Kev*_*enK 13

因此经过大量的调试和困扰很多人获取信息之后,我终于能够找到编写RunWithDebugEnabled应用程序的人,并了解它的运作方式.

在这种情况下,问题是Debug programs域管理员的本地策略中的权限已被删除,因此SeDebugPrivilege令牌不存在于进程的访问令牌中.如果它根本不存在则无法启用,我仍然知道无法将权限添加到现有访问令牌.


当前的魔法如何工作:
因此,RunWithDebugEnabled魔术应用程序将使用其管理员权限将自身安装为服务并自行启动,从而在SYSTEM用户帐户而不是域管理员下运行.使用SYSTEM权限,应用程序然后创建一个与管理员令牌相同的新访问令牌,仅SeDebugPrivilege存在令牌.这个新令牌用于CreateProcessAsUser()并运行SeDebugPrivilege以前缺少的新启用的程序.

我实际上并不喜欢这个"解决方案",并一直在寻找一种"更清洁"的方式来获得这种特权.我将在此处发布此问题作为另一个问题,我将尽力记住链接在这里,以帮助其他人跟进并供将来参考.

编辑: 从管理员帐户模拟SYSTEM(或等效)



我感谢你们花时间和精力帮助调试和解决这个问题.真的非常感谢!