/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;
}

												

获取全局描述符表GDT的内容的更多相关文章

  1. 全局描述符表GDT

    写在前面 添油加醋系列第二弹--剖析GDT 头文件:https://github.com/bajdcc/MiniOS/blob/master/include/gdt.h 实现:https://gith ...

  2. linux内核学习之全局描述符表(GDT)(二)

    来源:https://www.cnblogs.com/longintchar/p/5224406.html 在进入保护模式之前,我们先要学习一些基础知识.今天我们看一下全局描述符表(Global De ...

  3. Bran的内核开发教程(bkerndev)-06 全局描述符表(GDT)

    全局描述符表(GDT)   在386平台各种保护措施中最重要的就是全局描述符表(GDT).GDT为内存的某些部分定义了基本的访问权限.我们可以使用GDT中的一个索引来生成段冲突异常, 让内核终止执行异 ...

  4. GDT全局描述符表

    GDT全局描述符表 什么是GDT全局描述符表 GDT全称为Global Descriptor Table,全局描述符表. 保护模式的寻址方式不在使用寄存器分段的方式直接寻址方式了.而采用的是使用GDT ...

  5. 全局描述符表(GDT)——《x86汇编语言:从实模式到保护模式》读书笔记09

    在进入保护模式之前,我们先要学习一些基础知识.今天我们看一下全局描述符表(Global Descriptor Table, 简称GDT). 同实模式一样,在保护模式下,对内存的访问仍然使用段地址加偏移 ...

  6. js获取iframe里的body内容

    做个页面 需要加入a.html 使用的js动态添加iframe 直接JQ添加的 代码 $(".banner-box").after(“<iframe src="ht ...

  7. .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?

    原文:.NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用? 都知道可以在任务管理器中查看进程的 CPU 和内存占用,那么如何通过 .NET 编写代码的方式来获取到 ...

  8. javascript获取iframe框架中页面document对象,获取子页面里面的内容,iframe获取父页面的元素,

    javascript获取iframe框架中,加载的页面document对象 因为浏览器安全限制,对跨域访问的页面,其document对象无法读取.设置属性 function getDocument(i ...

  9. Java 获取*.properties配置文件中的内容 ,常见的两种方法

    import java.io.InputStream; import java.util.Enumeration; import java.util.List; import java.util.Pr ...

随机推荐

  1. (十三)数据库查询处理之QueryExecution(2)

    (十三)数据库查询处理之QueryExecution(2) 实验室这一周真的忙爆(虽然都是各种打杂的活)所以拖了很久终于在周末(摸鱼)把实验3做完了.同时准备把和查询这一块有关的博客补一下.然后就进入 ...

  2. CMU数据库(15-445)Lab3- QUERY EXECUTION

    Lab3 - QUERY EXECUTION 实验三是添加对在数据库系统中执行查询的支持.您将实现负责获取查询计划节点并执行它们的executor.您将创建执行下列操作的executor Access ...

  3. 如何优雅的移植JavaScript组件到Blazor

    Blazor作为一个新兴的交互式 Web UI 的框架,有其自身的优缺点,如果现有的 JavaScript 组件能移植到 Blazor,无疑让 Blazor 如虎添翼,本文就介绍一下自己在开发 Bul ...

  4. python 序列与字典

    序列概念: 序列的成员有序排列,可以通过下标访问到一个或几个元素,就类似与c语言的数组. 序列的通用的操作: 1:索引 11 = [1,2,3,4] 11[0] = 1 2:切片 11[1,2,3,4 ...

  5. 【MCU】移植AT32库&FreeRTOS教程

    目录 前言 1. 移植AT库 1.1 移植内核相关文件 1.2 移植芯片型号相关文件 1.3 移植芯片外设驱动库 1.4 移植配置文件及中断回调函数文件 2. 移植FreeRTOS源码 2.1 获取 ...

  6. windows一些知识

    宽字节 1.什么是ASCII码? 一张存储了字母大小写与一些符号的表,用一个字节表示,最高位不使用,最多只能存储128个符号或字母,但世界上有很多种语言,这远远不够 2.什么是扩展ASCII码? 把最 ...

  7. 加快Python运行速度

    01 使用哈希表的数据结构 如果在程序中遇到大量搜索操作时,并且数据中没有重复项,则可以使用查找而不是循环.举例如下: items = ['a', 'b',..,'100m'] #1000s of i ...

  8. " "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问>

    " "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问> 经过前面两章的学习,应该很清楚当你在 shell prompt 后面敲打键盘.直到 ...

  9. Kubernetes工作流程--<1>

    Kubernetes工作流程 客户端创建pod 流程: 用户管理员创建 Pod 的请求默认是通过kubectl 客户端管理命令 api server 组件进行交互的,默认会将请求发送给 API Ser ...

  10. RabbitMQ 入门 (Go) - 6. 数据持久化(上)

    从本节开始,我介绍一下如何将相关数据持久化到数据库,也就是上图中蓝色的部分. 目前的问题 我先运行 6 个传感器和2 个协调器,这里我使用了批处理文件: 运行后,看一下 RabbitMQ 的管理控制台 ...