+ d- N: i+ r! j/ p% u一会我们看到为什么我需要这些函数。下一步是得到"SeDebugPrivileges" 调整标记权限(我们可以这么做只有我们以管理员权限运行应用进程) b" A6 u- J7 @' r8 `* z . r0 K E9 V: l% h/ sif (SetPrivileges() == FALSE) 2 n: l# V/ V7 Z1 G5 `1 Jreturn FALSE; * r, J! \! K, b# U$ A5 X 0 K' f; x4 Z0 Z) w p3 i# z9 A' { 2 h6 j I8 I8 k# x' R这里是这个函数: # T3 p( `5 `) o t+ @6 q/ a4 o3 w' n9 H) H" O& w3 G" e' I" p( b- f: _
BOOL SetPrivileges(VOID): X0 P5 s, R0 }* V! \
{$ a7 T6 Q) s% Y8 f9 l/ H% x5 `
HANDLE hProc; : J/ M: N) {! o) q( N, Y% ]LUID luid;7 P% M# _) T* R8 A
TOKEN_PRIVILEGES tp; A8 J/ `7 c* ]) {4 ^- n3 x3 h4 d! n6 vHANDLE hToken;; Q7 n" l( k- G
TOKEN_PRIVILEGES oldtp;0 l L1 D$ S8 D; h s8 i
DWORD dwSize; ; h6 z4 @8 }' z# A# a! b5 b 9 @/ S, H0 `" z! S0 s. I8 dhProc = GetCurrentProcess();: h# \4 h6 \3 W! ~# C6 e
1 d& o# k0 c4 j( f$ I
if (!OpenProcessToken(hProc, TOKEN_QUERY | + _& |' x Z* l. s; U) lTOKEN_ADJUST_PRIVILEGES, &hToken))) F# o9 ]7 O* ~$ c
return FALSE; 0 D0 j& [0 ~1 u5 f* x/ B0 k , }: }- K% _! |. B+ E' U/ \& P# }* F% Cif (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))/ e8 S5 o/ A- P) E1 u _9 H
{8 [& s, q. V0 l7 [3 ]1 U/ c6 t
CloseHandle (hToken); 1 V1 D' f j% |return FALSE;6 y& a* x$ P5 `% x9 M
} ' W4 ]* `( h' d ]7 k4 {/ N7 ^/ q4 X& ?' m0 c8 ^) q3 B, s# H
ZeroMemory (&tp, sizeof (tp)); , b* j" o! F' ~% h ~$ ?6 I3 E. H: C' V- c
tp.PrivilegeCount = 1;/ S+ i$ `6 w. H% b/ B* Y$ s, x
tp.Privileges[0].Luid = luid; 0 \) K Z( C5 I' P+ d: a% Q$ etp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; % Q/ W" K$ |/ p/ y0 ~4 |) \+ ?0 F: m. M9 @% u4 o- K
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), 7 Q# m! [* Q9 [+ U) ?" p&oldtp, &dwSize))4 [# O2 y b# y* _0 M
{' S8 s: x( G5 }4 e8 P
CloseHandle(hToken);1 K5 v5 m* [% }& M
return FALSE; 3 P: V% R& |% H8 _* f}5 O( W* O# g7 x3 F, l
; j5 w# d# ]$ I' ~3 S5 mreturn TRUE; : y2 d' x8 M, a6 c0 i }}: R5 t9 m1 W; ^& {
* B( w3 |5 _1 M3 h
. P+ | K2 [3 ~2 {
然后我必须取得Winlogon的进程ID,所以我们必须浏览所有进程找到Winlogon:; x% f: h3 `. w- ~1 N8 m/ l
; S) F+ N% F8 F+ r8 H( [) U% h// search winlogon 0 A% |! H" J: ?4 C' m' S" o $ `% J# ~" Y, @" F/ g! s/ q# vdwSize2 = 256 * sizeof(DWORD); 6 K* x& Q9 d6 f" Z; b* d: n# X; N6 g: ^" F, d
do 1 g7 \% Z) o' a" A8 Q{ ( J6 c- U. a1 o) `( Eif (lpdwPIDs) , S) L# Q8 ^$ F
{ ; O; G, {. F0 U; R* ZHeapFree(GetProcessHeap(), 0, lpdwPIDs);0 L) `0 g$ d" D4 g4 U7 {' J* v
dwSize2 *= 2;9 w6 R ]+ l) G9 e O
}% v% S ~2 J# ^# c/ E0 h: T8 h$ e8 e* u
: [& j* i, I& M& E2 l/ e/ N, u* J$ b& `
lpdwPIDs = (LPDWORD) HeapAlloc(GetProcessHeap(), 0, dwSize2);3 ~4 b5 f" }: W
' U7 |+ z% R& p& T8 Fif (lpdwPIDs == NULL) . t4 z% m- _+ N1 u2 Kreturn FALSE;4 y% W- z) c( {3 y2 z0 u
8 T" q& E0 n+ F" ~1 a
if (!pEnumProcesses(lpdwPIDs, dwSize2, &dwSize)) - ?8 ^2 [$ Z. C7 m! n5 qreturn FALSE; ! O, M) J) g: u& B% P, u, l9 d# |1 x% x7 e& Q) x+ t
} while (dwSize == dwSize2);. ?- Y5 c% U) I
4 d3 |( e, s* s
dwSize /= sizeof(DWORD);* S. z+ y/ q+ O- s2 h+ {
' X' r, h/ Z7 p" ?$ i0 b! c
for (dwIndex = 0; dwIndex < dwSize; dwIndex++) y4 S: S" O4 B0 i2 ]0 R5 |{ / a- F6 C( \" n1 m: tBuffer[0] = 0;( J8 u$ p2 E" s3 e
- x$ @& X, k) t2 R& JhProcess = OpenProcess(PROCESS_QUERY_INFORMATION | * s; y; Z& Y5 b) d% G
PROCESS_VM_READ, FALSE, lpdwPIDs[dwIndex]);7 b4 v! Y6 ]5 r" @7 k3 f
i) e: A9 w) f
if (hProcess != NULL) 5 q6 E' r4 @0 T! V& d
{& x! f* T0 u* K$ R7 B- D
if (pEnumProcessModules(hProcess, &hMod,& I8 r) n# i8 e# R2 e1 A$ g, r
sizeof(hMod), &dwSize2)) % U# f( l' t1 x, c7 S* @{- t% n, [& @( q3 X8 `4 Z# j/ C
if (!pGetModuleFileNameExW(hProcess, hMod, & o# n& E5 J, b! SBuffer, sizeof(Buffer)))9 z0 Y) U& G% R
{ , u, L" L9 [; ^2 s- W5 cCloseHandle(hProcess); / I: X5 T6 a r. jcontinue; 8 {$ b. m. `. v: I# o} : D5 D. {8 z- e8 s: a: _} 1 l5 l h2 }- @% melse - J) j' F; a$ D, F: V{8 j' {% k$ h# C
CloseHandle(hProcess);. L4 G) {) b3 }8 v1 K2 H
continue; 4 t$ J9 t- j" c' ]) `}0 Z& l& ^9 P4 \0 n
- z( N4 B1 r6 y
if (Buffer[0] != 0) / ?- a( { X: m& L{ : T! s' P5 i" P2 RGetFileName(Buffer); 0 |7 h1 v& m- {7 n 8 J: `' C6 D( L: m) kif (CompareStringW(0, NORM_IGNORECASE, 5 B0 u$ C# q* z9 N/ U, X& r9 s+ ZBuffer, -1, WinLogon, -1) == CSTR_EQUAL) g5 U% l: z; _; B* T3 g; L
{ / t/ Y+ K5 S4 V3 F// winlogon process found 4 r$ W) _$ G* M, WWinLogonId = lpdwPIDs[dwIndex]; ' S/ i; W! \4 j1 _3 ~0 SCloseHandle(hProcess);; u+ }2 l2 d3 G4 N6 k
break;( P9 y* r, _) y( U
}9 Q* z3 d+ Q1 Z% A' c
' }3 _9 Z$ G1 C( w/ u1 |9 V! vdwLIndex++;. n' _4 i$ S( Z7 G4 _3 |
} 4 f D& c2 z7 \0 k ! \: D6 \0 Z+ r/ L4 F m# U; C( ACloseHandle(hProcess); ! s* X" E, ^& G} - J; I8 Y% | q' W6 {5 E6 t % }6 e# M2 M* v8 e0 |7 p# F# J} : d1 H) y5 S4 m4 D2 |/ d, Y. S, S' x1 u7 _+ d! H
if (lpdwPIDs)8 }! O$ U R5 t
HeapFree(GetProcessHeap(), 0, lpdwPIDs);6 G/ Q3 B/ x) M5 a+ |7 \: \
- ?- H X3 p, F, D! C$ j& W( G0 |+ D; f6 x9 i: N% O
' x/ ?( D8 u c- K1 x& E" I现在我们有了进程ID,我们能够打开这个进程:# R2 @$ y6 x; b# c) a
' u8 |$ W; h) f6 U2 A" a- R z
hWinLogon = OpenProcess(PROCESS_DUP_HANDLE, 0, WinLogonId);2 O, [4 o. N. P$ o! ^9 F! B ^& K
% D. B3 \: J. h6 jif (hWinLogon == NULL) 1 o$ R! G% ]' s) y1 M) h{ ; }: e5 ~! O3 P% N" creturn FALSE; . q, y6 b/ Z9 ]" V3 A$ g. A}: p: Q7 g1 J( K& F) I$ D2 ]" P
F( g0 l) j# a; r; x8 I" E
为什么我用PROCESS_DUP_HANDLE?那是什么呢?我们需要这个标记使用函数复制句柄(ZwDuplicateObject如果它听起来你很熟悉),我们会一会看到我们需要这个函数做什么。现在:# ]# {+ v7 D! w) s( @6 d2 ^
7 t; L5 X1 I; a& V, V$ b' J; y. A
5 @6 H% L; d" ^9 I
nt = pNtQuerySystemInformation(SystemHandleInformation, NULL, 0, &uSize); & ?% V) G0 T, t+ d$ u/ ]1 m* p3 I6 W! d* Q& i0 j. Q
while (nt == STATUS_INFO_LENGTH_MISMATCH) 2 [* Y) a! `$ L4 X# E{ $ q. J& a9 [& O, s) quSize += 0x1000;: F0 c: p+ t3 w( ~) E5 K+ q/ i
[8 u/ j! \) V( W/ w0 ~if (pSystemHandleInfo) 6 R" p/ T2 B# V# mVirtualFree(pSystemHandleInfo, 0, MEM_RELEASE); % D+ g( x& r! L( R ( Z5 H ]' u! t: M7 i0 hpSystemHandleInfo = (PSYSTEMHANDLEINFO) VirtualAlloc(NULL, uSize, 3 W H, c3 Z) L X6 k* b wMEM_COMMIT, PAGE_READWRITE);8 p h4 L2 `- O4 N# j# I0 Y' \. B
! Z5 A1 x' v& P3 h: P
if (pSystemHandleInfo == NULL)6 S/ y% g( v3 |5 d U3 x2 i5 y
{ o' h% a( R+ r4 h% qCloseHandle(hWinLogon);" f* g0 ?5 w: D9 h1 Y1 B/ o& T
return FALSE;" U5 W( G2 s" \# Q G- r; z/ @7 U( ]
}$ g* @( P) n+ q6 G. Y% G s
7 x y/ E+ {, ~! A/ Z
nt = pNtQuerySystemInformation(SystemHandleInformation,* o- |% l l1 j0 W
pSystemHandleInfo, uSize, &uBuff);0 }: P6 V2 s5 N: w: v
}: F4 L: k+ U) f
; t( U$ w5 q' o% E
if (nt != STATUS_SUCCESS)1 s" b1 p6 U8 m: {4 j- I
{ 8 ], a. \2 q( [$ H; z7 r% {6 YVirtualFree(pSystemHandleInfo, 0, MEM_RELEASE); ) E4 x# O6 s1 _" }: I: |& V, tCloseHandle(hWinLogon);( y! L Z0 ]$ l7 X6 g6 ^
return FALSE; % D5 k3 l( h5 `* D% D! m; C$ o} j/ p+ z) g( C/ I- @$ u6 E
- }( z( P8 m7 V) R8 H$ w7 d" P5 g这段代码重新获得所有的系统范围打开句柄,包括那些Winlogon进程。让我们看看下面的步骤: ; `0 R9 l7 T4 Y3 q7 M& Z/ y $ K: P; d' m, W( J d1)浏览所有打开的句柄检查那些属于Winlogon的 3 D% i; R9 j* T. V1 u! |7 S/ j# y& u. C1 ^% e; G7 c
2)复制每一个Winlogon句柄到我们的进程用DuplicateHandle,一会它会给我们权限去请求句柄/目标 名字用NtQueryObject。# x8 O4 M8 }) H( g" B. W$ K* `! e" E
5 E: t- Q9 {4 I( N
3)如果这个目标名称是那些我们想要阻止监视目录中的一个,我们需要再次呼叫DuplicateHandle用DUPLICATE_CLOSE_SOURCE标记然后呼叫CloseHandle关闭damn句柄。9 a* l2 d8 A Z9 r