gdt描述_获取全局描述符表GDT的内容 | 学步园

/stdfx.h文件

//Ring0环的程序

//测试环境VS2005

#ifndef _WIN32_WINNT// Allow use of features specific to Windows XP or later.

#define _WIN32_WINNT 0x0501// Change this to the appropriate value to target other versions of Windows.

#endif

#ifdef __cplusplus

extern "C"

{

#endif

#include

#include

#include

#include

#ifdef __cplusplus

}

#endif

//stdfx.cpp文件

//This file is used to build a precompiled header

#include "stdafx.h"

//GetGDT.cpp文件

#include "stdafx.h"

//SGDT返回的数据格式

#pragma pack(1)

typedef struct

{

USHORT GDTLimit; //GDT表的字节大小

ULONG GDTAddress; //GDT表的基址

}GDTINFO, *PGDTINFO;

#pragma pack()

//驱动的控制码

#define CTL_CODE( DeviceType, Function, Method, Access ) ( \

((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \

)

#define MY_BASE 0x800

#define MY_CTL_CODE(i) CTL_CODE(FILE_DEVICE_UNKNOWN, MY_BASE + i, METHOD_BUFFERED, FILE_ANY_ACCESS)

//设置控制码IOCTL_GET_GDT

#define IOCTL_GET_GDT MY_CTL_CODE(1)

//卸载例程

void GetGDTUnload(IN PDRIVER_OBJECT DriverObject);

//创建关闭例程

NTSTATUS GetGDTCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

//默认处理例程

NTSTATUS GetGDTDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

//驱动控制例程函数的声明

NTSTATUS DispathControlDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

#ifdef __cplusplus

//驱动入口函数

extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);

#endif

//入口函数

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

UNICODE_STRING DeviceName,Win32Device;

PDEVICE_OBJECT DeviceObject = NULL;

NTSTATUS status;

ULONG i;

//设置断点

KdBreakPoint();

//设置设备名称

RtlInitUnicodeString(&DeviceName, L"\\Device\\GetGDT0");

//设置设备连接符

RtlInitUnicodeString(&Win32Device, L"\\DosDevices\\GetGDT0");

//填充默认的派遣函数

for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)

{

DriverObject->MajorFunction[i] = GetGDTDefaultHandler;

}

//设置创建函数

DriverObject->MajorFunction[IRP_MJ_CREATE] = GetGDTCreateClose;

//设置关闭函数

DriverObject->MajorFunction[IRP_MJ_CLOSE] = GetGDTCreateClose;

//设置驱动控制函数

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispathControlDriver;

//设置卸载函数

DriverObject->DriverUnload = GetGDTUnload;

//创建设备对象

status = IoCreateDevice(DriverObject,

0,

&DeviceName,

FILE_DEVICE_UNKNOWN,

0,

FALSE,

&DeviceObject);

if (!NT_SUCCESS(status))

return status;

if (!DeviceObject)

return STATUS_UNEXPECTED_IO_ERROR;

//直接方式I/O

DeviceObject->Flags |= DO_DIRECT_IO;

//设置文件字对齐

DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;

//创建符号连接

status = IoCreateSymbolicLink(&Win32Device, &DeviceName);

if (!NT_SUCCESS(status))

return status;

//设备初始化完毕可以工作了

DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

return STATUS_SUCCESS;

}

//卸载例程

void GetGDTUnload(IN PDRIVER_OBJECT DriverObject)

{

UNICODE_STRING Win32Device;

RtlInitUnicodeString(&Win32Device, L"\\DosDevices\\GetGDT0");

//删除连接符

IoDeleteSymbolicLink(&Win32Device);

//删除设备

IoDeleteDevice(DriverObject->DeviceObject);

}

//创建关闭例程

NTSTATUS GetGDTCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

Irp->IoStatus.Status = STATUS_SUCCESS;

Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return STATUS_SUCCESS;

}

//默认处理例程

NTSTATUS GetGDTDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;

Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Irp->IoStatus.Status;

}

//驱动的控制例程函数

NTSTATUS DispathControlDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

PIO_STACK_LOCATION pIrpStack = NULL;

ULONG uIoControlCode = 0;

PVOID pIoBuffer = NULL;

ULONG uInSize = 0;

ULONG uOutSize = 0;

//设置断点

KdBreakPoint();

//获取当前IRP的堆栈

pIrpStack = IoGetCurrentIrpStackLocation(Irp);

//获取设备控制例程的控制代码

uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

//获取IRP的缓冲区

pIoBuffer = Irp->AssociatedIrp.SystemBuffer;

//获取缓冲区的输出长度

uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

switch(uIoControlCode)

{

//获取GDT表

case IOCTL_GET_GDT:

{

//设置断点

KdBreakPoint();

INT i = 0;

ULONG uLeng = 0;

GDTINFO gdtEntry;

ULONG gdtAddr = 0;

//获取GDTR寄存器的值

__asm sgdt gdtEntry;

//GDTR寄存器值的头两个字节表示的是GDT表的长度,后4个字节表示的是GDT表的地址

//获取GDT表的界限

uLeng = gdtEntry.GDTLimit;

//获取GDT表的基址

gdtAddr = gdtEntry.GDTAddress;

//拷贝GDT表值到输出缓冲区

RtlCopyMemory((CHAR*)pIoBuffer, (CHAR*)gdtAddr, uLeng);

uOutSize = uLeng;

status = STATUS_SUCCESS;

}

break;

}

//设置成功操作的字节数

if(status == STATUS_SUCCESS)

{

Irp->IoStatus.Information = uOutSize;

}

else

{

Irp->IoStatus.Information = 0;

}

//设置I/O状态

Irp->IoStatus.Status = status;

//完成请求

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return status;

}

//Ring3环程序的测试环境为VC6.0

//推荐在F5调试环境下测试

//注:在GDT表的解析时,好像出了错?

#include

#include

#include

//段的定义-64位

#pragma pack(1)

typedef struct

{

unsigned int m_Limit1:16; //段界限低16位

unsigned int m_BaseAddr1:24; //段基地址低24位

unsigned int m_Attributes:12; //段属性12位

unsigned int m_Limit2:4; //段界限高4位

unsigned int m_BaseAddr2:8; //段基地址高8位

}SEGMENT, *PSEGMENT;

//段基址32位

//段界限20位

#pragma pack()

//获取段基址

#define MAKESEGADDR(BaseAddr1, BaseAddr2)\

((unsigned long) (((unsigned short) (BaseAddr1)) | ((unsigned long) ((unsigned short) (BaseAddr2))) << 24))

//获取段界限

#define MAKESEGLIMIT(Limit1, Limit2)\

((unsigned long) (((unsigned short) (Limit1)) | ((unsigned long) ((unsigned short) (Limit2))) << 16))

//直接使用头文件不使用宏

//驱动控制所需要的宏

//#define METHOD_BUFFERED 0

//#define FILE_ANY_ACCESS 0

//#define FILE_DEVICE_UNKNOWN 0x00000022

//驱动的控制码

#define CTL_CODE( DeviceType, Function, Method, Access ) ( \

((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \

)

//0x800之前的数值系统保留

#define MY_BASE 0x800

#define MY_CTL_CODE(i) CTL_CODE(FILE_DEVICE_UNKNOWN, MY_BASE + i, METHOD_BUFFERED, FILE_ANY_ACCESS)

//设置控制码IOCTL_GET_GDT

#define IOCTL_GET_GDT MY_CTL_CODE(1)

//连接符

#define WIN32_LINK_NAME "\\\\.\\GetGDT0"

int main(int argc, char* argv[])

{

DWORD dwRead = 0;

BYTE szBuffer[0x1000];

//清零

RtlZeroMemory(szBuffer, 0, sizeof(szBuffer));

//打开文件句柄

HANDLE hFile = CreateFile(WIN32_LINK_NAME,

GENERIC_READ | GENERIC_WRITE,

0,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL);

if (hFile == INVALID_HANDLE_VALUE)

{

printf("CreateFile False!\r\n");

return 0;

}

//发送获取GDT表值的请求

BOOL blRet = DeviceIoControl(hFile, IOCTL_GET_GDT,

0, NULL,

szBuffer, sizeof(szBuffer),

&dwRead,

NULL);

if (blRet == FALSE)

{

printf("DeviceIoControl False!\r\n");

return 0;

}

DWORD dwSegBaseAddr = 0;

DWORD dwSegLimit = 0;

DWORD dwSegAttribt = 0;

PSEGMENT pSegmentEntry = NULL;

for (DWORD i = 0; i < dwRead; i += 8)

{

//GDT表的一项

pSegmentEntry = (PSEGMENT)(szBuffer+i);

//获取段基址-32位

dwSegBaseAddr = MAKESEGADDR(pSegmentEntry->m_BaseAddr1, pSegmentEntry->m_BaseAddr2);

//获取段界限-20位

dwSegLimit = MAKESEGLIMIT(pSegmentEntry->m_Limit1, pSegmentEntry->m_Limit2);

//获取段属性-12位

dwSegAttribt = pSegmentEntry->m_Attributes;

//显示GDT表项的值

printf("SegmentBase:%08X, SegmentLimit:%06X, SegmentAtrribute:%04X\r\n", dwSegBaseAddr, dwSegLimit, dwSegAttribt);

}

//暂停

system("pause");

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值