網站首頁 編程語言 正文
Windows內核中是無法使用vector
容器等數據結構的,當我們需要保存一個結構體數組時,就需要使用內核中提供的專用鏈表結構LIST_ENTRY
通過一些列鏈表操作函數對結構體進行裝入彈出等操作,如下代碼是本人總結的內核中使用鏈表存儲多個結構體的通用案例。
首先實現一個枚舉用戶進程功能,將枚舉到的進程存儲到鏈表結構體內。
#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; } // 內核鏈表操作 // By: LyShark 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.com \n"); GetAllProcess(); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
運行后將可以在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.com \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; }
輸出效果如下:
原文鏈接:https://www.cnblogs.com/LyShark/p/16723935.html
相關推薦
- 2023-01-31 golang獲取變量或對象類型的幾種方式總結_Golang
- 2022-06-21 Android實現登錄注冊功能_Android
- 2022-09-15 Python利用shutil實現拷貝文件功能_python
- 2022-04-16 實例講解python讀取各種文件的方法_python
- 2022-05-14 Centos8安裝docker報錯(錯誤提示:All?mirrors?were?tried)的問題_
- 2022-11-11 C++?左值引用與一級指針示例詳解_C 語言
- 2022-09-04 Go語言流程控制語句_Golang
- 2023-02-27 pandas?pd.cut()與pd.qcut()的具體實現_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支