【问题标题】:SeDebugPrivilege and OpenProcess on another account另一个帐户上的 SeDebugPrivilege 和 OpenProcess
【发布时间】:2015-12-29 13:03:03
【问题描述】:

我正在尝试打开在另一个用户帐户上运行的进程,当我以管理员身份运行我的应用程序时(右键单击 > 以管理员身份运行),我成功获得它,但我需要应用程序自行提升权限,这是我目前所拥有的:

procedure ChangePrivilege;
var
  NewState: TTokenPrivileges;
  luid: TLargeInteger;
  hToken: THandle;
  ReturnLength: DWord;
begin
  if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken) then
  begin
   if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'), luid) then
   begin
    NewState.PrivilegeCount:= 1;
    NewState.Privileges[0].Luid := luid;
    NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    if AdjustTokenPrivileges(hToken, False, NewState, 0, nil, ReturnLength) then
      WriteLn('Privileged');
   end;
    CloseHandle(hToken);
  end;
end;

这个函数执行得很好,我得到了“Privileged”输出,但是在我的 OpenProcess 上,我没有看到另一个帐户上运行的进程名称:

procedure ProcEnum;
var
  Snapshot, ProcessPID: THandle;
  pe: TProcessEntry32;
begin
  Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
  try
    pe.dwSize := SizeOf(pe);
    if Process32First(Snapshot, pe) then
      while Process32Next(Snapshot, pe) do
      begin
        try
          ProcessPID:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or
                                        PROCESS_VM_READ, false, pe.th32ProcessID);

          if (ProcessPID <> 0) then
            WriteLn(pe.szExeFile);
        finally
          ProcessPID:= 0;
          CloseHandle(ProcessPID);
        end;
      end;
  finally
    CloseHandle(Snapshot);
  end;
end;

我有什么遗漏的吗? 我刚刚在 Windows 2008 Server 上尝试了相同的代码,并且成功了。但是在 Windows 10 上工作时,问题仍然存在。

【问题讨论】:

  • 在 Process32First 之后,您已经有了要处理的第一条记录,但您跳过它并调用 Process32Next。并尝试为每条记录输出 szExeFile,只有在 OpenProcess 成功时才这样做。
  • 是的...我的想法是仅当 OpenProcess 成功时才编写 szExeFile...而且我看不到其他用户帐户上运行的进程。仅当右键单击 > 以管理员身份运行
  • 这似乎行得通。看起来您的实际代码与您在此处发布的代码之间存在差异。
  • 不,代码是一样的。我只是在计时器内运行 ProcEnum,但我不知道这是否有任何区别......我在 Windows 10 机器上。
  • 您是否尝试调用 GetLastError 来查看错误是否实际上是 ERROR_SUCCESS ?因为它可能是 ERROR_NOT_ALL_ASSIGNED

标签: delphi winapi


【解决方案1】:

1。 尝试查看Enabling and Disabling Privileges in C++。 由此看来,您似乎必须更改ChangePrivilege 以在AdjustTokenPrivileges 中指定TTokenPrivileges 的大小。现在是0。为了解决这类问题,我认为这就是为什么他们建议仔细检查GetLastError &lt;&gt; ERROR_NOT_ALL_ASSIGNED 的原因。 希望这些修改会有所帮助:

procedure ChangePrivilegeModified;
var
  NewState: TTokenPrivileges;
  luid: TLargeInteger;
  hToken: THandle;
  ReturnLength: DWord;
begin
  if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken) then
  begin
   if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'), luid) then
   begin
    NewState.PrivilegeCount:= 1;
    NewState.Privileges[0].Luid := luid;
    NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    if AdjustTokenPrivileges(hToken, False, NewState, SizeOf(TTokenPrivileges), nil, ReturnLength) then
    begin
      if GetLastError = ERROR_NOT_ALL_ASSIGNED then
        WriteLn('Change privilege failed: Not all assigned')
      else
        WriteLn('Privileged');
    end;
   end;
    CloseHandle(hToken);
  end;
end;

2。 如果 OpenProcess 仍然失败,那么从文档 OpenProcess function 中可以看到访问权限注意事项,在 Process Security and Access Rights 中进行了详细说明。要对OpenProcess 进行故障排除,请尝试将权限数量缩小到PROCESS_QUERY_LIMITED_INFORMATION = $1000

ProcessPID:= OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, false, pe.th32ProcessID );

这成功了吗?

【讨论】:

  • 是的,我按照你说的做了,现在我收到了失败的消息...这里可以做什么?没有什么?考虑到我是在管理员帐户上运行它,但不是右键单击 > 以管理员身份运行...
  • @LessStress 我发现这篇文章谈论的是必须设置的特权(手动方式见答案二):social.msdn.microsoft.com/Forums/en-US/…
【解决方案2】:

Process32First 返回时,它包含有关快照中第一个进程的信息。您通过调用Process32Next 忽略该过程。也许第一个过程,你未能处理的那个,就是你正在寻找的那个。

你的代码还有其他问题:

  1. 您不会以一致的方式检查返回值是否存在错误。
  2. 您错误地将进程句柄命名为 PID。
  3. 您泄漏了进程句柄,因为您没有关闭它们。相反,您会反复调用CloseHandle(0)

可能还有更多我没有发现的错误。

【讨论】:

  • 我修复了泄漏进程句柄和第一个进程忽略...我用更多细节回答了 Christian 的答案,请检查您是否也可以从那里提供帮助。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
相关资源
最近更新 更多