2017-03-13 87 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

相關問題