KillTimer 发表于 2022-4-30 14:27

用管理员权限获取UIAccess创建最高Z序的窗口

本帖最后由 KillTimer 于 2023-1-16 18:51 编辑

UIAccess可用于一些特殊的程序,让它们可以忽略UIPI(UI特权隔离)。这类程序一般以普通方式运行,但它们需要访问已提权的窗口,于是就有了这么个权限。UIAccess的另一个特性是可以创建Z序最高的窗口,Z序和窗口段在这个博客https://blog.csdn.net/weixin_43820461/article/details/107610331中有介绍,其中那个最高的窗口段就是有UIAccess权限的程序可以创建的。

一般情况下获取UIAccess权限很难,因为利用这个可以绕过UIPI而提权,可以看Raymond的技术博客:https://devblogs.microsoft.com/oldnewthing/20121213-00/?p=5843

那如果我们已经具备管理员权限,而只是想创建最高Z序的窗口(如用作截图工具的形状提示器),怎么办呢?
可以通过下面的方式实现:
遍历进程列表获取一个带SeTcbPrivilege权限的令牌(用户名一般是System),下面是缩略版代码:

PRIVILEGE_SET ps;
HANDLE hFinalToken;
const DWORD dwMaxPids = 16384;
DWORD dwSize, cbSize, i;
DWORD *pids = (DWORD*)LocalAlloc(LPTR, dwMaxPids * sizeof(*pids));
ps.PrivilegeCount = 1;
ps.Control = PRIVILEGE_SET_ALL_NECESSARY;
LookupPrivilegeValue(NULL, SE_TCB_NAME, &ps.Privilege.Luid);
EnumProcesses(pids, dwMaxPids * sizeof (*pids), &cbSize));
dwSize = cbSize >> 2;
for (i = 0; i < dwSize; ++i)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pids);
    HANDLE hToken;
    BOOL fTcbPrivileges;
    OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE, &hToken);
    if (PrivilegeCheck(hToken, &ps, &fTcbPrivileges) && fTcbPrivileges)
    {
      DuplicateTokenEx(
            hToken,
            TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
            NULL,
            SecurityAnonymous,
            TokenPrimary,
            &hFinalToken
      );
      // 这里已经获取令牌
    }
    CloseHandle(hToken);
    CloseHandle(hProcess);
}
LocalFree(pids);


用这个令牌启动另一个自身:

TCHAR szPath;
STARTUPINFO si = {sizeof (si)};
PROCESS_INFORMATION pi;
GetModuleFileName(NULL, szPath, MAX_PATH);
CreateProcessAsUser(hFinalToken, szPath, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);


在新进程中给另一个事先准备好的令牌设置TokenUIAccess:

BOOL fUIAccess = TRUE;
SetTokenInformation(hToken, TokenUIAccess, &fUIAccess, sizeof (fUIAccess));


然后就可以用它做你想做的事了。

完整的代码已经上传至https://github.com/killtimer0/uiaccess
也可以直接下载下面的(源码+可执行文件):


下面是获得最高Z序的效果图,其中左边的窗口未获取UIAccess,右边已获取,中间是置于顶层的任务管理器(ZBID_SYSTEM_TOOLS):


注意:这种方法一定不是官方推荐的做法,所以需要承担软件可能报毒的风险

2023-01-16更新:
修改了TokenUIAccess的实现方式,解决非管理员用户无法获取权限的问题

deepgo 发表于 2022-5-1 23:39

谢谢楼主分享 收藏保存了

zm55555 发表于 2022-5-2 09:23

谢谢分享!

asc2hex 发表于 2022-12-9 13:21

本帖最后由 asc2hex 于 2022-12-9 13:32 编辑

为什么我在win10 20H2中测试失败了呢?那个UIAccess复选框是灰色未选中状态,哪怕我使用TI权限启动它

KillTimer 发表于 2022-12-30 09:01

asc2hex 发表于 2022-12-9 13:21
为什么我在win10 20H2中测试失败了呢?那个UIAccess复选框是灰色未选中状态,哪怕我使用TI权限启动它

函数调用失败了,你可以看看错误代码是什么。那个复选框灰色是故意设置的,不管获取成不成功都是灰的。

KillTimer 发表于 2023-1-16 18:53

asc2hex 发表于 2022-12-9 13:21
为什么我在win10 20H2中测试失败了呢?那个UIAccess复选框是灰色未选中状态,哪怕我使用TI权限启动它

问题已经解决了,帖子和github同步更新

asc2hex 发表于 2023-1-29 10:05

本帖最后由 asc2hex 于 2023-1-29 10:23 编辑

KillTimer 发表于 2023-1-16 18:53
问题已经解决了,帖子和github同步更新
新年快乐,谢谢回复,已看到最新代码,测试成功.很有用,可以置顶,具此,我给自己的小工具添加了新的模块.再此感谢

不苦小和尚 发表于 2023-12-22 09:41

asc2hex 发表于 2023-1-29 10:05
新年快乐,谢谢回复,已看到最新代码,测试成功.很有用,可以置顶,具此,我给自己的小工具添加了新的模块.再此 ...

工具在哪里下载,我想测试一下

asc2hex 发表于 2023-12-22 14:17

不苦小和尚 发表于 2023-12-22 09:41
工具在哪里下载,我想测试一下

因不符合论坛原创软件发贴要求,无法分享在论坛,喜欢的话,可以在百度网盘下载测试
链接:https://pan.baidu.com/s/1AaCuXGbMDxPlu1gTPii71A?pwd=1234
提取码:1234
页: [1]
查看完整版本: 用管理员权限获取UIAccess创建最高Z序的窗口