2.1 Windows驱动开发:内核链表与结构体
在Windows
内核中,为了实现高效的数据结构操作,通常会使用链表和结构体相结合的方式进行数据存储和操作。内核提供了一个专门用于链表操作的数据结构LIST_ENTRY
,可以用来描述一个链表中的每一个节点。
使用链表来存储结构体时,需要在结构体中嵌入一个LIST_ENTRY
类型的成员变量,用来连接相邻的节点。通过一些列链表操作函数,如InitializeListHead、InsertHeadList、InsertTailList、RemoveEntryList
等,可以对链表中的结构体进行插入、删除、遍历等操作。
下面是一个简单的实现,用于枚举所有用户进程,并将进程信息存储到链表结构体中:
#include <ntifs.h>
#include <windef.h>
extern PVOID PsGetProcessPeb(_In_ PEPROCESS Process);
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
extern NTKERNELAPI PVOID PsGetProcessWow64Process(_In_ PEPROCESS Process);
extern NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process);
extern NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(IN PEPROCESS Process);
typedef struct
{
DWORD Pid;
UCHAR ProcessName[2048];
DWORD Handle;
LIST_ENTRY ListEntry;
}ProcessList;
// 根据进程ID返回进程EPROCESS结构体失败返回NULL
PEPROCESS LookupProcess(HANDLE Pid)
{
PEPROCESS eprocess = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = PsLookupProcessByProcessId(Pid, &eprocess);
if (NT_SUCCESS(Status))
{
return eprocess;
}
return NULL;
}
// 内核链表操作
BOOLEAN GetAllProcess()
{
PEPROCESS eproc = NULL;
LIST_ENTRY linkListHead;
// 初始化链表头部
InitializeListHead(&linkListHead);
ProcessList *pData = NULL;
for (int temp = 0; temp < 100000; temp += 4)
{
eproc = LookupProcess((HANDLE)temp);
if (eproc != NULL)
{
STRING nowProcessnameString = { 0 };
RtlInitString(&nowProcessnameString, PsGetProcessImageFileName(eproc));
// DbgPrint("进程名: %s --> 进程PID = %d --> 父进程PPID = %d\r\n",
// PsGetProcessImageFileName(eproc), PsGetProcessId(eproc), PsGetProcessInheritedFromUniqueProcessId(eproc));
// 分配内核堆空间
pData = (ProcessList *)ExAllocatePool(PagedPool, sizeof(ProcessList));
RtlZeroMemory(pData, sizeof(ProcessList));
// 设置变量
pData->Pid = (DWORD)PsGetProcessId(eproc);
RtlCopyMemory(pData->ProcessName, PsGetProcessImageFileName(eproc), strlen(PsGetProcessImageFileName(eproc)) * 2);
pData->Handle = (DWORD)PsGetProcessInheritedFromUniqueProcessId(eproc);
// 插入元素到
InsertTailList(&linkListHead, &pData->ListEntry);
ObDereferenceObject(eproc);
}
}
// 输出链表内的数据
while (!IsListEmpty(&linkListHead))
{
LIST_ENTRY *pEntry = RemoveHeadList(&linkListHead);
pData = CONTAINING_RECORD(pEntry, ProcessList, ListEntry);
DbgPrint("%d \n", pData->Pid);
DbgPrint("%s \n", pData->ProcessName);
DbgPrint("%d \n", pData->Handle);
ExFreePool(pData);
}
return TRUE;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint(("Uninstall Driver Is OK \n"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint("hello lyshark \n");
GetAllProcess();
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
DbgView是一款用于监视内核和应用程序调试输出的工具,可以输出各种调试信息和日志信息,包括OutputDebugString
函数输出的信息。当我们在内核中调用OutputDebugString
函数输出信息时,可以通过DbgView
查看输出结果,我们手动上述代码后将可以在DbgView
中看到输出的进程信息,如下图所示;
如果需要在内核模式中返回一个结构体,可以通过定义一个结构体指针作为函数参数,将结构体指针作为函数返回值来实现。返回结构体,则可以这样来写代码。
#include <ntifs.h>
#include <windef.h>
typedef struct
{
int count;
char username[256];
char password[256];
}MyData;
// 模拟返回一个结构
BOOLEAN GetProcess(PVOID OutPut)
{
RtlZeroMemory(OutPut, sizeof(MyData));
MyData *data = OutPut;
data->count = 100;
RtlCopyMemory(data->username, "lyshark.com", sizeof("lyshark.com"));
RtlCopyMemory(data->password, "https://www.cnblogs.com/lyshark", sizeof("https://www.cnblogs.com/lyshark"));
return TRUE;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint(("Uninstall Driver Is OK \n"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint("hello lyshark \n");
PVOID Ptr = (PVOID)ExAllocatePool(NonPagedPool, sizeof(MyData));
GetProcess(Ptr);
MyData *data = (MyData *)Ptr;
DbgPrint("count = %d \n", data->count);
DbgPrint("username = %s \n", data->username);
DbgPrint("password = %s \n", data->password);
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
输出效果如下图所示;
2.1 Windows驱动开发:内核链表与结构体的更多相关文章
- Windows驱动开发-内核常用内存函数
搞内存常用函数 C语言 内核 malloc ExAllocatePool memset RtlFillMemory memcpy RtlMoveMemory free ExFreePool
- windows 驱动开发入门——驱动中的数据结构
最近在学习驱动编程方面的内容,在这将自己的一些心得分享出来,供大家参考,与大家共同进步,本人学习驱动主要是通过两本书--<独钓寒江 windows安全编程> 和 <windows驱动 ...
- Windows驱动开发(中间层)
Windows驱动开发 一.前言 依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发. 二.初步环境 1.下载安装WDK7.1.0(WinDDK\7600.16385 ...
- [Windows驱动开发](一)序言
笔者学习驱动编程是从两本书入门的.它们分别是<寒江独钓——内核安全编程>和<Windows驱动开发技术详解>.两本书分别从不同的角度介绍了驱动程序的制作方法. 在我理解,驱动程 ...
- windows驱动开发推荐书籍
[作者] 猪头三 个人网站 :http://www.x86asm.com/ [序言] 很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都 ...
- Windows驱动——读书笔记《Windows驱动开发技术详解》
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
- Windows驱动开发-IRP的完成例程
<Windows驱动开发技术详解 >331页, 在将IRP发送给底层驱动或其他驱动之前,可以对IRP设置一个完成例程,一旦底层驱动将IRP完成后,IRP完成例程立刻被处罚,通过设置完成例程 ...
- C++第三十八篇 -- 研究一下Windows驱动开发(二)--WDM式驱动的加载
基于Windows驱动开发技术详解这本书 一.简单的INF文件剖析 INF文件是一个文本文件,由若干个节(Section)组成.每个节的名称用一个方括号指示,紧接着方括号后面的就是节内容.每一行就是一 ...
- C++第三十三篇 -- 研究一下Windows驱动开发(一)内部构造介绍
因为工作原因,需要做一些与网卡有关的测试,其中涉及到了驱动这一块的知识,虽然程序可以运行,但是不搞清楚,心里总是不安,觉得没理解清楚.因此想看一下驱动开发.查了很多资料,看到有人推荐Windows驱动 ...
- Windows 驱动开发 - 5
上篇<Windows 驱动开发 - 4>我们已经完毕了硬件准备. 可是我们还没有详细的数据操作,比如接收读写操作. 在WDF中进行此类操作前须要进行设备的IO控制,已保持数据的完整性. 我 ...
随机推荐
- 【mongodb】pymongo使用
pymongo基本使用 import pymongo from bson.objectid import ObjectId # 连接方式1 client = pymongo.MongoClient(h ...
- CS01 BOM客制化屏幕增强
一.BOM行项目新增定制字段 效果如下 二.前台增强实现步骤 1.行项目表新增字段 2.CMOD,增强项目PCSD0002:在行项目中增强(PCSD0003:在抬头增强) 3.双击创建定制化屏幕 4. ...
- LiveData的用法
一.实时数据LiveData 在上一节中,我们学习了ViewModel,了解到ViewModel的主要作用是存放页面所需要的各种数据.我们在示例代码中定义了接口,当数据发生变化的时候,采用接口的方式实 ...
- Vue3使用vue-video-player组件
1.安装依赖(亲测5.0.1版本可用,最新版本会找不到'vue-video-player/src/custom-theme.css'这个样式) yarn add vue-video-player@5 ...
- DDD领域驱动设计 (C# 整理自“老张的哲学”)
大话DDD领域驱动设计 概念 Domain Driven Design 领域驱动设计 第一个D(Domain): 领域:指围绕业务为核心而划分的实体模块. 第二个D(Driven): 驱动:这里的驱动 ...
- 小白学标准库之反射 reflect
1. 反射简介 反射是 元编程 概念下的一种形式,它在运行时操作不同类型的对象,检查对象的类型,大小等信息,对于没有源代码的包反射尤其有用. 设想一个场景,读取一个包中变量 a 的类型,并打印该类型的 ...
- android studio 如何把依赖导出成 jar
反编译工具 dex-tools-2.1-SNAPSHOT 第一步 用一个普通的app工程,引用所有的库,然后生成apk文件 第二步 把apk文件,改扩展名为zip,解压后,里面有几个*.dex文件,拷 ...
- 海思Hi35xx 通过uboot查看flash指定地址的数据
前言 在实际应用中有遇到过设备放置一段时间后设备不能启动的问题,uboot 完全没有响应,类似于flash中的数据被擦洗掉一样. 网上有介绍说是nandflash 不稳定,高温或是静电会导致nan ...
- [转帖]将 Cloudflare 连接到互联网的代理——Pingora 的构建方式
https://zhuanlan.zhihu.com/p/575228941 简介 今天,我们很高兴有机会在此介绍 Pingora,这是我们使用 Rust 在内部构建的新 HTTP 代理,它每天处理超 ...
- Windows 磁盘部分性能数据获取
Windows 磁盘部分性能数据获取 摘要 每次晚上加班总有收获 这次发现了一个fio for windows版本的压测程序, 准备学习和使用一下. https://github.com/axboe/ ...