驱动开发:内核遍历进程VAD结构体
在上一篇文章《驱动开发:内核中实现Dump进程转储》
中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍VAD
结构,该结构的全程是Virtual Address Descriptor
即虚拟地址描述符
,VAD是一个AVL
自平衡二叉树
,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个VAD
节点,由一个MMVAD
结构完整描述。
VAD结构的遍历效果如下:
那么这个结构在哪?每一个进程都有自己单独的VAD
结构树,这个结构通常在EPROCESS
结构里面里面,在内核调试模式下使用dt _EPROCESS
可得到如下信息。
lyshark.com 1: kd> dt _EPROCESS
ntdll!_EPROCESS
+0x500 Vm : _MMSUPPORT_FULL
+0x640 MmProcessLinks : _LIST_ENTRY
+0x650 ModifiedPageCount : Uint4B
+0x654 ExitStatus : Int4B
+0x658 VadRoot : _RTL_AVL_TREE
+0x660 VadHint : Ptr64 Void
+0x668 VadCount : Uint8B
+0x670 VadPhysicalPages : Uint8B
+0x678 VadPhysicalPagesLimit : Uint8B
可以看到在本系统中VAD的偏移是+0x658
紧跟其后的还有vadCount
的计数等。
VAD结构是如何被添加的?通常情况下系统调用VirtualAllocate
等申请一段堆内存时,则会在VAD树上增加一个结点_MMVAD
结构体,需要说明的是栈并不受VAD的管理。由系统直接分配空间,并把地址记录在了TEB中。
lyshark.com 0: kd> dt _MMVAD
nt!_MMVAD
+0x000 Core : _MMVAD_SHORT
+0x040 u2 : <anonymous-tag>
+0x048 Subsection : Ptr64 _SUBSECTION
+0x050 FirstPrototypePte : Ptr64 _MMPTE
+0x058 LastContiguousPte : Ptr64 _MMPTE
+0x060 ViewLinks : _LIST_ENTRY
+0x070 VadsProcess : Ptr64 _EPROCESS
+0x078 u4 : <anonymous-tag>
+0x080 FileObject : Ptr64 _FILE_OBJECT
结构体MMVAD
则是每一个VAD
内存块的属性,这个内存结构定义在WinDBG中可看到。
如上在EPROCESS
结构中可以找到VAD结构的相对偏移+0x658
以及进程VAD计数偏移+0x668
,我们首先通过!process 0 0
指令得到当前所有进程的EPROCESS
结构,并选中进程。
lyshark.com 0: kd> !process 0 0
PROCESS ffffe28fbb0860c0
SessionId: 1 Cid: 11a8 Peb: 0035c000 ParentCid: 11c8
DirBase: 309f3002 ObjectTable: ffffac87ba3da580 HandleCount: 145.
Image: x64.exe
此处的ffffe28fbb0860c0
正是我们所需要的EPROCESS
结构。
当需要得到该进程的VAD结构时,只需要使用!vad ffffe28fbb0860c0 + 0x658
来显示该进程的VAD树。
至于获取VAD有多少条,则可以直接使用!vad ffffe28fbb0860c0 + 0x668
来获取到。
既然手动可以遍历出来,那么自动化也并不难,首先定义头文件vad.h
同样这是微软定义,如果想要的到最新的,自己下载WinDBG调试内核输入命令。
#pragma once
#include <ntifs.h>
typedef struct _MM_GRAPHICS_VAD_FLAGS // 15 elements, 0x4 bytes (sizeof)
{
/*0x000*/ ULONG32 Lock : 1; // 0 BitPosition
/*0x000*/ ULONG32 LockContended : 1; // 1 BitPosition
/*0x000*/ ULONG32 DeleteInProgress : 1; // 2 BitPosition
/*0x000*/ ULONG32 NoChange : 1; // 3 BitPosition
/*0x000*/ ULONG32 VadType : 3; // 4 BitPosition
/*0x000*/ ULONG32 Protection : 5; // 7 BitPosition
/*0x000*/ ULONG32 PreferredNode : 6; // 12 BitPosition
/*0x000*/ ULONG32 PageSize : 2; // 18 BitPosition
/*0x000*/ ULONG32 PrivateMemoryAlwaysSet : 1; // 20 BitPosition
/*0x000*/ ULONG32 WriteWatch : 1; // 21 BitPosition
/*0x000*/ ULONG32 FixedLargePageSize : 1; // 22 BitPosition
/*0x000*/ ULONG32 ZeroFillPagesOptional : 1; // 23 BitPosition
/*0x000*/ ULONG32 GraphicsAlwaysSet : 1; // 24 BitPosition
/*0x000*/ ULONG32 GraphicsUseCoherentBus : 1; // 25 BitPosition
/*0x000*/ ULONG32 GraphicsPageProtection : 3; // 26 BitPosition
}MM_GRAPHICS_VAD_FLAGS, *PMM_GRAPHICS_VAD_FLAGS;
typedef struct _MM_PRIVATE_VAD_FLAGS // 15 elements, 0x4 bytes (sizeof)
{
/*0x000*/ ULONG32 Lock : 1; // 0 BitPosition
/*0x000*/ ULONG32 LockContended : 1; // 1 BitPosition
/*0x000*/ ULONG32 DeleteInProgress : 1; // 2 BitPosition
/*0x000*/ ULONG32 NoChange : 1; // 3 BitPosition
/*0x000*/ ULONG32 VadType : 3; // 4 BitPosition
/*0x000*/ ULONG32 Protection : 5; // 7 BitPosition
/*0x000*/ ULONG32 PreferredNode : 6; // 12 BitPosition
/*0x000*/ ULONG32 PageSize : 2; // 18 BitPosition
/*0x000*/ ULONG32 PrivateMemoryAlwaysSet : 1; // 20 BitPosition
/*0x000*/ ULONG32 WriteWatch : 1; // 21 BitPosition
/*0x000*/ ULONG32 FixedLargePageSize : 1; // 22 BitPosition
/*0x000*/ ULONG32 ZeroFillPagesOptional : 1; // 23 BitPosition
/*0x000*/ ULONG32 Graphics : 1; // 24 BitPosition
/*0x000*/ ULONG32 Enclave : 1; // 25 BitPosition
/*0x000*/ ULONG32 ShadowStack : 1; // 26 BitPosition
}MM_PRIVATE_VAD_FLAGS, *PMM_PRIVATE_VAD_FLAGS;
typedef struct _MMVAD_FLAGS // 9 elements, 0x4 bytes (sizeof)
{
/*0x000*/ ULONG32 Lock : 1; // 0 BitPosition
/*0x000*/ ULONG32 LockContended : 1; // 1 BitPosition
/*0x000*/ ULONG32 DeleteInProgress : 1; // 2 BitPosition
/*0x000*/ ULONG32 NoChange : 1; // 3 BitPosition
/*0x000*/ ULONG32 VadType : 3; // 4 BitPosition
/*0x000*/ ULONG32 Protection : 5; // 7 BitPosition
/*0x000*/ ULONG32 PreferredNode : 6; // 12 BitPosition
/*0x000*/ ULONG32 PageSize : 2; // 18 BitPosition
/*0x000*/ ULONG32 PrivateMemory : 1; // 20 BitPosition
}MMVAD_FLAGS, *PMMVAD_FLAGS;
typedef struct _MM_SHARED_VAD_FLAGS // 11 elements, 0x4 bytes (sizeof)
{
/*0x000*/ ULONG32 Lock : 1; // 0 BitPosition
/*0x000*/ ULONG32 LockContended : 1; // 1 BitPosition
/*0x000*/ ULONG32 DeleteInProgress : 1; // 2 BitPosition
/*0x000*/ ULONG32 NoChange : 1; // 3 BitPosition
/*0x000*/ ULONG32 VadType : 3; // 4 BitPosition
/*0x000*/ ULONG32 Protection : 5; // 7 BitPosition
/*0x000*/ ULONG32 PreferredNode : 6; // 12 BitPosition
/*0x000*/ ULONG32 PageSize : 2; // 18 BitPosition
/*0x000*/ ULONG32 PrivateMemoryAlwaysClear : 1; // 20 BitPosition
/*0x000*/ ULONG32 PrivateFixup : 1; // 21 BitPosition
/*0x000*/ ULONG32 HotPatchAllowed : 1; // 22 BitPosition
}MM_SHARED_VAD_FLAGS, *PMM_SHARED_VAD_FLAGS;
typedef struct _MMVAD_FLAGS2 // 7 elements, 0x4 bytes (sizeof)
{
/*0x000*/ ULONG32 FileOffset : 24; // 0 BitPosition
/*0x000*/ ULONG32 Large : 1; // 24 BitPosition
/*0x000*/ ULONG32 TrimBehind : 1; // 25 BitPosition
/*0x000*/ ULONG32 Inherit : 1; // 26 BitPosition
/*0x000*/ ULONG32 NoValidationNeeded : 1; // 27 BitPosition
/*0x000*/ ULONG32 PrivateDemandZero : 1; // 28 BitPosition
/*0x000*/ ULONG32 Spare : 3; // 29 BitPosition
}MMVAD_FLAGS2, *PMMVAD_FLAGS2;
typedef struct _MMVAD_SHORT
{
RTL_BALANCED_NODE VadNode;
UINT32 StartingVpn; /*0x18*/
UINT32 EndingVpn; /*0x01C*/
UCHAR StartingVpnHigh;
UCHAR EndingVpnHigh;
UCHAR CommitChargeHigh;
UCHAR SpareNT64VadUChar;
INT32 ReferenceCount;
EX_PUSH_LOCK PushLock; /*0x028*/
struct
{
union
{
ULONG_PTR flag;
MM_PRIVATE_VAD_FLAGS PrivateVadFlags; /*0x030*/
MMVAD_FLAGS VadFlags;
MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;
MM_SHARED_VAD_FLAGS SharedVadFlags;
}Flags;
}u1;
PVOID EventList; /*0x038*/
}MMVAD_SHORT, *PMMVAD_SHORT;
typedef struct _MMADDRESS_NODE
{
ULONG64 u1;
struct _MMADDRESS_NODE* LeftChild;
struct _MMADDRESS_NODE* RightChild;
ULONG64 StartingVpn;
ULONG64 EndingVpn;
}MMADDRESS_NODE, *PMMADDRESS_NODE;
typedef struct _MMEXTEND_INFO // 2 elements, 0x10 bytes (sizeof)
{
/*0x000*/ UINT64 CommittedSize;
/*0x008*/ ULONG32 ReferenceCount;
/*0x00C*/ UINT8 _PADDING0_[0x4];
}MMEXTEND_INFO, *PMMEXTEND_INFO;
struct _SEGMENT
{
struct _CONTROL_AREA* ControlArea;
ULONG TotalNumberOfPtes;
ULONG SegmentFlags;
ULONG64 NumberOfCommittedPages;
ULONG64 SizeOfSegment;
union
{
struct _MMEXTEND_INFO* ExtendInfo;
void* BasedAddress;
}u;
ULONG64 SegmentLock;
ULONG64 u1;
ULONG64 u2;
PVOID* PrototypePte;
ULONGLONG ThePtes[0x1];
};
typedef struct _EX_FAST_REF
{
union
{
PVOID Object;
ULONG_PTR RefCnt : 3;
ULONG_PTR Value;
};
} EX_FAST_REF, *PEX_FAST_REF;
typedef struct _CONTROL_AREA // 17 elements, 0x80 bytes (sizeof)
{
/*0x000*/ struct _SEGMENT* Segment;
union // 2 elements, 0x10 bytes (sizeof)
{
/*0x008*/ struct _LIST_ENTRY ListHead; // 2 elements, 0x10 bytes (sizeof)
/*0x008*/ VOID* AweContext;
};
/*0x018*/ UINT64 NumberOfSectionReferences;
/*0x020*/ UINT64 NumberOfPfnReferences;
/*0x028*/ UINT64 NumberOfMappedViews;
/*0x030*/ UINT64 NumberOfUserReferences;
/*0x038*/ ULONG32 u; // 2 elements, 0x4 bytes (sizeof)
/*0x03C*/ ULONG32 u1; // 2 elements, 0x4 bytes (sizeof)
/*0x040*/ struct _EX_FAST_REF FilePointer; // 3 elements, 0x8 bytes (sizeof)
// 4 elements, 0x8 bytes (sizeof)
}CONTROL_AREA, *PCONTROL_AREA;
typedef struct _SUBSECTION_
{
struct _CONTROL_AREA* ControlArea;
}SUBSECTION, *PSUBSECTION;
typedef struct _MMVAD
{
MMVAD_SHORT Core;
union /*0x040*/
{
UINT32 LongFlags2;
//现在用不到省略
MMVAD_FLAGS2 VadFlags2;
}u2;
PSUBSECTION Subsection; /*0x048*/
PVOID FirstPrototypePte; /*0x050*/
PVOID LastContiguousPte; /*0x058*/
LIST_ENTRY ViewLinks; /*0x060*/
PEPROCESS VadsProcess; /*0x070*/
PVOID u4; /*0x078*/
PVOID FileObject; /*0x080*/
}MMVAD, *PMMVAD;
typedef struct _RTL_AVL_TREE // 1 elements, 0x8 bytes (sizeof)
{
/*0x000*/ struct _RTL_BALANCED_NODE* Root;
}RTL_AVL_TREE, *PRTL_AVL_TREE;
typedef struct _VAD_INFO_
{
ULONG_PTR pVad;
ULONG_PTR startVpn;
ULONG_PTR endVpn;
ULONG_PTR pFileObject;
ULONG_PTR flags;
}VAD_INFO, *PVAD_INFO;
typedef struct _ALL_VADS_
{
ULONG nCnt;
VAD_INFO VadInfos[1];
}ALL_VADS, *PALL_VADS;
typedef struct _MMSECTION_FLAGS // 27 elements, 0x4 bytes (sizeof)
{
/*0x000*/ UINT32 BeingDeleted : 1; // 0 BitPosition
/*0x000*/ UINT32 BeingCreated : 1; // 1 BitPosition
/*0x000*/ UINT32 BeingPurged : 1; // 2 BitPosition
/*0x000*/ UINT32 NoModifiedWriting : 1; // 3 BitPosition
/*0x000*/ UINT32 FailAllIo : 1; // 4 BitPosition
/*0x000*/ UINT32 Image : 1; // 5 BitPosition
/*0x000*/ UINT32 Based : 1; // 6 BitPosition
/*0x000*/ UINT32 File : 1; // 7 BitPosition
/*0x000*/ UINT32 AttemptingDelete : 1; // 8 BitPosition
/*0x000*/ UINT32 PrefetchCreated : 1; // 9 BitPosition
/*0x000*/ UINT32 PhysicalMemory : 1; // 10 BitPosition
/*0x000*/ UINT32 ImageControlAreaOnRemovableMedia : 1; // 11 BitPosition
/*0x000*/ UINT32 Reserve : 1; // 12 BitPosition
/*0x000*/ UINT32 Commit : 1; // 13 BitPosition
/*0x000*/ UINT32 NoChange : 1; // 14 BitPosition
/*0x000*/ UINT32 WasPurged : 1; // 15 BitPosition
/*0x000*/ UINT32 UserReference : 1; // 16 BitPosition
/*0x000*/ UINT32 GlobalMemory : 1; // 17 BitPosition
/*0x000*/ UINT32 DeleteOnClose : 1; // 18 BitPosition
/*0x000*/ UINT32 FilePointerNull : 1; // 19 BitPosition
/*0x000*/ ULONG32 PreferredNode : 6; // 20 BitPosition
/*0x000*/ UINT32 GlobalOnlyPerSession : 1; // 26 BitPosition
/*0x000*/ UINT32 UserWritable : 1; // 27 BitPosition
/*0x000*/ UINT32 SystemVaAllocated : 1; // 28 BitPosition
/*0x000*/ UINT32 PreferredFsCompressionBoundary : 1; // 29 BitPosition
/*0x000*/ UINT32 UsingFileExtents : 1; // 30 BitPosition
/*0x000*/ UINT32 PageSize64K : 1; // 31 BitPosition
}MMSECTION_FLAGS, *PMMSECTION_FLAGS;
typedef struct _SECTION // 9 elements, 0x40 bytes (sizeof)
{
/*0x000*/ struct _RTL_BALANCED_NODE SectionNode; // 6 elements, 0x18 bytes (sizeof)
/*0x018*/ UINT64 StartingVpn;
/*0x020*/ UINT64 EndingVpn;
/*0x028*/ union {
PCONTROL_AREA ControlArea;
PVOID FileObject;
}u1; // 4 elements, 0x8 bytes (sizeof)
/*0x030*/ UINT64 SizeOfSection;
/*0x038*/ union {
ULONG32 LongFlags;
MMSECTION_FLAGS Flags;
}u; // 2 elements, 0x4 bytes (sizeof)
struct // 3 elements, 0x4 bytes (sizeof)
{
/*0x03C*/ ULONG32 InitialPageProtection : 12; // 0 BitPosition
/*0x03C*/ ULONG32 SessionId : 19; // 12 BitPosition
/*0x03C*/ ULONG32 NoValidationNeeded : 1; // 31 BitPosition
};
}SECTION, *PSECTION;
引入vad.h
头文件,并写入如下代码,此处的eprocess_offset_VadRoot
以及eprocess_offset_VadCount
则是上方得出的相对于EPROCESS
结构的偏移值,每个系统都不一样,版本不同偏移值会不同。
#include "vad.h"
#include <ntifs.h>
// 定义VAD相对于EProcess头部偏移值
#define eprocess_offset_VadRoot 0x658
#define eprocess_offset_VadCount 0x668
VOID EnumVad(PMMVAD Root, PALL_VADS pBuffer, ULONG nCnt)
{
if (!Root || !pBuffer || !nCnt)
{
return;
}
__try
{
if (nCnt > pBuffer->nCnt)
{
// 得到起始页与结束页
ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;
endptr = endptr << 32;
ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;
startptr = startptr << 32;
// 得到根节点
pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;
// 起始页: startingVpn * 0x1000
pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;
// 结束页: EndVpn * 0x1000 + 0xfff
pBuffer->VadInfos[pBuffer->nCnt].endVpn = ((endptr | Root->Core.EndingVpn) << PAGE_SHIFT) + 0xfff;
// VAD标志 928 = Mapped 1049088 = Private ....
pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;
// 验证节点可读性
if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea))
{
if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4)))
{
pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);
}
}
pBuffer->nCnt++;
}
if (MmIsAddressValid(Root->Core.VadNode.Left))
{
// 递归枚举左子树
EnumVad((PMMVAD)Root->Core.VadNode.Left, pBuffer, nCnt);
}
if (MmIsAddressValid(Root->Core.VadNode.Right))
{
// 递归枚举右子树
EnumVad((PMMVAD)Root->Core.VadNode.Right, pBuffer, nCnt);
}
}
__except (1)
{
}
}
BOOLEAN EnumProcessVad(ULONG Pid, PALL_VADS pBuffer, ULONG nCnt)
{
PEPROCESS Peprocess = 0;
PRTL_AVL_TREE Table = NULL;
PMMVAD Root = NULL;
// 通过进程PID得到进程EProcess
if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)Pid, &Peprocess)))
{
// 与偏移相加得到VAD头节点
Table = (PRTL_AVL_TREE)((UCHAR*)Peprocess + eprocess_offset_VadRoot);
if (!MmIsAddressValid(Table) || !eprocess_offset_VadRoot)
{
return FALSE;
}
__try
{
// 取出头节点
Root = (PMMVAD)Table->Root;
if (nCnt > pBuffer->nCnt)
{
// 得到起始页与结束页
ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;
endptr = endptr << 32;
ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;
startptr = startptr << 32;
pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;
// 起始页: startingVpn * 0x1000
pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;
// 结束页: EndVpn * 0x1000 + 0xfff
pBuffer->VadInfos[pBuffer->nCnt].endVpn = (endptr | Root->Core.EndingVpn) << PAGE_SHIFT;
pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;
if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea))
{
if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4)))
{
pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);
}
}
pBuffer->nCnt++;
}
// 枚举左子树
if (Table->Root->Left)
{
EnumVad((MMVAD*)Table->Root->Left, pBuffer, nCnt);
}
// 枚举右子树
if (Table->Root->Right)
{
EnumVad((MMVAD*)Table->Root->Right, pBuffer, nCnt);
}
}
__finally
{
ObDereferenceObject(Peprocess);
}
}
else
{
return FALSE;
}
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"));
typedef struct
{
ULONG nPid;
ULONG nSize;
PALL_VADS pBuffer;
}VADProcess;
__try
{
VADProcess vad = { 0 };
vad.nPid = 4520;
// 默认有1000个线程
vad.nSize = sizeof(VAD_INFO) * 0x5000 + sizeof(ULONG);
// 分配临时空间
vad.pBuffer = (PALL_VADS)ExAllocatePool(PagedPool, vad.nSize);
// 根据传入长度得到枚举数量
ULONG nCount = (vad.nSize - sizeof(ULONG)) / sizeof(VAD_INFO);
// 枚举VAD
EnumProcessVad(vad.nPid, vad.pBuffer, nCount);
// 输出VAD
for (size_t i = 0; i < vad.pBuffer->nCnt; i++)
{
DbgPrint("StartVPN = %p | ", vad.pBuffer->VadInfos[i].startVpn);
DbgPrint("EndVPN = %p | ", vad.pBuffer->VadInfos[i].endVpn);
DbgPrint("PVAD = %p | ", vad.pBuffer->VadInfos[i].pVad);
DbgPrint("Flags = %d | ", vad.pBuffer->VadInfos[i].flags);
DbgPrint("pFileObject = %p \n", vad.pBuffer->VadInfos[i].pFileObject);
}
}
__except (1)
{
}
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
程序运行后输出效果如下:
驱动开发:内核遍历进程VAD结构体的更多相关文章
- Linux进程: task_struct结构体成员
一:简介 为了管理进程,内核必须对每个进程所做的事情进行清除的描叙. 比如:内核必须知道进程优先级,他是正在CPU上运行还是因为某些事件被阻塞了,给它分配了什么样的地址空间,允许它访问哪个文件等等.这 ...
- Linux 内核网络协议栈 ------sk_buff 结构体 以及 完全解释 (2.6.16)
转自:http://blog.csdn.net/shanshanpt/article/details/21024465 在2.6.24之后这个结构体有了较大的变化,此处先说一说2.6.16版本的sk_ ...
- iOS开发-Object-C学习之结构体使用
前言:定义结构体并不是定义一个变量,而是定义了种数据类型. 结构体作用: 结构体和其他类型基础数据类型一样,例如int类型,char类型 只不过结构体可以做成你想要的数据类型.以方便日后的使用. 在实 ...
- C++遍历目录+_finddata_t结构体用法
Struct _finddata_t是用来存储文件各种信息的结构体,使用这个结构体要引用的头文件为“ #include <io.h>”它的结构体定义如下: struct _finddata ...
- Windows驱动开发-内核常用内存函数
搞内存常用函数 C语言 内核 malloc ExAllocatePool memset RtlFillMemory memcpy RtlMoveMemory free ExFreePool
- iOS开发--打印NSRange,CGRect等结构体
使用对应的转换NSStringFromCGPoint NSStringFromCGSize NSStringFromCGRect NSStringFromCGAffineTransform ...
- VAD树结构体的属性以及遍历
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html VAD树的属性以及遍历 前面学习过的PFNDATABSAE是管理物 ...
- C++第四十篇 -- 研究一下Windows驱动开发(三)-- NT式驱动的基本结构
对于NT式驱动来说,主要的函数是DriverEntry例程.卸载例程及各个IRP的派遣例程. 一.驱动加载过程与驱动入口函数(DriverEntry) 和编写普通应用程序一样,驱动程序有个入口函数,也 ...
- 《Windows驱动开发技术详解》之驱动程序的基本结构
驱动对象 每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候被内核中的对象管理程序所创建的.驱动对象用DRIVER_OBJECT数据结构表示,它作为驱动的一个实例被内核加载,并 ...
随机推荐
- flex 我所理解不够深刻的内容
1.align-items属性 父元素 align-items属性定义项目在交叉轴上如何对齐. flex-start:交叉轴的起点对齐. flex-end:交叉轴的终点对齐. center:交叉轴 ...
- 【洛谷P1754 球迷购票问题】题解
传送门 卡特兰数经典 \(\texttt{AB}\) 分拆问题. 分析: 题意相当于排列 \(n\) 个 \(\texttt A\) 和 \(n\) 个 \(\texttt B\),使得相邻 \(\t ...
- 利用DockerHub在Centos7.7环境下部署Nginx反向代理Gunicorn+Flask独立架构
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_165 上一篇文章:Docker在手,天下我有,在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像,是在 ...
- 当我们谈论算法我们在谈论什么:由疫情核酸检测想到的分治算法(Divide-and-Conquer)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_159 北京的疫情一波未平一波又起,由此看来,战"疫"将是一场旷日持久的战争,绝不能掉以轻心.轻易言胜.病毒随时 ...
- 5.4 NOI模拟
\(5.4\ NOI\)模拟 \(T1\) 想到分讨,但是暴力输出一下方案之后有很多特别的情况要讨论,就弃了... 假设\(a\)是原序列,\(b\)是我们得到的序列 设\(i\)是最长公共前缀,\( ...
- 羽夏看Linux内核——引导启动(上)
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...
- django中的静态文件
静态文件 1.什么是静态文件 在django中静态文件是指那些图片.css样式.js样式.视频.音频等静态资源. 2.为什么要配置静态文件 这些静态文件往往不需要频繁的进行变动,如果我们将这些静态文件 ...
- Docker 15 Compose
参考源 https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from=333.999.0.0 https://www.bilibili.com/vid ...
- .NET 开源工作流: Slickflow流程引擎高级开发(十) -- BpmnJS流程设计器集成
前言: 在Slickflow产品开发过程中,前端流程设计器经历了几个不同的版本(jsPlumb, mxGraph等),目的是为了在设计流程时的用户体验更加良好,得到客户的好评和认可.BpmnJS流程设 ...
- x64dbg 插件开发环境配置
x64dbg 是一款开源的应用层反汇编调试器,旨在对没有源代码的可执行文件进行恶意软件分析和逆向工程,同时 x64dbg 还允许用户开发插件来扩展功能,插件开发环境的配置非常简单,如下将简单介绍x64 ...