システムサービス配信を構築することでブロック&フィルタリング(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でユーザ層と通信して放行するかどうかを尋ねるという考え方である.
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 }