/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 <ntddk.h> #include <ntddstor.h> #include <mountdev.h> #include <ntddvol.h> #ifdef __cplusplus } #endif
</pre><pre name="code" class="cpp"><pre name="code" class="cpp">//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; }
</pre><pre name="code" class="cpp"><pre name="code" class="cpp">//Ring3环程序的测试环境为VC6.0 //推荐在F5调试环境下测试 //注:在GDT表的解析时,好像出了错? #include <stdlib.h> #include <Windows.h> #include <winioctl.h> //段的定义-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)) //直接使用<winioctl.h>头文件不使用宏 //驱动控制所需要的宏 //#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; }