7、代码间的跳转(跨段跳转)--Windows内核学习笔记

1、短调用
–指令格式:CALL 立即数/寄存器/内存
–CALL指令的作用:指令执行之前,先把下一行指令的地址,压入堆栈中,相当于PUSH进去,PUSH完成后会把后边的值写入到EIP中,所以这个指令执行后的效果如下图:
–通常一个函数执行完毕后,会用RET指令进行返回 ,RET指令相当于POP EIP,将返回值的地址弹到EIP中,然后ESP加4
在这里插入图片描述
2、长调用(跨段不提权)
–指令格式:CALL CS:EIP(EIP是废弃的,只是为了保证语法的兼容)
–当一个CALL后面跟了六个字节,那这个CALL就是一个长调用
–JMP不影响堆栈
–这个CALL指令是影响堆栈的
–CALL执行前,首先拿着CS拆分段选择子>>通过段选择子查表>>通过查表查找到段描述符>>开始做权限的匹配是否符合>>如果符合就会把段描述符的值取出来,将CS修改了>> 由当前CS的段描述符决定往哪里跳转
–CALL指令通常是和RET指令配对的
–当CALL执行的时候,CS里面原有的值就会被覆盖掉,所以我们需要将原来的值保存到堆栈中
–普通的CALL调用只是在堆栈中存储一个返回地址
–但是这种长调用,它往堆栈中存储的不仅仅是一个返回值,还有一个调用这CS,这个调用者的CS是CALL之前的
–怎么理解跨段?
答:修改CS就是跨段
–怎么理解不提权
答:CS这个段选择子,找到的那个DPL跟当前的CPL一样,都是三环
当我修改了CS,修改前CPL是三环,修改后CPL还是三环,这种情况我们称之为跨段但不提权
–当我不提权的时候,仅仅是跨段的时候,用的还是原来的堆栈,没有变化,原来堆栈在哪还是在哪,所以这个值直接就压入原来的堆栈中了
–当使用长调用的时候,就不可以用RET了,因为RET只会将一个返回地址弹入到EIP中。所以这种代码对应的指令就是RETF。
–如果RETF的时候,不做权限检查,那不就意味着我随便跳一个平级的代码段,然后调完了,把堆栈中的值给改了,这个时候,这个值是随便改的
–代码和堆栈是永远不分家的
在这里插入图片描述
3、长调用(跨段并提权)
–指令格式:CALL CS:EIP(EIP是废弃的),其堆栈图如图所示:
–因为CS和SS是成对使用的,所以当CS提权后就不可以再访问原来的堆栈了,所以需要一块新的堆栈
–ESP记录的永远都是当前栈顶的栈顶指针
–因为原来的堆栈是3环的堆栈,当CS和SS提权后需要换一个零环的堆栈
–发生改变的寄存器 ESP EIP CS SS
在这里插入图片描述
总结
1、跨段调用时,一旦有权限切换,就会切换堆栈
2、CS权限一旦改变,SS的权限也会随着改变,CS与SS的特权等级必须一样
3、JMP FAR只能跳转到同级非一致代码段,但CALL FAR可以通过调用门提权

3、调用门
指令格式:CALL CS:EIP(EIP是废弃的)
执行步骤
3.1、根据CS的值 查找GDT表 找到对应的段描述符 这个描述符是一个调用门
3.2、再调用门描述符中存储另一个代码段 段的选择子
3.3、段选择子指向的段 段.Base + 偏移地址 就是真正要执行的地址
3.4、第12位置 = 0 代表系统段,第12位 = 1 代表数据段或者代码段
3.5、Type域中的 1100 代表的是调用门
3.6、当执行这块代码的时候CPL是3,那么DPL就为3
3.7、门描述符中有两个 段内偏移量 这两个加起来是32位 上面的是低16位,下面的是高16位,它们俩拼出来的值,就是这个代码要执行的地址

门描述符

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值