GetCurrentProcessID           得到当前进程的ID

OpenProcessToken         得到进程的令牌句柄

LookupPrivilegeValue         查询进程的权限

AdjustTokenPrivileges         判断令牌权限

要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关的访问权的OpenProcess操作,只要当前进程具有SeDeDebug权限就可以了。要是一个用户是Administrator或是被给予了相应的权限,就可以具有该权限。可是,就算我们用Administrator帐号对一个系统安全进程执行OpenProcess(PROCESS_ALL_ACCESS,FALSE,         dwProcessID)还是会遇到“访问拒绝”的错误。什么原因呢?原来在默认的情况下进程的一些访问权限是没有被使能(Enabled)的,所以我们要做的首先是使能这些权限。与此相关的一些API函数有OpenProcessToken、LookupPrivilegevalue、AdjustTokenPrivileges。我们要修改一个进程的访问令牌,首先要获得进程访问令牌的句柄,这可以通过OpenProcessToken得到,函数的原型如下:

BOOL     OpenProcessToken(

HANDLE     ProcessHandle,      //要修改访问权限的进程句柄

DWORD     DesiredAccess,       //指定你要进行的操作类型

PHANDLE     TokenHandle        //返回的访问令牌指针

);

第一参数是要修改访问权限的进程句柄;

第三个参数就是返回的访问令牌指针;

第二个参数指定你要进行的操作类型,

如要修改令牌我们要指定第二个参数为TOKEN_ADJUST_PRIVILEGES(其它一些参数可参考Platform SDK)。

通过这个函数我们就可以得到当前进程的访问令牌的句柄(指定函数的第一个参数为GetCurrentProcess()就可以了)。

接着我们可以调用AdjustTokenPrivileges对这个访问令牌进行修改。

AdjustTokenPrivileges的原型如下:

BOOL AdjustTokenPrivileges(

HANDLETokenHandle,         // 访问令牌的句柄

BOOLDisableAllPrivileges,   // 决定是进行权限修改还是除能(Disable)所有权限

PTOKEN_PRIVILEGESNewState,   //{指明要修改的权限,是一个指向TOKEN_PRIVILEGES结构的指针,该结构包含一个数组,数据组的每个项指明了权限的类型和要进行的操作;}

DWORD BufferLength,//结构PreviousState的长度,如果PreviousState为空,该参数应为NULL

PTOKEN_PRIVILEGES PreviousState,  //指向TOKEN_PRIVILEGES结构的指针,存放修改前的访问权限的信息

PDWORDReturnLength      //实际PreviousState结构返回的大小

);

第一个参数是访问令牌的句柄;

第二个参数决定是进行权限修改还是除能(Disable)所有权限;

第三个参数指明要修改的权限,是一个指向TOKEN_PRIVILEGES结构的指针,该结构包含一个数组,数据组的每个项指明了权限的类型和要进行的操作;

第四个参数是结构PreviousState的长度,如果PreviousState为空,该参数应为NULL;

第五个参数也是一个指向TOKEN_PRIVILEGES结构的指针,存放修改前的访问权限的信息,可空;

最后一个参数为实际PreviousState结构返回的大小。

在使用这个函数前再看一下TOKEN_PRIVILEGES这个结构,其声明如下:

typedef    struct TOKEN_PRIVILEGES   {

DWORD                       PrivilegeCount;

LUID_AND_ATTRIBUTES         Privileges[];

}TOKEN_PRIVILEGES,         *PTOKEN_PRIVILEGES;

PrivilegeCount指的数组原素的个数,接着是一个LUID_AND_ATTRIBUTES类型的数组,

再来看一下LUID_AND_ATTRIBUTES这个结构的内容,声明如下:

typedef struct  LUID_AND_ATTRIBUTES {

LUID             Luid;

DWORD            Attributes;

}LUID_AND_ATTRIBUTES,    *PLUID_AND_ATTRIBUTES

第二个参数就指明了我们要进行的操作类型,有三个可选项:

SE_PRIVILEGE_ENABLED

SE_PRIVILEGE_ENABLED_BY_DEFAULT

SE_PRIVILEGE_USED_FOR_ACCESS

要使能一个权限就指定Attributes为SE_PRIVILEGE_ENABLED。

第一个参数就是指权限的类型,是一个LUID的值,LUID就是指locally         unique         identifier,我想GUID大家是比较熟悉的,和GUID的要求保证全局唯一不同,LUID只要保证局部唯一,就是指在系统的每一次运行期间保证是唯一的就可以了。

另外和GUID相同的一点,LUID也是一个64位的值,相信大家都看过GUID那一大串的值,我们要怎么样才能知道一个权限对应的LUID值是多少呢?这就要用到另外一个API函数LookupPrivilegevalue,其原形如下:

BOOL LookupPrivilegeValue(

LPCTSTRlpSystemName,    //系统的名称,若为空,则在当前的sysytem查找。

LPCTSTRlpName,           // 指明了权限的名称,如“SeDebugPrivilege”。

PLUIDlpLuid             // 返回LUID的指针

);

第一个参数是系统的名称,如果是本地系统只要指明为NULL就可以了,

第三个参数就是返回LUID的指针,

第二个参数就是指明了权限的名称,如“SeDebugPrivilege”。

在Winnt.h中还定义了一些权限名称的宏,如:

#define         SE_BACKUP_NAME                       TEXT("SeBackupPrivilege")

#define         SE_RESTORE_NAME                    TEXT("SeRestorePrivilege")

#define         SE_SHUTDOWN_NAME                 TEXT("SeShutdownPrivilege")

#define         SE_DEBUG_NAME                         TEXT("SeDebugPrivilege")

这样通过这三个函数的调用,我们就可以用OpenProcess(PROCESS_ALL_ACCESS,FALSE,   dwProcessID)来打获得任意进程的句柄,并且指定了所有的访问权。

GetCurrentProcessID、OpenProcessToken、LookupPrivilegeValue相关推荐

  1. GetCurrentProcessID、OpenProcessToken、LookupPrivilegeValue、AdjustTokenPrivileges

    GetCurrentProcessID            得到当前进程的ID OpenProcessToken               得到进程的令牌句柄 LookupPrivilegeVal ...

  2. GetCurrentProcessID、OpenProcessToken

    GetCurrentProcessID        得到当前进程的ID    OpenProcessToken           得到进程的令牌句柄 LookupPrivilegeValue    ...

  3. C# 实现系统关机、注销、重启、休眠、挂起

    C# 实现系统关机.注销.重启.休眠.挂起 原文:C# 实现系统关机.注销.重启.休眠.挂起 核心代码如下: using System; using System.Text; using System ...

  4. 获取进程全路径方法(支持xp、win7、win10系统)

    获取进程全路径方法(支持xp.win7.win10系统) 获取进程的全路径的函数包括GetModuleFileNameEx.GetProcessImageFileName.QueryFullProce ...

  5. 使用第三方SDK(如微信、qq、快看、头条等),调用接口405 Method Not Allowed

    使用第三方SDK(如微信.qq.快看.头条等),调用接口405 Method Not Allowed 错误描述:postman请求正常,但客户端调用后接口没有反应,但返回了405错误. 解决方法:第三 ...

  6. 什么是原码、反码、补码?什么是按位与?范围数字按位与!

    前言:学过计算机基础的大家都知道什么是二进制,什么是"与"运算,这里先给大家复习一下. 举一个简单的例子: 5的二进制表示是0101(补齐4位) 7的二进制表示是0111(补齐4位 ...

  7. 大数据中用到的新的数据类型bigint、decimal、smallint、tinyint

    在对比oracle数据库和大数据库的时候,发现了几个用以存放数字的新的类型bigint.decimal.smallint.tinyint,为了对比之间的不同,我进行了统计 bigint 可以精确的表示 ...

  8. 【golang程序包推荐分享】go-ini、viper、godoc

    [golang程序包推荐&分享]go-ini.viper.godoc 一.go-ini 1.程序包简介 2.下载安装 3.简单使用[截取自官网] 二.viper 1.程序包简介 2.下载安装 ...

  9. Redis 笔记(16)— info 指令和命令行工具(查看内存、状态、客户端连接数、监控服务器、扫描大key、采样服务器、执行批量命令等)

    Info 命令返回关于 Redis 服务器的各种信息和统计数值.通过给定可选的参数 section ,可以让命令只返回某一部分的信息. 1. 显示模块 server : 一般 Redis 服务器信息, ...

最新文章

  1. 虚拟主播上线:多模态将改变人机交互的未来
  2. cmd文件打开闪退_批处理闪退、运行中断等问题的处理
  3. linux内核提供的内存操作函数
  4. sqlerror.java.1055,at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
  5. Debug Assert Failed 怎么办?
  6. Windows进程与线程学习笔记(四)—— 等待链表调度链表
  7. 图书《图像并行处理技术》简介
  8. 新疆农业大学计算机科学与技术专业怎么样,新疆农业大学计算机科学与技术专业2016年在新疆理科高考录取最低分数线...
  9. Oracle与MySQL使用区别
  10. Linux使用FlowScan
  11. Linux命令之sudo
  12. python入门:基础,列表、元组、字典及集合类型
  13. 在线文件管理系统 下载地址
  14. Python-os.mkdir() 方法
  15. matlab 相位谱_电气信息类专业课程之matlab系统仿真 第九章 提高仿真能力需要案例(1)...
  16. tl494cn逆变器电路图_用TL494制作的逆变电源
  17. Android技术知识点:如何添加字体资源
  18. quasar使用keep alive警告 Component inside <Transition> renders non-element root node
  19. Pytorch.Dataloader 详细深度解读和微修改源代码心得
  20. Mockplus的组件(弹出菜单)的简单使用方法。

热门文章

  1. 突然关机导致git文件受损,如何处理
  2. 技术负责人的三种角色
  3. SpringMVC 项目中 Quartz 定时任务的设置纪要
  4. cronexpression 详解
  5. C语言读写配置文件--转载
  6. 数组的选择--固定大小数组模板array存在的意义!
  7. 如何获得瑞星网络安全工程师
  8. 部队人员官兵请假管理系统
  9. 解决xcode升级插件失效
  10. angular ngClick 阻止冒泡和默认行为