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尺寸过小会一定程度降低收发包效率. 自己 ...
随机推荐
- 关于线上bug
之所以想写下线上bug,因为发觉有些公司对线上bug的处理是比较严格甚至是很苛刻,涉及到的相关人可能会因此而背黑锅. 之所以会存在这样情况,因为公司各部门都有关联,特别是用户.老板的投诉,也给公司会造 ...
- clearstatcache清除文件状态缓存
当使用下列任何函数时stat(),lstat(),file_exists(),is_writable(),is_readable(),is_executable(),is_file(),is_dir( ...
- Golang/Python/PHP带你彻底学会gRPC
目录 一.gRPC是什么? 二.Protocol Buffers是什么? 三.需求:开发健身房服务 四.最佳实践 Golang 1. 安装protoc工具 2. 安装protoc-gen-go 3. ...
- 前端笔记--css样式笔记
一.浮动 定位布局 1.浮动布局 left 元素向左浮动 right 元素向右浮动 例如:设置2个按钮,要使得按钮在同一行位置摆放,可以使用浮动,令按钮浮动到右边.注意,先设置float的按钮,例如: ...
- Windows GDI 窗口与 Direct3D 屏幕截图
前言 Windows 上,屏幕截图一般是调用 win32 api 完成的,如果 C# 想实现截图功能,就需要封装相关 api.在 Windows 上,主要图形接口有 GDI 和 DirectX.GDI ...
- 前端每日实战:52# 视频演示如何用纯 CSS 创作一个小球绕着圆环盘旋的动画
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/gKxyWo 可交互视频 此视频是可 ...
- Spring MVC系列-(1) Spring概述
1. Spring概述 本章主要介绍Spring中的体系结构和常见概念,比如bean.控制反转(Inverse of Control,IoC)等. 1.1 体系结构 Spring 框架提供约 20 个 ...
- 『配置』服务器搭建 Office Online Server2016 实现文档预览
博主有话说:这个过程我遇到了很多错误,所以出了一个错误整理文章,所以当你在配置过程中遇到了问题,可以先去这篇文章里找找!加油! 先打开我吧:https://www.cnblogs.com/pukua/ ...
- vue的子组件不能进行router的切换
在用vue开发过程中,偶然一次使用在子组件中进行router的切换,发现不起作用,后来才反应过来,子组件只是一个组件,vue的路由的切换只能是在父组件(也就是真正的页面)里面进行跳转!
- PHP的json_encode和json_decode的区别
经常搞混的两个PHP函数: json_encode()是对变量进行json编码 json_encode()为要编码的值,且该函数只对utf8编码的数据有效 json_decode($json)对jso ...