首页
社区
课程
招聘
[求助]在驱动级别如何获取调用该驱动的进程pid
发表于: 2013-3-19 17:52 15471

[求助]在驱动级别如何获取调用该驱动的进程pid

2013-3-19 17:52
15471
刚接触驱动,很多函数还不了解,正在Hook注册表操作函数ZwSetValueKey,保证只有指定进程可以修改注册表,但是我查到一个ZwAllocateLocallyUniqueId函数,只要写到函数里编译就会出错,如图
代码在附件里,希望各位大神帮忙看看,或者有更好的hook注册表操作函数的方法也可以教教我这个小白,像那个Detours什么的就不用了,我电脑上编译生成不了lib(XP + VC++6.0)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (19)
雪    币: 281
活跃值: (33)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
pid = PsGetCurrentProcessId();

eprocess = PsGetCurrentProcess();
pid = eprocess->UniqueProcessId;
2013-3-19 18:29
0
雪    币: 78
活跃值: (74)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
连接错误,貌似ZwAllocateLocallyUniqueId在vista之后才支持。
如果要获得processid,二楼正解
2013-3-19 19:05
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
第一种需要类型转换吗?我编译后没有起到过滤作用

第二种我编译时提示结构体里没有UniqueProcessId

求指教
2013-3-20 10:23
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
第一种需要类型转换吗?我编译后没有起到过滤作用

第二种我编译时提示结构体里没有UniqueProcessId

求指教
2013-3-20 10:24
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
PsGetCurrentProcess返回的是进程结构体,结构体名称是EPROCESS,但这个结构体没有公开,你可以用WINDBG查查这个结构体的
//下面是WINDBG显示的XPSP3 EPROCESS的一部分
kd> dt nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : Ptr32 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY

由于没有公开,所以你可以自己定义,然后使用,也可以(ULONG)(PULONG*)((char*)eprocess + 0x84)(XPSP3偏移是0x84)去访问,但兼容性就有些问题了。
当前,XP以上呢,系统提供了一个函数PsGetProcessId,可以从eprocess获取PID的,PsGetProcessId(eprocess)就是进程ID.
一般你用第一种方法PsGetCurrentProcessId就行了
PsGetCurrentProcessId和PsGetProcessId返回的是HANDLE值,但这个值就是PID,如果你不习惯,你可以强制转换为ULONG, ULONG CurrentProcessId = (ULONG)PsGetCurrentProcessId();
至于不起作用,那你查查其他方面的问题。
2013-3-20 10:38
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
能否帮忙看看代码呢?我是新手又急用,不会调试sys,实现的功能是对ZwSetValueKey进行hook达到过滤功能,信任列表是system,lsass.exe,taskmgr.exe,regedit.exe

#include "ntddk.h"

typedef enum _SYSTEM_INFORMATION_CLASS { 
	SystemBasicInformation, 				// 0 
	SystemProcessorInformation, 			// 1 
	SystemPerformanceInformation, 			// 2
	SystemTimeOfDayInformation, 			// 3
	SystemNotImplemented1, 				// 4
	SystemProcessesAndThreadsInformation, 		// 5
	SystemCallCounts, 					// 6
	SystemConfigurationInformation, 			// 7
	SystemProcessorTimes, 				// 8
	SystemGlobalFlag, 					// 9
	SystemNotImplemented2, 				// 10
	SystemModuleInformation, 				// 11
	SystemLockInformation, 				// 12
	SystemNotImplemented3, 				// 13
	SystemNotImplemented4, 				// 14
	SystemNotImplemented5, 				// 15
	SystemHandleInformation, 				// 16
	SystemObjectInformation, 				// 17
	SystemPagefileInformation, 				// 18
	SystemInstructionEmulationCounts, 			// 19
	SystemInvalidInfoClass1, 				// 20
	SystemCacheInformation, 				// 21
	SystemPoolTagInformation, 				// 22
	SystemProcessorStatistics, 				// 23
	SystemDpcInformation, 				// 24
	SystemNotImplemented6, 				// 25
	SystemLoadImage, 					// 26
	SystemUnloadImage, 				// 27
	SystemTimeAdjustment, 				// 28
	SystemNotImplemented7, 				// 29
	SystemNotImplemented8, 				// 30
	SystemNotImplemented9, 				// 31
	SystemCrashDumpInformation, 			// 32
	SystemExceptionInformation, 			// 33
	SystemCrashDumpStateInformation, 			// 34
	SystemKernelDebuggerInformation, 			// 35
	SystemContextSwitchInformation, 			// 36
	SystemRegistryQuotaInformation, 			// 37
	SystemLoadAndCallImage, 				// 38
	SystemPrioritySeparation, 				// 39
	SystemNotImplemented10, 				// 40
	SystemNotImplemented11, 				// 41
	SystemInvalidInfoClass2, 				// 42
	SystemInvalidInfoClass3, 				// 43
	SystemTimeZoneInformation, 				// 44
	SystemLookasideInformation, 			// 45
	SystemSetTimeSlipEvent, 				// 46
	SystemCreateSession, 				// 47
	SystemDeleteSession, 				// 48
	SystemInvalidInfoClass4, 				// 49
	SystemRangeStartInformation, 			// 50
	SystemVerifierInformation, 				// 51
	SystemAddVerifier, 				// 52
	SystemSessionProcessesInformation 			// 53
} SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_THREAD_INFORMATION {
	LARGE_INTEGER KernelTime;
	LARGE_INTEGER UserTime;
	LARGE_INTEGER CreateTime;
	ULONG WaitTime;
	PVOID StartAddress;
	CLIENT_ID ClientId;
	KPRIORITY Priority;
	KPRIORITY BasePriority;
	ULONG ContextSwitchCount;
	LONG State;
	LONG WaitReason;
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;

typedef struct _SYSTEM_PROCESS_INFORMATION {
	ULONG NextEntryDelta;
	ULONG ThreadCount;
	ULONG Reserved1[6];
	LARGE_INTEGER CreateTime;
	LARGE_INTEGER UserTime;
	LARGE_INTEGER KernelTime;
	UNICODE_STRING ProcessName;
	KPRIORITY BasePriority;
	ULONG ProcessId;
	ULONG InheritedFromProcessId;
	ULONG HandleCount;
	ULONG Reserved2[2];
	VM_COUNTERS VmCounters;
	IO_COUNTERS IoCounters;
	SYSTEM_THREAD_INFORMATION Threads[1];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;

NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
	IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
	OUT PVOID SystemInformation,
	IN ULONG SystemInformationLength,
	OUT PULONG ReturnLength OPTIONAL
);

#pragma pack(1)	//SSDT表的结构
typedef struct ServiceDescriptorEntry {
	unsigned int *ServiceTableBase;
	unsigned int *ServiceCounterTableBase; //Used only in checked build
	unsigned int NumberOfServices;
	unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

PMDL m_MDL;
PVOID *m_Mapped;

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;	//变量名是不能变的,因为是从外部导入
#define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) _Orig = (PVOID) InterlockedExchange( (PLONG) &m_Mapped[SYSCALL_INDEX(_Function)], (LONG) _Hook)

NTSYSAPI NTSTATUS NTAPI ZwSetValueKey(
	IN HANDLE KeyHandle, 
	IN PUNICODE_STRING ValueName, 
	IN ULONG TitleIndex, 
	IN ULONG Type, 
	IN PVOID Data, 
	IN ULONG DataSize
	);
typedef NTSTATUS (*ZWSETVALUEKEY)(
	IN HANDLE KeyHandle, 
	IN PUNICODE_STRING ValueName, 
	IN ULONG TitleIndex, 
	IN ULONG Type, 
	IN PVOID Data, 
	IN ULONG DataSize
	);

NTSTATUS NewZwSetValueKey(
	IN HANDLE KeyHandle, 
	IN PUNICODE_STRING ValueName, 
	IN ULONG TitleIndex, 
	IN ULONG Type, 
	IN PVOID Data, 
	IN ULONG DataSize
	);

ZWSETVALUEKEY OldZwSetValueKey = NULL;


ULONG pid[10] = {0};
int icount = 0;

NTSTATUS Ring0EnumProcess()
{
	UNICODE_STRING usMy[4];
	UNICODE_STRING usSys;
	int comp=0;
	int icnt = 0;
	
	ULONG cbBuffer = 0x8000; // 初始化缓冲大小 32kb
	PVOID pBuffer = NULL;
	NTSTATUS Status;
	PSYSTEM_PROCESS_INFORMATION pInfo;
	do
	{
		pBuffer = ExAllocatePool (NonPagedPool, cbBuffer); //分配内存缓冲区
		if (pBuffer == NULL) // 如果内存分配失败
			return 1;
	        Status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL);
		if (Status == STATUS_INFO_LENGTH_MISMATCH) //如果缓冲区太小
		{
			ExFreePool(pBuffer); // 释放缓冲区
			cbBuffer *= 2; // 增加缓冲区到原来的两倍大小 
		}
		else if (!NT_SUCCESS(Status)) // 如果执行失败
		{
			ExFreePool(pBuffer); // 释放分配的内存
			return 1; //返回1并拖出
		}
	}
	while (Status == STATUS_INFO_LENGTH_MISMATCH);

	pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;

	for (;;) 
	{
		LPWSTR pszProcessName = pInfo->ProcessName.Buffer; 
		if (pszProcessName == NULL) 
		pszProcessName = L"NULL"; // 如果获取文件名失败

		
		RtlInitUnicodeString(&(usMy[0]),L"system");
		RtlInitUnicodeString(&(usMy[1]),L"lsass.exe");
		RtlInitUnicodeString(&(usMy[2]),L"taskmgr.exe");
		RtlInitUnicodeString(&(usMy[3]),L"regedit.exe");
		RtlInitUnicodeString(&usSys,pszProcessName);

		icnt = 0;
		for(; icnt < 4; icnt++)
		{
			if(!RtlCompareUnicodeString(&(usMy[icnt]),&usSys,TRUE))
			{
				comp = 0;
				break;
			}
			else comp = 1;
		}
		if (comp==0)
		{
			pid[icount++]=pInfo->ProcessId;
			//KdPrint(("发现要保护的进程\n"));
		}

		//DbgPrint("pid %d ps %S\n",pInfo->ProcessId,pInfo->ProcessName.Buffer);

		if (pInfo->NextEntryDelta == 0) 
			break; 

		pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)+ pInfo->NextEntryDelta); 
	}
	ExFreePool(pBuffer);
	return 0; 
}

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
	PVOID OldFunc = NULL;
	HOOK_SYSCALL(ZwSetValueKey, OldZwSetValueKey, OldFunc);
	if(m_MDL)
	{
		MmUnmapLockedPages(m_Mapped, m_MDL);
		IoFreeMdl(m_MDL);
	}
	//KdPrint(("[*]驱动卸载完毕.\n"));
}

NTSTATUS NewZwSetValueKey(IN HANDLE KeyHandle, 
								IN PUNICODE_STRING ValueName, 
								IN ULONG TitleIndex, 
								IN ULONG Type, 
								IN PVOID Data, 
								IN ULONG DataSize
	)
{
	//自己的注册表处理函数
	//long lPid = (long)PsGetCurrentProcessId();
	//PEPROCESS peProcess = PsGetCurrentProcess();
	//if(lPid == pid)
	//if((long)peProcess->UniqueProcessId == pid)
	//{
	//	return STATUS_ACCESS_DENIED;
	//}
	ULONG lPid = (ULONG)PsGetCurrentProcessId();
	int i = 0;
	for(;i < icount - 1; i++)
	{
		if(lPid == pid[i])
			return OldZwSetValueKey(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize);
	}
	return STATUS_ACCESS_DENIED;
}






NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	DriverObject->DriverUnload = OnUnload;
	m_MDL = MmCreateMdl(NULL,KeServiceDescriptorTable.ServiceTableBase,KeServiceDescriptorTable.NumberOfServices*4);
	if(!m_MDL)
	{
		return STATUS_UNSUCCESSFUL;
	}
	
	MmBuildMdlForNonPagedPool(m_MDL);//非分页内存

	m_MDL->MdlFlags = m_MDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;

	
	m_Mapped = MmMapLockedPages(m_MDL, KernelMode);//锁定
	
	HOOK_SYSCALL(ZwSetValueKey,NewZwSetValueKey,OldZwSetValueKey);

	//KdPrint(("[*]驱动程序加载完毕.\n"));

	return STATUS_SUCCESS;
}
2013-3-20 11:37
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
第一,Ring0EnumProcess要调用
第二,调用Ring0EnumProcess前,相关进程要开启,比如你在DriverEntry里调用Ring0EnumProcess,那么在驱动启动前,像Regedit.exe要开着,否则Ring0EnumProcess枚举不到Regedit进程,那么你后边用regedit.exe做实验的时候,就肯定会失败
第三,NewZwSetValueKey里的for(;i < icount - 1; i++),谁告诉你icount减一的呢?这是C基础,for(;i < icount; i++)
2013-3-20 12:00
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
呃,第三个错误确实是失误,因为用了++以为要减一呢,很感谢帮我扫盲了
2013-3-20 13:00
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
按照你说的做了,还是不行,依旧被拦截了
2013-3-20 13:40
0
雪    币: 219
活跃值: (793)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
11
我看到了挂机党
2013-3-20 13:47
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我试了可以,才回复你的,你再把改完的代码拿出来,看看吧
2013-3-20 13:55
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
低调,我没有挂机,我就让页面几分钟刷新一次而已,哈哈
2013-3-20 13:57
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
保护问题已解决,那么怎么样才能实现每次调用ZwSetValueKey之前调用一下Ring0EnumProcess函数呢?直接在hook的函数里调用会报错。。。
2013-3-20 13:57
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
PsGetProcessImageFileName可以获得进程名,微软没有归档,但导出了,你在你的代码声明一下就可以用了,声明如下
NTKERNELAPI
UCHAR *
PsGetProcessImageFileName(
                                                  __in PEPROCESS Process
                                                  );

用的时候可以PUCHAR ProcessName = PsGetProcessImageFileName(PsGetCurrentProcess());

ProcessName 就是ANSI的进程名,直接判断即可,不过需要注意的是,这个获得的名称和EXE的文件名有些小区别,就是如果EXE文件名超过15个字节,15个字节后面的将会被截断再作为进程名,这个你自己试试就知道该怎么处理了。
2013-3-20 14:25
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这些函数你都是怎么知道的?我查msdn都没有找到啊!!!
2013-3-20 16:58
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
熟能生巧。就跟你的家一样,你天天走,怎么都不会走错门,我要是只过去几次,指不定还会认错门。
2013-3-20 17:12
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
这样一试,然后就蓝屏了,是不是哪里还有其他要注意的啊?

UCHAR* CurrentExecuteName = PsGetProcessImageFileName(PsGetCurrentProcess());
	if(!RtlCompareString(CurrentExecuteName, "system", TRUE)
		|| !RtlCompareString(CurrentExecuteName, "lsass.exe", TRUE)
		|| !RtlCompareString(CurrentExecuteName, "taskmgr.exe", TRUE)
		|| !RtlCompareString(CurrentExecuteName, "setkey.exe", TRUE))
		return OldZwSetValueKey(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize);
	else return STATUS_ACCESS_DENIED;
2013-3-20 17:40
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
难道你编译不看warning的么?
编译原则是不允许出现警告的!
!RtlCompareString(CurrentExecuteName, "setkey.exe", TRUE),你看看这个函数的参数是什么类型的,PSTRING,STRING是什么?是个结构体啊,跟你刚才用RtlInitUnicodeString一用,STRING,也是需要RtlInitString的。
2013-3-20 18:16
0
雪    币: 14
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
wdk的警告好像被我屏蔽到W1了,不然根本通过不了编译的,我才接触驱动不到一个星期,都是在依葫芦画瓢的做事情,哪里看得懂这些东西啊
2013-3-20 19:40
0
游客
登录 | 注册 方可回帖
返回
//