通过构造系统服务分发实现拦截&过滤 (仿360游戏保险箱)

想写这个程序主要是因为看了KSSD的一篇帖子,http://bbs.pediy.com/showthread.php?t=108378

讲 的是360保险箱保护游戏账号的原理,实际上就是对各种请求的拦截。这个帖子是大约6年前的了,我简单的看了一下现在的360保险箱应该不再采用这种方法 了,不再去HOOK KiFastCallEntry了,而且多增加了几个事件通知回调。这里主要是跟着那篇帖子作者的分析,来自己实现一个360游戏保险箱。

这里主要的思路就是HOOK住系统服务的分发,这已经不是什么新鲜的手法了。比方说,很多外挂作者都使用了内核重载来突破游戏保护的重重HOOK,内核重载也是劫持KiFastCallEntry来实现劫持服务分发的。这篇文章没有用什么前沿的技术,这里只是做一个练习。

基本流程是

1.应用层:

负责安装驱动模块并与驱动通信,由用户选择是否要放行指定操作

2.内核层:

(1)设置SSDT HOOK并调用HOOK 函数,进行栈回溯获取KiFastCallEntry()基址
(2)利用KiFastCallEntry()基址暴力搜索找到HOOK点位置并设置Inline Hook
(3)判断服务请求是否合法,合法则放行,不合法则传递消息给用户层,由用户决定是否放行

其实以上三步就是360保险箱的做法,程序里的有些内容因为不知道该怎么写,所以直接由那篇帖子的汇编分析逆写出来了。

  1 #include "ntddk.h"
  2 #include <ntdef.h>
  3
  4 #define NtSetEventID 219
  5
  6 typedef struct ServiceDescriptorEntry {
  7     unsigned int *ServiceTableBase;
  8     unsigned int *ServiceCounterTableBase;
  9     unsigned int NumberOfServices;
 10     unsigned char *ParamTableBase;
 11 } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
 12
 13 __declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
 14
 15 NTSTATUS ZwSetEvent(__in HANDLE  EventHandle,__out_opt PLONG  PreviousState);
 16
 17 HANDLE HandleTemp = (HANDLE)0x288C58F1;
 18 ULONG NtSetEventAddress;
 19 ULONG KiFastCallEntryAddress;
 20 ULONG TheHookAddress;
 21 ULONG YesOrNo=0;
 22 ULONG AddressOffset = 0;
 23 ULONG TempDword;
 24 ULONG ProcessPID = 0;
 25 ULONG pid, DispatchAddress, TempBufferCopy;
 26 PULONG DwordAddress = 0;
 27 INT8 i;
 28 INT8 *PbyteAddress;
 29 KSPIN_LOCK MySpinLock1;
 30 KSPIN_LOCK MySpinLock2;
 31 KSPIN_LOCK MySpinLock3;
 32 KIRQL TempKirql1;
 33 KIRQL TempKirql2;
 34 //设置SSDT HOOK 用来栈回溯得到KiFastCallEntry地址
 35 NTSTATUS HookSSDT(PVOID FuncAdress)
 36 {
 37     ULONG OutTemp = 0;
 38     NtSetEventAddress = (ULONG)KeServiceDescriptorTable.ServiceTableBase[NtSetEventID];
 39     KeInitializeSpinLock(&MySpinLock1);
 40     KeAcquireSpinLock(&MySpinLock1,&TempKirql1);
 41     _asm {
 42             cli
 43             push eax
 44             mov  eax, cr0
 45             and  eax, not 10000h
 46             mov  cr0, eax
 47             pop eax
 48     }
 49     KeServiceDescriptorTable.ServiceTableBase[NtSetEventID] = (ULONG)FuncAdress;
 50     __asm {
 51             push eax
 52             mov  eax, cr0
 53             or eax, 10000h
 54             mov  cr0, eax
 55             pop eax
 56             sti
 57     }
 58     KeReleaseSpinLock(&MySpinLock1,&TempKirql1);
 59     ZwSetEvent(HandleTemp,
 60         &OutTemp);
 61     return STATUS_SUCCESS;
 62 }
 63 //解除SSDT HOOK
 64 void UnhookSSDTHook()
 65 {
 66     KeInitializeSpinLock(&MySpinLock2);
 67     KeAcquireSpinLock(&MySpinLock2,&TempKirql1);
 68     _asm {
 69             cli
 70             push eax
 71             mov  eax, cr0
 72             and  eax, not 10000h
 73             mov  cr0, eax
 74             pop eax
 75     };
 76     KeServiceDescriptorTable.ServiceTableBase[NtSetEventID] = NtSetEventAddress;
 77
 78     _asm {
 79             push eax
 80             mov  eax, cr0
 81             or eax, 10000h
 82             mov  cr0, eax
 83             pop eax
 84             sti
 85     };
 86     KeReleaseSpinLock(&MySpinLock2,&TempKirql1);
 87     return;
 88 }
 89 ULONG TheDispatchFunc(ULONG arg1, ULONG arg2, ULONG arg3)
 90 {
 91     pid = (ULONG)PsGetCurrentProcessId();
 92     if (arg1 > 450)
 93     {
 94         return arg2;
 95     }
 96     //说明是SSDT服务分发
 97     if (arg3== (ULONG)KeServiceDescriptorTable.ServiceTableBase)
 98     {
 99         //拦截122和257号调用
100         if (arg1==122||arg1==257)
101         {
102
103             {
104                 return arg2;
105             }
106         }
107         else
108         {
109             return arg2;
110         }
111     }
112     return arg2;
113 }
114 //被挂载在KiFastCallEntry中(作为一个中转函数)
115 __declspec(naked) void InlineFunc()
116 {
117     _asm {
118             pushad
119             pushfd
120
121             push edi//服务表基址
122             push ebx//服务地址
123             push eax//服务序号
124             call TheDispatchFunc
125             mov DispatchAddress,eax
126
127             popfd
128             popad
129             //补全被覆盖的函数
130             mov ebx,DispatchAddress
131             SUB ESP, ECX
132             SHR ECX, 02
133
134             jmp TempBufferCopy
135     };
136
137 }
138 //被挂载在SSDT的函数,需判断伪句柄
139 //并且要进行Inline HOOK
140 __declspec(naked) void SSDTFunc()
141 {
142     _asm {
143             push eax
144             mov eax, [esp + 8]
145             mov TempDword, eax
146             pop eax
147     }
148
149     if (TempDword == HandleTemp)
150     {
151         _asm {
152             push eax
153             mov eax, [esp + 4]
154             mov KiFastCallEntryAddress, eax
155             mov TempBufferCopy,eax
156             pop eax
157             };
158         UnhookSSDTHook();
159     }
160     else
161     {
162         _asm {
163             jmp NtSetEventAddress
164         };
165     }
166     for (i = 0; i < 200; i++)
167     {
168
169         if (*((PULONG)KiFastCallEntryAddress)==0xe9c1e12b)
170         {
171             TheHookAddress = KiFastCallEntryAddress;
172             YesOrNo = 1;
173             break;
174         }
175         KiFastCallEntryAddress--;
176     }
177     if (YesOrNo)
178     {
179         AddressOffset = (ULONG)InlineFunc - 5 - (ULONG)TheHookAddress;
180         PbyteAddress = (INT8 *)TheHookAddress;
181         *PbyteAddress = 0xe9;
182         DwordAddress = (PULONG)((ULONG)TheHookAddress + 1);
183         *DwordAddress = AddressOffset;
184     }
185     _asm{retn 0x8 }
186 }
187 NTSTATUS UnloadFunc(PDRIVER_OBJECT MyDriver, PUNICODE_STRING RegPath)
188 {
189     //清理必要资源
190     return STATUS_SUCCESS;
191 }
192 NTSTATUS DriverEntry(PDRIVER_OBJECT MyDriver, PUNICODE_STRING RegPath)
193 {
194     NTSTATUS Status = 0;
195     MyDriver->DriverUnload = UnloadFunc;
196     Status = HookSSDT((PVOID)SSDTFunc);
197     if (!NT_SUCCESS(Status))
198     {
199         return 1;
200     }
201     return STATUS_SUCCESS;
202 }
时间: 2024-08-24 20:20:42

通过构造系统服务分发实现拦截&过滤 (仿360游戏保险箱)的相关文章

MVC的Filters(拦截过滤)的Error页面

报错拦截过滤到error页面 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class ExceptionAttribute : FilterAttribute, IExceptionFilter { /*报错回到报错页Error*/ /* *CreateTime:2013‎年‎3‎月‎18‎日 */ public

仿360加速球。(实现内存释放)

FloatCircleView的实现自定义view 创建WindowManager窗体管理类管理悬浮小球和底部大窗体 MyProgreeView手机底部窗体中小球的实现 FloatMenuView的实现 MyFloatService MainActivity的实现 现在手机上的悬浮窗应用越来越多,对用户来说,最常见的悬浮窗应用就是安全软件的悬浮小控件,拿360卫士来说,当开启悬浮窗时,它是一个小球,小球可以拖动,当点击小球出现大窗体控件,可以进行进一步的操作如:释放手机内存等等.于是借着慕课网的

前端的小玩意(9.4)——做一个仿360工具箱的web页面(自动生成所有图标,对图标添加响应逻辑)

前端的小玩意(9.1)--做一个仿360工具箱的web页面(Tab按钮切换) http://blog.csdn.net/qq20004604/article/details/52216203 前端的小玩意(9.2)--做一个仿360工具箱的web页面(全部工具里面的模板) http://blog.csdn.net/qq20004604/article/details/52226223 前端的小玩意(9.3)--做一个仿360工具箱的web页面(我的工具里的模板和样式) http://blog.c

Android -- 桌面悬浮,仿360

实现原理                                                                               这种桌面悬浮窗的效果很类似与Widget,但是它比Widget要灵活的多.主要是通过WindowManager这个类来实现的,调用这个类的addView方法用于添加一个悬浮窗,updateViewLayout方法用于更新悬浮窗的参数,removeView用于移除悬浮窗.其中悬浮窗的参数有必要详细说明一下. WindowManager

WinForm 仿360界面控件

因为经常要做一些1.2千行的小工具,WinForm自带的TabCtrl又不美观,所以想做成360的样子,在网上找来找去,都只有散乱的代码,没有可以通用的结构,所以自己写了一个简易的通用控件. 控件主要功能 添加按钮和对应的Userctrl页面,或者相应的Action函数:整个控件是透明背景,窗体的背景将被作为整体背景,即支持类似换肤功能:可自定义按钮的遮罩函数. 支持Userctrl页面切换 支持Action(无参数无返回值)委托 主要类型实现 切换按钮派生自RatioButton,因为已经实现

前端的小玩意(9.3)——做一个仿360工具箱的web页面(我的工具里的模板和样式)

前端的小玩意(9.1)--做一个仿360工具箱的web页面(Tab按钮切换) http://blog.csdn.net/qq20004604/article/details/52216203 前端的小玩意(9.2)--做一个仿360工具箱的web页面(全部工具里面的模板) http://blog.csdn.net/qq20004604/article/details/52226223 (三)我的工具页面布局 如图: 首先将其分为二部分: 第一部分是上方整体红色方框区域: 包含若干个独立按钮,按钮

Android静默安装实现方案,仿360手机助手秒装和智能安装功能

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/47803149 之前有很多朋友都问过我,在Android系统中怎样才能实现静默安装呢?所谓的静默安装,就是不用弹出系统的安装界面,在不影响用户任何操作的情况下不知不觉地将程序装好.虽说这种方式看上去不打搅用户,但是却存在着一个问题,因为Android系统会在安装界面当中把程序所声明的权限展示给用户看,用户来评估一下这些权限然后决定是否要安装该程序,但如果使用了静默安装的方式,也就没

仿360在Launcher画面显示内存使用率的浮窗(基础版)

MainActivity如下: package cc.cc; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.app.Activity; import android.content.Context; import android.content.Intent; /**

Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8689140 大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多高手喜欢把自己的经验写在网上,供大家来学习,我也是从中受惠了很多,在此我深表感谢.可是我发现我却从来没有将自己平时的一些心得拿出来与大家分享,共同学习,太没有奉献精神了.