zoukankan      html  css  js  c++  java
  • <转载>提升程序的特权(AdjustTokenPrivileges)

    首先列出需要的函数

    1.OpenProcessToken

    2.AdjustTokenPrivileges

    3. LookupPrivilegeValue

    --------------------------------------------------------------

    首先需要获取进程的令牌句柄

    OpenProcessToken的原型.

    1
    2
    3
    4
    5
    BOOL WINAPI OpenProcessToken( 
      __in          HANDLE ProcessHandle, 
      __in          DWORD DesiredAccess, 
      __out         PHANDLE TokenHandle 
    );

    第一个参数 进程句柄(当前进程为GetCurrentProcess()为参数)

    第二个参数 访问令牌特权

    第三个参数 返回的参数 就是AdjustTokenPrivileges的第一个参数

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    HANDLE hToken; 
         
    bool retn = OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken); 
         
    if(!retn) 
         
         
          return//获取令牌失败。。 
         
    }

    注:第二个参数 是令牌的权限,这个权限是要有修改权限的特权,意思就是要把你程序的权限修改得更高。

    关于其他权限可以查MSDN..            所有权限可以写TOKEN_ALL_ACCESS ,去查看一个令牌特权可以用TOKEN_QUERY

    这个下面函数有写。

    --------------------------------------------------------------

    首先先说一下使用AdjustTokenPrivileges需要的。

    在这个函数中的第3和第5个参数中需要用到一个TOKEN_PRIVILEGES的结构体,在这个结构体中还有个LUID_AND_ATTRIBUTES结构体

    TOKEN_PRIVILEGES结构体

    1
    2
    3
    4
    5
    6
    typedef struct _TOKEN_PRIVILEGES 
         
           DWORD PrivilegeCount;  
           LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; 
    }TOKEN_PRIVILEGES;

    下面的参数是个特权数组。

    上面的参数是要修改的特权数目

    LUID_AND_ATTRIBUTES 结构体

    1
    2
    3
    4
    5
    typedef struct _LUID_AND_ATTRIBUTES  
    {   
           LUID Luid;   
           DWORD Attributes; 
    } LUID_AND_ATTRIBUTES;

    第一个参数是Luid是一个标志,不同的Luid代表着各种不同的特权类型

    第二个参数是要这个特权干嘛,如启用这个特权(SE_PRIVILEGE_ENABLED)

    这里的Luid的值需要用LookupPrivilegeValue来获取。

    ------------------------------------------------------------------------------------------

     LookupPrivilegeValue的原型

    1
    2
    3
    4
    5
    BOOL WINAPI LookupPrivilegeValue( 
      __in_opt      LPCTSTR lpSystemName, 
      __in          LPCTSTR lpName, 
      __out         PLUID lpLuid 
    );

    第一个参数是系统的名字,如果为NULL,就是本地名字(这里就填NULL)

    第二个参数是特权的名字,要查看详细特权,看我的博客里翻译分类里的 包含特权 的文章。(在这里写SE_DEBUG_NAME)

    第三个参数就可以通过指针返回一个LUID类型的Luid的标识了。 通过这个值就可以填入刚才的结构体里了。

    ----------------------------------------------------------------------------------------------------------------------------

    最后就可以介绍AdjustTokenPrivilege就应该没什么问题了。

    它的原型为:

    1
    2
    3
    4
    5
    6
    7
    8
    BOOL WINAPI AdjustTokenPrivileges( 
      __in          HANDLE TokenHandle, 
      __in          BOOL DisableAllPrivileges, 
      __in_opt      PTOKEN_PRIVILEGES NewState, 
      __in          DWORD BufferLength, 
      __out_opt     PTOKEN_PRIVILEGES PreviousState, 
      __out_opt     PDWORD ReturnLength 
    );

    第一个参数为OpenProcessToken第三个指针参数传出的句柄值

    第二个参数为是否禁用所有所有的特权(这里填false)

    第三个参数为新的TOKEN_PRIVILEGES的特权结构体指针

    第四个参数是上面结构体的字节长度(sizeof)

    第五个参数是 接受原先的特权的结构体

    第六个参数也是这个结构体的字节长度的指针

    在这里后两个参数不用管。

    详细看我的博客翻客相关说明

    MSDN里说

    如果第五个参数不是NULL,在OpenProcessToken加特权时除了需要指定TOKEN_ADJUST_PRIVILEGES还必须指定TOKEN_QUERY

    如果第五个参数是NULL,你不接受原先的结构体(第六个当然也是NULL), 就不用再指定附加的TOKEN_QUERY的特权了。

    还要注意:

     就算这个函数返回为真,还要调用GetLastError()来检验是否完全成功。

    如果返回ERROR_SUCCESS就代表修改非常成功 。。。其他的返回值 查我博客。 

    这个非常重要!!

    还有就是Vista和Window7 里 一定要开管理员模式 才能获取成功

    ----------------------------------------------------

    完整的例子

    可以直接复制到VC 6.0里

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <windows.h>    
    #include <iostream>    
    using namespace std;    
          
          
    void main()    
    {    
            BOOL retn;    
            HANDLE hToken;    
            retn = OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken);    
            if(retn != TRUE)    
            {    
                        cout<<"获取令牌句柄失败!"<<endl;    
                        return;    
            }    
            
            TOKEN_PRIVILEGES tp; //新特权结构体    
            LUID Luid;    
            retn = LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&Luid);    
          
            if(retn != TRUE)    
            {    
                        cout<<"获取Luid失败"<<endl;    
                        return;    
            }    
                    //给TP和TP里的LUID结构体赋值    
            tp.PrivilegeCount = 1;    
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;    
            tp.Privileges[0].Luid = Luid;    
               
            AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);    
            if(GetLastError() != ERROR_SUCCESS)    
            {    
                        cout<<"修改特权不完全或失败!"<<endl;    
            }    
           else  
           {    
                        cout<<"修改成功!"<<endl;    
           }    
    }
  • 相关阅读:
    hdu 1269 迷宫城堡 (并查集)
    hdu 1272 小希的迷宫 (深搜)
    hdu 1026 Ignatius and the Princess I (深搜)
    hdu 1099 Lottery
    hdu 1068 Girls and Boys (二分匹配)
    几个基础数位DP(hdu 2089,hdu 3555,uestc 1307 windy 数)
    hdu 1072 Nightmare (广搜)
    hdu 1398 Square Coins (母函数)
    hdu 1253 胜利大逃亡 (深搜)
    hdu 1115 Lifting the Stone (求重心)
  • 原文地址:https://www.cnblogs.com/ChangTan/p/3279490.html
Copyright © 2011-2022 走看看