前几日在网上看到MJ0011大虾写的一篇《ObjectType HOOK干涉注册表操作(bypass icesword,gmer,NIAP,etc.)》的文章,感觉很有兴趣。MJ大虾的文章给出的代码主要是干涉注册表的。而ObjectType 可以干涉的不只是注册表,所以就想到用同样的方法去干涉文件的访问,举一反三嘛。
然后问题就出现了,先看看那代码吧。
/ StopOpen.c
#include <ntddk.h>
#define MAX_PATH 266
#define NUMBER_HASH_BUCKETS 37
#define LINK_NAME L"\\DosDevices\\StopOpenLink"
#define DEVICE_NAME L"\\Device\\StopLinkName"
PVOID pOldParseProcedure = NULL;
typedef struct _OBJECT_DIRECTORY_ENTRY {
struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
PVOID Object;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
typedef struct _OBJECT_DIRECTORY {
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ];
struct _OBJECT_DIRECTORY_ENTRY **LookupBucket;
BOOLEAN LookupFound;
USHORT SymbolicLinkUsageCount;
struct _DEVICE_MAP *DeviceMap;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
typedef struct _DEVICE_MAP {
ULONG ReferenceCount;
POBJECT_DIRECTORY DosDevicesDirectory;
ULONG DriveMap;
UCHAR DriveType[ 32 ];
} DEVICE_MAP, *PDEVICE_MAP;
typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT Length;
BOOLEAN UseDefaultObject;
BOOLEAN CaseInsensitive;
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 {
ERESOURCE Mutex;
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;
#ifdef POOL_TAGGING
ULONG Key;
#endif //POOL_TAGGING
} OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OBJECT_CREATE_INFORMATION {
ULONG Attributes;
HANDLE RootDirectory;
PVOID ParseContext;
KPROCESSOR_MODE ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
typedef struct _OBJECT_HEADER {
LONG PointerCount;
union {
LONG HandleCount;
PSINGLE_LIST_ENTRY SEntry;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;
POBJECT_TYPE pObHeader= NULL;
NTSTATUS pNewParseProcedure(POBJECT_DIRECTORY RootDirectory,
POBJECT_TYPE ObjectType,
PACCESS_STATE AccessState,
KPROCESSOR_MODE AccessCheckMode,
ULONG Attributes,
PUNICODE_STRING ObjectName,
PUNICODE_STRING RemainingName,
PVOID ParseContext ,
PSECURITY_QUALITY_OF_SERVICE SecurityQos ,
PVOID *Object)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
WCHAR wOpenName[MAX_PATH];
RtlCopyMemory(wOpenName,ObjectName->Buffer,ObjectName->MaximumLength);
if (wcsstr(wOpenName,L"2.TXT"))
{
return STATUS_OBJECT_NAME_NOT_FOUND;
}
__asm
{
push eax
push Object
push SecurityQos
push ParseContext
push RemainingName
push ObjectName
push Attributes
movzx eax, AccessCheckMode
push eax
push AccessState
push ObjectType
push RootDirectory
call pOldParseProcedure
mov ntStatus, eax
pop eax
}
return ntStatus;
}
NTSTATUS InstallHook()
{
NTSTATUS ntStatus;
HANDLE hFile;
UNICODE_STRING StName;
OBJECT_ATTRIBUTES obAttrib;
IO_STATUS_BLOCK ioStaBlock;
PVOID pObject = NULL;
KdPrint(("it start now!\n"));
RtlInitUnicodeString(&StName,L"\\DosDevices\\C:\\1.txt");
InitializeObjectAttributes(&obAttrib,&StName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,\
0,NULL);
ntStatus = ZwOpenFile(&hFile,GENERIC_ALL,&obAttrib,&ioStaBlock,\
0,FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("File Not Open\n"));
return ntStatus;
}
KdPrint(("File Open\n"));
ntStatus = ObReferenceObjectByHandle(hFile,GENERIC_ALL,NULL,KernelMode,&pObject,NULL);
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("Object Not Open\n"));
return ntStatus;
}
KdPrint(("Object Open\n"));
__asm
{
cli;
mov eax, cr0;
and eax, not 10000h;
mov cr0, eax;
}
__asm
{
push eax;
mov eax,pObject;
mov eax,[eax-10h];
mov pObHeader,eax;
pop eax;
}
pOldParseProcedure = pObHeader->TypeInfo.ParseProcedure;
if (!MmIsAddressValid(pOldParseProcedure))
{
ObDereferenceObject(pObject);
ntStatus = ZwClose(hFile);
return ntStatus;
}
pObHeader->TypeInfo.ParseProcedure = pNewParseProcedure;
__asm
{
mov eax, cr0;
or eax, 10000h;
mov cr0, eax;
sti;
}
ntStatus = ZwClose(hFile);
return ntStatus;
}
NTSTATUS soDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIrpSt = NULL;
pIrpSt = IoGetCurrentIrpStackLocation(pIrp);
ntStatus = pIrp->IoStatus.Status;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return ntStatus;
}
void soUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uTempString;
__asm
{
cli;
mov eax, cr0
and eax, not 10000h
mov cr0, eax
}
pObHeader->TypeInfo.ParseProcedure = pOldParseProcedure;
__asm
{
mov eax, cr0;
or eax, 10000h
mov cr0, eax;
sti;
}
RtlInitUnicodeString(&uTempString,LINK_NAME);
IoDeleteSymbolicLink(&uTempString);
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING uLinkName;
UNICODE_STRING uDeviceName;
PDEVICE_OBJECT ObDevice;
RtlInitUnicodeString(&uDeviceName,DEVICE_NAME);
ntStatus = IoCreateDevice(DriverObject,0,&uDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&ObDevice);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
RtlInitUnicodeString(&uLinkName,LINK_NAME);
ntStatus = IoCreateSymbolicLink(&uLinkName,&uDeviceName);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = soDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = soDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = soDispatch;
DriverObject->DriverUnload = soUnload;
InstallHook();
return ntStatus;
} 用Windbg跟了一下,发现在pNewParseProcedure函数中出了问题。
本来是想通过ObjectName->Buffer得到打开的文件名,然后看其中有没有2.TXT这个字符串进行过滤的。但是我用Windbg看了看ObjectName->Buffer,貌似找不到我打开文件的文件名。实在没办法了上论坛请教各位。请各位赐教!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!