首页
社区
课程
招聘
[求助]HOOK ObjectType 干涉文件访问
发表于: 2008-8-29 17:03 12351

[求助]HOOK ObjectType 干涉文件访问

2008-8-29 17:03
12351
前几日在网上看到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,貌似找不到我打开文件的文件名。实在没办法了上论坛请教各位。请各位赐教!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (31)
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
2
你的pNewParseProcedure的参数不对,很明显不同的Object,对应的参数个数是不同的,而你还是照着MJ的code改,当然会错。

正确的是下面这个:


NTSTATUS
NTAPI
IopParseFile(IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object)
2008-8-29 19:54
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
3
再提示下,你要做的是判断参数1 -->ParseObject 的情况,进行过滤....
2008-8-29 19:59
0
雪    币: 86
活跃值: (56)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
4
哦试试看,谢谢啦~
2008-8-29 20:16
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
5
你是武大搞GIS的,全中国最好的。。。

牛人啊。。。
2008-8-29 20:27
0
雪    币: 86
活跃值: (56)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
6
没你牛~~~我已经3~~~~~~~

OK改了~~~
2008-8-29 21:16
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
7
啥叫大3,我也大3啊。。。

不要觉得大3,就还有很多机会去学习,就有资本,大学时间过得很快的啊,得定制一个目标,然后为之努力.

若一个初中生说"没你牛, 我才初一",你是啥感觉???
2008-8-29 22:26
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
8
你应该说,"我已经大3了"
2008-8-29 22:30
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
9
IopXXX俄国的rootkit强奸了好几年了
2008-8-29 22:38
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
objecttype,目前大家玩的都不多呀
2008-8-29 22:47
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
好多牛人都还是学生啊
差距太大了
2008-8-29 22:55
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
12
应该说真正的牛人都浅水,....看不到..只有学生比较有时间出来
2008-8-29 23:49
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13

话说进程/线程玩过一点,rKu能扫出来。

ObjectHook还是貌好玩的~。相对隐蔽吧。
2008-8-30 10:58
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
14
其实很好检测.....自己解释PDB或者麻烦点读原始内核文件....
2008-8-30 13:35
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
照着sudami大大的做法改,果然成功了,能够捕捉到我要保护的文件名,但是还是有问题,不知道该返回什么值,貌似return STATUS_OBJECT_NAME_NOT_FOUND不起作用
2008-11-26 15:41
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
16
重定向就可以了.不需要返回什么. 给他一个fake object.再调用原来的函数.
2008-11-26 18:41
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17


NTSTATUS pNewParseProcedure(PFILE_OBJECT 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);
  //PFILE_OBJECT pf=(PFILE_OBJECT)RootDirectory;
   

  if (wcsstr(RootDirectory->FileName.Buffer,L"\\2.txt"))
  {
        RootDirectory=  pObject ;  //重定向到1.txt
        DbgPrint("succed%ws\n",RootDirectory->FileName.Buffer);
         //return STATUS_OBJECT_NAME_NOT_FOUND;
  }
  else  DbgPrint("%ws\n",RootDirectory->FileName.Buffer);
  __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;

}

莫名其妙的还是不行。。。都已经把2.txt定向1.txt了,但还是可以打开2.txt
2008-11-26 21:46
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
我死的心都有了,
2008-11-29 09:13
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
19
....
嘿嘿~~重定向...
2008-11-30 02:01
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
。。。。。。大大们。。咱小白帮忙看看为什么重定向还是不能成功。。
2008-11-30 10:56
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
21
没那么麻烦,
直接参考Vxk同学 和 sudami的BLOG里面的文章, 你就会发现为什么不成功了...
源代码啊...
2008-11-30 11:02
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
翻遍大米同学跟vxk同学的blog终于找到了,居然两个字符串都要改。。。。。。大米同学真是好人呐。。。
2008-11-30 11:45
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
终于成功了,vxk同学的一句 extern POBJECT_TYPE *IoDeviceObjectType;提醒了咱
原来咱一直用fileobject,怪不得获得的字符串总是一些奇怪的东西。。。。重定向真好
好想知道,怎么才能做到想大米blog里面删掉再出现呢,我按vxk同学那样做貌似没有这个效果。。。。
2008-11-30 12:27
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
24
恭喜恭喜~~

小技巧,没什么用.玩玩还可以~
2008-11-30 12:42
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
哦。。。原来只要定向到系统文件就可以了。。。真好玩。。。哈哈
重定向真是太逗了。。。。咱也加入膜拜vxk大大的行列
2008-11-30 13:00
0
游客
登录 | 注册 方可回帖
返回
//