【2021.03.19】长调用与短调用

要点回顾

  1. 通过前文知道JMP FAR可以实现段间跳转,如果要实现跨段的调用就必须要学习CALL FAR,也就是长调用。
  2. CALL FAR 比 JMP FAR 要复杂,JMP并不影响堆栈,而CALL指令会影响。

短调用

指令格式:CALL 立即数/寄存器/内存

发生改变的寄存器:ESP、EIP

长调用(跨段不提权)

指令格式:CALL CS:EIP(EIP是废弃的)

并不使用后面的EIP,EIP是被废弃的。

主要是CS段寄存器中的段选择子,通过段选择子去查询GDT表找一个段描述符,且该段描述符必须是调用门

  1. 想跳到另一个段中,需要提供一个段选择子。
  2. 如果目标段与当前段是同级别的,比如CPL都是3,称为跨段不提权。
  3. 如果是这种情况,堆栈的变化与短调用不同的是:会先压入调用者的CS,把当前CS段选择子压入堆栈中,然后执行。并且ESP+8,ESP+8以后指向的仍然是返回地址。

这个时候,如果执行完了长调用,如果想返回就不能像原来短调用使用RET来返回,如果使用RET是没有办法把CS段选择子赋值回去的。

  1. 长调用执行后,需要使用长返回(RETF)来从另一个段跳转回来。
  2. 修改ESP,并将原来保存的段选择子重新赋值给CS段寄存器。

发生改变的寄存器:ESP、EIP、CS

长调用(跨段并提权)

指令格式:CALL CS:EIP(EIP是废弃的)

执行前:3环权限

执行后:0环权限

当跨段提权的时候,执行后的堆栈已经不是原来的堆栈了。且CS、ESP、CS都发生了切换。

发生改变的寄存器:ESP、EIP、CS、SS

总结

  1. 跨段调用时,一旦有权限切换,伴随着的就有堆栈的切换。
  2. CS的权限一旦改变,SS的权限也要随着改变,CS与SS的等级必须一样
  3. JMP FAR 只能跳转到同级非一致代码段,但 CALL FAR 可以通过调用门提权,提升 CPL 的权限。

思考

SS 与 ESP 从哪里来?参见 TSS 段。

猜你喜欢

转载自blog.csdn.net/qq_18120361/article/details/115012190