接着就来实现对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;}
经验总结扩展阅读
- 市场开发战略是什么?
- 完 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数据驱动