Hook集合----SSDTHook(x86 Win7)
最近在学习Ring0层Hook的一些知识点,很久就写完SSDTHook的代码了,但是一直没有整理成笔记,最近有时间也就整理整理。
介绍:
SSDTHook 实质是利用Ntoskrnl.exe 中全局导出的SSDT来进行Hook,SSDT(SystemServiceDescriptorTable,系统服务描述表),为什么要去用到SSDT表呢?
我们看一下ZwOpenProcess实现就明白了。为什么不用Nt系列函数,可以看我之前的文章。
kd> u 0x8485acd8
nt!ZwOpenProcess:
8485acd8 b8 be000000 mov eax,0BEh
8485acdd 8d542404 lea edx,[esp+]
8485ace1 9c pushfd
8485ace2 6a08 push
8485ace4 e8d5190000 call nt!KiSystemService (8485c6be)
8485ace9 c21000 ret 10h
nt!ZwOpenProcessToken:
8485acec b8bf000000 mov eax,0BFh
8485acf1 8d542404 lea edx,[esp+]
KiSystemService是系统调用的内核入口,也是从Ring3陷入Ring0的关键点。在第一句中mov eax,0BEh 中的BEh在我看来就是一个序号,相当于中断向量表中的中断类型号一样,在SSDT表中通过这序号,才找到真正的NtOpenProcess函数的代码出。很容易就能理解,我们为什么要找这个。原因在于:我们要把SSDT表中相应位置的函数地址替换掉,就实现了Hook。
(一)
⚪首先找到全局导出的KeServiceDescriptorTable。
⚪然后从MmGetSystemRoutineAddress函数中获取ZwOpenProcess函数地址。
⚪从ZwOpenProcess中获取序号。
⚪将SSDT表所在页属性改为可读可写的状态。
⚪将自己写好的Fake函数地址替换进去即可。
Hook之前: Hook之后:
(二)
/*
typedef struct _SYSTEM_SERVICE_DESCRIPTOR_TABLE_
{
PVOID ServiceTableBase; //这个指向系统服务函数地址表
PULONG ServiceCounterTableBase;
ULONG NumberOfService; //服务函数的个数
ULONG ParamTableBase;
}SYSTEM_SERVICE_DESCRIPTOR_TABLE, *PSYSTEM_SERVICE_DESCRIPTOR_TABLE; 0x84988b00 struct _SYSTEM_SERVICE_DESCRIPTOR_TABLE_ *
ServiceTableBase 0x8489d43c
ServiceCounterTableBase 0x00000000
NumberOfService 0x191
ParamTableBase 0x8489da84
*/
extern PSYSTEM_SERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
PUCHAR __ZwOpenProcess = NULL;
PMDL __MDL = NULL;
PVOID *__ServiceTableBase = NULL;
LPFN_NTOPENPROCESS __NtOpenProcess = NULL;
BOOLEAN __IsHook = FALSE; #define SSDT_INDEX(ZwFunctionAddress) * (PULONG)((PUCHAR)ZwFunctionAddress +1)
#define SSDT_HOOK(ZwFunctionAddress,FakeFunctionAddress,OriginalFunctionAddress)\
OriginalFunctionAddress = (PVOID) InterlockedExchange((PLONG)&__ServiceTableBase[SSDT_INDEX(ZwFunctionAddress)],(LONG)FakeFunctionAddress)
#define SSDT_UNHOOK(ZwFunctionAddress,OriginalFunctionAddress)\
(PVOID) InterlockedExchange((PLONG)&__ServiceTableBase[SSDT_INDEX(ZwFunctionAddress)],(LONG)OriginalFunctionAddress)
NTSTATUS SSDTHook(BOOLEAN IsOk)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING v1;
RtlInitUnicodeString(&v1, L"ZwOpenProcess"); if (IsOk)
{
__ZwOpenProcess = (PUCHAR)MmGetSystemRoutineAddress(&v1);
/*
2: kd> u 0x8485acd8
nt!ZwOpenProcess:
8485acd8 b8 be000000 mov eax,0BEh
8485acdd 8d542404 lea edx,[esp+4]
8485ace1 9c pushfd
8485ace2 6a08 push 8
8485ace4 e8d5190000 call nt!KiSystemService (8485c6be)
8485ace9 c21000 ret 10h
nt!ZwOpenProcessToken:
8485acec b8bf000000 mov eax,0BFh
8485acf1 8d542404 lea edx,[esp+4] */
if (__ZwOpenProcess)
{
if (__MDL == NULL)
{
__MDL = MmCreateMdl(NULL, KeServiceDescriptorTable->ServiceTableBase,
KeServiceDescriptorTable->NumberOfService * sizeof(PVOID));
if (!__MDL)
{
return Status;
}
MmBuildMdlForNonPagedPool(__MDL);
//设置标志让内存变成读写
__MDL->MdlFlags = __MDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
__ServiceTableBase = MmMapLockedPages(__MDL, KernelMode);
} if (__ServiceTableBase)
{
if (!__IsHook)
{
//开始HOOK
SSDT_HOOK(__ZwOpenProcess, FakeNtOpenProcess, __NtOpenProcess);
Status = STATUS_SUCCESS;
/*
2: kd> u 0x84a31ba1
nt!NtOpenProcess:
84a31ba1 8bff mov edi,edi
84a31ba3 55 push ebp
84a31ba4 8bec mov ebp,esp
84a31ba6 51 push ecx
84a31ba7 51 push ecx
84a31ba8 64a124010000 mov eax,dword ptr fs:[00000124h]
84a31bae 8a803a010000 mov al,byte ptr [eax+13Ah]
84a31bb4 8b4d14 mov ecx,dword ptr [ebp+14h] */ __IsHook = TRUE;
} }
}
}
else
{
if (__IsHook)
{
SSDT_UNHOOK(__ZwOpenProcess, __NtOpenProcess);
__IsHook = FALSE;
}
if (__MDL)
{
MmUnmapLockedPages(__ServiceTableBase, __MDL);
IoFreeMdl(__MDL);
__MDL = NULL;
Status = STATUS_SUCCESS; } } return Status;
} NTSTATUS FakeNtOpenProcess( PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId)
{ __try
{
PEPROCESS EProcess = PsGetCurrentProcess();
if (EProcess != NULL && IsRealProcess(EProcess))
{
char * ProcessName = (ULONG_PTR)EProcess + x86_IMAGEFILENAME_OFFSET;
if (strcmp(ProcessName, "HookRing3.exe")==)
{
return STATUS_ACCESS_DENIED;
}
}
}
__except ()
{
return GetExceptionCode();
}
return ((LPFN_NTOPENPROCESS)__NtOpenProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); }
Hook集合----SSDTHook(x86 Win7)的更多相关文章
- 一个简单的Object Hook的例子(win7 32bit)
Object Hook简单的来说就是Hook对象,这里拿看雪上的一个例子,因为是在win7 32位上的,有些地方做了些修改. _OBJECT_HEADER: kd> dt _OBJECT_HEA ...
- Android的so注入( inject)和函数Hook(基于got表) - 支持arm和x86
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/53942648 前面深入学习了古河的Libinject注入Android进程,下面来 ...
- android hook 框架 libinject2 简介、编译、运行
Android so注入-libinject2 简介.编译.运行 Android so注入-libinject2 如何实现so注入 Android so注入-Libinject 如何实现so注入 A ...
- 01.WAMP搭建 [Win7+Apache2.4+MySQL5.7+PHP7
WAMP搭建[Win7+Apache2.4+MySQL5.7+PHP7 一.背景 将电脑光驱位拆换成固态硬盘(120g),专门装了一个系统用于工作.之前一直使用PHPstudy和WAMP这种集成环境, ...
- win7 xp 双系统安装记录
原机win7 64 增加xp x86 win7在c盘,xp装h盘 1.老毛桃pe,雨林木风gho,蓝屏,0000007b 2.通用pe.雨林木风gho,蓝屏,00000007b 3.pe设置h盘为系统 ...
- Android下so注入和hook
一.前言 总结一下这两天学习的Android注入so文件,通过遍历got表hook函数调用 1.注入so文件 2.so文件中遍历got表hook函数 二.注入so文件 1)注入进程 1.编程思路分为以 ...
- android hook 框架 libinject 如何实现so注入
前面两篇 android hook 框架 libinject2 简介.编译.运行 android hook 框架 libinject2 如何实现so注入 实际运行并分析了 Android中的so注入( ...
- CApiHook__Api钩子类
见过网上有很多ApiHook的类,但是都不尽入人意,要么就是写的不够好不够完善,要么就是跑不起来. 用别人写的代码总是有种不安心,所以自己就花了一晚上写了CApiHook类.已经尽量确保自己写的类是非 ...
- UDP收发buffer尺寸对收发包流量的影响
下午验证一个高流量发包问题时,发现了一个值得记录的问题:socket的收发buffer尺寸是会影响收发包的效率的,高流量通讯时,若socket的收发buffer尺寸过小会一定程度降低收发包效率. 自己 ...
随机推荐
- Android APP性能及专项测试
移动测试. Android测试 .APP测试 Android篇 1. 性能测试 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试 Android的a ...
- php获取远程图片并把它保存到本地
/* *功能:php多种方式完美实现下载远程图片保存到本地 *参数:文件url,保存文件名称,使用的下载方式 *当保存文件名称为空时则使用远程文件原来的名称 */ function getImage( ...
- 全差分运算放大器ADA4930的分析(1)
AD转换芯片的模拟信号输入端方式为:全差分.伪差分.单端输入,其中全差分输入的效果最佳,现阶段ADC转换器为了提高其性能,建议用户使用全差分的输入方式.(AD7982.ADS8317等都能实现信号的全 ...
- react-native 使用leanclound消息推送
iOS消息推送的基本流程 1.注册:为应用程序申请消息推送服务.此时你的设备会向APNs服务器发送注册请求.2. APNs服务器接受请求,并将deviceToken返给你设备上的应用程序 3.客户端应 ...
- .NET Core 获取主机运行资源的库
简介 CZGL.SystemInfo 是一个支持 Windows 和 Linux 的资源信息获取库,用于获取系统环境.机器资源信息.系统资源使用情况. Nuget 搜索 CZGL.SystemInfo ...
- python 深浅拷贝 元组 字典 集合操作
深浅拷贝 :值拷贝 :ls = [,,] res = ls 则print(res)就是[,,] 浅拷贝 :ls.copy() 深拷贝:ls3 = deepcopy(ls) # 新开辟列表空间,ls列表 ...
- Flink系列之1.10版流式SQL应用
随着Flink 1.10的发布,对SQL的支持也非常强大.Flink 还提供了 MySql, Hive,ES, Kafka等连接器Connector,所以使用起来非常方便. 接下来咱们针对构建流式SQ ...
- Python1-变量
一.变量和简单数据类型 1.变量 命名规则: 变量名组成——字母.下划线.数字(不可做首字符): 用下划线分隔单词,不可包含空格: 关键字和函数名不可做变量名: 小写字母做变量名,不建议使用大小写的字 ...
- markdown从入门到放弃word和PDF
Markdown是一个「轻量级」的「标记语言」. 淡定!!!我知道很多"编外人员"看到这句话之后已经没有兴趣再看下去了. 但是请不要关掉这个页面!!! Markdown很简单!!! ...
- 【Python】2.16学习笔记 运算符,位运算符,if-else语句
复合运算符 a *= b # a = a * b a += b # a = a + b a -= b # a = a - b ... 位运算符 对数字进行二进制运算 按位与 &,二进制位都为一 ...