システムサービス配信を構築することでブロック&フィルタリング(360ゲームの金庫を模倣)を実現

23831 ワード

このプログラムを書きたいのは主にKSSDの投稿を見たからです.http://bbs.pediy.com/showthread.php?t=108378
360金庫でゲームアカウントを保護する原理を話していますが、実際には様々なリクエストをブロックしています.この投稿は約6年前ですが、今の360の金庫を簡単に見てみると、この方法はもう採用されていないはずです.
ここでの主な考え方はHOOK住システムサービスの配布であり,これはもはや新鮮な手法ではない.例えば、多くの外挂け作者はカーネルの重荷重を使ってゲームの保护の重いHOOKを突破して、カーネルの重荷重もKiFastCallEntryをハイジャックしてハイジャックサービスの配布を実现します.この文章はただ練習のために書いただけだ.
基本プロセスは
1.アプリケーション層:
ドライバモジュールのインストールとドライバとの通信を担当し、ユーザーが指定した操作を実行するかどうかを選択します.
2.コア層:
(1)SSDT HOOKを設定してHOOK関数を呼び出し,スタック遡及取得KiFastCallEntry()ベースアドレスを取得する(2)KiFastCallEntry()ベースアドレス暴力検索によりHOOKポイントの位置を見つけてInline Hookを設定する(3)サービス要求が正当であるか否かを判断し,合法であれば放行し,法則に合わないメッセージをユーザ層に伝達し,ユーザが放行するか否かを決定する
実は以上の3歩は360金庫のやり方で、プログラムの中のいくつかの内容はどのように書くべきか分からないので、直接その招待状のアセンブリ分析から逆に書きました.
 
 
実はネット上にはHOOK KiFastCallEntryのコードがたくさんありますが、ebxをハイジャックしてサービスをハイジャックして配布する例は見つからなかったので、私が書いたのは
sub esp, ecx
shr ecx, 2
mov ebx,FuncAddress
結局ずっとブルースクリーンで、まる2日間調整してもどこの問題も見つからなかった.
後でグループで順番をこう変えると聞きました
mov ebx,FuncAddress
sub esp, ecx
shr ecx, 2
 
結果は本当にBSODを触発することはありません.原理が何なのか分かりません.本質的な違いはないと思います(レジスタもスタックも変えていません)が、1つ目はだめです.
もともと1つのデバイスオブジェクトを生成してアプリケーション層と通信すべきだったが、ブルースクリーンではなかなかできなかったので、後で話しましょう.コアのプログラムはこれです.
SSDTインデックスに基づいてどのような関数であるかを知り、カーネルスタックにSSDT関数のパラメータをインデックスし(call ebxではパラメータがスタックに入っているに違いないので)、最後に状況に応じてIRPでユーザ層と通信して放行するかどうかを尋ねるという考え方である.
 
 
  1 #include "ntddk.h"   //  :WDK 7.1 WIN XP SP3     
  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 PVOID AddressOfFuncAddress;
 18 HANDLE HandleTemp = (HANDLE)0x288C58F1;
 19 ULONG NtSetEventAddress, TheHookAddress,KiFastCallEntryAddress;
 20 ULONG YesOrNo=0;
 21 ULONG AddressOffset = 0;
 22 ULONG TempDword,Test;
 23 ULONG ProcessPID = 0;
 24 ULONG pid, DispatchAddress, TempBufferCopy;
 25 PULONG DwordAddress = 0;
 26 INT8 i;
 27 INT8 *PbyteAddress;
 28 KSPIN_LOCK MySpinLock1;
 29 KSPIN_LOCK MySpinLock2;
 30 KSPIN_LOCK MySpinLock3;
 31 KIRQL TempKirql1;
 32 KIRQL TempKirql2;
 33 ULONG DebugAddress = 0,FuncAddress;
 34 //  SSDT HOOK        KiFastCallEntry  
 35 Check()
 36 NTSTATUS HookSSDT(PVOID FuncAdress)
 37 {
 38     ULONG OutTemp = 0;
 39     NtSetEventAddress = (ULONG)KeServiceDescriptorTable.ServiceTableBase[NtSetEventID];
 40     DebugAddress=(ULONG)&KeServiceDescriptorTable.ServiceTableBase[NtSetEventID];
 41     KeInitializeSpinLock(&MySpinLock1);
 42     KeAcquireSpinLock(&MySpinLock1,&TempKirql1);
 43     _asm {    
 44             cli
 45             push eax
 46             mov  eax, cr0
 47             and  eax, not 10000h
 48             mov  cr0, eax
 49             pop eax
 50     }
 51     KeServiceDescriptorTable.ServiceTableBase[NtSetEventID] = (ULONG)FuncAdress;
 52     __asm {
 53             push eax
 54             mov  eax, cr0
 55             or eax, 10000h
 56             mov  cr0, eax
 57             pop eax
 58             sti
 59     }
 60     KeReleaseSpinLock(&MySpinLock1,&TempKirql1);
 61     ZwSetEvent(HandleTemp,
 62         &OutTemp);
 63     return STATUS_SUCCESS;
 64 }
 65 //  SSDT HOOK
 66 void UnhookSSDTHook()
 67 {
 68     KeInitializeSpinLock(&MySpinLock2);
 69     KeAcquireSpinLock(&MySpinLock2,&TempKirql1);
 70     _asm {
 71             cli
 72             push eax
 73             mov  eax, cr0
 74             and  eax, not 10000h
 75             mov  cr0, eax
 76             pop eax
 77     };
 78     KeServiceDescriptorTable.ServiceTableBase[NtSetEventID] = NtSetEventAddress;
 79 
 80     _asm {
 81             push eax
 82             mov  eax, cr0
 83             or eax, 10000h
 84             mov  cr0, eax
 85             pop eax
 86             sti
 87     };
 88     KeReleaseSpinLock(&MySpinLock2,&TempKirql1);
 89     return;
 90 }
 91 ULONG TheDispatchFunc(ULONG arg1, ULONG arg2, ULONG arg3)
 92 {    
 93     if (arg3== (ULONG)KeServiceDescriptorTable.ServiceTableBase)
 94     {
 95         //               
 96     }
 97     return arg2;
 98 
 99 }
100 //    KiFastCallEntry (        )
101 __declspec(naked) void InlineFunc()
102 {
103     
104     
105     _asm {
106             pushad
107             pushfd
108 
109             push edi//     
110             push ebx//    
111             push eax//    
112             call TheDispatchFunc
113             mov FuncAddress,eax
114             
115             popfd
116             popad
117             //        
118             mov ebx, FuncAddress
119             sub esp, ecx
120             shr ecx, 2
121             
122 
123             jmp TempBufferCopy
124             
125     };
126 
127 }
128 //    SSDT   ,      
129 //     Inline HOOK
130 __declspec(naked) void SSDTFunc()
131 {
132     _asm {
133             push eax
134             mov eax, [esp + 8]
135             mov TempDword, eax
136             pop eax
137     }
138 
139     if (TempDword == HandleTemp)
140     {
141         _asm {
142             push eax
143             mov eax, [esp + 4]
144             mov KiFastCallEntryAddress, eax
145             pop eax
146             };
147         UnhookSSDTHook();
148     }
149     else
150     {    
151         //_asm {int 3};
152         _asm {
153             jmp NtSetEventAddress
154         };
155     }
156     for (i = 0; i < 200; i++)
157     {
158         
159         if (*((PULONG)KiFastCallEntryAddress)==0xe9c1e12b)
160         {
161             TheHookAddress = KiFastCallEntryAddress;
162             YesOrNo = 1;
163             break;
164         }
165         KiFastCallEntryAddress--;
166     }
167     if (YesOrNo)
168     {    
169         AddressOffset = (ULONG)InlineFunc - 5 - (ULONG)TheHookAddress;
170         PbyteAddress = (INT8 *)TheHookAddress;
171         *PbyteAddress = 0xe9;
172         DwordAddress = (PULONG)((ULONG)TheHookAddress + 1);
173         *DwordAddress = AddressOffset;
174         TempBufferCopy = (ULONG)PbyteAddress + 5;
175     }
176     //_asm {int 3};
177     _asm{retn 0x8 }
178 }
179 NTSTATUS UnloadFunc(PDRIVER_OBJECT MyDriver, PUNICODE_STRING RegPath)
180 {
181     //      
182     return STATUS_SUCCESS;
183 }
184 NTSTATUS DriverEntry(PDRIVER_OBJECT MyDriver, PUNICODE_STRING RegPath)
185 {
186     NTSTATUS Status = 0;
187     AddressOfFuncAddress=ExAllocatePool(NonPagedPool, 4);
188     MyDriver->DriverUnload = UnloadFunc;
189     Status = HookSSDT((PVOID)SSDTFunc);
190     if (!NT_SUCCESS(Status))
191     {
192         return 1;
193     }
194     return STATUS_SUCCESS;
195 }