• <转载>提升程序的特权(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;    
           }    
    }
  • 相关阅读:
    jQuery 选择器
    DOM 文档对象模型+倒计时
    javascript简单写出国际象棋棋盘
    javascript循环语句及函数
    JAVASCRIPT基础
    用纯CSS做的图片切换
    项目练习总结
    用CSS做的简单弹窗
    CSS布局元素
    jQuery属性/CSS使用例子
  • 原文地址:https://www.cnblogs.com/ChangTan/p/3279490.html
Copyright © 2020-2023  润新知