接着就来实现对PEB的获取操作,以64位为例,我们需要调用PsGetProcessPeb()这个内核函数 , 因为该内核函数没有被公开所以调用之前需要头部导出,该函数需要传入用户进程的EProcess结构,该结构可用PsLookupProcessByProcessId函数动态获取到,获取到以后直接KeStackAttachProcess()附加到应用层进程上,即可直接输出进程的PEB结构信息,如下代码 。
#include "peb.h"#include <ntifs.h>// 定义导出NTKERNELAPI PVOID NTAPI PsGetProcessPeb(_In_ PEPROCESS Process);VOID UnDriver(PDRIVER_OBJECT driver){ DbgPrint(("Uninstall Driver Is OK \n"));}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){ DbgPrint("hello lyshark \n"); NTSTATUS status = STATUS_UNSUCCESSFUL; PEPROCESS eproc = NULL; KAPC_STATE kpc = { 0 }; PPEB64 pPeb64 = NULL; __try {// HANDLE)4656 进程PIDstatus = PsLookupProcessByProcessId((HANDLE)4656, &eproc);// 得到64位PEBpPeb64 = (PPEB64)PsGetProcessPeb(eproc);DbgPrint("PEB64 = %p \n", pPeb64);if (pPeb64 != 0){// 验证可读性ProbeForRead(pPeb64, sizeof(PEB32), 1);// 附加进程KeStackAttachProcess(eproc, &kpc);DbgPrint("进程基地址: 0x%p \n", pPeb64->ImageBaseAddress);DbgPrint("ProcessHeap = 0x%p \n", pPeb64->ProcessHeap);DbgPrint("BeingDebugged = %d \n", pPeb64->BeingDebugged);// 脱离进程KeUnstackDetachProcess(&kpc);} } __except (EXCEPTION_EXECUTE_HANDLER) {Driver->DriverUnload = UnDriver;return STATUS_SUCCESS; } Driver->DriverUnload = UnDriver; return STATUS_SUCCESS;}PEB64代码运行后,我们加载驱动即可看到如下结果:

文章插图
而相对于64位进程来说 , 获取32位进程的PEB信息可以直接调用PsGetProcessWow64Process()函数得到,该函数已被导出可以任意使用,获取PEB代码如下 。
#include "peb.h"#include <ntifs.h>// 定义导出NTKERNELAPI PVOID NTAPI PsGetProcessPeb(_In_ PEPROCESS Process);VOID UnDriver(PDRIVER_OBJECT driver){ DbgPrint(("Uninstall Driver Is OK \n"));}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){ DbgPrint("hello lyshark \n"); NTSTATUS status = STATUS_UNSUCCESSFUL; PEPROCESS eproc = NULL; KAPC_STATE kpc = { 0 }; PPEB32 pPeb32 = NULL; __try {// HANDLE)4656 进程PIDstatus = PsLookupProcessByProcessId((HANDLE)6164, &eproc);// 得到32位PEBpPeb32 = (PPEB32)PsGetProcessWow64Process(eproc);DbgPrint("PEB32 = %p \n", pPeb32);if (pPeb32 != 0){// 验证可读性ProbeForRead(pPeb32, sizeof(PEB32), 1);// 附加进程KeStackAttachProcess(eproc, &kpc);DbgPrint("进程基地址: 0x%p \n", pPeb32->ImageBaseAddress);DbgPrint("ProcessHeap = 0x%p \n", pPeb32->ProcessHeap);DbgPrint("BeingDebugged = %d \n", pPeb32->BeingDebugged);// 脱离进程KeUnstackDetachProcess(&kpc);} } __except (EXCEPTION_EXECUTE_HANDLER) {Driver->DriverUnload = UnDriver;return STATUS_SUCCESS; } Driver->DriverUnload = UnDriver; return STATUS_SUCCESS;}PEB32代码运行后,我们加载驱动即可看到如下结果:

文章插图
【驱动开发:内核通过PEB得到进程参数】
推荐阅读
- 完 golang开发:go并发的建议
- 三十七 Java开发学习----SpringBoot多环境配置及配置文件分类
- 🔥支持 Java 19 的轻量级应用开发框架,Solon v1.10.4 发布
- 驱动开发:内核取ntoskrnl模块基地址
- VScode开发STM32/GD32单片机-MakeFile工程JlinkRTT配置
- 一个C#开发者学习SpringCloud搭建微服务的心路历程
- VScode开发STM32/GD32单片机-环境搭建
- python+request+pymysql+pytest数据驱动
- 18 基于.NetCore开发博客项目 StarBlog - 实现本地Typora文章打包上传
- 2 Libgdx游戏开发——接水滴游戏实现