Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

ShadowSSDT Hook

$
0
0

ShadowSSDT表的获取

这里的ShadowSSDT表的获取是通过函数KeAddSystemServiceTable来获取的。
使用这个函数的原因:
1、这个函数是已经导出的,可以在代码中直接使用。
2、这个函数里面使用了ShadowSSDT,包含了ShadowSSDT的地址。
可以使用WinDbg查看该函数代码,如下:
kd> u KeAddSystemServiceTable l 30
nt!KeAddSystemServiceTable:
83fa3008 8bff            mov     edi,edi
83fa300a 55              push    ebp
83fa300b 8bec            mov     ebp,esp
83fa300d 837d1801        cmp     dword ptr [ebp+18h],1
83fa3011 7760            ja      nt!KeAddSystemServiceTable+0x6b (83fa3073)
83fa3013 8b4518          mov     eax,dword ptr [ebp+18h]
83fa3016 c1e004          shl     eax,4
83fa3019 83b8c009f88300  cmp     dword ptr nt!KeServiceDescriptorTable (83f809c0)[eax],0
83fa3020 7551            jne     nt!KeAddSystemServiceTable+0x6b (83fa3073)
83fa3022 8d88000af883    lea     ecx,nt!KeServiceDescriptorTableShadow (83f80a00)[eax]
83fa3028 833900          cmp     dword ptr [ecx],0
83fa302b 7546            jne     nt!KeAddSystemServiceTable+0x6b (83fa3073)
83fa302d 837d1801        cmp     dword ptr [ebp+18h],1
83fa3031 8b5508          mov     edx,dword ptr [ebp+8]
83fa3034 56              push    esi
83fa3035 8b7510          mov     esi,dword ptr [ebp+10h]
83fa3038 57              push    edi
83fa3039 8b7d14          mov     edi,dword ptr [ebp+14h]
83fa303c 8911            mov     dword ptr [ecx],edx
83fa303e 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
83fa3041 8988040af883    mov     dword ptr nt!KeServiceDescriptorTableShadow+0x4 (83f80a04)[eax],ecx
83fa3047 89b0080af883    mov     dword ptr nt!KeServiceDescriptorTableShadow+0x8 (83f80a08)[eax],esi
83fa304d 89b80c0af883    mov     dword ptr nt!KeServiceDescriptorTableShadow+0xc (83f80a0c)[eax],edi
83fa3053 7418            je      nt!KeAddSystemServiceTable+0x65 (83fa306d)

在代码中获取ShadowSSDT的方式是暴力搜索,代码如下:
ULONG GetShadowTableAddress()
{
	ULONG dwordatbyte, i;
	PUCHAR p = (PUCHAR)KeAddSystemServiceTable;
	for(i = 0; i < 0x1024; i++, p++)
	{
		__try
		{
			dwordatbyte = *(PULONG)p;
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			return NULL;
		}
		if(MmIsAddressValid((PVOID)dwordatbyte))
		{
			//这里得到的以dwordatbyte为首地址的数据是否与KeServiceDescriptorTable的前16字节相同
			if(memcmp((PVOID)dwordatbyte, KeServiceDescriptorTable, 16) == 0)
			{
				//地址相同,则排除,因为要找到的是ShadowSSDT,而不是SSDT。
				if((PVOID)dwordatbyte == KeServiceDescriptorTable)
					continue;
				return dwordatbyte;
			}
		}
	}
	return NULL;
}

ShadowSSDT Hook

ShadowSSDT的Hook方法与SSDT的Hook方法基本一样,不同的地方是以下几点:
1、ShadowSSDT Hook之前需要先KeAttachProcess一个有界面的进程,一般会操作explorer.exe
2、由于KeAttachProcess需要传入一个类型为PEPROCESS的参数,需要通过进程名获取该进程的PEPROCESS结构体。
3、Hook完成之后使用KeDetachProcess获取Attach的进程。

简单说一下通过进程名获取该进程的PEPROCESS结构体的方法:
使用PsGetProcessImageFileName获取当前进程的结构体,以此向前或向后遍历搜索,获取结构体中的进程名信息与需要的进程名比较。在这个里面需要处理的两个地方,由于系统版本不同,导致PEPROCESS结构体中进程名的偏移不同,因此需要先判断系统,设置不同的偏移;第二个是PsGetProcessImageFileName该函数只能运行于PASSIVE_LEVEL层,所以需要获取当前的IRQL进行判断。

疑问

关于KeAttachProcess和KeDetachProcess,
我想在Hook之后,KeAttachProcess一个进程,然后,在卸载Hook之后,再执行KeDetachProcess函数,但是当我Hook完成之后,运行一会,就出现系统蓝屏了,难道KeAttachProcess之后,对ShadowSSDT做完操作,就必须先KeDetachProcess吗?

作者:l0g1n 发表于2013-12-26 0:49:24 原文链接
阅读:145 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>