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]