zoukankan      html  css  js  c++  java
  • 获取全局描述符表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 <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!
    ");
    		return 0;
    	}
    	
    	//发送获取GDT表值的请求
    	BOOL blRet = DeviceIoControl(hFile, IOCTL_GET_GDT, 
    								0, NULL, 
    								szBuffer, sizeof(szBuffer), 
    								&dwRead, 
    								NULL);
    	if (blRet == FALSE)
    	{
    		printf("DeviceIoControl False!
    ");
    		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
    ", dwSegBaseAddr, dwSegLimit, dwSegAttribt);
    		
    	}
    	
    	//暂停
    	system("pause");
    	
    	return 0;
    }
    


    
                                        
    
  • 相关阅读:
    Bzoj1101 [POI2007]Zap
    Bzoj2393 Cirno的完美算数教室
    UVa10891 Game of Sum
    Bzoj4128 Matrix
    类的组合
    继承
    属性查找与绑定方法
    类与对象
    面向对象程序设计——基础概念
    修改个人信息的程序
  • 原文地址:https://www.cnblogs.com/csnd/p/11800747.html
Copyright © 2011-2022 走看看