【2021.03.21】调用门:下

要点回顾

前文提到了调用门的执行过程,那么本篇文章就一起来了解一下:调用门的参数传递

代码回顾

void __declspec(naked) GetRegister()
{
    __asm
    {
        pushad
        pushfd
 
        mov eax,0x8003f00c    //读取高2G内存
        mov ebx,[eax]
        mov dwH2GValue,ebx
        sgdt GDT;             //读取GDT
 
        popfd
        popad
 
        retf                  //注意返回, 不能是ret
    }
}

上面的代码在前文中出现过,通过调用门提升到了0环权限后执行。

真正起作用的是 mov eax,0x8003f00c、mov ebx,[eax]、mov dwH2GValue,ebx、sgdt GDT。

其中 sgdt GDT的sgdt并不是读取GDT表,而是读取GDTR这个寄存器。

SGDT这个指令通常是给操作系统软件使用的,但是如果要在应用层去使用它,也不会导致异常。

也就是说 sgdt GDT 这条代码在3环没有提权的情况下也是可以使用的。

调用门描述符

前文提到过调用门的门描述符S位必须为0,当它为0的时候才能说明是一个系统段描述符,而不是代码段/数据段描述符,且TYPE位为1100才是一个调用门。

构造有参数的调用门门描述符

0040EC03`00081030:3个参数。

kd> eq 8003f048 0040EC03`00081030

代码论证

#include "stdafx.h"
#include <windows.h>

DWORD x;
DWORD y;
DWORD z;

void __declspec(naked) GateProc()
{
    __asm
    {
        pushad
        pushfd

        //以下是读取参数并赋值给全局变量

        mov eax,[esp+0x24+0x8+0x8]
        mov dword ptr ds:[x],eax
        mov eax,[esp+0x24+0x8+0x4]
        mov dword ptr ds:[y],eax
        mov eax,[esp+0x24+0x8+0x0]
        mov dword ptr ds:[z],eax

        //以上是读取参数并赋值给全局变量

        popfd
        popad

        retf 0xC                //注意堆栈平衡, 写错直接蓝屏
    }
}

void PrintRegister()
{
    //打印确认参数是否正确
    printf("%x %x %x\n",x,y,z);
}

int main()
{
    char buff[6];

    *(DWORD*)&buff[0] = 0x12345678;
    *(WORD*)&buff[6] = 0x48;

    __asm
    {
        push 1
        push 2
        push 3

        call fword ptr[buff]
    }

    PrintRegister();

    getchar();

    return 0;
}

注意:当使用有参数的调用门,参数是需要自己压栈的,如代码中压入了1、2、3,然后才调用。

总结

  1. 当通过调用门,权限不变的时候,会 PUSH 两个值:CS返回地址。新的CS的值由调用门决定。
  2. 当通过调用门,权限改变的时候,会 PUSH 四个值:SS(原来的堆栈段选择子)ESP(原来的栈顶)CS(原来的段选择子)返回地址。新的CS的值由调用门决定,新的SS和ESP由TSS提供。
  3. 通过调用门调用时,要执行哪行代码由调用门决定,但使用 RETF 返回时,由堆栈中压入的值决定。也就是说:进入时只能按照固定路线行动,离开时可以翻墙(只要改变堆栈里面的值就可以前往任意地方)。
  4. 可不可以再建立一个门出去呢?也就是使用 CALL。答案是可以,前门进后门出。

思考

思考一:

代码论证中的代码 pushad、pushfd、popad、popfd有必要吗?

思考二:

代码论证中的以下代码中标红的部分读取参数为什么要这么写呢?

mov eax,[esp+0x24+0x8+0x8]
mov dword ptr ds:[x],eax
mov eax,[esp+0x24+0x8+0x4]
mov dword ptr ds:[y],eax
mov eax,[esp+0x24+0x8+0x0]
mov dword ptr ds:[z],eax

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值