国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

修改 Windows 文件訪問權(quán)限的多種方法

這篇具有很好參考價值的文章主要介紹了修改 Windows 文件訪問權(quán)限的多種方法。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

提示:本文修改后包含編程方法以及附注的工具方法,傳統(tǒng)的資源管理器交互方法等等。

由于文件是安全對象,因此訪問它們受訪問控制模型控制,該模型控制對 Windows 中所有其他安全對象的訪問。?

更改文件或目錄對象的安全描述符,需要調(diào)用?SetNamedSecurityInfo?或?SetSecurityInfo?等函數(shù)。

ACLAccess Control List,用來表示用戶(組)權(quán)限的列表,包括?DACL?和?SACL
ACEAccess Control Entry,ACL?中的元素;
DACLDiscretionary Access Control List,用來表示安全對象權(quán)限的列表;
SACLSystem Access Control List,用來記錄對安全對象訪問的日志。

關(guān)于這幾個概念已經(jīng)有很多資料解釋,這里就不詳細展開了。(以下僅介紹通過 Win32API 修改文件安全屬性的一些內(nèi)容)。

本文以 SetNamedSecurityInfo 函數(shù)為例,簡單講解如何通過編程修改指定文件的 ACL 主體和添加 ACE 條目。后文修改的文件比較特殊,它們受到本地內(nèi)置安全主體?TrustedInstaller 的完全控制保護,本文旨在通過相關(guān)?API?實現(xiàn)修改這類文件的完全控制權(quán)限。有關(guān)內(nèi)置安全主體?TrustedInstaller 的信息,需要具有一定的知識基礎(chǔ),限于篇幅原因這里不詳細展開。


一、編程實現(xiàn)方法闡述

1.1 修改 ACL 的所有者

SetNamedSecurityInfo 函數(shù)用于在指定對象的安全描述符(ACL)中設(shè)置指定的安全信息。 調(diào)用方按名稱標識對象。

這里的按名稱標識對象,表示設(shè)置安全信息時候,目標對象名是字符串格式,且對于不同對象類型的字符串格式,可以參閱說明:SE_OBJECT_TYPE。我們這里要修改NTFS文件系統(tǒng)中指定文件的安全屬性,按照標準需要填寫文件絕對路徑的寬字符串,其中路徑以反斜杠 (" / ") 或者雙斜杠 (" \\ ") 給出,并且要以 NULL 結(jié)尾。

下面給出該函數(shù)的參數(shù):

DWORD SetNamedSecurityInfoW(
  [in]           LPWSTR               pObjectName,
  [in]           SE_OBJECT_TYPE       ObjectType,
  [in]           SECURITY_INFORMATION SecurityInfo,
  [in, optional] PSID                 psidOwner,
  [in, optional] PSID                 psidGroup,
  [in, optional] PACL                 pDacl,
  [in, optional] PACL                 pSacl
);

這些參數(shù)的定義是:

pObjectName 指定目標對象的名稱;
ObjectType 指示 pObjectName 的類型,如果修改 NTFS 文件則填寫為 SE_FILE_OBJECT;
SecurityInfo 指示要設(shè)置的安全信息的類型;
psidOwner 指向標識對象所有者的 SID 結(jié)構(gòu)的指針;
psidGroup 指向標識對象主組的 SID 的指針;
pDacl 指向 對象的新 DACL 的指針;
pSacl 指向 對象的新 SACL 的指針。

其中,如果 SecurityInfo 填寫為 OWNER_SECURITY_INFORMATION 表明對安全主體的操作(也就是控制列表所有者);如果填寫為?DACL_SECURITY_INFORMATION 則表明對安全對象(ACE)的權(quán)限的操作。這里需要注意:如果調(diào)用方令牌對應(yīng)的賬戶標識符(SID)不是文件安全主體指向的賬戶標識符,則對安全對象權(quán)限的操作會被拒絕

修改文件安全屬性需要進程的令牌具有一定的訪問控制權(quán)限,這里我們需要獲取兩個權(quán)限?SE_SECURITY_NAME 和?SE_TAKE_OWNERSHIP_NAME 。這兩個權(quán)限可以通過?AdjustTokenPrivileges 函數(shù)獲得,而賦予新的令牌則需要調(diào)用方線程具有管理員權(quán)限。所以進程需要以提升的令牌啟動才能正確獲取權(quán)限。

從零開始的項目都是不容易的,有一個參考最好不過了。這里我們可以參考資源管理器的功能實現(xiàn)文件安全屬性的修改,下面的圖片展示了通過資源管理器查看的目標文件的安全屬性頁面信息:

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具
目標文件的安全屬性信息頁

通過觀察,我們可以發(fā)現(xiàn),當前的所有者為 TrustedInstaller 并且只有它具有完全控制權(quán)限,其他安全對象只具有讀取和執(zhí)行的權(quán)限。此外我們還發(fā)現(xiàn),對于該文件權(quán)限修改的按鈕都是灰色或者具有盾牌圖標。我們將其與用戶具有完全訪問控制權(quán)的文件安全信息進行對比,就可以發(fā)現(xiàn)所有者信息起到了至關(guān)重要的作用,調(diào)用方必須為文件的安全主體或者權(quán)限比安全主體高,否則不能修改安全屬性表。所以當正確獲取權(quán)限后,我們首先需要修改文件的安全主體(所有者)。

首先我們簡述一下通過資源管理器進行修改的步驟:

Step 1: 首先選中要修改的文件(夾),打開右鍵菜單,在菜單中找到“屬性”項目,點擊打開屬性對話框;

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

Step 2: 在屬性對話框中選中“安全”選項卡,右下角點擊“高級(安全設(shè)置)”按鈕;

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

Step 3: 可以看到該頁面包含兩個主要部分:1)所有者;2)成員及其權(quán)限

并且后面都有帶有盾牌的“更改”按鈕,再結(jié)合說明文檔可知,如果當前進程代表的賬戶權(quán)限低于所有者所具有的權(quán)限,則低權(quán)限進程不具有修改高權(quán)限進程的權(quán)限能力;

這里我們需要先修改所有者,點擊最上面的TrustedInstaller字樣后面的更改按鈕,此時可能彈出UAC對話框提示用戶需要提升權(quán)限,也可能沒有提示直接提升(取決于計算機配置的UAC警告級別)

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

Step 4: 此時會彈出選擇所有者的對話框,點擊“高級”按鈕展開這個編輯器窗口:

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

Step 5: 在高級窗口中點擊立即查找,在查找的列表中找到當前登陸用戶的用戶名,然后點擊確定,或者選擇everyone(字面意思,代表任何用戶)。

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

Step 6: 逐級確定并應(yīng)用,可以發(fā)現(xiàn)所有者被成功更改:

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

最后一步點擊“應(yīng)用”,然后再點擊確定,應(yīng)用更改,隨后重新打開高級安全設(shè)置頁面,選擇要修改權(quán)限的成員,并發(fā)現(xiàn)編輯區(qū)域按鈕被點亮,點擊“添加/編輯”:

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

隨后,在打開的窗口中,先點擊藍色字“選擇主體”,類似于修改所有者的操作完成權(quán)限配置,并點擊確定,最后點擊應(yīng)用即可完成整個修改操作:

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

最后,補充一下修改完成后改回TrustedInstaller的方法:在更改所有者時候,直接輸入?NT SERVICE\TrustedInstaller 需要注意不能有拼寫錯誤!然后其他步驟不變。

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具

我們通過設(shè)置?SetNamedSecurityInfo 函數(shù)的?SecurityInfo 參數(shù)為 OWNER_SECURITY_INFORMATION 并指定 psidOwner 為指向新所有者的安全描述符 (SID) 結(jié)構(gòu)的指針。

SID 就相當于所有者的身份證,那么我們?nèi)绾潍@取到所需要的 SID 呢?

LookupAccountName 函數(shù)可供獲取指定用戶名對應(yīng)的 SID 。

其參數(shù)如下:

BOOL LookupAccountNameW(
  [in, optional]  LPCWSTR       lpSystemName,
  [in]            LPCWSTR       lpAccountName,
  [out, optional] PSID          Sid,
  [in, out]       LPDWORD       cbSid,
  [out, optional] LPWSTR        ReferencedDomainName,
  [in, out]       LPDWORD       cchReferencedDomainName,
  [out]           PSID_NAME_USE peUse
);

其中,lpAccountName 指向指定帳戶名稱的以?NULL 結(jié)尾的字符串的指針。這里的本地賬戶名稱可以通過輸入已知的字符串如 "Administrators" 。注:采用 domain_name\user_name 格式的完全限定字符串來確保 LookupAccountName?函數(shù)在所需域中查找?guī)簦疚牟徽劶坝騼?nèi)操作,只談本地操作。

關(guān)于賬戶名稱的獲取,有多種方法,如 GetUserName 可以獲得創(chuàng)建當前調(diào)用線程所在帳戶名稱的字符串,環(huán)境變量函數(shù) GetEnvironmentVariable?通過設(shè)置 lpName 參數(shù)為"USERNAME"可以獲得當前所在帳戶名稱的字符串;使用 Windows Terminal Session API 獲取當前會話對應(yīng)的賬戶名稱字符串,等等。這里通過 WTSQuerySessionInformation 函數(shù)并指定相關(guān)參數(shù)設(shè)置以獲取當前登錄賬戶的名稱:

WTSQuerySessionInformationW(
        WTS_CURRENT_SERVER_HANDLE, 
        WTS_CURRENT_SESSION, 
        WTS_INFO_CLASS::WTSUserName, 
        &userName, 
        &nameSize);

然后將得到的字符串傳遞給?LookupAccountName 函數(shù),獲取對應(yīng)的 SID 。

隨后,調(diào)用?SetNamedSecurityInfo 并設(shè)置?pObjectName,?ObjectType,?SecurityInfo?psidOwner?參數(shù)即可修改目標對象的所有者。

1.2 修改訪問控制對象 (ACE) 信息

本文以在原有DACL表上添加新的對象權(quán)限為例進行講解。有關(guān)于覆蓋、刪除、復(fù)制的方法需要自行調(diào)試。

一種通用的更新方法就是先獲取到原始的DACL表,然后將其與要添加的內(nèi)容合并為一張新的表。最后將新的表更新到文件對應(yīng)的表上。

整個過程我們需要這幾個步驟:

Step1: 調(diào)用 GetNamedSecurityInfo 并設(shè)置 DACL_SECURITY_INFORMATION 類型,獲取舊的DACL表;

Step2: 調(diào)用 BuildExplicitAccessWithName 用于構(gòu)建一個 ACE,包含需要的權(quán)限;

Step3: 調(diào)用 SetEntriesInAcl 合并 ACE 到 舊的DACL,返回合并后的新的 DACL;

Step4: 調(diào)用 SetNamedSecurityInfo 綁定新的 DACL 到文件對象。

一個典型的示例代碼如下,其中 Step2 也可以直接為結(jié)構(gòu)體成員賦值:

DWORD AddAceToObjectsSecurityDescriptor(
    LPTSTR pszObjName,          // name of object
    SE_OBJECT_TYPE ObjectType,  // type of object
    LPWSTR pszTrustee,          // trustee for new ACE
    TRUSTEE_FORM TrusteeForm,   // format of trustee structure
    DWORD dwAccessRights,       // access mask for new ACE
    ACCESS_MODE AccessMode,     // type of ACE
    DWORD dwInheritance         // inheritance flags for new ACE
)
{
    DWORD dwRes = 0;
    PACL pOldDACL = NULL, pNewDACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea = {};

    if (NULL == pszObjName)
        return ERROR_INVALID_PARAMETER;
    printf("|*|:為用戶 %ws 獲取文件:%ws 的訪問權(quán)限。\n", pszTrustee, pszObjName);
    // Get a pointer to the existing DACL.

    dwRes = GetNamedSecurityInfoW(pszObjName, ObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, &pOldDACL, NULL, &pSD);
    if (ERROR_SUCCESS != dwRes) {
        printf("GetNamedSecurityInfo Error %u\n", dwRes);
        goto Cleanup;
    }

    // Initialize an EXPLICIT_ACCESS structure for the new ACE. 

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    //ea.grfAccessPermissions = dwAccessRights;
    //ea.grfAccessMode = AccessMode;
    //ea.grfInheritance = dwInheritance;
    //ea.Trustee.TrusteeForm = TrusteeForm;
    //ea.Trustee.ptstrName = pszTrustee;
    // 生成指定用戶帳戶的訪問控制信息(這里指定賦予全部的訪問權(quán)限)

    BuildExplicitAccessWithNameW(&ea, pszTrustee, dwAccessRights, AccessMode, dwInheritance);
    // Create a new ACL that merges the new ACE
    // into the existing DACL.

    dwRes = SetEntriesInAclW(1, &ea, pOldDACL, &pNewDACL);
    if (ERROR_SUCCESS != dwRes) {
        printf("SetEntriesInAcl Error %u\n", dwRes);
        goto Cleanup;
    }

    // Attach the new ACL as the object's DACL.

    dwRes = SetNamedSecurityInfoW(pszObjName, ObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, pNewDACL, NULL);
    if (ERROR_SUCCESS != dwRes) {
        printf("SetNamedSecurityInfo Error %u\n", dwRes);
        goto Cleanup;
    }
    else {
        printf("成功:已經(jīng)為用戶 %ws 獲取文件:%ws 的訪問權(quán)限。\n", pszTrustee, pszObjName);
        return dwRes;
    }

Cleanup:

    if (pSD != NULL)
        LocalFree((HLOCAL)pSD);
    if (pNewDACL != NULL)
        LocalFree((HLOCAL)pNewDACL);

    std::cout << "|*|:操作失敗! " << std::endl;
    return -1;
}

通過以上方法即可對指定路徑文件進行安全訪問權(quán)限的修改。

二、完整編程代碼

2.1 完整代碼

下面是按照上文思路編寫的簡單實現(xiàn)代碼,需要將編譯好的程序在提升的命令行中執(zhí)行,命令行參數(shù)為 TestFile.exe <文件路徑> 。(編譯環(huán)境:Visual Studio C++)

#include <iostream>
#include <stdio.h>
#include <aclapi.h>
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <aclapi.h>
#include <wtsapi32.h>

#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "Wtsapi32.lib")

#define MAX_NAME 260

BOOL SetPrivilege(
    HANDLE hToken,          // access token handle
    LPCWSTR lpszPrivilege,  // name of privilege to enable/disable
    BOOL bEnablePrivilege   // to enable or disable privilege
)
{
    TOKEN_PRIVILEGES tp;
    LUID luid;

    if (!LookupPrivilegeValueW(
        NULL,            // lookup privilege on local system
        lpszPrivilege,   // privilege to lookup 
        &luid))        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError());
        return FALSE;
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;

    // Enable the privilege or disable all privileges.

    if (!AdjustTokenPrivileges(
        hToken,
        FALSE,
        &tp,
        sizeof(TOKEN_PRIVILEGES),
        (PTOKEN_PRIVILEGES)NULL,
        (PDWORD)NULL))
    {
        printf("AdjustTokenPrivileges error: %u\n", GetLastError());
        return FALSE;
    }

    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)

    {
        printf("The token does not have the specified privilege. \n");
        return FALSE;
    }

    return TRUE;
}

BOOL SeTakeOwnershipToken()
{

    printf("|*|操作:獲取相關(guān)權(quán)限。該特權(quán)可以修改目標文件的 Ownership。\n");
    HANDLE hToken;
    BOOL bRet = OpenProcessToken(
        GetCurrentProcess(),    // 進程句柄(當前進程)
        TOKEN_ALL_ACCESS,    // 全權(quán)訪問令牌
        &hToken    // 返回的參數(shù) 進程令牌句柄 (就是AdjustTokenPrivileges的第一個參數(shù))
    ); // 獲取進程的令牌句柄
    if (bRet != TRUE) {
        printf("獲取令牌句柄失敗!\nPlease wait...\n");
        return FALSE;
    }
    // 提升權(quán)限
    BOOL set_SECURITY = SetPrivilege(hToken, SE_SECURITY_NAME, TRUE);
    if (!set_SECURITY || GetLastError() != ERROR_SUCCESS)
    {
        printf("提升SECURITY權(quán)限失敗 Error: %u\n|*|:操作失敗!\nPlease wait...\n", GetLastError());
        Sleep(5000);
        return FALSE;
    }
    // 提升獲得所有者權(quán)限
    BOOL set_OWNER = SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE);
    if (!set_OWNER || GetLastError() != ERROR_SUCCESS)
    {
        printf("提升TAKE OWNERSHIP權(quán)限失敗 Error: %u\n|*|:操作失敗!\nPlease wait...\n", GetLastError());
        Sleep(5000);
        return FALSE;
    }
    printf("提升權(quán)限成功! \n");
    return TRUE;
}


BOOL ChangeTrusteeViaObjectsSecurity(
    LPTSTR pszObjName,          // name of object
    LPTSTR pszTrustee,          // trustee for new ACE
    SE_OBJECT_TYPE ObjectType,  // type of object. value :SE_FILE_OBJECT, /* 注冊表為:SE_REGISTRY_KEY */
    SECURITY_INFORMATION  SecurityInfo  // Security Operational Information. value:OWNER_SECURITY_INFORMATION

)
{
    DWORD dwRes = 0;
    // LookupAccountName函數(shù)所需要的變量
    wchar_t* userName = nullptr;
    wchar_t sid[MAX_NAME]{ L'\0' };
    DWORD nameSize = 0;

    WTSQuerySessionInformationW(
        WTS_CURRENT_SERVER_HANDLE, 
        WTS_CURRENT_SESSION, 
        WTS_INFO_CLASS::WTSUserName, 
        &userName, 
        &nameSize);

    wchar_t userSID[MAX_NAME]{ L'\0' };
    wchar_t userDomain[MAX_NAME]{ L'\0' };
    DWORD sidSize = sizeof(userSID);
    DWORD signSidSize = sizeof(userSID);
    DWORD domainSize = sizeof(userDomain) / sizeof(WCHAR);


    SID_NAME_USE snu;
    dwRes = LookupAccountNameW(NULL,
        userName,
        userSID,
        &sidSize,
        userDomain,
        &domainSize,
        &snu);
    WTSFreeMemory(userName);
    //獲取用戶名SID
    if (ERROR_SUCCESS != dwRes)// 調(diào)用成功返回值為0
    {
        PSID_IDENTIFIER_AUTHORITY psia = GetSidIdentifierAuthority(userSID);
        signSidSize = swprintf_s(sid, sizeof(sid)/sizeof(wchar_t), L"S-%lu-", SID_REVISION);
        signSidSize = (signSidSize + swprintf_s(sid + wcslen(sid), sizeof(sid), L"%-lu", psia->Value[5]));


        int i = 0;
        int subAuthorities = *GetSidSubAuthorityCount(userSID);


        for (i = 0; i < subAuthorities; i++)
        {
            signSidSize += swprintf_s(sid + signSidSize, sizeof(sid), L"-%lu", *GetSidSubAuthority(userSID, i));
        }
        printf("Account SID: %ws\n", sid);
        // 更改所有者
        if (!SetNamedSecurityInfoW
        (pszObjName,
            ObjectType, /* 注冊表為:SE_REGISTRY_KEY */
            SecurityInfo, /* 更改所有者 */
            &userSID, /* 需要更改所有者的SID */
            NULL, NULL, NULL))
        {
            printf("成功更改所有者! \n");
            return TRUE;
        }
        else {
            printf("Security Info:OWNER_SECURITY_INFORMATION.\nSetNamedSecurityInfo Error %u\nPlease wait...\n", dwRes);
            Sleep(5000);
        }
    }
    else {
        printf("LookupAccountName Error %u\nPlease wait...\n", dwRes);
        Sleep(5000);
    }
    return FALSE;
}


DWORD AddAceToObjectsSecurityDescriptor(
    LPTSTR pszObjName,          // name of object
    SE_OBJECT_TYPE ObjectType,  // type of object
    LPWSTR pszTrustee,          // trustee for new ACE
    TRUSTEE_FORM TrusteeForm,   // format of trustee structure
    DWORD dwAccessRights,       // access mask for new ACE
    ACCESS_MODE AccessMode,     // type of ACE
    DWORD dwInheritance         // inheritance flags for new ACE
)
{
    DWORD dwRes = 0;
    PACL pOldDACL = NULL, pNewDACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea = {};

    if (NULL == pszObjName)
        return ERROR_INVALID_PARAMETER;
    printf("|*|:為用戶 %ws 獲取文件:%ws 的訪問權(quán)限。\n", pszTrustee, pszObjName);
    // Get a pointer to the existing DACL.

    dwRes = GetNamedSecurityInfoW(pszObjName, ObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, &pOldDACL, NULL, &pSD);
    if (ERROR_SUCCESS != dwRes) {
        printf("GetNamedSecurityInfo Error %u\n", dwRes);
        goto Cleanup;
    }

    // Initialize an EXPLICIT_ACCESS structure for the new ACE. 

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    //ea.grfAccessPermissions = dwAccessRights;
    //ea.grfAccessMode = AccessMode;
    //ea.grfInheritance = dwInheritance;
    //ea.Trustee.TrusteeForm = TrusteeForm;
    //ea.Trustee.ptstrName = pszTrustee;
    // 生成指定用戶帳戶的訪問控制信息(這里指定賦予全部的訪問權(quán)限)

    BuildExplicitAccessWithNameW(&ea, pszTrustee, dwAccessRights, AccessMode, dwInheritance);
    // Create a new ACL that merges the new ACE
    // into the existing DACL.

    dwRes = SetEntriesInAclW(1, &ea, pOldDACL, &pNewDACL);
    if (ERROR_SUCCESS != dwRes) {
        printf("SetEntriesInAcl Error %u\n", dwRes);
        goto Cleanup;
    }

    // Attach the new ACL as the object's DACL.

    dwRes = SetNamedSecurityInfoW(pszObjName, ObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, pNewDACL, NULL);
    if (ERROR_SUCCESS != dwRes) {
        printf("SetNamedSecurityInfo Error %u\n", dwRes);
        goto Cleanup;
    }
    else {
        printf("成功:已經(jīng)為用戶 %ws 獲取文件:%ws 的訪問權(quán)限。\n", pszTrustee, pszObjName);
        return dwRes;
    }

Cleanup:

    if (pSD != NULL)
        LocalFree((HLOCAL)pSD);
    if (pNewDACL != NULL)
        LocalFree((HLOCAL)pNewDACL);

    std::cout << "|*|:操作失敗! " << std::endl;
    return -1;
}



int wmain(int argc, wchar_t* argv[])
{
    setlocale(LC_CTYPE, "CHS");//讓wprintf()支持中文
    if (argc != 2)
    {
        std::cout << "Invalid Parameters!" << std::endl;
        return 0;
    }

    wchar_t* path = argv[1];
    wchar_t* pszObjName = path;

    // 獲取當前用戶名
    wchar_t* currentUser = nullptr;
    DWORD dwSize_currentUser = 0;

    WTSQuerySessionInformationW(
        WTS_CURRENT_SERVER_HANDLE, 
        WTS_CURRENT_SESSION,
        WTS_INFO_CLASS::WTSUserName,
        &currentUser,
        &dwSize_currentUser);

    if (!SeTakeOwnershipToken()) {
        std::cout << "|*|:在未獲得SE_TAKE_OWNERSHIP_NAME特權(quán)時,繼續(xù)更改文件所有者可能失敗! " << std::endl;
    }

    // 更改ACL下的安全主體,以獲得ACE控制權(quán)
    if (ChangeTrusteeViaObjectsSecurity(pszObjName,
        currentUser, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION))
    {
        // 覆蓋ACL以獲得完全控制的訪問權(quán)限
        if (AddAceToObjectsSecurityDescriptor(pszObjName,
            SE_FILE_OBJECT,
            currentUser,
            TRUSTEE_IS_OBJECTS_AND_SID,
            GENERIC_ALL,
            GRANT_ACCESS,
            SUB_CONTAINERS_AND_OBJECTS_INHERIT) == -1)
        {
            std::cout << "ACE操作已執(zhí)行。" << std::endl;
        }
    }
    else {
        std::cout << "無法更改ACL下的安全主體,繼續(xù)更改ACE控制權(quán)可能會失敗。" << std::endl;
        // 覆蓋ACL以獲得完全控制的訪問權(quán)限
        if (AddAceToObjectsSecurityDescriptor(pszObjName,
            SE_FILE_OBJECT,
            currentUser,
            TRUSTEE_IS_OBJECTS_AND_SID,
            GENERIC_ALL,
            GRANT_ACCESS,
            SUB_CONTAINERS_AND_OBJECTS_INHERIT) == -1)
        {
            std::cout << "ACE操作已執(zhí)行。" << std::endl;
        }

    }
    std::cout << "所有操作已完成。" << std::endl;
    system("pause");

    return 0;
}

2.2 調(diào)試效果

下圖是在提升的命令提示符中執(zhí)行的效果:

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具
程序執(zhí)行過程

從圖中可見程序執(zhí)行完畢,并且沒有錯誤。

下圖展示的是程序執(zhí)行完畢后,目標對象的屬性變化:

windows 目錄權(quán)限,C++學(xué)習(xí)筆記,Windows 基礎(chǔ)編程,windows,c++,測試工具
目標被修改后的安全屬性

從圖中可以看出目標對象的所有者發(fā)生變化,且為當前登陸賬戶添加了完全控制權(quán)限。

三、利用Windows工具實現(xiàn)修改安全控制對象權(quán)限

3.1 通過 ICacls 命令實現(xiàn)修改訪問控制權(quán)限

? ?? ?icacls

? ? ? Intergrity Control Access Control List: 完整性權(quán)限控制列表
? ? ? Windows系統(tǒng)下控制文件及文件夾的訪問權(quán)限的命令行指令,相當于Linux中的chmod
原命令cacls已經(jīng)被廢棄。

? ? ? 這一篇博客園作者整理的命令詳細信息比較全面清晰:Cacls和ICacls - 儺舞 - 博客園 (cnblogs.com)

3.2 通過 powershell / 注冊表 實現(xiàn)修改訪問控制權(quán)限

就不詳細列出了,這里給出一篇知乎,整理的也比較全面:滲透技巧——Windows下的Access Control List - 知乎


本文為原創(chuàng)文章,轉(zhuǎn)載請注明出處。(修改于:2023/9/19)

本人博客:漣幽516-CSDN博客漣幽516擅長C++學(xué)習(xí)筆記,Win10動態(tài)壁紙開發(fā),Windows上的編程,等方面的知識,漣幽516關(guān)注python,c++,c語言,系統(tǒng)安全領(lǐng)域.https://blog.csdn.net/qq_59075481文章來源地址http://www.zghlxwxcb.cn/news/detail-754118.html

到了這里,關(guān)于修改 Windows 文件訪問權(quán)限的多種方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Linux - samba實現(xiàn)Linux與windows文件共享——共享文件夾目標文件訪問權(quán)限被拒絕解決方案(超詳細,看不懂你怪我)

    Linux - samba實現(xiàn)Linux與windows文件共享——共享文件夾目標文件訪問權(quán)限被拒絕解決方案(超詳細,看不懂你怪我)

    ????????最近做一個項目,需要用到linux上的內(nèi)容,于是需要將linux與window共享文件,上網(wǎng)查閱了一些資料,做完了之后,總結(jié)一下自己遇到的問題,以及自己是咋解決的,供大家參考。 這里其實只需要一步就可以操作出來,現(xiàn)在我們看一下: 一、打開虛擬機,選擇設(shè)置

    2024年02月04日
    瀏覽(27)
  • Linux中如何修改文件或目錄的權(quán)限?

    ? 在Linux系統(tǒng)中,文件權(quán)限是非常重要的一個概念,它能夠決定誰可以訪問文件,以及可以執(zhí)行哪些操作,正確地設(shè)置文件權(quán)限可以確保系統(tǒng)的安全性和穩(wěn)定性,那么如何設(shè)置文件權(quán)限呢?以下是詳細的內(nèi)容: 在 Linux 系統(tǒng)中,可以使用 `chmod` 命令來修改文件或目錄的權(quán)限。

    2024年02月07日
    瀏覽(89)
  • 【ubuntu】修改文件夾(目錄)及其內(nèi)部文件的權(quán)限

    目錄 修改文件夾(目錄)及其內(nèi)部文件的權(quán)限 在 Ubuntu 中,你可以使用 chmod 命令來修改文件夾(目錄)及其內(nèi)部文件的權(quán)限。下面是一個將文件夾及其內(nèi)部所有文件的權(quán)限都修改為相同權(quán)限的示例命令: 其中, permission 是權(quán)限設(shè)置,表示所需的權(quán)限,例如 755 或 777 , fold

    2024年02月03日
    瀏覽(25)
  • UOS共享文件夾給windows系統(tǒng)訪問的方法

    UOS共享文件夾給windows系統(tǒng)訪問的方法

    1、前提條件:UOS主機和windows主機處于同一個局域網(wǎng)內(nèi) 2、在UOS主機中選擇需要共享的文件夾點擊右鍵,把共享文件夾勾選上,可以允許匿名訪問(即不需要輸入任何賬號密碼),選擇完成后退出。 3、在UOS系統(tǒng)上右鍵點擊打開終端,輸入ifconfig,查看當前UOS系統(tǒng)的IP地址。 4、

    2024年02月14日
    瀏覽(136)
  • Linux Tip 03 文件類型屬性、權(quán)限管理、拓展名、主要目錄介紹、文件的相關(guān)操作、文件內(nèi)容查看、文件的修改、文件和目錄的權(quán)限、文件的查找

    一、用戶的存儲 在Linux系統(tǒng)中 系統(tǒng)上所有的賬號和一般身份的用戶以及root的相關(guān)信息都存在/etc/passwd這個文件中 個人的密碼記錄在/etc/shadow中 所有的組名都記錄在/etc/group中 二、文件類型和屬性 三、文件和目錄的權(quán)限管理 四、文件的類型 五、文件的拓展名 文件長度的限制

    2023年04月10日
    瀏覽(96)
  • windows 環(huán)境修改 Docker 存儲目錄

    windows 環(huán)境修改存儲目錄 docker 安裝時不提供指定安裝路徑和數(shù)據(jù)存儲路徑的選項,且默認是安裝在C盤的。C盤比較小的,等docker運行久了,一大堆的東西放在上面容易導(dǎo)致磁盤爆掉。所以安裝前可以做些準備,讓安裝的實際路徑不在C盤,當然安裝好的的,也可以卸載了重新來

    2024年02月16日
    瀏覽(20)
  • 頭歌--第1關(guān):Linux文件權(quán)限修改(Linux文件/目錄高級管理一)

    頭歌--第1關(guān):Linux文件權(quán)限修改(Linux文件/目錄高級管理一)

    任務(wù)描述 假設(shè)系統(tǒng)中存在一個文件 File ,修改該文件的權(quán)限,根據(jù)實際需求添加/刪除該文件讀、寫、執(zhí)行權(quán)限,通過本關(guān)的學(xué)習(xí),我們學(xué)會如何讓一個文件允許哪些用戶訪問或禁止哪些用戶訪問。 本關(guān)任務(wù):學(xué)會如何修改文件的權(quán)限。 相關(guān)知識 Linux 系統(tǒng)中的每個文件都有

    2024年02月05日
    瀏覽(188)
  • windows10/11 修改docker鏡像存儲目錄

    windows10/11 修改docker鏡像存儲目錄 docker默認pull的鏡像在c盤,隨著鏡像的增加,C 盤很快就滿了,直接影響不少程序的正常使用,使用下面的操作可以將鏡像路徑移動到其他位置 查看docker的狀態(tài) 確保docker為關(guān)閉狀態(tài),如果state下為running時,直接退出docker 關(guān)閉所有正在運行的實例

    2024年02月13日
    瀏覽(51)
  • windows 訪問SAMBA提示沒有權(quán)限

    1 檢查配置文件 /etc/samba/smb.conf 是否有問題 2 開放共享目錄權(quán)限 3 確保linux下防火墻關(guān)閉 4 確保setlinux關(guān)閉 臨時關(guān)閉 徹底禁用 在 /etc/sysconfig/selinux 或者 /etc/grub.conf 中添加

    2024年02月02日
    瀏覽(16)
  • 【W(wǎng)indows】你不能訪問此共享文件夾,因為你的組織安全策略...解決方法

    【W(wǎng)indows】你不能訪問此共享文件夾,因為你的組織安全策略...解決方法

    ?Win+R鍵打開運行窗口,輸入gpedit.msc進入本地組策略編輯器。 找到計算機配置,然后點擊管理模板,找到網(wǎng)絡(luò),然后點擊lanman工作站,將右側(cè)窗口中的啟用不安全的來吧登錄開啟就解決了 設(shè)置為已啟用,應(yīng)用后確定,就可以正常訪問了 然后我們繼續(xù)訪問共享文件夾,發(fā)現(xiàn)就

    2024年02月01日
    瀏覽(90)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包