您的位置:首页 > 其它

关于windows内核SSDT HOOK的一点思考

2015-07-02 00:39 459 查看
关于windows内核SSDT HOOK的一点思考

----------------TTL

关于windows内核,一直是众多OS黑客所喜欢又不敢触及的地方,确实,内核的知识实在是隐晦,又生涩难懂。我觉得OS hacker和WEB hacker确实存在差别。一般来讲,OS hacker的难度要很大。因为二进制的漏洞相比于web漏洞难度大,主要是无源。web有源码,挖掘漏洞自然相对就很简单(但也需要扎实的基本功和良好的知识基础)。

那么关于什么是SSDT呢?我有一点自己的思考。

首先百度百科也说了SSDT的含义。SSDT就是windows内核的一个十分庞大的地址索引表,在这个地址索引表上,有内核服务的地址。这些地址组成了一个线性的地址序列,也就是数组,每个数组元素就是一个指针。这个指针就是内核中的系统服务的地址。

在不同的操作系统上,SSDT也是不一样的。所以SSDT HOOK 的代码要做到兼容难度也是不小。其实用户层的程序在执行的过程中,首先调用win32平台上的API,然后进入内核,在SSDT的庞大地址索引表中寻找对应的内核服务的地址。这样就将上层的API和内核的服务对应了起来。

接下来,看一下代码,代码是我学习梦老大的。在这里,感谢梦老大。

#pragma pack(1)

typedef struct ServiceDescriptorEntry {

unsigned int *ServiceTableBase;

unsigned int *ServiceCounterTableBase; //仅适用于checked build版本

unsigned int NumberOfServices;

unsigned char *ParamTableBase;

} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;

#pragma pack()

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

首先我声明一个ServiceDescriptorTableEntry_t结构体。这个结构体来管理SSDT,也就是SSDT都在这个表中指向。

void PageProtectOn()

{

__asm{//恢复内存保护

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

}

void PageProtectOff()

{

__asm{//去掉内存保护

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

}

首先谢了两个内存保护开启和关闭的函数,论坛上很多大神都采用这种风格,我也就延续大大们的风格。

首先,在Windbg中,查看了eProcess这个数据结构。后面的代码中我会用到。



可看到,在我的系统中,偏移0x174是ImageFileName。

然后利用XueTr查看了SSDT。



从表中可以看出,NtOpenProcess被腾讯的程序在内核被HOOK了,不仅仅是腾讯,像360,百度的一些安全软件,在底层也是疯狂的HOOK。这也是病毒对抗越来越趋向于底层化的原因。从图看到,NtOpenProcess在SSDT中是122号。

主要代码:

NTSTATUS NewNtOpenProcess (

__out PHANDLE ProcessHandle,

__in ACCESS_MASK DesiredAccess,

__in POBJECT_ATTRIBUTES ObjectAttributes,

__in_opt PCLIENT_ID ClientId

)

{

KdPrint(("NewNtOpenProcess"));

KdPrint(("%s",(char*)PsGetCurrentProcess()+0x174));

return ((NTOPENPROCESS)g_ntopenprocess)(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);

}

NTSTATUS HookNtOpenProcess()

{

NTSTATUS
status;

status = STATUS_SUCCESS;

PageProtectOff();

g_ntopenprocess = KeServiceDescriptorTable.ServiceTableBase[122];

KeServiceDescriptorTable.ServiceTableBase[122] = (unsigned int)NewNtOpenProcess;

PageProtectOn();

return status;

}

VOID UnHookNtOpenProcess()

{

PageProtectOff();

KeServiceDescriptorTable.ServiceTableBase[122] = (unsigned int)g_ntopenprocess;

PageProtectOn();

}

VOID MyUnload(PDRIVER_OBJECT pDriverObject)

{

UnHookNtOpenProcess();

}

NTSTATUS DriverEntry(PDRIVER_OBJECTpDriverObject,PUNICODE_STRING Reg_Path)

{

HookNtOpenProcess();

pDriverObject->DriverUnload = MyUnload;

return STATUS_SUCCESS;

}

在新的NtOpenProcess我们什么也不做,只打印一条消息,和一条被哪个程序调用的名称。

效果如图:





从图中看到,NtOpenProcess已经被我们的sys所HOOK住,并不是之前的腾讯的程序了。

HOOK成功
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: