admin 发表于 2024-12-25 22:18:44

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

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= {0}; //“默认”CPU最多有16个核心

void GetGDT(ULONG64 *Base, WORD *Limit)
{
      typedef void (__fastcall *SCFN)(void);
      UCHAR data= {0};
      PVOID p=&data;
      SCFN scfn=NULL;
      UCHAR shellcode=
            "\x48\xB8\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F" //9
            "\x0F\x01\x00"                           //12
            "\xC3";                                    //13
      /*
                mov rax,xxxxxxxxxxxxxxxxh
                sgdt
                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= {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.CpuId=(UCHAR)j;
                        GdtInfo.GdtBase=GdtBase;
                        GdtInfo.GdtLimit=GdtLimit;
                        GdtInfo.ItemBase=MakeULONG64ForGDT(GdtEntry.BaseLow,(UCHAR)(GdtEntry.Bits.BaseMiddle),(UCHAR)(GdtEntry.Bits.BaseHigh),GdtEntry.BaseUpper);
                        GdtInfo.ItemLimit=GdtEntry.LimitLow;
                        GdtInfo.DPL=(UCHAR)GdtEntry.Bits.Dpl;
                        GdtInfo.P=(UCHAR)GdtEntry.Bits.Present;
                        GdtInfo.G=(UCHAR)GdtEntry.Bits.Granularity;
                        GdtInfo.Type=GdtEntry.Bits.Type;
                        GdtInfo.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;
      ULONGOffsetHigh;
      ULONGReserved1;
} IDTENTRY64, *PIDTENTRY64;


IDTENTRY64 IdtInfo= {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, 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();
}

页: [1]
查看完整版本: WIN64枚举GDT以及枚举并恢复IDT的代码