内核学习笔记

更新时间:2024-06-27 17:29:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

2016.5.18 windows内存管理

1. 通过VAD树枚举进程DLL(通过processID)

VAD(Virtual address descriptor) 是一棵平衡二叉搜索树。管理着一个进程的虚拟内存。当然其中也包含着一个进程的dll模块信息。首先通过windbg查看各个对象的数据结构: (1) dt !process 0 0 //查看所有进程

PROCESS 822d7508 SessionId: 0 Cid: 063c Peb: 7ffd4000 ParentCid: 061c DirBase: 048001e0 ObjectTable: e14c2190 HandleCount: 345. Image: explorer.exe

(2) dt _eprocess 822d7508 //查看该进程信息

+0x118 HardwareTrigger : 0 +0x11c VadRoot : 0x8248f8f0 Void +0x120 VadHint : 0x8248f8f0 Void (3) dt _MMVAD 0x8248f8f0 //查看VAD结构

+0x000 StartingVpn : 0x1ed0 +0x004 EndingVpn : 0x1ef4 +0x008 Parent : (null) +0x00c LeftChild : 0x82418340 _MMVAD +0x010 RightChild : 0x82196f00 _MMVAD +0x014 u : __unnamed +0x018 ControlArea : (null) +0x01c FirstPrototypePte : (null) +0x020 LastContiguousPte : (null) (4) dt _MMVAD 0x82418340 //查看左节点

+0x000 StartingVpn : 0x1d90 +0x004 EndingVpn : 0x1d9f +0x008 Parent : 0x8248f8f0 _MMVAD +0x00c LeftChild : 0x824184d0 _MMVAD +0x010 RightChild : 0x8241fab8 _MMVAD +0x014 u : __unnamed +0x018 ControlArea : 0x0a040004 _CONTROL_AREA ControlArea地址为0x0a040004,说明节点为空,使用命令查看也为空

(5) dt _MMVAD 0x824184d0 //查看右节点

+0x000 StartingVpn : 0x1d10 +0x004 EndingVpn : 0x1d1f +0x008 Parent : 0x82418340 _MMVAD +0x00c LeftChild : 0x824fe1e8 _MMVAD +0x010 RightChild : 0x82418450 _MMVAD +0x014 u : __unnamed +0x018 ControlArea : 0x0a040004 _CONTROL_AREA +0x01c FirstPrototypePte : 0x53646156 _MMPTE +0x020 LastContiguousPte : 0x00001d00 _MMPTE +0x024 u2 : __unnamed (6) dt _MMVAD 0x82196f00 //继续查看右节点

+0x000 StartingVpn : 0x16790 +0x004 EndingVpn : 0x167b2 +0x008 Parent : 0x8248f8f0 _MMVAD +0x00c LeftChild : 0x822b1d78 _MMVAD +0x010 RightChild : 0x823b61c0 _MMVAD +0x014 u : __unnamed +0x018 ControlArea : 0x8248d538 _CONTROL_AREA +0x01c FirstPrototypePte : 0xe1a4f948 _MMPTE +0x020 LastContiguousPte : 0xfffffffc _MMPTE

(7) dt _control_area 0x8248d538 //查看控制区域内信息

+0x000 Segment : 0xe1a4f908 _SEGMENT +0x004 DereferenceList : _LIST_ENTRY [ 0x0 - 0x0 ] +0x00c NumberOfSectionReferences : 0 +0x010 NumberOfPfnReferences : 0x1d +0x014 NumberOfMappedViews : 1 +0x018 NumberOfSubsections : 5 +0x01a FlushInProgressCount : 0 +0x01c NumberOfUserReferences : 1 +0x020 u : __unnamed +0x024 FilePointer : 0x8241b628 _FILE_OBJECT +0x028 WaitingForDeletion : (null) +0x02c ModifiedWriteCount : 0 +0x02e NumberOfSystemCacheViews : 0 (8) dt _FILE_OBJECT 0x8241b628 //查看调用dll

+0x030 FileName: _UNICODE_STRING \ (9) dt _SEGMENT 0xe1a4f908

//查看调用dll的基本信息

+0x010 SizeOfSegment : 0x41000 +0x018 SegmentPteTemplate : _MMPTE +0x020 NumberOfCommittedPages : 0 +0x024 ExtendInfo : (null) +0x028 SystemImageBase : (null) +0x02c BasedAddress : 0x10930000 Void

从Windbg可以看出要找某个进程的dll要通过 Eprocess->vadroot(+0x11c)

->MMVAD

->LeftChild(+0x00c) ->RightChild(+0x010)

->Segment(+0x000)->SizeOfSegment(+0x010)

->BasedAddress(+0x02c) ->ControlArea(+0x018)->FilePointer(+0x024)->FileName(+0x030)

源码如下(基于http://blog.sina.com.cn/s/blog_6a03b6ef0101jea8.html修改): 一、通过进程ID获取进程的所有dll #include #include #include //通过VAD枚举进程DLL #define VADOFFSET 0x11c //_EPROCESS->VadRoot #define LEFTCHILDOFFSET 0x00c //_MMVAD->LefCchild #define RIGHTCHILDOFFSET 0x010 //_MMVAD->RightChild #define CONTROLAREAOFFSET 0x018 //_MMVAD->ControlArea #define FILEPOINTEROFFSET 0x024 //_CONTROL_AREA->FilePointer //segment #define SIZEOFFSET 0x010 //_SEGMENT->SizeOfSegment #define BASEOFFSET 0x02c //_SEGMENT->BasedAddress //FILEname #define FILENAMEOFFSET 0x030 //_FILE_OBJECT->FileName #define ENUM_DEVICENAME L\#define ENUM_LINKNAME L\NTKERNELAPI NTSTATUS PsLookupProcessByProcessId( __in HANDLE ProcessId, __deref_out PEPROCESS *Process ); VOID SearchDLLByVAD(ULONG vad) { ULONG leftChild; ULONG rightChild; ULONG controlarea; ULONG segment; ULONG FilePointer; PUNICODE_STRING FileName; ULONG size; ULONG base; leftChild = *(PULONG)((ULONG)vad+LEFTCHILDOFFSET); if(!MmIsAddressValid((PVOID)leftChild)){ return; } else { SearchDLLByVAD(leftChild); } rightChild=*(PULONG)((ULONG)vad+RIGHTCHILDOFFSET); if(!MmIsAddressValid((PVOID)rightChild)){ return; } else { SearchDLLByVAD(rightChild); } controlarea = *(PULONG)((ULONG)vad+CONTROLAREAOFFSET); if(!MmIsAddressValid((PVOID)controlarea)){ return; } segment = *(PULONG)((ULONG)controlarea); if(!MmIsAddressValid((PVOID)segment)){ return; } //获取模块的信息 size = *(PULONG)((ULONG)segment+SIZEOFFSET); base = *(PULONG)((ULONG)segment+BASEOFFSET); FilePointer = *(PULONG)((ULONG)controlarea+FILEPOINTEROFFSET); FileName = (PUNICODE_STRING)(FilePointer+FILENAMEOFFSET); DbgPrint(\模块基地址为xX,大小为xX,模块名称为%wZ\\n\,size,base,FileName); } VOID EnumDllByProcess(PEPROCESS pProcess) { ULONG vad; DbgPrint(\,pProcess); if(!MmIsAddressValid((PVOID)pProcess)){ } vad = *(PULONG)((ULONG)pProcess+VADOFFSET); DbgPrint(\,vad); if(!MmIsAddressValid((PVOID)vad)){ return; } SearchDLLByVAD(vad); } VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject) { UNICODE_STRING LinkName; RtlInitUnicodeString(&LinkName,ENUM_LINKNAME); IoDeleteSymbolicLink(&LinkName); IoDeleteDevice(pDriverObject->DeviceObject); DbgPrint(\); } NTSTATUS GeneralDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return status; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING registryPath) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING DeviceName; UNICODE_STRING LinkName; PDEVICE_OBJECT pDeviceObject; PEPROCESS pProcess; DbgPrint(\); RtlInitUnicodeString(&DeviceName,ENUM_DEVICENAME); IoCreateDevice(pDriverObject,0,&DeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&pDeviceObject); DbgPrint(\); return;

RtlInitUnicodeString(&LinkName,ENUM_LINKNAME); IoCreateSymbolicLink(&LinkName,&DeviceName); pDriverObject->MajorFunction[IRP_MJ_CREATE] = pDriverObject->MajorFunction[IRP_MJ_CLOSE] = pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GeneralDispatch; pDriverObject->DriverUnload = DriverUnload; PsLookupProcessByProcessId((HANDLE)1480,&pProcess); EnumDllByProcess(pProcess); return status; } 二、通过进程名获取进程的dll 思想:遍历进程比较进程名 PEPROCESS GetPProcessFromImageFileName(LPTSTR pName) { PEPROCESS Process;//eProcess; LPTSTR ProcessName; //ULONG Count; for (ProcessId = 0; ProcessId < 1999; ProcessId += 4) ULONG ProcessId; { if (PsLookupProcessByProcessId((HANDLE)ProcessId, &Process) == STATUS_SUCCESS) } } return Process; { } if (Process != 0) { } if (MmIsAddressValid((PVOID)Process)) { } DbgPrint(\,Process); ProcessName = (LPTSTR)((ULONG)Process+IMAGEFILENAMEOFFSET); DbgPrint(\,ProcessName); if(strcmp(ProcessName,pName)==0) { } return Process;

2. 字符串类型比较 3. Hook

? Inline Hook

Inline Hook是通过修改前5个字节,函数的前两个指令是 Push ebp Mov ebp,esp

这两条指令所占的机器码正好是5个字节 可将其改为 Jmp addr //也是5个字节

但是采用此类inline hook会经常蓝屏,因为现在电脑基本都是多CPU的,所以当修改的函数是经常被调用的,就会hook的过程被打断,从而导致蓝屏,而一个比较简单的解决办法是调用ExInterlockedCompareExchange64函数(一次性修改8个字节,否则修改失败)

? SSDT Hook

本文来源:https://www.bwwdw.com/article/1zr3.html

Top