system权限创建用户权限进程
来源:互联网 发布:知乎怎么发不了文章 编辑:程序博客网 时间:2024/05/19 14:50
windows编程的人都知道,在其操作系统下,进程被创建,通常被赋予很多属性,其中一项属性就是用户名,及进程所属的权限。打开任务管理器,可查看到(查看不到,点击查看,选择列即可)
通常桌面系统explorer的权限是User权限,即用户权限的,它可以是你administrator,可以是你PC的名字,可以是Guest等,所以我们开启并运行的所有进程都继承它的权限。
若想运行具备system权限的explorer,则可参考以前的文章
切换具有SYSTEM权限的控制台或桌面
在添加服务后,服务所对应的进程权限是SYSTEM权限,那么由这个SYSTEM调用的所有子进程,在常规下,都将是SYSTEM权限,如果有这样一个需求,需要通过服务调用某个具备User权限的进程,则需要通过CreateProcess
API的扩展即,CreateProcessAsUser.
WINADVAPI BOOLWINAPI 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桌面应用程序,在系统框架上,我会选择,一个服务对应一个权限进程,一个随用户桌面的自启动程序随用户权限,这样子,分而治之也不会太乱,至少,用这种跨权限调用子进程的方法风险太高。
- system权限创建用户权限进程
- 创建SYSTEM用户权限的进程
- 在SYSTEM权限下创建用户进程方法
- 用户权限设置和进程权限提升
- 【总结】用户权限设置和进程权限提升
- 【总结】用户权限设置和进程权限提升
- 用户权限设置和进程权限提升
- 【总结】用户权限设置和进程权限提升
- "SYSTEM"用户创建进程
- 创建SYSTEM进程
- 从SYSTEM权限将到当前用户权限代码
- Android系统system用户权限和root权限的获取
- Android系统system用户权限和root权限的获取
- Android系统system用户权限和root权限的获取
- 创建高权限进程
- 创建高权限进程
- 创建高权限进程
- 创建高权限进程
- 实现Windows数据绑定 上机练习
- Android PopupWindow使用总结
- 基于博创S3C6410l键盘驱动分析与更改
- Kubernetes 高级特性集锦
- linux的进程相关函数简单总结
- system权限创建用户权限进程
- bzoj2160 拉拉队排练
- 基本的bash shell命令(文件以及目录处理)
- 独立任务最优调度问题
- 文章标题 POJ 1426 :Find The Multiple (dfs)
- Android控件之Chronometer(定时器)
- 天猫双12爬虫(福利:266万条商品数据免费下载)
- Linux下如何搭建stm32开发环境
- mysql Access denied for user ‘root’@’localhost’ (using password: YES)解决方法