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 查看评论