最近在学习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)的更多相关文章

  1. 一个简单的Object Hook的例子(win7 32bit)

    Object Hook简单的来说就是Hook对象,这里拿看雪上的一个例子,因为是在win7 32位上的,有些地方做了些修改. _OBJECT_HEADER: kd> dt _OBJECT_HEA ...

  2. Android的so注入( inject)和函数Hook(基于got表) - 支持arm和x86

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/53942648 前面深入学习了古河的Libinject注入Android进程,下面来 ...

  3. android hook 框架 libinject2 简介、编译、运行

    Android so注入-libinject2 简介.编译.运行 Android so注入-libinject2  如何实现so注入 Android so注入-Libinject 如何实现so注入 A ...

  4. 01.WAMP搭建 [Win7+Apache2.4+MySQL5.7+PHP7

    WAMP搭建[Win7+Apache2.4+MySQL5.7+PHP7 一.背景 将电脑光驱位拆换成固态硬盘(120g),专门装了一个系统用于工作.之前一直使用PHPstudy和WAMP这种集成环境, ...

  5. win7 xp 双系统安装记录

    原机win7 64 增加xp x86 win7在c盘,xp装h盘 1.老毛桃pe,雨林木风gho,蓝屏,0000007b 2.通用pe.雨林木风gho,蓝屏,00000007b 3.pe设置h盘为系统 ...

  6. Android下so注入和hook

    一.前言 总结一下这两天学习的Android注入so文件,通过遍历got表hook函数调用 1.注入so文件 2.so文件中遍历got表hook函数 二.注入so文件 1)注入进程 1.编程思路分为以 ...

  7. android hook 框架 libinject 如何实现so注入

    前面两篇 android hook 框架 libinject2 简介.编译.运行 android hook 框架 libinject2 如何实现so注入 实际运行并分析了 Android中的so注入( ...

  8. CApiHook__Api钩子类

    见过网上有很多ApiHook的类,但是都不尽入人意,要么就是写的不够好不够完善,要么就是跑不起来. 用别人写的代码总是有种不安心,所以自己就花了一晚上写了CApiHook类.已经尽量确保自己写的类是非 ...

  9. UDP收发buffer尺寸对收发包流量的影响

    下午验证一个高流量发包问题时,发现了一个值得记录的问题:socket的收发buffer尺寸是会影响收发包的效率的,高流量通讯时,若socket的收发buffer尺寸过小会一定程度降低收发包效率. 自己 ...

随机推荐

  1. Android APP性能及专项测试

    移动测试. Android测试 .APP测试 Android篇 1. 性能测试 Android性能测试分为两类:1.一类为rom版本(系统)的性能测试2.一类为应用app的性能测试 Android的a ...

  2. php获取远程图片并把它保存到本地

    /* *功能:php多种方式完美实现下载远程图片保存到本地 *参数:文件url,保存文件名称,使用的下载方式 *当保存文件名称为空时则使用远程文件原来的名称 */ function getImage( ...

  3. 全差分运算放大器ADA4930的分析(1)

    AD转换芯片的模拟信号输入端方式为:全差分.伪差分.单端输入,其中全差分输入的效果最佳,现阶段ADC转换器为了提高其性能,建议用户使用全差分的输入方式.(AD7982.ADS8317等都能实现信号的全 ...

  4. react-native 使用leanclound消息推送

    iOS消息推送的基本流程 1.注册:为应用程序申请消息推送服务.此时你的设备会向APNs服务器发送注册请求.2. APNs服务器接受请求,并将deviceToken返给你设备上的应用程序 3.客户端应 ...

  5. .NET Core 获取主机运行资源的库

    简介 CZGL.SystemInfo 是一个支持 Windows 和 Linux 的资源信息获取库,用于获取系统环境.机器资源信息.系统资源使用情况. Nuget 搜索 CZGL.SystemInfo ...

  6. python 深浅拷贝 元组 字典 集合操作

    深浅拷贝 :值拷贝 :ls = [,,] res = ls 则print(res)就是[,,] 浅拷贝 :ls.copy() 深拷贝:ls3 = deepcopy(ls) # 新开辟列表空间,ls列表 ...

  7. Flink系列之1.10版流式SQL应用

    随着Flink 1.10的发布,对SQL的支持也非常强大.Flink 还提供了 MySql, Hive,ES, Kafka等连接器Connector,所以使用起来非常方便. 接下来咱们针对构建流式SQ ...

  8. Python1-变量

    一.变量和简单数据类型 1.变量 命名规则: 变量名组成——字母.下划线.数字(不可做首字符): 用下划线分隔单词,不可包含空格: 关键字和函数名不可做变量名: 小写字母做变量名,不建议使用大小写的字 ...

  9. markdown从入门到放弃word和PDF

    Markdown是一个「轻量级」的「标记语言」. 淡定!!!我知道很多"编外人员"看到这句话之后已经没有兴趣再看下去了. 但是请不要关掉这个页面!!! Markdown很简单!!! ...

  10. 【Python】2.16学习笔记 运算符,位运算符,if-else语句

    复合运算符 a *= b # a = a * b a += b # a = a + b a -= b # a = a - b ... 位运算符 对数字进行二进制运算 按位与 &,二进制位都为一 ...