最近在学习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. selenium之浏览器、元素、鼠标等操作总结

    1    控制浏览器 Selenium 主要提供的是操作页面上各种元素的方法,但它也提供了操作浏览器本身的方法,比如浏览器的大小以及浏览器后退.前进按钮等. 1.1  控制浏览器窗口大小 在不同的浏览 ...

  2. 新浪微博PC端登录分析

    本来给自己定了个2018的目标,平均每月写两篇文章,现在已经快三月了,第一篇稿子才憋出来,惭愧呀,直入主题吧,今天给大家带来的是新浪微博PC端的模拟登陆. 工具 这次使用的工具是Charles和chr ...

  3. STL标准库中的容器

    容器:顾名思义,我的理解就是把同一种数据类型括起来,作为一捆.如vector<int> ,vector就是个容器,里面全是一个个的int型数据. 容器包括三大块: 顺序型容器: (1)ve ...

  4. js中的函数应用

    js中的函数应用 什么是函数,函数的概念 函数就像一个黑匣子,里面的东西你都不知道,但是你提供一些材料放进去,他可以制造出你需要的东西; 可以让多个一样的功能封装组合起来,然后想执行几次就执行几次 函 ...

  5. 万维网(WWW)

    万维网(WWW) 一.万维网概述 万维网 WWW (World Wide Web)是一个大规模的.联机式的信息储藏所. 万维网用链接的方法能非常方便地从因特网上的一个站点访问另一个站点,从而主动地按需 ...

  6. 硬件小白学习之路(1)稳压芯片LM431

    图稳压芯片LM431简介 偶然的机会接触到LM431这个芯片,周末晚上打发无聊的时光,查资料进行剖析. LM431的Symbol Diagram和Functional Diagram如图1所示,下面分 ...

  7. JAVA Integer值的范围

    原文出处:http://hi.baidu.com/eduask%C9%BD%C8%AA/blog/item/227bf4d81c71ebf538012f53.html package com.test ...

  8. GitOps入门与实践:如何集成Git和K8S?

    也许你之前听说过GitOps,但是对其并不了解.在本文中,我将对其进行简单介绍,它其实是一个应用程序开发和管理中的一个术语,其核心思想是将应用系统的声明性基础架构和应用程序存放在Git的版本控制库中. ...

  9. PTP从时钟授时模块应用及介绍

    PTP从时钟授时模块应用及介绍 随着网络技术的不断进步和发展,NTP网络时间协议已经满不了一些精密设备和仪器的精度要求,这时就需要精度更高的PTP协议,PTP协议是一种应用于分布式测量和控制系统中的精 ...

  10. 【python pip】一招解决pip下载过慢问题

    目录 概述 壹:问题描述 贰:解决过程 一.问题分析 二.问题解决 方法一:下载时加入参数-i [镜像源地址] 方法二:设置源 三.国内镜像源地址 叁:作者有话 作者 概述 在我们经常使用pip安装插 ...