当前位置: 首页 > news >正文

上海网站建设联系方式app设计网站推荐

上海网站建设联系方式,app设计网站推荐,鞍山建站,牛天下网站做的怎么样在Windows内核中,每个设备驱动程序都需要一个DRIVER_OBJECT对象,该对象由系统创建并传递给驱动程序的DriverEntry函数。驱动程序使用此对象来注册与设备对象和其他系统对象的交互,并在操作系统需要与驱动程序进行交互时使用此对象。DRIVER_OB…

在Windows内核中,每个设备驱动程序都需要一个DRIVER_OBJECT对象,该对象由系统创建并传递给驱动程序的DriverEntry函数。驱动程序使用此对象来注册与设备对象和其他系统对象的交互,并在操作系统需要与驱动程序进行交互时使用此对象。DRIVER_OBJECT对象还包含了与驱动程序所管理的设备对象相关联的设备扩展结构,以及用于处理I/O请求的函数指针等信息。它是驱动程序与操作系统内核之间的桥梁,用于协调设备的操作和管理。

本章将探索驱动程序开发的基础部分,了解驱动对象DRIVER_OBJECT结构体的定义,一般来说驱动程序DriverEntry入口处都会存在这样一个驱动对象,该对象内所包含的就是当前所加载驱动自身的一些详细参数,例如驱动大小,驱动标志,驱动名,驱动节等等,每一个驱动程序都会存在这样的一个结构,首先来看一下微软对其的定义;

typedef struct _DRIVER_OBJECT {CSHORT Type;                                // 驱动类型CSHORT Size;                                // 驱动大小PDEVICE_OBJECT DeviceObject;                // 驱动对象ULONG Flags;                                // 驱动的标志PVOID DriverStart;                          // 驱动的起始位置ULONG DriverSize;                           // 驱动的大小PVOID DriverSection;                        // 指向驱动程序映像的内存区对象PDRIVER_EXTENSION DriverExtension;          // 驱动的扩展空间UNICODE_STRING DriverName;                  // 驱动名字PUNICODE_STRING HardwareDatabase;PFAST_IO_DISPATCH FastIoDispatch;PDRIVER_INITIALIZE DriverInit;PDRIVER_STARTIO DriverStartIo;PDRIVER_UNLOAD DriverUnload;                 // 驱动对象的卸载地址PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT;

那么如果我们想要遍历出当前自身驱动的一些基本信息,我们只需要在驱动的头部解析_DRIVER_OBJECT即可得到全部的数据,这段代码可以写成如下样子,其中的IRP_MJ_这一系列则是微软的调用号,不同的RIP代表着不同的涵义,但一般驱动也就会用到如下这几种调用号。

#include <ntifs.h>VOID UnDriver(PDRIVER_OBJECT driver)
{DbgPrint(("Uninstall Driver Is OK \n"));
}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{DbgPrint("hello lyshark \n");Driver->DriverUnload = UnDriver;DbgPrint("驱动名字 = %wZ \n", Driver->DriverName);DbgPrint("驱动起始地址 = %p | 大小 = %x | 结束地址 %p \n",Driver->DriverStart,Driver->DriverSize,(ULONG64)Driver->DriverStart + Driver->DriverSize);DbgPrint("卸载地址 = %p\n", Driver->DriverUnload);DbgPrint("IRP_MJ_READ地址 = %p\n", Driver->MajorFunction[IRP_MJ_READ]);DbgPrint("IRP_MJ_WRITE地址 = %p\n", Driver->MajorFunction[IRP_MJ_WRITE]);DbgPrint("IRP_MJ_CREATE地址 = %p\n", Driver->MajorFunction[IRP_MJ_CREATE]);DbgPrint("IRP_MJ_CLOSE地址 = %p\n", Driver->MajorFunction[IRP_MJ_CLOSE]);DbgPrint("IRP_MJ_DEVICE_CONTROL地址 = %p\n", Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL]);// 输出完整的调用号for (auto i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++){DbgPrint("IRP_MJ调用号 = %d | 函数地址 = %p \r\n", i, Driver->MajorFunction[i]);}Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

编译这段程序,签名并运行,我们即可看到如下输出信息,此时当前自身驱动的详细参数都可以被输出;

当然运用_DRIVER_OBJECT对象中的DriverSection字段我们完全可以遍历输出当前系统下所有的驱动程序的具体信息,DriverSection结构指向了一个_LDR_DATA_TABLE_ENTRY结构,结构的微软定义如下;

typedef struct _LDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;LIST_ENTRY InMemoryOrderLinks;LIST_ENTRY InInitializationOrderLinks;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT TlsIndex;union {LIST_ENTRY HashLinks;struct {PVOID SectionPointer;ULONG CheckSum;};};union {struct {ULONG TimeDateStamp;};struct {PVOID LoadedImports;};};
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

为了能够遍历出所有的系统驱动,我们需要得到pLdr结构,该结构可通过Driver->DriverSection的方式获取到,获取到之后通过pLdr->InLoadOrderLinks.Flink得到当前驱动的入口地址,而每一次调用pListEntry->Flink都将会指向下一个驱动对象,通过不断地循环CONTAINING_RECORD解析,即可输出当前系统内所有驱动的详细信息。这段程序的写法可以如下所示;

#include <ntifs.h>typedef struct _LDR_DATA_TABLE_ENTRY {LIST_ENTRY InLoadOrderLinks;LIST_ENTRY InMemoryOrderLinks;LIST_ENTRY InInitializationOrderLinks;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT TlsIndex;union {LIST_ENTRY HashLinks;struct {PVOID SectionPointer;ULONG CheckSum;};};union {struct {ULONG TimeDateStamp;};struct {PVOID LoadedImports;};};
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;VOID UnDriver(PDRIVER_OBJECT driver)
{DbgPrint(("Uninstall Driver Is OK \n"));
}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{DbgPrint("hello lyshark \n");Driver->DriverUnload = UnDriver;PLDR_DATA_TABLE_ENTRY pLdr = NULL;PLIST_ENTRY pListEntry = NULL;PLIST_ENTRY pCurrentListEntry = NULL;PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;pLdr = (PLDR_DATA_TABLE_ENTRY)Driver->DriverSection;pListEntry = pLdr->InLoadOrderLinks.Flink;pCurrentListEntry = pListEntry->Flink;// 判断是否结束while (pCurrentListEntry != pListEntry){// 获取LDR_DATA_TABLE_ENTRY结构pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);if (pCurrentModule->BaseDllName.Buffer != 0){DbgPrint("模块名 = %wZ | 模块基址 = %p | 模块入口 = %p | 模块时间戳 = %d \n",pCurrentModule->BaseDllName,pCurrentModule->DllBase,pCurrentModule->EntryPoint,pCurrentModule->TimeDateStamp);}pCurrentListEntry = pCurrentListEntry->Flink;}Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

编译这段程序,签名并运行,我们即可看到如下输出信息,此时当前自身驱动的详细参数都可以被输出;

通过使用上一篇文章《内核字符串拷贝与比较》中所介绍的的RtlCompareUnicodeString函数,还可用于对比与过滤特定结果,以此来实现通过驱动名返回驱动基址的功能。

LONGLONG GetModuleBaseByName(PDRIVER_OBJECT pDriverObj, UNICODE_STRING ModuleName)
{PLDR_DATA_TABLE_ENTRY pLdr = NULL;PLIST_ENTRY pListEntry = NULL;PLIST_ENTRY pCurrentListEntry = NULL;PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;pListEntry = pLdr->InLoadOrderLinks.Flink;pCurrentListEntry = pListEntry->Flink;while (pCurrentListEntry != pListEntry){// 获取LDR_DATA_TABLE_ENTRY结构pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);if (pCurrentModule->BaseDllName.Buffer != 0){// 对比模块名if (RtlCompareUnicodeString(&pCurrentModule->BaseDllName, &ModuleName, TRUE) == 0){return (LONGLONG)pCurrentModule->DllBase;}}pCurrentListEntry = pCurrentListEntry->Flink;}return 0;
}

上这段代码的使用也非常简单,通过传入一个UNICODE_STRING类型的模块名,即可获取到模块基址并返回,至于如何初始化UNICODE_STRING则在《内核字符串转换方法》中有详细的介绍,此处你只需要这样来写。

NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{DbgPrint("hello lyshark \n");UNICODE_STRING unicode;// 获取WinDDK驱动基地址RtlUnicodeStringInit(&unicode, L"WinDDK.sys");LONGLONG winddk_address = GetModuleBaseByName(Driver, unicode);DbgPrint("WinDDK模块基址 = %p \n", winddk_address);// 获取ACPI驱动基地址RtlUnicodeStringInit(&unicode, L"ACPI.sys");LONGLONG acpi_address = GetModuleBaseByName(Driver, unicode);DbgPrint("ACPI模块基址 = %p \n", acpi_address);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

运行这段驱动程序,即可分别输出WinDDK.sys以及ACPI.sys两个驱动模块的基地址;

http://www.yayakq.cn/news/39038/

相关文章:

  • 北京网站建设建站公司wordpress大学打不开
  • 网络设计的步骤包括东莞搜索seo关键词
  • 印度购物网站排名网站建设需经历的步骤
  • 内蒙古建设兵团网站网站数据每隔几秒切换怎么做的
  • 网站外链分析有哪些室内设计网站
  • 品牌网站案例网页设计入门+齿轮
  • 电子商务网站建设首要问题是人工智能网站开发
  • 简单的方法搭建网站太平洋建设集团有限公司网站
  • 公司网站要备案么鞍山网站制作一般需要多少钱
  • 网站项目的推广网络推广公司怎么找客户
  • 网站建设宣传素材免费的网站
  • 服务器网站慢的原因怎么在自己的网站上做链接
  • 仿牌网站空间wordpress 豆瓣电影
  • 是不是做推广都得有网站注册一个公司的流程
  • 招投标网站销售怎么做网络营销推广计划
  • 五个常见的电子商务网站网址wordpress固定链接标签加上页面
  • wordpress用户注册功能wordpress seo知乎
  • 外贸免费网站制作企业商务网
  • 做高端生活方式的网站网页设计规范导航栏尺寸
  • 个人网站开发总结文档企业网站内容建设 知乎
  • 加强网站互动交流平台建设自查网页版微信二维码加载失败
  • 公司网站建设的基本流程杭州建设工程交易网
  • 免费网站空间可上传网站一键搭建网站系统
  • wordpress themepath整站建设和网站优化
  • 那个网站教做仙芋鲜泸州网站建设公司
  • 做公司 网站pc响应式网站设计
  • 网站建设对接流程图对电子商务网站建设的理解
  • 陕西有没有做网站普查公司积极推进政务网站建设
  • 网站建设与管理专业好吗企业网站建设该怎么描述
  • 南沙外贸网站建设青创网站首页