system权限创建用户权限进程

windows编程的人都知道,在其操作系统下,进程被创建,通常被赋予很多属性,其中一项属性就是用户名,及进程所属的权限。打开任务管理器,可查看到(查看不到,点击查看,选择列即可)

这里写图片描述

通常桌面系统explorer的权限是User权限,即用户权限的,它可以是你administrator,可以是你PC的名字,可以是Guest等,所以我们开启并运行的所有进程都继承它的权限。
若想运行具备system权限的explorer,则可参考以前的文章

切换具有SYSTEM权限的控制台或桌面

在添加服务后,服务所对应的进程权限是SYSTEM权限,那么由这个SYSTEM调用的所有子进程,在常规下,都将是SYSTEM权限,如果有这样一个需求,需要通过服务调用某个具备User权限的进程,则需要通过CreateProcess
API的扩展即,CreateProcessAsUser.

WINADVAPI BOOL
WINAPI CreateProcessAsUser (
    __in_opt    HANDLE hToken,
    __in_opt    LPCSTR lpApplicationName,
    __inout_opt LPSTR lpCommandLine,
    __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in        BOOL bInheritHandles,
    __in        DWORD dwCreationFlags,
    __in_opt    LPVOID lpEnvironment,
    __in_opt    LPCSTR lpCurrentDirectory,
    __in        LPSTARTUPINFOA lpStartupInfo,
    __out       LPPROCESS_INFORMATION lpProcessInformation
);

其中hToken是最关键的,它表示进程所需要的会话令牌,通俗点就是权限的一个标识,有了它,就可以创建其他权限的进程了。

hToken的获取,网上资料特别多,就不列举了,这里直接贴关键代码

int CreateProcessByToken(LPSTR lpTokenProcessName,LPSTR lpProcess,LPSTR lpCommend)
{
    HANDLE hToken = 0;
    LPSTR lpName = lpTokenProcessName;
    HANDLE hProcessSnap = 0;
    PROCESSENTRY32 pe32 = {0};
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    pe32.dwSize = sizeof(PROCESSENTRY32);
    for(Process32First(hProcessSnap,&pe32);Process32Next(hProcessSnap,&pe32);)
    {
        if(strcmp(strupr(pe32.szExeFile),strupr(lpName))) continue;
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);
        OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
        CloseHandle(hProcessSnap);
    }
    if(hToken == 0) return 0;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = "winsta0\\default";
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    return CreateProcessAsUser(hToken,lpProcess,lpCommend,0,0,FALSE,NORMAL_PRIORITY_CLASS,0,0,&si,&pi);
}

调用方式为

char tokenname[64]="explorer.exe";
CreateProcessByToken(tokenname,0,"myservice_userchild.exe");

注意第一参数必须是非常量的,因为使用了strupr。
添加服务并启用服务,可以看到启动的子进程为User用户名了。

这里写图片描述

添加服务的方法太easy

sc create myservice_service_service binPath= "E:\code\system2user\Debug\myservice.exe" type= own start= auto

完整的示例已分享

http://download.csdn.net/detail/huanglong8/9708203

看过《windows核心编程》的小伙伴们,肯定比较熟悉第四章,在第四章中有讲到获取进程信息的示例和相关技术说明。于是乎,我又做了如下实验,windows进程的用户名很多,还有NETWORK SERVICE,LOCAL SERVICE等,那么SYSTEM是否再获取token后,仍然可以调用出具备此权限的子进程呢?改写代码,将子进程调用加入到循环中。

for(Process32First(hProcessSnap,&pe32);Process32Next(hProcessSnap,&pe32);)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);
    OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = "winsta0\\default";
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    CreateProcessAsUser(hToken,lpProcess,lpCommend,0,0,FALSE,NORMAL_PRIORITY_CLASS,0,0,&si,&pi);
}

启动服务后,发现调用的子进程中并没有SERVICE的权限进程。
这里写图片描述

在用LookupAccountSid 函数进行遍历获取用户名时,和书籍提供的样例程序是一样的,获取到了SYSTEM,USER,SERVICE等一系列权限token,但使用CreateProcessAsUser时,却针对其他权限调用失败,很是困惑。查阅网上的说法,说事因为主进程权限不够导致。所以,我便切换到SYSTEM用户桌面下。

启动服务,仍然是上面那种情况,失败。
但控制台直接调用,却意外成功了。

这里写图片描述

惊奇的发现,居然没有User,好吧,我已慌乱。

按照网上的说法,需要提主进程的权限,参考核心编程中的样例,试过了,并未成功,所以就不贴出来了。

由此可以知道,如果SYSTEM启动用户权限进程是可以做到的,但是启动其他权限进程,则无法做到。不知道有没有其他小伙伴有更好的示例和方法,欢迎分享啊。

最后贴出最佳的解决方案,针对Windows桌面应用程序,在系统框架上,我会选择,一个服务对应一个权限进程,一个随用户桌面的自启动程序随用户权限,这样子,分而治之也不会太乱,至少,用这种跨权限调用子进程的方法风险太高。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值