内核数据结构
1.LIST_ENTRY
2.HASH表
3.TREE树
4.LookAside结构
一.LIST_ENTRY
获取成员在结构体中的偏移
根据上面得到Entry
LIST_ENTRY使用方法
例子:删除文件夹下的所有文件
1.LIST_ENTRY
2.HASH表
3.TREE树
4.LookAside结构
一.LIST_ENTRY
typedef _struct _MYDATA_LIST
{
LIST_ENTRY Entry;
WCHAR NameBuffer[MAX_PATH];
} MYDATA_LIST_ENTRY,
*PMYDATA_LIST_ENTRY;
PLIST_ENTRY pListHead;//头指针
typedef struct _LIST_ENTRY
{
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY,*PLIST_ENTRY;
获取成员在结构体中的偏移
#define offsetof(s,m) (size_t)&(((s *)0)->m)
根据上面得到Entry
PMYDATA_LIST_ENTRY dataEntry = CONTAINING_RECORD(pList, MYDATA_LIST_ENTRY, Entry);
dataEntry->wszFileName
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
LIST_ENTRY使用方法
LIST_ENTRY listHead;//头指针
PMYDATA_LIST_ENTRY tmpEntry;//结点,须自己初始化值
InitializeListHead(&listHead);//初始化
InsertHeadList(&listHead, &tmpEntry->Entry); //结点头插入
InsertTailList(&listHead, &tmpEntry->Entry); //结点尾插入
如果是接点头移除 节点为插入则为队列
头部插入头部删除 就是栈 尾部插入 尾部删除也是栈
IsListEmpty(&listHead);//判断是否为空链表
PLIST_ENTRY listEntry = RemoveHeadList(&listHead);//移除
PLIST_ENTRY listEntry = RemoveTailList(&listHead);//移除
//枚举
PLIST_ENTRY plistHead = &listHead;
PLIST_ENTRY pList = NULL;
PMYDATA_LIST_ENTRY dataEntry = NULL;
For(pList = plistHead ->Flink; pList != plistHead; pList = pList->Flink)
{
dataEntry = CONTAINING_RECORD(pList,
MYDATA_LIST_ENTRY, Entry);
DbgPrint(“%S\n”, dataEntry->NameBuffer);
}
RemoveEntryList(&dataEntry->Entry);
//删除
while(!IsListEmpty(&listHead))
{
listEntry = RemoveHeadList(&listHead);
dataEntry = CONTAINING_RECORD(
listEntry,
SBPROCESS_ENTRY,
Entry
);
DbgPrint(“%ws\n”, dataEntry->NameBuffer);
RemoveEntryList(listEntry);//删除接点
ExFreePool(dataEntry);
}
例子:删除文件夹下的所有文件
#include <ntddk.h>
typedef unsigned long ULONG;
typedef struct _FILE_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
typedef struct _FILE_LIST_ENTRY {
LIST_ENTRY Entry;
PWSTR NameBuffer;
} FILE_LIST_ENTRY, *PFILE_LIST_ENTRY;
NTSTATUS
ZwQueryDirectoryFile(
__in HANDLE FileHandle,
__in_opt HANDLE Event,
__in_opt PIO_APC_ROUTINE ApcRoutine,
__in_opt PVOID ApcContext,
__out PIO_STATUS_BLOCK IoStatusBlock,
__out PVOID FileInformation,
__in ULONG Length,
__in FILE_INFORMATION_CLASS FileInformationClass,
__in BOOLEAN ReturnSingleEntry,
__in_opt PUNICODE_STRING FileName,
__in BOOLEAN RestartScan
);
NTSTATUS
dfDeleteFile(const WCHAR *fileName)
{
OBJECT_ATTRIBUTES objAttributes = {0};
IO_STATUS_BLOCK iosb = {0};
HANDLE handle = NULL;
FILE_DISPOSITION_INFORMATION disInfo = {0};
UNICODE_STRING uFileName = {0};
NTSTATUS status = 0;
RtlInitUnicodeString(&uFileName, fileName);
InitializeObjectAttributes(&objAttributes, &uFileName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateFile(
&handle,
SYNCHRONIZE | FILE_WRITE_DATA | DELETE,
&objAttributes,
&iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DELETE_ON_CLOSE,
NULL,
0);
if (!NT_SUCCESS(status))
{
if (status == STATUS_ACCESS_DENIED)
{
status = ZwCreateFile(
&handle,
SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
&objAttributes,
&iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(status))
{
FILE_BASIC_INFORMATION basicInfo = {0};
status = ZwQueryInformationFile(handle, &iosb,
&basicInfo, sizeof(basicInfo), FileBasicInformation);
if (!NT_SUCCESS(status))
{
KdPrint(("ZwQueryInformationFile(%wZ) failed(%x)\n", &uFileName, status));
}
basicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
status = ZwSetInformationFile(handle, &iosb,
&basicInfo, sizeof(bas