• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            微塵--KeepMoving

            為了忘卻的記憶
            posts - 3, comments - 2, trackbacks - 0, articles - 13
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            GetCurrentProcessID 得到當(dāng)前進(jìn)程的ID OpenProcessToken 得到進(jìn)程的令牌句柄LookupPrivilegeValue 查詢進(jìn)程的權(quán)限 AdjustTokenPrivileges 判斷令牌權(quán)限

            要對一個(gè)任意進(jìn)程(包括系統(tǒng)安全進(jìn)程和服務(wù)進(jìn)程)進(jìn)行指定了寫相關(guān)的訪問權(quán)的OpenProcess操作,只要當(dāng)前進(jìn)程具有SeDeDebug權(quán)限就可以了。要是一個(gè)用戶是Administrator或是被給予了相應(yīng)的權(quán)限,就可以具有該權(quán)限。可是,就算我們用Administrator帳號對一個(gè)系統(tǒng)安全進(jìn)程執(zhí)行OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwProcessID)還是會(huì)遇到“訪問拒絕”的錯(cuò)誤。什么原因呢?原來在默認(rèn)的情況下進(jìn)程的一些訪問權(quán)限是沒有被使能(Enabled)的,所以我們要做的首先是使能這些權(quán)限。與此相關(guān)的一些API函數(shù)有OpenProcessToken、LookupPrivilegevalue、AdjustTokenPrivileges。我們要修改一個(gè)進(jìn)程的訪問令牌,首先要獲得進(jìn)程訪問令牌的句柄,這可以通過OpenProcessToken得到,函數(shù)的原型如下:

            BOOL OpenProcessToken(
            HANDLE ProcessHandle,
            DWORD DesiredAccess,
            PHANDLE TokenHandle
            );
            第一參數(shù)是要修改訪問權(quán)限的進(jìn)程句柄;第三個(gè)參數(shù)就是返回的訪問令牌指針;第二個(gè)參數(shù)指定你要進(jìn)行的操作類型,如要修改令牌我們要指定第二個(gè)參數(shù)為TOKEN_ADJUST_PRIVILEGES(其它一些參數(shù)可參考Platform SDK)。通過這個(gè)函數(shù)我們就可以得到當(dāng)前進(jìn)程的訪問令牌的句柄(指定函數(shù)的第一個(gè)參數(shù)為GetCurrentProcess()就可以了)。接著我們可以調(diào)用AdjustTokenPrivileges對這個(gè)訪問令牌進(jìn)行修改。AdjustTokenPrivileges的原型如下:
            BOOL AdjustTokenPrivileges(
            HANDLE TokenHandle, // handle to token
            BOOL DisableAllPrivileges, // disabling option
            PTOKEN_PRIVILEGES NewState, // privilege information
            DWORD BufferLength, // size of buffer
            PTOKEN_PRIVILEGES PreviousState, // original state buffer
            PDWORD ReturnLength // required buffer size
            );
            第一個(gè)參數(shù)是訪問令牌的句柄;第二個(gè)參數(shù)決定是進(jìn)行權(quán)限修改還是除能(Disable)所有權(quán)限;第三個(gè)參數(shù)指明要修改的權(quán)限,是一個(gè)指向TOKEN_PRIVILEGES結(jié)構(gòu)的指針,該結(jié)構(gòu)包含一個(gè)數(shù)組,數(shù)據(jù)組的每個(gè)項(xiàng)指明了權(quán)限的類型和要進(jìn)行的操作; 第四個(gè)參數(shù)是結(jié)構(gòu)PreviousState的長度,如果PreviousState為空,該參數(shù)應(yīng)為NULL;第五個(gè)參數(shù)也是一個(gè)指向TOKEN_PRIVILEGES結(jié)構(gòu)的指針,存放修改前的訪問權(quán)限的信息,可空;最后一個(gè)參數(shù)為實(shí)際PreviousState結(jié)構(gòu)返回的大小。在使用這個(gè)函數(shù)前再看一下TOKEN_PRIVILEGES這個(gè)結(jié)構(gòu),其聲明如下:

            typedef struct _TOKEN_PRIVILEGES {
            DWORD PrivilegeCount;
            LUID_AND_ATTRIBUTES Privileges[];
            } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
            PrivilegeCount指的數(shù)組原素的個(gè)數(shù),接著是一個(gè)LUID_AND_ATTRIBUTES類型的數(shù)組,再來看一下LUID_AND_ATTRIBUTES這個(gè)結(jié)構(gòu)的內(nèi)容,聲明如下:

            typedef struct _LUID_AND_ATTRIBUTES {
            LUID Luid;
            DWORD Attributes;
            } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES

            第二個(gè)參數(shù)就指明了我們要進(jìn)行的操作類型,有三個(gè)可選項(xiàng): SE_PRIVILEGE_ENABLED、SE_PRIVILEGE_ENABLED_BY_DEFAULT、SE_PRIVILEGE_USED_FOR_ACCESS。要使能一個(gè)權(quán)限就指定Attributes為SE_PRIVILEGE_ENABLED。第一個(gè)參數(shù)就是指權(quán)限的類型,是一個(gè)LUID的值,LUID就是指locally unique identifier,我想GUID大家是比較熟悉的,和GUID的要求保證全局唯一不同,LUID只要保證局部唯一,就是指在系統(tǒng)的每一次運(yùn)行期間保證是唯一的就可以了。另外和GUID相同的一點(diǎn),LUID也是一個(gè)64位的值,相信大家都看過GUID那一大串的值,我們要怎么樣才能知道一個(gè)權(quán)限對應(yīng)的LUID值是多少呢?這就要用到另外一個(gè)API函數(shù)LookupPrivilegevalue,其原形如下:

            BOOL LookupPrivilegevalue(
            LPCTSTR lpSystemName, // system name
            LPCTSTR lpName, // privilege name
            PLUID lpLuid // locally unique identifier
            );
            第一個(gè)參數(shù)是系統(tǒng)的名稱,如果是本地系統(tǒng)只要指明為NULL就可以了,第三個(gè)參數(shù)就是返回LUID的指針,第二個(gè)參數(shù)就是指明了權(quán)限的名稱,如“SeDebugPrivilege”。在Winnt.h中還定義了一些權(quán)限名稱的宏,如:

            #define SE_BACKUP_NAME TEXT("SeBackupPrivilege")

            #define SE_RESTORE_NAME TEXT("SeRestorePrivilege")

            #define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")

            #define SE_DEBUG_NAME TEXT("SeDebugPrivilege")

            這樣通過這三個(gè)函數(shù)的調(diào)用,我們就可以用OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwProcessID)來打獲得任意進(jìn)程的句柄,并且指定了所有的訪問權(quán)。

            ==微塵附加:完整源代碼, 出自Windows核心編程
            BOOL EnableDebugPrivilege(BOOL bEnable)
            {
                  //Enabling the debug privilege allows the application to see
                  //information about service application
                 BOOL fOK = FALSE;     //Assume function fails
                 HANDLE hToken;
                 //Try to open this process's acess token
                 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
                {
                     //Attempt to modify the "Debug" privilege
                     TOKEN_PRIVILEGES tp;
                     tp.PrivilegeCount = 1;
                     LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
                     tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
                    AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
                    fOk  = (GetLastError() ==  ERROR_SUCESS);
                    CloseHandle(hToken);
               }
               return fOk;
            }
                }
            91久久精品视频| 久久午夜福利无码1000合集| 久久福利片| 青青久久精品国产免费看 | 久久久精品国产免大香伊| 香港aa三级久久三级| 日韩一区二区久久久久久| 久久99精品国产一区二区三区| 99精品久久久久久久婷婷| 午夜精品久久久久成人| 久久精品国产亚洲AV忘忧草18| 精品久久久久久久久久中文字幕| 久久久亚洲AV波多野结衣| 日本精品久久久久久久久免费| 一级做a爰片久久毛片免费陪| 久久久久久狠狠丁香| 国产偷久久久精品专区| 久久久久久国产a免费观看不卡| 国内精品伊人久久久久影院对白 | 久久精品国产AV一区二区三区| 久久久久国产日韩精品网站| 亚洲v国产v天堂a无码久久| 潮喷大喷水系列无码久久精品| 久久AAAA片一区二区| 精品久久久久久中文字幕人妻最新| 无码伊人66久久大杳蕉网站谷歌| 国产精品岛国久久久久| 无码AV波多野结衣久久| 久久综合久久性久99毛片| 久久久91人妻无码精品蜜桃HD| AV无码久久久久不卡蜜桃| 国产成人精品白浆久久69| 99久久国产综合精品麻豆| jizzjizz国产精品久久| 久久青青草原亚洲av无码| 亚洲国产精品嫩草影院久久| 久久久久亚洲精品天堂久久久久久| 嫩草影院久久99| 国产精品美女久久久| 亚洲伊人久久大香线蕉苏妲己| 国产精品久久久久久搜索|