古月不傲 发表于 2020-2-24 23:52

读取段描述符

本帖最后由 古月不傲 于 2020-2-24 23:57 编辑

#include <ntddk.h>

#define ES        4        //0x23        00100011
#define CS        3        //0x1B        00011011
#define SS        4        //0x23        00100011
#define DS        4        //0x23        00100011
#define FS        7        //0x3B        00111011
#define GS                //NULL

//段寄存器
typedef struct _SegmentRegister
{
        ULONG        uLimit;                //段限长
        ULONG        uBase;                //段基址
        USHORT        uAttributes;//段属性
        USHORT        uSelector;        //段选择子
}SegmentRegister, *PSegmentRegister;

//段选择子
typedef struct _SegmentSelector
{
        USHORT        uRPL : 2;        //请求特权级别
        USHORT        uTI : 1;        //表指示位                0:GDT        1:LDT
        ULONG        uIndex : 13;//GDT下标
}SegmentSelector, *PSegmentSelector;

//全局描述符表
typedef struct _GDTENTRY
{
        USHORT        uLimitLow;        //GDT大小
        USHORT        uBaseLow;        //低地址
        ULONG        uHighWord;        //高地址
}GDTENTRY, *PGDTENTRY;

//段描述符
typedef struct _SegmentDescriptor
{
        //低32位
        USHORT        uLowLimit;                //低限长
        USHORT        uLowBase;                //低地址
        //高32位
        UCHAR        uBaseMid;                //中地址
        UCHAR        uType : 4;                //段描述符类型                                                       
        UCHAR        uS : 1;                        //段类型标识                                 0:系统段        1:代码段或数据段
        UCHAR        uDPL : 2;                //段描述符特权级别                        0:0环                1:3环
        UCHAR        uPresent : 1;        //段存在位                                        0:段不存在        1:段存在
        UCHAR        uHighLimit : 4;        //高限长
        UCHAR        uAVL : 1;                //操作系统使用                                默认为0
        UCHAR        uReserved : 1;        //保留位                                        默认为0
        UCHAR        uDB : 1;                //指令、堆栈、扩展的大小         0:16位        1:32位
        UCHAR        uG : 1;                        //段限长标识                                0:0x000FFFFF(字节) 1:0xFFFFFFFF(4G)
        UCHAR        uBaseHigh;                //高地址       
}SegmentDescriptor, *PSegmentDescriptor;

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
        KdPrint(("驱动卸载成功\n"));
}

//读取GDT基址
VOID ReadGdtrInfo()
{
        GDTENTRY gdtr = { 0 };
        __asm
        {
                sgdt gdtr;
        }
        KdPrint(("sgdt.uBase = %x sgdt.uLimit = %x\n", (gdtr.uHighWord << 16) + gdtr.uBaseLow, gdtr.uLimitLow));
}

//读取段描述符
VOID ReadSegmentDescriptor(ULONG uIndex)
{
        GDTENTRY gdtr = { 0 };
        __asm
        {
                sgdt gdtr;
        }
        PGDTENTRY pGdtr = &gdtr;
        PSegmentDescriptor pSegmentDescriptor = NULL;
        pSegmentDescriptor = (PSegmentDescriptor)((gdtr.uHighWord << 16) + gdtr.uBaseLow);
        KdPrint(("高地址:%x\n段限长标识:%x\n指令、堆栈、扩展的大小:%x\n保留位:%x\n操作系统使用:%x\n\
        高限长:%x\n段存在位:%x\n段描述符特权级别:%x\n段类型标识:%x\n段描述符类型:%x\n中地址:%x\n低地址:%4x\n低限长:%4x\n",
        pSegmentDescriptor.uBaseHigh, pSegmentDescriptor.uG, pSegmentDescriptor.uDB,
        pSegmentDescriptor.uReserved, pSegmentDescriptor.uAVL, pSegmentDescriptor.uHighLimit,
        pSegmentDescriptor.uPresent, pSegmentDescriptor.uDPL, pSegmentDescriptor.uS,
        pSegmentDescriptor.uType, pSegmentDescriptor.uBaseMid, pSegmentDescriptor.uLowBase,
        pSegmentDescriptor.uLowLimit));
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pStrRegPath)
{
        KdPrint(("驱动加载成功\n"));
        pDriverObject->DriverUnload = DriverUnload;
        ReadGdtrInfo();
       
        PCHAR pRegistersName = { "es", "cs", "ss", "ds" };
        UCHAR uRegisters = { ES ,CS,SS,DS };
        for (ULONG i = 0; i < 4; i++)
        {
                KdPrint(("%s:\n", pRegistersName));
                ReadSegmentDescriptor(uRegisters);
        }

        return STATUS_SUCCESS;
}

Stand412 发表于 2020-2-25 00:04

niupi
niupi

royzone 发表于 2020-2-25 00:19

证明我的存在
页: [1]
查看完整版本: 读取段描述符