首页
社区
课程
招聘
[讨论]有人能成功hook掉 win32k! ValidateHwnd这个函数么
发表于: 2011-4-8 17:50 14564

[讨论]有人能成功hook掉 win32k! ValidateHwnd这个函数么

2011-4-8 17:50
14564
win32k!ValidateHwnd这个函数大概是win32k.sys中调用频次最高的一个函数,所以我就华丽丽的蓝了,如果哪位能成功hook并且分享下,在下感激不尽

为了节约大家时间,我贴出 shadow ssdt 寻址,ValidateHwnd 寻址 , shadow ssdt hook 模板的代码,希望能为你节约一些时间~

///////////////////////////shadow ssdt寻址////////////////////////////////
/////////////////////////KeServiceDescriptorTable是ssdt,即主表的地址,另外KeServiceDescriptorTableShadow是个全局ULONG

NTSTATUS GetServiceTableShadowAddr(
    OUT ULONG* Address)
{
PLIST_ENTRY CurrentProcessLink=NULL,CurrentThreadLink=NULL,StartProcessLink=NULL,StartThreadLink=NULL;
ULONG   CurrentProcess=(ULONG)PsGetCurrentProcess();
ULONG   CurrentServiceTable,LastRecord=0;
ULONG*  pCurrentServiceTable=NULL;

CurrentProcessLink=StartProcessLink=(LIST_ENTRY*)((ULONG)CurrentProcess+PROCESS_LINK_OFFSET);
do
{
    CurrentThreadLink=StartThreadLink=(LIST_ENTRY*)(*(ULONG*)((ULONG)CurrentProcessLink-PROCESS_LINK_OFFSET+THREAD_LIST_HEAD));
	do
	{
	    pCurrentServiceTable=(ULONG*)((ULONG)CurrentThreadLink-THREAD_LINK_OFFSET+SERVICE_TABLE_OFFSET);
		if(MmIsAddressValid((PVOID)pCurrentServiceTable))
		{
		    CurrentServiceTable=*pCurrentServiceTable;
		    KdPrint(("CurrentThread's Service Table: %X \n",CurrentServiceTable));
		    //不指向KeServiceDescriptorTable 就指向 KeServiceDescriptorTableShadow
		    if(CurrentServiceTable!=(ULONG)KeServiceDescriptorTable)
		    {
			    if(LastRecord)
				{
				    //只有当两次相邻的不相等数据吻合,才可以认为是shadow ssdt
				    if(LastRecord==CurrentServiceTable)
					{
		                *Address=CurrentServiceTable;
			            KdPrint(("KeServiceDescriptorTableShadow: %X \n",CurrentServiceTable));
			            return STATUS_SUCCESS;
					}	
				}
				//记录上一次不相等的数据
                LastRecord=CurrentServiceTable;				
		    }
		}
        CurrentThreadLink=CurrentThreadLink->Flink;
	}
    while(CurrentThreadLink!=StartThreadLink);	
	CurrentProcessLink=CurrentProcessLink->Flink;
}
while(CurrentProcessLink!=StartProcessLink);
return STATUS_UNSUCCESSFUL;
}


////////////////////////////////ValidateHwnd寻址//////////////////////
//////////////////////////传入参数是NtUserQueryWindow的地址
/////////////////////////这个地址在后面的shadow sdt hook中代码中会出现
ULONG GetValidateHwndAddr(const ULONG NtUserQueryWindow)
{
ULONG Addr=NtUserQueryWindow;
ULONG offset;
int   calc=0;
while(calc<2) //第二个E8 CALL就是ValidateHwnd的地址
{
	Addr++;
    if(MmIsAddressValid((PVOID)Addr))
	{
	    if(*(PBYTE)Addr==0xe8) calc++;
	}
}
offset=*(ULONG*)(Addr+1);
if(offset) return (offset+Addr+5);
 else return 0;
}


//////////////////////////////shadow sdt hook代码///////////////

void HookShadowSdt()
{
PEPROCESS   Target=NULL;
NTSTATUS    status;
KIRQL       irql;
KSPIN_LOCK  lock;
KAPC_STATE  ApcState;

status=LookUpProcessPointerByName("csrss.exe",&Target);
if(NT_SUCCESS(status))
{
    status=GetServiceTableShadowAddr(&KeServiceDescriptorTableShadow);
	if(NT_SUCCESS(status))
	{
	    status=ObReferenceObjectByPointer((PVOID)Target,
		                                    0,
											*PsProcessType,
											KernelMode);
		if(NT_SUCCESS(status))
		{
	        KeStackAttachProcess(Target,&ApcState);
		    KeInitializeSpinLock(&lock);
	         PPOFF();
		    KeAcquireSpinLock(&lock,&irql);
			//这里加上对win32k.sys的修改,如sdt hook,inline hook
		    KeReleaseSpinLock(&lock,irql);
		    PPON();
			KeUnstackDetachProcess(&ApcState);
			ObDereferenceObject((PVOID)Target);
		}	
	}

}
}


////////////////////////注解: LookUpProcessPointerByName是遍历链表得到EPROCESS指针, PPON ,PPOFF 分别是开关页保护

好了,就这些。希望你能成功hook 掉win32k!ValidateHwnd,然后共享下~ 谢了

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
2
搞它干什么啊……
2011-4-8 18:39
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
这函数蛮有用的哈,我主要是防GetWindow,但是这个函数我没办法在ring 0定位,我用IDA看了半天,没发现能有途径弄到它,所以只好hook掉这个ValidateHwnd咯……貌似还更简单
2011-4-8 18:58
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
教主,能不能弄个小驱动帮我测试下?

主要代码都在那里了哦,应该花不了几分钟~  呃,主要是看看hook处理部分 , 这个函数调用频率太高了~
2011-4-8 19:22
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
5
有人试过了么,发蓝屏上来欣赏下呗
2011-4-8 19:53
0
雪    币: 284
活跃值: (106)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
6
仅仅是fastcall而已,挂钩没啥难度,当作stdcall处理就杯具了,另外自己获取自旋锁没啥子用,NtUserXXX里面第一个Call就是获取全局锁,这个才有意义……另外GetWindow为啥要拦截这个。。。。。
2011-4-8 22:21
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
win32k!ValidateHwnd这个是个什么函数?

函数的名字还有个感叹号?
2011-4-8 22:23
0
雪    币: 544
活跃值: (264)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
8
win32k.sys里面的一个名为ValidateHwnd的函数

感叹号把它看做是::,相当于win32.sys这个“类”里面的一个成员函数,win32k::ValidateHwnd
2011-4-8 22:57
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
9
谢了,的确没注意……居然是fastcall,把堆栈损坏了,但是并不是所有NtUserxxx都会call那个EnterCrit,呃~ 至于为什么拦这个,是因为这个比较好拦,GetWindow不论它的uCmd为什么,想要获取其他句柄,就必须用ValidateHwnd将一个HWND映射成WND的指针~ so ~
2011-4-8 23:09
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
10
直接把你代码丢上来,这样改起来,就跟你的要求一致了
2011-4-12 15:29
0
雪    币: 3
活跃值: (466)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
Mark   2020.05.08 今天开始也要HOOK一下 VAlidateHwnd
2020-5-28 23:54
0
雪    币: 13
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
XP有这个函数吗。。
2020-8-11 19:47
0
游客
登录 | 注册 方可回帖
返回
//