12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 216|回复: 0

保护模式笔记八 调用门提权(无参+有参)

[复制链接]
发表于 2021-7-18 18:45:29 | 显示全部楼层 |阅读模式
前言

所有保护模式索引链接:保护模式笔记一 保护模式先容
在先前的保护模式笔记七 CALL 长调用与短调用中没有具体分析长调用的实例,接下来补充其需要的相干知识:调用门
调用门

调用门的作用

调用门可以用来提权,通过提权可以实现访问高地址空间等RING0(内核)层才气进行的操纵
调用门和长调用关系

回顾先前的笔记可知:
长调用CALL FAR CS:EIP指令要调用的地址是由CS段选择子查GDT得到的调用门 段形貌符得来的,后面的EIP不发挥作用
调用门执行流程


  • 根据CS的值 查GDT,找到对应的段形貌符 这个形貌符是一个调用门
  • 在调用门形貌符中存储另一个代码段的选择子
  • 选择子指向的段 段.Base + 偏移地址 就是真正要执行的地址
调用门形貌符

对比段形貌符


调用门形貌符结构


当一个段形貌符是一个调用门形貌符时,有以下特征:

  • S位为0,表示该段形貌符为系统段形貌符(调用门形貌符属于系统段形貌符)
  • Type域为1100,表示该段形貌符为32位调用门
  • 低16位到31位由原本的基地址变为存储一个段选择子,该段选择子才和代码真正要调用的地址相干
  • 真正要调用的地址 = 段选择子所指向的段.Base + 32位的段中偏移 (段中偏移分为两部分:高位31-16位和低位15-0位)
  • 段.Base默认为0,故真正要调用的地址 = 32位的段中偏移
给出段形貌符和调用门形貌符各部分的对比(上半部分为段形貌符,下半部分为调用门形貌符):
数据位31-242322212019-161514-131211-87-0寄义BaseGD/B0AVLSeg.LimitPDPLSTypeBase解释基地址粒度默认操纵大小固定为0用于系统软件使用段大小限定有效位特权等级形貌符类型段类型基地址数据位31-161514-131211-87-54-0寄义offsetPDPLSType无param.count解释段中偏移有效位特权等级值为0值为1100值为000参数计数数据位31-1615-0寄义Base AdressSegment Limit解释基地址段大小限定数据位31-1615-0寄义selectoroffset解释段选择子段中偏移构造无参调用门形貌符

了解了调用门形貌符的结构后,尝试本身构造一个无参的调用门形貌符,如下:
数据位31-161514-131211-87-54-0寄义offsetPDPLSType无param解释段中偏移有效位特权等级值为0值为1100值为000参数值(二进制)0111011000000000数据位31-1615-0寄义selectoroffset解释段选择子段中偏移值(十六进制)0x00080得到调用门形貌符为:0000EC00`00080000
段中偏移暂时不明确要调用的代码段,先置0
示例代码

接下来给出一段演示代码:
#include #include  __declspec(naked) void callGate(){         _asm{                 int 3                                //软中断                 retf                                //注意这里长调用对应长返回         } }int main(){        char buff[6];        //*(DWORD*)&buff[0]= 0x12345678;        //低地址32位为0x12345678,EIP已废弃,故随便填即可        //*(DWORD*)&buff[4]=0x48;                        //高地址16位为0x48,段选择子        //也可以换作这种写法        _asm{                mov dword ptr ds:[buff],0x12345678        //低32位赋值废弃EIP                lea eax,dword ptr ds:[buff]                        //将buff地址给EAX                add eax,4                                                        //地址+4,即得到高地址                mov word ptr ds:[eax],0x48                        //高16位赋值段选择子selector        }        //使用 调用门        _asm{                call fword ptr ds:[buff]                        //fword 数据宽度为6字节        }        return 0;}代码阐明

代码非常简朴,重要分为两部分:

  • callGate:调用门真正要调用的函数,先软中断,然后长返回
  • main:先构造一个CS:EIP,这里为0x48:0x12345678,然后使用调用门
关于构造CS:EIP,可以观察到赋值后buff在内存中的存储情况:

可以看到CS:EIP在内存中由高地址到低地址存储,为0x004812345678
将门形貌符写入GDT

在代码中,CS的也就是段选择子的值为0x48,该选择子指向的GDT的地址为要写入的地址
关于Selector和GDT地址的对应关系在保护模式笔记三 段形貌符和段选择子中已经阐明过了,这里不再赘述
确定门形貌符

在写入GDT前,还需要确定要写入的值,前面已经构造好了的门形貌符为:0x0000EC00`00080000
但其段中偏移还未确定,于是使用VC++ 6.0查看要调用的代码的地址:
进入debug模式,中断后,选中callGate函数,然后右键→Go to Disassembly(查看反汇编)


可以得到要调用的函数的地址为0x00401020
将得到的要调用的函数地址填入门形貌符中对应的offset得到:

  • 原:0000EC00`00080000
  • 现:0040EC00`00081020
于是得到确定的门形貌符为0040EC00`00081020
写入门形貌符

确定完门形貌符和要写入的地址后,就可以将其写入GDT了,操纵如下:
指令如下:
r gdtr                                查看gdtrdq 0x8003f000                以qword查看地址,这里的地址为上面得到的gdtr地址eq 8003f048 0040EC00`00081020                写入门形貌符dq 0x8003f000                查看是否写入乐成过程图如下:

执行代码

执行代码结果如下:
Windbg获取到了代码中的int 3断点

可以看到此时中断的地址正是门形貌符中的偏移地址(要调用的地址 = 段.Base+Offset,Base默认为0,故要调用的地址就直接即是门形貌符中的offset)
原本的Ring3(应用)层的int 3断点不会被Windbg所捕获,但这里通过门形貌符提权后变为了Ring0(内核层)权限,故会引起Windbg的捕获
可以查看此时的寄存器情况:
r
此时的CS正是前面构造的门形貌符中的selector(选择子)
接下来继承单步执行
t
可以看到int 3的下一行代码位retf,也就是callGate函数里的代码中的下一行,由此可以确定调用乐成
对比执行前后寄存器

前面只提到了CS段寄存器的变化,现在来总览对比执行前后寄存器的变化:
执行前寄存器情况

在使用调用门的汇编语句处下断点,断下后得到:

得到此时的寄存器情况:
寄存器值ESP12FF2CEBP12FF80CS1BDS23ES23SS23FS3BGS0执行后寄存器情况


得到此时的寄存器情况:
寄存器值ESPB1026DD0EBP12FF80CS08DS23ES23SS10FS30GS0变化对比

寄存器执行前值执行后值是否变化ESP12FF2CB1026DD0√EBP12FF8012FF80×CS1B08√DS2323×ES2323×SS2310√FS3B30√GS00×可以得出变化的寄存器有:ESP、CS、SS、FS
通过调用门提权后,前后寄存器的变化涉及到TSS,这里先纪录下变化,具体细节留作之后
构造有参调用门形貌符

示例代码

#include #include int a,b,c; __declspec(naked) void callGate(){         _asm{                pushad                                                        //将所有32位通用寄存器压入堆栈        pushfd                                                        //将32位标记寄存器EFLFAGS压入堆栈        //关于为何是通过ESP+XXX寻址详见后续的堆栈情况阐明                mov eax,[esp+0x24+0x8+0x8]                //从堆栈中取出第一个参数                mov dword ptr ds:[a],eax                //将取出的参数赋值给全局变量a                mov eax,[esp+0x24+0x8+0x4]                //从堆栈中取出第二个参数                mov dword ptr ds:,eax                //将取出的参数赋值给全局变量b        mov eax,[esp+0x24+8+0]                        //从堆栈中取出第三个参数                mov dword ptr ds:[c],eax                //将取出的参数赋值给全局变量c                popfd                                                        //将所有32位通用寄存器出栈                popad                                                        //将所有32位标记寄存器EFLFAGS出栈                retf 0xC//注意这里长调用对应长返回,堆栈平衡 0xC=12=3*4=参数个数*参数的数据宽度(单位字节)         } }int main(){        char buff[6];        //*(DWORD*)&buff[0]= 0x12345678;        //低地址32位为0x12345678,EIP已废弃,故随便填即可        //*(DWORD*)&buff[4]=0x48;                        //高地址16位为0x48,段选择子        //也可以换作这种写法        _asm{                mov dword ptr ds:[buff],0x12345678        //低32位赋值废弃EIP                lea eax,dword ptr ds:[buff]                        //将buff地址给EAX                add eax,4                                                        //地址+4,即得到高地址                mov word ptr ds:[eax],0x48                        //高16位赋值段选择子selector        }        //使用 调用门        _asm{                push 1                push 2                push 3                call fword ptr ds:[buff]                        //fword 数据宽度为6字节        }        printf("%X\t%X\t%X\n",a,b,c);        return 0;}代码阐明

与构造无参调用门形貌符相比,重要变化为:

  • 在使用调用门前压入了三个参数:1、2、3
  • 调用代码作用为:①保护现场(压入所有通用寄存器和标记寄存器);②从堆栈中取出对应的参数;③将取出的参数赋值给对应的全局变量
  • 调用代码最后要平衡堆栈,ret 0xC         0xC=12=3*4=参数个数*参数的数据宽度(单位字节)
  • 在调用结束后,输出调用后被赋值的全局变量,验证参数是否乐成传递
堆栈情况阐明

堆栈调用情况按执行流程顺序依次阐明:
执行前(压入参数后)


纪录下此时的堆栈情况:
地址相对栈顶地址值阐明0012FF20ESP3压入的第三个参数0012FF24ESP+42压入的第二个参数0012FF28ESP+81压入的第一个参数切换到调用代码后


纪录下此时的堆栈情况:
地址相对栈顶地址值阐明B9CAFDC4ESP0040D4E8执行后要返回的地址B9CAFDC8ESP+0x41B执行后要恢复的段选择子:CSB9CAFDCCESP+0x83压入的第三个参数B9CAFDD0ESP+0xC2压入的第二个参数B9CAFDD4ESP+0x101压入的第一个参数B9CAFDD8ESP+0x140012FF20执行后要恢复的堆栈寄存器:ESPB9CAFDDCESP+0x1823执行后要恢复的段选择子:SS保存通用寄存器组后


纪录下此时的堆栈情况:
地址相对栈顶地址值阐明B9CAFDA4~B9CAFDC0ESP~ESP+0x1C略通用寄存器组B9CAFDC4ESP+0x200040D4E8执行后要返回的地址B9CAFDC8ESP+0x20+0x41B执行后要恢复的段选择子:CSB9CAFDCCESP+0x20+0x83压入的第三个参数B9CAFDD0ESP+0x20+0xC2压入的第二个参数B9CAFDD4ESP+0x20+0x101压入的第一个参数B9CAFDD8ESP+0x20+0x140012FF20执行后要恢复的堆栈寄存器:ESPB9CAFDDCESP+0x20+0x1823执行后要恢复的段选择子:SS保存标记寄存器后


纪录下此时的堆栈情况:
地址相对栈顶地址值阐明B9CAFDA0ESP0x202标记寄存器B9CAFDA4~B9CAFDC0ESP+0x4~ESP+0x4+0x1C略通用寄存器组B9CAFDC4ESP+0x4+0x200040D4E8执行后要返回的地址B9CAFDC8ESP+0x4+0x20+0x41B执行后要恢复的段选择子:CSB9CAFDCCESP+0x4+0x20+0x83压入的第三个参数B9CAFDD0ESP+0x4+0x20+0xC2压入的第二个参数B9CAFDD4ESP+0x4+0x20+0x101压入的第一个参数B9CAFDD8ESP+0x4+0x20+0x140012FF20执行后要恢复的堆栈寄存器:ESPB9CAFDDCESP+0x4+0x20+0x1823执行后要恢复的段选择子:SS将门形貌符写入GDT

确定门形貌符

先确定段中偏移:进入debug模式,中断后,选中callGate函数,然后右键→Go to Disassembly(查看反汇编)


可以得到要调用的函数的地址为0x0040D480
将得到的要调用的函数地址填入门形貌符中对应的offset得到:

  • 原:0000EC00`00080000
  • 现:0040EC00`0008D480
因为此次调用门形貌符需要传递三个参数,故修改为:
0040EC03`0008D480
PS:修改了门形貌符结构中的param.count,如不认识可回顾上面的 调用门形貌符结构
于是得到确定的门形貌符为0040EC03`0008D480
写入门形貌符

确定完门形貌符和要写入的地址后,就可以将其写入GDT了,操纵如下:
指令如下:
r gdtr                                查看gdtrdq 8003f000                以qword查看地址,这里的地址为上面得到的gdtr地址eq 8003f048 0040EC03`0008D480                写入门形貌符dq 8003f000                查看是否写入乐成过程图如下:

执行代码

执行代码结果如下:

代码执行后,能够正确地输出三个参数,构造有参调用门形貌符乐成
总结


  • 当通过门,权限不变的时候,只会PUSH两个值:①CS(新的CS的值由调用门决定) ;②返回地址
  • 当通过门,权限改变的时候,会PUSH四个值:①SS;② ESP;③ CS ;④ 返回地址   (新的CS的值由调用门决定  新的SS和ESP由TSS提供
  • 通过门调用时,要执行代码的地址由调用门中的选择子决定;使用RETF返回时,由堆栈中压入的返回地址决定
关于TSS的内容留作之后的笔记(* ̄3 ̄)╭
PS:写得比力匆忙,可能会有谬误之处,欢迎指出
</strong>
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-4-29 14:53 , Processed in 0.140625 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表