如何在system进程下模拟administrator进程调用windowsAPI

转载出处:http://my.oschina.net/macwe/blog/348656

我们新建了一个网络映射,现在需要在我们的服务进程中访问这个远程磁盘,结果发现QueryDosDevice、NetUseEnum、GetLogicalDriveStrings均不可用。怎么办?

我们新建了一个网络映射,现在需要在我们的服务进程中访问这个远程磁盘,结果发现QueryDosDevice、NetUseEnum、GetLogicalDriveStrings均不可用。怎么办?

因为磁盘映射是和当前账户关联的,当账户登录之后才会存在这个盘符。(可以试试在同一个系统上建立两个账户,它们可以将不同的网络位置映射成同一个盘符。当然盘符只是一个逻辑符号,系统正真的符号是\Device\Mup和\Device\LanmanRedirector 的UNC形式标识,这样系统内部是不会重复的)。

我们的磁盘映射是Administrator账户创建的,而服务进程是SYSTEM账户。试了好多种方法都没有解决如何高效的在SYSTEM账户下的访问远程磁盘。

于是想能不能在SYSTEM账户下模拟Administrator的账户访问呢,问了公司的大神后觉得可行。就上网查找相关的资料。顺便这里记录一下以备以后查看。

方法如下:

  • 1.得到当前登录用户的Token。

    WTSGetActiveConsoleSessionId()

    WTSQueryUserToken()

  • 2.模拟当前登录用户

    ImpersonateLoggedOnUser()

  • 3.接下来可以使用本地磁盘的函数进行操作了

    。。。。。。。。。

  • 4.操作完成之后别忘了RevertToSelf。再换回SYSTEM。

程序中的代码:

头文件

?
1
2
#include <Wtsapi32.h>
#pragma comment(lib, "Wtsapi32.lib")


1.如果当前账户是SYSTEM,需要切换到当前激活账户的环境来执行

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HANDLE  hTokenUser = NULL;
DWORD  ConsoleSessionId = 0;
BOOL  bImpersonateLoggedOnUser = FALSE;
char  userName[256] = {0};
DWORD  userNameLen =  sizeof (userName);
 
GetUserName(userName, &userNameLen);
if  (0 == stricmp( "SYSTEM" , userName))
{
     // 得到当前激活用户的会话ID
     ConsoleSessionId = WTSGetActiveConsoleSessionId();
     // 得到当前登录用户的令牌
     if  (WTSQueryUserToken(ConsoleSessionId, &hTokenUser))
     {
         // 模仿成当前登录用户
         bImpersonateLoggedOnUser = ImpersonateLoggedOnUser(hTokenUser);
     }
}


2.用完后

?
1
2
3
4
5
// 终止模拟,返回
     if  (bImpersonateLoggedOnUser)
     {
         RevertToSelf();
     }


注意事项:

1.该功能可能不支持Win2003以下版本的系统,我还没测试。

2.这里说的当前登录用户指的是哪个用户?看MSDN上的这一段话:

The session identifier of the session that is attached to the physical console. If there is no session attached to the physical console, (for example, if the physical console session is in the process of being attached or detached), this function returns 0xFFFFFFFF.


参考资料:

http://www.programlife.net/impersonateloggedonuser.html

http://hi.baidu.com/robinwjbgui/blog/item/7ab0a213b2b2bf866438db10.html

http://msdn.microsoft.com/en-us/library/windows/desktop/aa378612(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/aa383835(v=vs.85).aspx


===============================

2014-11-26更新:

接受老大的建议:上述代码中有一处不严谨。判断是否有SYSTEM权限比判用户名更好

判断代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
BOOL  CurrentUserIsLocalSystem()
{
     BOOL  bIsLocalSystem = FALSE;
     PSID psidLocalSystem;
     SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
 
     BOOL  fSuccess = ::AllocateAndInitializeSid(&ntAuthority, 1, SECURITY_LOCAL_SYSTEM_RID,
                                         0, 0, 0, 0, 0, 0, 0, &psidLocalSystem);
     if  (fSuccess) 
     {
         fSuccess = ::CheckTokenMembership(0, psidLocalSystem, &bIsLocalSystem);
         ::FreeSid(psidLocalSystem);
     }
 
     return  bIsLocalSystem;
}

参考资料:

http://support.microsoft.com/kb/118626/zh-cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值