登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 618|回复: 0

WIN64枚举GDT以及枚举并恢复IDT的代码

[复制链接]

171

主题

21

回帖

1106

积分

管理员

积分
1106
发表于 2024-12-25 22:18:44 | 显示全部楼层 |阅读模式
GDT:
typedef union _KGDTENTRY64
{
        struct
        {
                USHORT LimitLow;
                USHORT BaseLow;                                //base:2B
                union
                {
                        struct
                        {
                                UCHAR BaseMiddle;        //base:1B
                                UCHAR Flags1;
                                UCHAR Flags2;
                                UCHAR BaseHigh;                //BASE:1B
                        } Bytes;
                        struct
                        {
                                ULONG BaseMiddle:8;
                                ULONG Type:4;
                                ULONG S:1;
                                ULONG Dpl:2;                //DPL
                                ULONG Present:1;        //P
                                ULONG LimitHigh:4;
                                ULONG System:1;
                                ULONG LongMode:1;
                                ULONG DefaultBig:1;
                                ULONG Granularity:1;//G
                                ULONG BaseHigh:8;
                        } Bits;
                };
                ULONG BaseUpper;                        //base:4B
                ULONG MustBeZero;
        };
        UINT64 Alignment;
} KGDTENTRY64, *PKGDTENTRY64;

ULONG64 MakeULONG64ForGDT(USHORT BaseLow, UCHAR BaseMiddle, UCHAR BaseHigh, ULONG BaseUpper)
{
        ULONG64 ul64=0;
        memcpy(((PUCHAR)(&ul64))+0,&BaseLow,2);
        memcpy(((PUCHAR)(&ul64))+2,&BaseMiddle,1);
        memcpy(((PUCHAR)(&ul64))+3,&BaseHigh,1);
        memcpy(((PUCHAR)(&ul64))+4,&BaseUpper,4);
        return ul64;
}

typedef struct _GDT_INFO
{
        UCHAR        CpuId;
        UCHAR        DPL;
        UCHAR        P;
        UCHAR        G;
        WORD        GdtLimit;
        WORD        ItemLimit;
        ULONG64        GdtBase;
        ULONG64 ItemBase;
        ULONG        Type;
        ULONG        Selector;
} GDT_INFO, *PGDT_INFO;

GDT_INFO GdtInfo[256]= {0}; //“默认”CPU最多有16个核心

void GetGDT(ULONG64 *Base, WORD *Limit)
{
        typedef void (__fastcall *SCFN)(void);
        UCHAR data[10]= {0};
        PVOID p=&data[0];
        SCFN scfn=NULL;
        UCHAR shellcode[15]=
            "\x48\xB8\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F" //9
            "\x0F\x01\x00"                             //12
            "\xC3";                                    //13
        /*
                mov rax,xxxxxxxxxxxxxxxxh
                sgdt [rax]
                ret
        */
        memcpy(shellcode+2,&p,8);
        scfn=(SCFN)MALLOC_NPP(14);
        memcpy(scfn,shellcode,14);
        scfn();
        memcpy(Base,data+2,8);
        memcpy(Limit,data,2);
        FREE(scfn);
}

ULONG EnumGDT()
{
        ULONG c=0,j=0,k=0,gec=0;
        ULONG CpuNumber=KeNumberProcessors;
        ULONG64 GdtBase=0;
        WORD GdtLimit=0;
        KGDTENTRY64 GdtEntry[16]= {0};
        memset(GdtInfo,0,sizeof(GDT_INFO)*256);
        for(j=0; j<CpuNumber; j++)
        {
                KeSetSystemAffinityThread(j+1);
                GetGDT(&GdtBase,&GdtLimit);
                KeRevertToUserAffinityThread();
                if(GdtLimit>256){GdtLimit=256;}
                memcpy(GdtEntry,(PVOID)GdtBase,GdtLimit);
                gec=(GdtLimit+1)/16;
                for(k=0; k<gec; k++)
                {
                        GdtInfo[c].CpuId=(UCHAR)j;
                        GdtInfo[c].GdtBase=GdtBase;
                        GdtInfo[c].GdtLimit=GdtLimit;
                        GdtInfo[c].ItemBase=MakeULONG64ForGDT(GdtEntry[k].BaseLow,(UCHAR)(GdtEntry[k].Bits.BaseMiddle),(UCHAR)(GdtEntry[k].Bits.BaseHigh),GdtEntry[k].BaseUpper);
                        GdtInfo[c].ItemLimit=GdtEntry[k].LimitLow;
                        GdtInfo[c].DPL=(UCHAR)GdtEntry[k].Bits.Dpl;
                        GdtInfo[c].P=(UCHAR)GdtEntry[k].Bits.Present;
                        GdtInfo[c].G=(UCHAR)GdtEntry[k].Bits.Granularity;
                        GdtInfo[c].Type=GdtEntry[k].Bits.Type;
                        GdtInfo[c].Selector=k*16;
                        c++;
                }
                if(c>256){break;}
        }
        return c;
}
IDT:
/*
nt!_KIDTENTRY64
   +0x000 OffsetLow        : Uint2B
   +0x002 Selector         : Uint2B
   +0x004 IstIndex         : Pos 0, 3 Bits
   +0x004 Reserved0        : Pos 3, 5 Bits
   +0x004 Type             : Pos 8, 5 Bits
   +0x004 Dpl              : Pos 13, 2 Bits
   +0x004 Present          : Pos 15, 1 Bit
   +0x006 OffsetMiddle     : Uint2B
   +0x008 OffsetHigh       : Uint4B
   +0x00c Reserved1        : Uint4B
   +0x000 Alignment        : Uint8B
*/
typedef struct _IDTENTRY64
{
        USHORT OffsetLow;
        USHORT Selector;
        USHORT BitInfo;
        USHORT OffsetMiddle;
        ULONG  OffsetHigh;
        ULONG  Reserved1;
} IDTENTRY64, *PIDTENTRY64;


IDTENTRY64 IdtInfo[8192]= {0}; //“默认”CPU最多有32个核心

ULONG EnumIDT()
{
        PUCHAR CurrentIdtBaseAddressOffset,CurrentIdtBaseAddress;
        ULONG c=0,j=0;
        ULONG CpuNumber=KeNumberProcessors;
        memset(IdtInfo,0,sizeof(IDTENTRY64)*256);
        for(j=0; j<CpuNumber; j++)
        {
                KeSetSystemAffinityThread(j+1);
                CurrentIdtBaseAddressOffset=(PUCHAR)__readmsr(0xC0000101) + 0x38;
                KeRevertToUserAffinityThread();
                CurrentIdtBaseAddress=(PUCHAR)(*(ULONG64*)CurrentIdtBaseAddressOffset);
                memcpy(&IdtInfo[j*256], CurrentIdtBaseAddress, 256*sizeof(IDTENTRY64));
                c=c+256;
                if(c > 256*32){break;}
        }
        return c;
}

void SplitQWORDforIDT(ULONG64 Number, ULONG *high, USHORT *middle, USHORT *low)
{
        memcpy(high,((PUCHAR)&Number)+4,4);
        memcpy(middle,((PUCHAR)&Number)+2,2);
        memcpy(low,((PUCHAR)&Number),2);
}

void ModifyIDT(UCHAR cpu, UCHAR id, ULONG64 Address)
{
        ULONG high_dword=0;
        USHORT mid_word=0,low_word=0;
        PIDTENTRY64 TargetAddress;
        PUCHAR CurrentIdtBaseAddressOffset,CurrentIdtBaseAddress;
        KeSetSystemAffinityThread(cpu+1);
        CurrentIdtBaseAddressOffset=(PUCHAR)__readmsr(0xC0000101) + 0x38;
        KeRevertToUserAffinityThread();
        CurrentIdtBaseAddress=(PUCHAR)(*(ULONG64*)CurrentIdtBaseAddressOffset);
        TargetAddress=(PIDTENTRY64)(CurrentIdtBaseAddress+id*16);
        SplitQWORDforIDT(Address,&high_dword,&mid_word,&low_word);
        _disable();
        TargetAddress->OffsetLow=low_word;
        TargetAddress->OffsetMiddle=mid_word;
        TargetAddress->OffsetHigh=high_dword;
        _enable();
}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-4-11 19:03 , Processed in 0.095240 second(s), 22 queries , Yac On.

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

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