利用GDT进入RING0

BOOL CallRing0_NtSystemDebugControl_GDT(PVOID pvRing0FuncAddr, PVOID pParam)

    PLDT_DESCRIPTOR pLDTDescriptor;
    GDTR gdtr;
    WORD CallgateAddr[3];
    WORD wGDTIndex = 1;
    ULONG nRetLength;
    PBYTE GDT_buff=NULL;
    BOOL  bRet = FALSE;   
   
    __try
    {
        // Initial the NtSystemDebugControl function
        if( ! InitialNtSystemDebugControl() ) __leave;
       
        // Get the gdt
        _asm Sgdt [gdtr];
        GDT_buff = (PBYTE) malloc(gdtr.wGDTLimit);
        if( GDT_buff == NULL ) __leave;
        nRetLength = ReadPhysicalMEM(
            gdtr.dwGDTBase,
            GDT_buff,
            gdtr.wGDTLimit);
        if( nRetLength != gdtr.wGDTLimit ) __leave;
       
        // Skip the null descriptor
        pLDTDescriptor = (PLDT_DESCRIPTOR)(GDT_buff + 8);
       
        // Search for a free GDT descriptor
        for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
        {
            if (pLDTDescriptor->Type == 0    &&
                pLDTDescriptor->System == 0  &&
                pLDTDescriptor->DPL == 0      &&
                pLDTDescriptor->Present == 0)
            {
                // Found one !
                // Now we need to transform this descriptor into a callgate.
                // Note that we're using selector 0x28 since it corresponds
                // to a ring 0 segment which spans the entire linear address
                // space of the processor (0-4GB).
                PCALLGATE_DESCRIPTOR pCallgate;
                pCallgate = (PCALLGATE_DESCRIPTOR) pLDTDescriptor;
                pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
                pCallgate->Selector = 0x08;
                pCallgate->ParamCount = 0;
                pCallgate->Unused = 0;
                pCallgate->Type = 0xc;
                pCallgate->System = 0;
                pCallgate->DPL = 3;
                pCallgate->Present = 1;
                pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);
               
                // Flush the gdt
                nRetLength = WritePhysicalMEM(
                    gdtr.dwGDTBase,
                    GDT_buff,
                    gdtr.wGDTLimit);
                if( nRetLength != gdtr.wGDTLimit ) __leave;



                // Prepare the far call parameters
                CallgateAddr[0] = 0x0;
                CallgateAddr[1] = 0x0;
                CallgateAddr[2] = (wGDTIndex << 3) | 3;

                // Please fasten your seat belts!
                // We're about to make a hyperspace jump into RING 0.
                _asm push pParam;
                _asm Call FWORD PTR [CallgateAddr];

                // We have made it !
                // Now free the GDT descriptor
                memset(pLDTDescriptor, 0, 8);
                nRetLength = WritePhysicalMEM(
                    gdtr.dwGDTBase,
                    GDT_buff,
                    gdtr.wGDTLimit);
                if( nRetLength != gdtr.wGDTLimit ) __leave;

                // Our journey was successful. Seeya.
                bRet = TRUE;
                __leave;
            }
            // Advance to the next GDT descriptor
            pLDTDescriptor++;
        }
  }
  __finally
  {
     FreeNtSystemDebugControl();

     if( GDT_buff )
         free(GDT_buff);
     return bRet;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值