c语言查看进程权限,用户权限设置和进程权限提升

使用某些Windows API的时候需要提升进程的默认权限,例如RegRestoreKey需要SE_RESTORE_NAME 和SE_BACKUP_NAME 权限。在这种情况下,我们需要使用到一组Windows API提升进程权限。需要的函数有:

1.OpenProcessToken

2.LookupPrivilegeValue

3.AdjustTokenPrivileges

使用这组函数提升权限的前提是进程具备该权限,只是访问令牌中没有启用该权限。如果进程的访问令牌中本身就没有关联该权限,这AdjustTokenPrivileges函数调用将会返回ERROR_NOT_ALL_ASSIGNED(值为1300L)的错误码。如何让进程具有该权限?可以通过“控制面板”—“管理工具”—“本地安全策略”—“本地策略”—“用户权利指派”设置将该权限关联到指定的用户分组或用户上。具体设置如下图所示:

win7之本地安全策略启动:

1.单击“控制面板”--“系统和安全”--“管理工具”--“本地安全策略”,会进入“本地安全策略”界面。

2..win+R--secpol.msc,也可以。

利用AdjustTokenPrivileges提升权限,准确的说不是提升,而是将访问令牌中禁用的权限启用。

[cpp]

view plain

copy

BOOLSetPrivilege(HANDLEhToken,//accesstokenhandleLPCTSTRlpszPrivilege,//nameofprivilegetoenable/disableBOOLbEnablePrivilege//toenableordisableprivilege){TOKEN_PRIVILEGEStp;LUIDluid;if(!LookupPrivilegeValue(NULL,//lookupprivilegeonlocalsystemlpszPrivilege,//privilegetolookup&luid))//receivesLUIDofprivilege{printf("LookupPrivilegeValueerror:%u\n",GetLastError());returnFALSE;}tp.PrivilegeCount=1;tp.Privileges[0].Luid=luid;if(bEnablePrivilege)tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;elsetp.Privileges[0].Attributes=0;//Enabletheprivilegeordisableallprivileges.if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL)){printf("AdjustTokenPrivilegeserror:%u\n",GetLastError());returnFALSE;}if(GetLastError()==ERROR_NOT_ALL_ASSIGNED){printf("Thetokendoesnothavethespecifiedprivilege.\n");returnFALSE;}returnTRUE;}voidmain(){HANDLEhToken;BOOLbRet=OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken);SetPrivilege(hToken,SE_DEBUG_NAME,TRUE);}

这段代码在xp上没有问题,但如果在windows 7 或者vista上,如果程序以标准用户启动,AdjustTokenPrivileges将会调用失败,以管理员身份启动没有问题。

这是因为在Windows 7上,标准用户权限很少,没有Debug权限,更无从谈起启用Debug权限,用户可以以管理员和标准用户两种方式启用控制台,输入命令whoami /ALL来查看两种权限下权限的不同。

PS:即使提升调试权限,也不意味着对其它进程调用OpenProcess会成功(例如win7系统下的system和audiodg进程)

下面解释这三个函数:

首先需要获取进程的令牌句柄

OpenProcessToken的原型.

[cpp]

view plain

copy

BOOLWINAPIOpenProcessToken(__inHANDLEProcessHandle,__inDWORDDesiredAccess,__outPHANDLETokenHandle);

第一个参数 进程句柄(当前进程为GetCurrentProcess()为参数)

第二个参数 访问令牌特权

第三个参数 返回的参数 就是AdjustTokenPrivileges的第一个参数

例子:

[cpp]

view plain

copy

HANDLEhToken;boolretn=OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken);if(!retn){return;//获取令牌失败。。}

注:第二个参数 是令牌的权限,这个权限是要有修改权限的特权,意思就是要把你程序的权限修改得更高。

关于其他权限可以查MSDN.. 所有权限可以写TOKEN_ALL_ACCESS ,去查看一个令牌特权可以用TOKEN_QUERY

这个下面函数有写。

--------------------------------------------------------------

首先先说一下使用AdjustTokenPrivileges需要的。

在这个函数中的第3和第5个参数中需要用到一个TOKEN_PRIVILEGES的结构体,在这个结构体中还有个LUID_AND_ATTRIBUTES结构体

TOKEN_PRIVILEGES结构体

[cpp]

view plain

copy

typedefstruct_TOKEN_PRIVILEGES{DWORDPrivilegeCount;LUID_AND_ATTRIBUTESPrivileges[ANYSIZE_ARRAY];}TOKEN_PRIVILEGES;

下面的参数是个特权数组。

上面的参数是要修改的特权数目

LUID_AND_ATTRIBUTES 结构体

[cpp]

view plain

copy

typedefstruct_LUID_AND_ATTRIBUTES{LUIDLuid;DWORDAttributes;}LUID_AND_ATTRIBUTES;

第一个参数是Luid是一个标志,不同的Luid代表着各种不同的特权类型

第二个参数是要这个特权干嘛,如启用这个特权(SE_PRIVILEGE_ENABLED)

这里的Luid的值需要用LookupPrivilegeValue来获取。

------------------------------------------------------------------------------------------

LookupPrivilegeValue的原型

[cpp]

view plain

copy

BOOLWINAPILookupPrivilegeValue(__in_optLPCTSTRlpSystemName,__inLPCTSTRlpName,__outPLUIDlpLuid);

第一个参数是系统的名字,如果为NULL,就是本地名字(这里就填NULL)

第二个参数是特权的名字,要查看详细特权,看我的博客里翻译分类里的 包含特权 的文章。(在这里写SE_DEBUG_NAME)

第三个参数就可以通过指针返回一个LUID类型的Luid的标识了。 通过这个值就可以填入刚才的结构体里了。

----------------------------------------------------------------------------------------------------------------------------

最后就可以介绍AdjustTokenPrivilege就应该没什么问题了。

它的原型为:

[cpp]

view plain

copy

BOOLWINAPIAdjustTokenPrivileges(__inHANDLETokenHandle,__inBOOLDisableAllPrivileges,__in_optPTOKEN_PRIVILEGESNewState,__inDWORDBufferLength,__out_optPTOKEN_PRIVILEGESPreviousState,__out_optPDWORDReturnLength);

第一个参数为OpenProcessToken第三个指针参数传出的句柄值

第二个参数为是否禁用所有所有的特权(这里填false)

第三个参数为新的TOKEN_PRIVILEGES的特权结构体指针

第四个参数是上面结构体的字节长度(sizeof)

第五个参数是 接受原先的特权的结构体

第六个参数也是这个结构体的字节长度的指针

在这里后两个参数不用管。

MSDN里说

如果第五个参数不是NULL,在OpenProcessToken加特权时除了需要指定TOKEN_ADJUST_PRIVILEGES还必须指定TOKEN_QUERY

如果第五个参数是NULL,你不接受原先的结构体(第六个当然也是NULL), 就不用再指定附加的TOKEN_QUERY的特权了。

还要注意:

就算这个函数返回为真,还要调用GetLastError()来检验是否完全成功。如果GetLastError()==ERROR_SUCCESS就代表修改非常成功 ,这个非常重要!!

还有就是Vista和Window7 里 一定要开管理员模式 才能获取成功

----------------------------------------------------

完整的例子

可以直接复制运行

[cpp]

view plain

copy

#include#includeusingnamespacestd;voidmain(){BOOLretn;HANDLEhToken;retn=OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken);if(retn!=TRUE){cout<

参考:

7276760

http://hi.baidu.com/honfei/item/c8f53302a60104c32f4c6b76

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值