2017-03-13 73 views
1

我有一个应用程序调用WNetAddConnection2来映射网络驱动器。除非以管理员身份运行应用程序(右键单击 - 以管理员身份运行),否则该功能将完美工作,在这种情况下,函数将返回0(成功),但映射的驱动器不会显示。从“以管理员身份运行”进程使用WNetAddConnection2映射网络驱动器不起作用

这里似乎正在发生的是有两个上下文,其中我的程序正在运行的管理员和其中运行Windows资源管理器的用户之一,我正在寻找映射的驱动器。我认为驱动器映射成功地在“Admin Context”中,但在“用户上下文”中不可见。

当我以管理员身份运行时Environment.GetLogicalDrives()包含我尝试映射的驱动器号,使我认为映射在“Admin Context”中成功。

道歉,如果我完全有错误的想法与多个上下文,但它似乎是我所看到的最好的解释。

有两个可能的回答这个问题:

1)如何映射一个驱动器,以便它在所有情况可见?

2)如何从没有管理员权限的“以管理员身份运行”进程(即在“用户环境”)内执行某些操作(进程/线程/ API调用)?

+0

相关:http://stackoverflow.com/questions/42767614/ –

回答

1

1)驱动器将仅在登录会话可见与LUID与您的令牌TOKEN_STATISTICS.AuthenticationId

将创建符号链接对象下\Sessions\0\DosDevices\<LogonId>\<X>:\Device\LanmamRedirector\;<X>:<LogonId>\server\share作为结果驱动<X>:将只对可见在<LogonId>会话中运行的进程。运行“作为管理员”的过程有不同的<LogonId>比较过程不运行“作为管理员”

2),你需要调用NetUseAddWNetAddConnection2之前冒充另一个上下文。

例如,您可以枚举进程,找到具有相同终端的浏览器SessionId(不会与登录会话混淆)并模拟它(打开它的标记,复制和模拟)。或者更一般的开放在同一终端会话作为过程的每一个进程令牌,查询它令牌TokenElevationTypeTOKEN_ELEVATION_TYPE),如果TokenElevationTypeLimited - 调用之前复制和模仿此令牌,NetUseAdd


如何执行的东西(例如,在“用户 上下文中”),从“以管理员身份运行 ”进程(进程/线程/ API调用)工作代码

例如:

#include <TlHelp32.h> 

#define BOOL_TO_ERR(b) ((b) ? NOERROR : GetLastError()) 

ULONG RunNonElevated(PCWSTR lpApplicationName, PWSTR lpCommandLine) 
{ 
    HANDLE hToken; 

    ULONG err = BOOL_TO_ERR(OpenProcessToken(NtCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hToken)); 

    if (err != NOERROR) 
    { 
     return err; 
    } 

    DWORD cb, rcb; 

    union { 
     TOKEN_ELEVATION_TYPE tet; 
     TOKEN_LINKED_TOKEN tlt; 
    }; 

    TOKEN_STATISTICS ts; 
    LUID AuthenticationId = {}; 

    BOOL bSearchToken = FALSE, bFound = FALSE; 

    err = BOOL_TO_ERR(GetTokenInformation(hToken, TokenElevationType, &tet, sizeof(tet), &rcb)); 

    if (err == NOERROR) 
    { 
     if (tet == TokenElevationTypeFull) 
     { 
      err = BOOL_TO_ERR(GetTokenInformation(hToken, TokenLinkedToken, &tlt, sizeof(tlt), &rcb)); 

      if (err == NOERROR) 
      { 
       err = BOOL_TO_ERR(GetTokenInformation(tlt.LinkedToken, TokenStatistics, &ts, sizeof(ts), &rcb)); 

       CloseHandle(tlt.LinkedToken); 

       if (bSearchToken = (err == NOERROR)) 
       { 
        AuthenticationId.LowPart = ts.AuthenticationId.LowPart; 
        AuthenticationId.HighPart = ts.AuthenticationId.HighPart; 

        TOKEN_PRIVILEGES tp = { 
         1, { { { SE_DEBUG_PRIVILEGE } , SE_PRIVILEGE_ENABLED } } 
        }; 

        AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); 
       } 
      } 
     } 
    } 

    CloseHandle(hToken); 

    STARTUPINFO si = { sizeof (si) }; 
    PROCESS_INFORMATION pi; 

    if (bSearchToken) 
    { 
     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 

     if (hSnapshot != INVALID_HANDLE_VALUE) 
     { 
      PROCESSENTRY32W pe = { sizeof(pe) }; 

      static volatile UCHAR guz; 

      PVOID stack = alloca(guz); 

      cb = 0, rcb = FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges[SE_MAX_WELL_KNOWN_PRIVILEGE]); 

      union { 
       PVOID buf; 
       PTOKEN_PRIVILEGES ptp; 
      }; 

      BOOL fHavePrivs = FALSE; 

      if (Process32FirstW(hSnapshot, &pe)) 
      { 
       do 
       { 
        if (HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID)) 
        { 
         if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE, &hToken)) 
         { 

          if (!fHavePrivs) do 
          { 
           if (cb < rcb) 
           { 
            cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack); 
           } 

           if (GetTokenInformation(hToken, TokenPrivileges, buf, cb, &rcb)) 
           { 
            if (ULONG PrivilegeCount = ptp->PrivilegeCount) 
            { 
             int n = 3; 
             BOOL fAdjust = FALSE; 

             PLUID_AND_ATTRIBUTES Privileges = ptp->Privileges; 
             do 
             { 
              switch (Privileges->Luid.LowPart) 
              { 
              case SE_ASSIGNPRIMARYTOKEN_PRIVILEGE: 
              case SE_INCREASE_QUOTA_PRIVILEGE: 
              case SE_DEBUG_PRIVILEGE: 
               if (!(Privileges->Attributes & SE_PRIVILEGE_ENABLED)) 
               { 
                Privileges->Attributes |= SE_PRIVILEGE_ENABLED; 
                fAdjust = TRUE; 
               } 

               if (!--n) 
               { 
                if (DuplicateTokenEx(hToken, 
                 TOKEN_ADJUST_PRIVILEGES|TOKEN_IMPERSONATE, 
                 0, SecurityImpersonation, TokenImpersonation, 
                 &tlt.LinkedToken)) 
                { 
                 if (fAdjust) 
                 { 
                  AdjustTokenPrivileges(tlt.LinkedToken, FALSE, ptp, rcb, NULL, NULL); 
                 } 
                 fHavePrivs = SetThreadToken(0, tlt.LinkedToken); 
                 CloseHandle(tlt.LinkedToken); 
                } 
                goto __1; 
               } 
              } 
             } while (Privileges++, --PrivilegeCount); 
            } 
            break; 
           } 

          } while (GetLastError() == ERROR_INSUFFICIENT_BUFFER); 

__1: 
          if (fHavePrivs && 
           GetTokenInformation(hToken, TokenStatistics, &ts, sizeof(ts), &rcb) && 
           ts.AuthenticationId.LowPart == AuthenticationId.LowPart && 
           ts.AuthenticationId.HighPart == AuthenticationId.HighPart) 
          { 
           bFound = DuplicateTokenEx(hToken, 
            TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY, 
            0, SecurityImpersonation, TokenPrimary, &tlt.LinkedToken); 
          } 
          CloseHandle(hToken); 
         } 
         CloseHandle(hProcess); 
        } 
       } while (!bFound && Process32NextW(hSnapshot, &pe)); 
      } 
      CloseHandle(hSnapshot); 

      if (bFound) 
      { 
       err = BOOL_TO_ERR(CreateProcessAsUserW(tlt.LinkedToken, lpApplicationName, lpCommandLine, 
        NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)); 

       CloseHandle(tlt.LinkedToken); 

       if (err == NOERROR) 
       { 
        CloseHandle(pi.hThread); 
        CloseHandle(pi.hProcess); 
       } 
      } 
     } 
    } 
    else if (err == NOERROR) 
    { 
     if ((err = BOOL_TO_ERR(CreateProcessW(lpApplicationName, lpCommandLine, 
      NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))) == NOERROR) 
     { 
      CloseHandle(pi.hThread); 
      CloseHandle(pi.hProcess); 
     } 
    } 

    return err; 
} 
+0

你能提供你提到在哪些代码示例(2)? – trungdinhtrong

+1

@trungdinhtrong - 我粘贴代码(2) - 但是如果你的进程代码不是'TokenElevationTypeFull'类型 - 这意味着你运行不升级('TokenElevationTypeLimited'情况下)或者作为内置管理或UAC如果关闭('TokenElevationTypeDefault' case ) - 在这种情况下没有意义exec额外的过程 – RbMm

+0

非常感谢,RbMm。 – trungdinhtrong

相关问题