函数RtlAdjustPrivliege封装在NtDll.dll中(在所有DLL加载之前加载),被微软严格保密,就是说你在MSDN上查不到关于他的任何信息。

先来看看这个函数的定义(Winehq给出):
NTSTATUS RtlAdjustPrivilege
(
ULONG    Privilege,
BOOLEAN Enable,
BOOLEAN CurrentThread,
PBOOLEAN Enabled
)

参数的含义:
Privilege [In] Privilege index tochange.                        
// 所需要的权限名称,可以到MSDN查找关于ProcessToken & Privilege内容可以查到

Enable [In] If TRUE, then enable the privilege otherwisedisable.
// 如果为True 就是打开相应权限,如果为False 则是关闭相应权限

CurrentThread [In] If TRUE, then enable in callingthread, otherwise process.
// 如果为True 则仅提升当前线程权限,否则提升整个进程的权限

Enabled [Out] Whether privilege was previously enabled ordisabled.
// 输出原来相应权限的状态(打开 | 关闭)

很多人大概没有听说过他的大名,但是相信有很多人见过进程提权的过程
拷一段我写的提权上来吧

BOOL ImproveProcPriv()
{
    HANDLE token;
    //提升权限
    if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&token))
    {
        MessageBox(NULL,"打开进程令牌失败...","错误",MB_ICONSTOP);
        returnFALSE;
    }
    TOKEN_PRIVILEGES tkp;
    tkp.PrivilegeCount = 1;
    ::LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if(!AdjustTokenPrivileges(token,FALSE,&tkp,sizeof(tkp),NULL,NULL))
    {
        MessageBox(NULL,"调整令牌权限失败...","错误",MB_ICONSTOP);
        returnFALSE;
    }
    CloseHandle(token);
    return TRUE;
}

看看吧,这个提权快要累死了...

但是 如果有这个函数就不一样了,你可以只用一个函数就实现这个功能,甚至功能远多于上面的代码...

通过恰当的IDE设置和必要的Defination,上面这个函数的功能你完全可以通过一行代码来实现。

RtlAdjustPrivilege(SE_DEBUG_NAME,1,0,NULL);

正文:

下面我们看一下这个函数是怎么运行的,顺便学习下强大的IDA
IDA 载入ntdll.dll (我这里载入的是 WinDBG自动下载的 Symbol里面的英文版本 可能不同的Windows版本略有不同)

先把函数的原型给输入IDA 方便一下阅读,然后开始阅读汇编代码了(党和国家考验我们的时候到了)。
看看Graph View 真的是很牛啊...
看看函数最开头...

mov     edi, edi       ; 这句话是废指令
push    ebp
mov     ebp, esp
sub     esp, 30h       ; 48个字节的子过程域Auto变量
cmp     [ebp+CurrentThread], 1 ; 判断CurrentThread参数是否被指定为1
mov     eax, dword_7C97B0C8
mov     [ebp+var_4], eax
mov     eax, [ebp+Enabled]
mov     [ebp+IsEnabled], eax ; BOOL *IsEnabled = Enabled;
lea     eax, [ebp+var_28]
push    eax
jz      loc_7C93378B

判断是调整进程权限还是线程权限,
CurrentThread == TRUE
push    0
push   28h             ;TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
push    0FFFFFFFEh      ;GetCurrentThread()
call    ZwOpenThreadToken
jmp     loc_7C929A7A

CurrentThread == FALSE
push   28h             ;TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
push    0FFFFFFFFh      ;GetCurrentProcess()
call    NtOpenProcessToken

然后两个代码块同时指向这里
loc_7C929A7A:          ; 很明白了吧 判断进程/线程令牌是否成功被打开
test    eax, eax
jl      short loc_7C929AE4; 没成功则跳

若 执行成功

mov     eax, [ebp+Privilege]
mov     [ebp+dwPrivilege], eax
mov     al, [ebp+Enable]
xor     ecx, ecx       ; ecx清零
neg     al
push    esi
mov     [ebp+NewState], 1
mov     [ebp+var_C], ecx
sbb     eax, eax
and     eax, 2
mov     [ebp+var_8], eax
lea     eax, [ebp+ReturnLength] ; 实际返回长度
push    eax
lea     eax, [ebp+OldState]
push   eax             ; 旧的特权指针
push   10h             ;sizeof(TOKEN_PRIVILEGES)
lea     eax, [ebp+NewState]
push   eax             ; 新的特权指针
push   ecx             ;FALSE 因为上面有xor ecx,ecx
push    [ebp+TokenHandle]
call    NtAdjustPrivilegesToken ; 调用AdjustPrivilegesToken提权
push    [ebp+TokenHandle]
mov     esi, eax       ; eax备份
call    ZwClose        ; 关闭 内核对象句柄
cmp     esi, 106h       ; 判断NtAdjustPrivilege执行情况 106h =STATUS_NOT_ALL_ASSIGNED
jz      loc_7C947DF2

判断是否执行成功之后,开始输出最后一个参数

cmp     [ebp+OldState], 0
mov     ecx, [ebp+IsEnabled]
jnz     loc_7C929E99

若 OldState != 0 则

mov     al,[ebp+Enable]         ; 应该很明显了 把Enable变量赋给al 也就是eax最后两位

若OldState == 0 则

mov     eax, [ebp+var_18]
shr     eax, 1
and     al, 1
jmp     loc_7C929ADF

这个函数大致流程就是这样。

到这里差不多可以按一下传说中的F5了

int __stdcallRtlAdjustPrivilege(int Privilege, char Enable, charCurrentThread, int Enabled)
{
int result; //eax@2
signed intAdjustResult; // esi@4
char returnValue; //al@7
int v7; //[sp+2Ch] [bp-4h]@1
int IsEnabled; //[sp+4h] [bp-2Ch]@1
int TokenHandle; //[sp+8h] [bp-28h]@2
int dwPrivilege; //[sp+20h] [bp-10h]@4
signed intNewState; // [sp+1Ch] [bp-14h]@4
int v12; //[sp+24h] [bp-Ch]@4
int v13; //[sp+28h] [bp-8h]@4
int OldState; //[sp+Ch] [bp-24h]@4
char ReturnLength; //[sp+0h] [bp-30h]@4
unsigned intv16; // [sp+18h] [bp-18h]@11

v7 = dword_7C97B0C8;
IsEnabled = Enabled;
if ( CurrentThread == 1 )
    result = ZwOpenThreadToken(-2, 40, 0, &TokenHandle);
else
    result = NtOpenProcessToken(-1, 40, &TokenHandle);
if ( result >= 0 )
{
    dwPrivilege = Privilege;
    NewState = 1;
    v12 = 0;
    v13 = -(Enable != 0) & 2;
    AdjustResult = NtAdjustPrivilegesToken(TokenHandle, 0,&NewState, 16, &OldState, &ReturnLength);
    ZwClose(TokenHandle);
    if ( AdjustResult == 262 )
      AdjustResult = -1073741727;
    if ( AdjustResult >= 0 )
    {
      if ( OldState )
        returnValue = (v16 >> 1) &1;
      else
        returnValue = Enable;
      *(_BYTE *)IsEnabled = returnValue;
    }
    result = AdjustResult;
}
return result;
}

可读性好像仍然不高,看看这个...

/******************************************************************************
*RtlAdjustPrivilege         [NTDLL.@]
*
* Enables or disables a privilege from the callingthread or process.
*
* PARAMS
* Privilege     [I] Privilegeindex to change.
* Enable       [I] If TRUE, then enable the privilege otherwise disable.
* CurrentThread [I] If TRUE, then enable in callingthread, otherwise process.
* Enabled       [O]Whether privilege was previously enabled or disabled.
*
* RETURNS
* Success: STATUS_SUCCESS.
* Failure: NTSTATUS code.
*
* SEE ALSO
* NtAdjustPrivilegesToken, NtOpenThreadToken,NtOpenProcessToken.
*
*/
NTSTATUS WINAPI
RtlAdjustPrivilege(ULONG Privilege,
                  BOOLEAN Enable,
                  BOOLEAN CurrentThread,
                  PBOOLEAN Enabled)
{
    TOKEN_PRIVILEGES NewState;
    TOKEN_PRIVILEGES OldState;
    ULONG ReturnLength;
    HANDLE TokenHandle;
    NTSTATUS Status;

TRACE("(%d, %s, %s,%p)\n", Privilege, Enable ? "TRUE": "FALSE",
        CurrentThread ? "TRUE" : "FALSE",Enabled);

if (CurrentThread)
    {
        Status =NtOpenThreadToken(GetCurrentThread(),
                                  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                                  FALSE,
                                  &TokenHandle);
    }
    else
    {
        Status =NtOpenProcessToken(GetCurrentProcess(),
                                   TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                                   &TokenHandle);
    }

if (!NT_SUCCESS(Status))
    {
        WARN("Retrievingtoken handle failed (Status %x)\n", Status);
        returnStatus;
    }

OldState.PrivilegeCount = 1;

NewState.PrivilegeCount = 1;
    NewState.Privileges[0].Luid.LowPart = Privilege;
    NewState.Privileges[0].Luid.HighPart = 0;
    NewState.Privileges[0].Attributes = (Enable) ?SE_PRIVILEGE_ENABLED : 0;

Status = NtAdjustPrivilegesToken(TokenHandle,
                                    FALSE,
                                    &NewState,
                                    sizeof(TOKEN_PRIVILEGES),
                                    &OldState,
                                    &ReturnLength);
    NtClose (TokenHandle);
    if (Status ==STATUS_NOT_ALL_ASSIGNED)
    {
        TRACE("Failedto assign all privileges\n");
        returnSTATUS_PRIVILEGE_NOT_HELD;
    }
    if (!NT_SUCCESS(Status))
    {
        WARN("NtAdjustPrivilegesToken()failed (Status %x)\n", Status);
        returnStatus;
    }

if (OldState.PrivilegeCount== 0)
        *Enabled = Enable;
    else
        *Enabled =(OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);

return STATUS_SUCCESS;
}

修改进程权限(转载)相关推荐

  1. Windows提升进程权限

    Windows提升进程权限 文章一: 在枚举/结束系统进程或操作系统服务时,会出现权限不足而失败的情况,这时就需要提升自己进程到系统权限,其实提升权限的代码很简单的,看过的最经典的应该是<WIN ...

  2. Go 学习笔记(44)— Go 标准库之 os(获取文件状态、获取/修改文件权限、创建、删除目录和文件、获取进程ID、设置获取环境变量)

    1. 概述 os 包提供了操作系统函数的不依赖平台的接口.失败的调用会返回错误值而非错误码.通常错误值里包含更多信息.例如,如果某个使用一个文件名的调用(如Open.Stat)失败了,打印错误时会包含 ...

  3. linux如何改文件用户组权限,linux修改文件权限和用户组管理小结

    如何在linux下修改组权限 chmod g+r path/file 加读权限 当前目录 chmod -R g+r path/file 加读权限 当前目录以及子目录 g-r 减读权限 g+w 加写权限 ...

  4. 该计算机不支持更改权限,不能删除文件,也不能修改文件权限. 解决方法

    无法删除文件,无法修改文件权限 是时候在C盘上安装Adobe Reader了. 卸载后,它完全消失了,然后重新安装在E驱动器上. 卸载后,文件夹(路径: E: \ Adob​​e Reader \ R ...

  5. (linux)查看及修改文件权限以及相关

    查看文件权限的语句: 在终端输入: ls -l xxx.xxx (xxx.xxx是文件名) 那么就会出现相类似的信息,主要都是这些: -rw-rw-r-- 一共有10位数 其中: 最前面那个 - 代表 ...

  6. windows 8 修改文件权限

    修改文件权限 和应用需要管理员身份运行类似,Windows 下很多文件默认没有完全控制的权限,需要手动修改.例如苦大仇深的 hosts 文件,右键选择属性按照下图修改即可.(在 Win 7 中基本一致 ...

  7. linux 用户身份与进程权限

    基本概念 用户 对于支持多任务的 Linux 系统来说,用户就是获取资源的凭证. 权限 权限用来控制用户对计算机资源(CPU.内存.文件等)的访问,一般会分为认证和授权两步.比如用户先经过认证机制(a ...

  8. Problem 61 修改进程的显示名称

    Problem 61 修改进程的显示名称? Ans: 要更改一个进程的显示名称,需要使用系统调用 prctl(), 其中PR_SET_NAME可用于修改进程显示名字. 测试程序: # include ...

  9. 【Android 逆向】修改运行中的 Android 进程的内存数据 ( 使用 IDA 分析要修改的内存特征 | 根据内存特征搜索修改点 | 修改进程内存 )

    文章目录 一.使用 IDA 分析要修改的内存特征 二.根据内存特征搜索修改点 三.修改进程内存 一.使用 IDA 分析要修改的内存特征 在前的博客 [Android 逆向]逆向修改游戏应用 ( 分析应 ...

最新文章

  1. 如何修改Exchange邮件报警信息
  2. java List集合总结
  3. Bag of Words cpp实现(stable version 0.01)
  4. java Thread 类的几种方法
  5. 在linux系统下使用C语言操作临时文件
  6. 如何保存一个函数_如何表达一个“分段函数”之学习Matlab Function模块
  7. 个人空间风格模版php,ThinkPHP 模板布局
  8. c++ 虚函数,纯虚函数的本质区别
  9. (新聞) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球
  10. mysql-安装教程
  11. java socket 异步回调函数_浅谈socket同步和异步、阻塞和非阻塞、I/O模型
  12. Bailian2716 全局变量【字符流】
  13. 外包以小时计算金额的费用_全了!各大税种的计算公式,建议收藏!
  14. java在线播放_Java实现视频在线播放flv视频
  15. dcdc转换器计算机显示,DC/DC转换器
  16. 21. 合并两个有序链表 C语言
  17. 手机上php文件用什么打开方式,php是什么文件格式 php文件打开方法【图文】
  18. Win10使用PowerShell命令行查看cpu温度
  19. 从尺规作图到机器证明
  20. html5 jquery paint plugin,5+最好的画板,并在画布上手动绘制JavaScript和jQuery插件

热门文章

  1. 大数据时代如何赢得财务人才
  2. 软件开发有多少种方式
  3. Tomcat7.0源码分析——Session管理分析(上)
  4. bash shell命令(1)
  5. Viewpager的创建和使用——————————不懂的大家可以问,欢迎提问
  6. 增大apache 2的最大连接数
  7. Spring(1)_Bean初始化_逻辑图
  8. Javascript深入浅出
  9. 2017软件工程实践第二次作业(数独)
  10. HDU 5411 CRB and Puzzle (2015年多校比赛第10场)