您的位置:首页 > 运维架构

动态监控驱动、dll、exe加载

2013-10-30 20:27 316 查看
/*
windows2003 x86/x64 window7 x86 windows2008 R2 x64测试通过
*/

#include <ntddk.h>
#include "nt_help.h"
DRIVER_INITIALIZE DriverEntry;

typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT Length;
BOOLEAN UseDefaultObject;
BOOLEAN CaseInsensitive;
#if WINVER>=0x0600
ULONG ObjectTypeCode;
#endif
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
BOOLEAN MaintainTypeList;
POOL_TYPE PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
PVOID DumpProcedure;
PVOID OpenProcedure;
PVOID CloseProcedure;
PVOID DeleteProcedure;
PVOID ParseProcedure;
PVOID SecurityProcedure;
PVOID QueryNameProcedure;
PVOID OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

typedef struct _OBJECT_TYPE {
#if WINVER<0x0600
ERESOURCE Mutex;
#endif
LIST_ENTRY TypeList;
UNICODE_STRING Name;            // Copy from object header for convenience
PVOID DefaultObject;
ULONG Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
OBJECT_TYPE_INITIALIZER TypeInfo;
} OBJECT_TYPE, *POBJECT_TYPE;

extern POBJECT_TYPE* MmSectionObjectType;
PVOID pNtCreateSection = NULL;
SYSTEM_MODULE_INFORMATION ntModInfo = {0};

#pragma alloc_text(INIT, DriverEntry)

NTSTATUS DevicePassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION  irpSp;

irpSp = IoGetCurrentIrpStackLocation(Irp);
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}

VOID DriverUnload (IN PDRIVER_OBJECT DriverObject)
{
(*MmSectionObjectType)->TypeInfo.OpenProcedure = NULL;
KdPrint(("DriverUnload Done!\n"));
}

#if WINVER>=0x0600
NTSTATUS HookSectionOpen(
IN ULONG OpenReason,
IN ULONG AccessMode,
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK* GrantedAccess,
IN ULONG HandleCount
)
#else
NTSTATUS HookSectionOpen(
IN ULONG OpenReason,
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG HandleCount
)
#endif
{
PVOID* esp = (PVOID*)&esp;
PVOID* esp_end = (PVOID*)((((DWORD64)esp>>12) + 1)<<12);        //4k round up
PVOID* p = esp;
ULONG SectionPageProtection, AllocationAttributes;
HANDLE FileHandle;
NTSTATUS Status;

/*
* do stack walk back to NtCreateSection function
*/
while (p < esp_end &&
(*p < pNtCreateSection ||
*p > (PVOID)((PBYTE)pNtCreateSection + 0x300)))
p++;

if (p >= esp_end){
//KdPrint(("no found NtCreateSection %p -> %p\n", esp, esp_end));
return STATUS_SUCCESS;
}

//KdPrint(("%p HookSectionOpen-Object:%p esp:%p %p\n", pNtCreateSection, Object, esp, *p));
#ifdef _WIN64
/*
* esp layout look likes[2003 X64 DUMP]:
fffff800`0104113d nt!KiSystemServiceCopyEnd+0x3 retaddr <-------call nt!NtCreateSection
fffffadf`f662ec00  00000000`00000000 param1
fffffadf`f662ec08  00000000`000f001f param2 DesiredAccess
fffffadf`f662ec10  00000000`00000000
fffffadf`f662ec18  00000000`00000000
fffffadf`f662ec20  00000100`00000010 SectionPageProtection
fffffadf`f662ec28  00000000`01000000 AllocationAttributes
fffffadf`f662ec30  00000000`0000054c FileHandle
* - ...
*/
p++;
/*
* search retaddr -> nt!KiSystemServiceCopyEnd
*/
while (p < esp_end &&
(*p < ntModInfo.ImageBase ||
*p > (PVOID)((PBYTE)ntModInfo.ImageBase + ntModInfo.ImageSize)))
p++;

if (p >= esp_end){
//KdPrint(("no found nt!KiSystemxxxx %p -> %p\n", esp, esp_end));
return STATUS_SUCCESS;
}
#else
/* stack DUMP from 2003/x86
* ebp = p - 1
fa06f4d8  fa06f540
fa06f4dc  80908715 nt!NtCreateSection+0x15c
...
fa06f540  fa06f564
fa06f544  808234cb nt!KiFastCallEntry+0xf8
fa06f548  fa06f668 param1
*/
p = (PVOID*)*(p - 1);
p++;
#endif

SectionPageProtection = (ULONG)*(p + 5);
AllocationAttributes = (ULONG)*(p + 6);
FileHandle = *(p + 7);

//KdPrint(("%x %x %p\n", SectionPageProtection, AllocationAttributes, FileHandle));

if (FileHandle
&& SectionPageProtection == PAGE_EXECUTE
&& (AllocationAttributes == SEC_IMAGE || AllocationAttributes == 0x100000)){
/* windows7 AllocationAttributes = 0x100000 to LoadDriver */
PFILE_OBJECT File;

Status = ObReferenceObjectByHandle (FileHandle,
0,
NULL,
KernelMode,
(PVOID *)&File,
NULL);

if (!NT_SUCCESS(Status)) {
return STATUS_SUCCESS;
}
KdPrint(("FileName:%wZ\n", &File->FileName));
ObDereferenceObject(File);
}

return STATUS_SUCCESS;
}

BOOL GetNtImgBase(PSYSTEM_MODULE_INFORMATION modInfo)
{
PSYSMODULELIST sysModuleList = NULL;
ULONG size, i;

NtQuerySystemInformation(SystemModuleInformation, &size, 0, &size);
sysModuleList = ExAllocatePoolWithTag(PagedPool, size, 'hlpm');

if (sysModuleList){
NtQuerySystemInformation(SystemModuleInformation, sysModuleList, size, NULL);
/* nt module should be the first one */
*modInfo = *sysModuleList->Modules;
ExFreePool(sysModuleList);
return TRUE;
}
return FALSE;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
DWORD i;
UNICODE_STRING sFuncName;

RtlInitUnicodeString(&sFuncName, L"NtCreateSection");
pNtCreateSection = MmGetSystemRoutineAddress(&sFuncName);

if (!GetNtImgBase(&ntModInfo)){
KdPrint(("EnumSysModule nt base failed!\n"));
return STATUS_UNSUCCESSFUL;
}

KdPrint(("nt:%p pNtCreateSection:%p\nMmSectionObjectType:%p %p %p\n",
ntModInfo.ImageBase,
pNtCreateSection,
*MmSectionObjectType,
(*MmSectionObjectType)->TypeInfo.OpenProcedure,
(*MmSectionObjectType)->TypeInfo.DeleteProcedure));

(*MmSectionObjectType)->TypeInfo.OpenProcedure = HookSectionOpen;

for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = DevicePassthrough;

DriverObject->DriverUnload = DriverUnload;

return STATUS_SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: