📄 w2k_spy.c
字号:
break; } } pdNext++; } } return // number of arguments ok (j == dParameters) && // no handles involved (((phObject == NULL) && (hObject == NULL)) || // new handle, successfully registered ((phObject != NULL) && SpyHandleRegister (psp, PsGetCurrentProcessId (), *phObject, OBJECT_NAME (poa))) || // registered handle SpyHandleSlot (psp, PsGetCurrentProcessId (), hObject) || // filter disabled (!gfSpyHookFilter)); }// -----------------------------------------------------------------DWORD SpyWriteType (PSPY_PROTOCOL psp, BYTE bEscape, BYTE bType, PVOID pData) { HANDLE hProcess = PsGetCurrentProcessId (); DWORD n = 0; switch (bType) { case 'b': { n = SpyWriteBoolean (psp, bType, *(BOOLEAN *) pData); break; } case 'a': { n = SpyWriteAnsi (psp, bType, *(PBYTE *) pData); break; } case 'w': { n = SpyWriteWide (psp, bType, *(PWORD *) pData, MAXDWORD); break; } case 'u': { n = SpyWriteUnicode (psp, bType, *(PUNICODE_STRING *) pData); break; } case 'n': { n = SpyWriteNumber (psp, bType, *(DWORD *) pData); break; } case 'l': { n = SpyWriteLarge (psp, bType, *(PLARGE_INTEGER *) pData); break; } case 's': { n = SpyWriteStatus (psp, bType, *(NTSTATUS *) pData); break; } case 'i': { n = SpyWriteIoStatus (psp, bType, *(PIO_STATUS_BLOCK *) pData); break; } case 'c': { n = SpyWriteClientId (psp, bType, *(PCLIENT_ID *) pData); break; } case 'd': { n = SpyWriteDword (psp, bType, *(PDWORD *) pData); break; } case 'p': { n = SpyWritePointer (psp, bType, *(PVOID *) pData); break; } case 'o': { n = SpyWriteObject (psp, bType, *(POBJECT_ATTRIBUTES *) pData); break; } case '+': { n = SpyWriteNewHandle (psp, bType, hProcess, *(PHANDLE *) pData); break; } case '!': { n = SpyWriteOpenHandle (psp, bType, hProcess, *(HANDLE *) pData); break; } case '-': { n = SpyWriteClosedHandle (psp, bType, hProcess, *(HANDLE *) pData); break; } default: { n = (bEscape == bType ? SpyWriteChar (psp, 0, bType) : SpyWriteChar (psp, bEscape, bType)); break; } } return n; }// -----------------------------------------------------------------DWORD SpyWriteFormat (PSPY_PROTOCOL psp, PBYTE pbFormat, PVOID pParameters) { PBYTE pbData; PDWORD pdData; DWORD i; DWORD n = 0; pbData = pbFormat; pdData = pParameters; while (*pbData) { for (i = 0; pbData [i] && (pbData [i] != '%'); i++); n += SpyWriteData (psp, pbData, i); pbData += i; if (*pbData) { n += SpyWriteType (psp, *pbData, *(pbData+1), pdData++); if (*++pbData) ++pbData; } } return n; }// =================================================================// SERVICE DESCRIPTOR TABLE HOOKS// =================================================================NTSTATUS SpyHookWait (void) { return MUTEX_WAIT (gpDeviceContext->kmProtocol); }// -----------------------------------------------------------------LONG SpyHookRelease (void) { return MUTEX_RELEASE (gpDeviceContext->kmProtocol); }// -----------------------------------------------------------------void SpyHookReset (void) { SpyHookWait (); SpyWriteReset (&gpDeviceContext->SpyProtocol); SpyHookRelease (); return; }// -----------------------------------------------------------------DWORD SpyHookRead (PBYTE pbData, DWORD dData, BOOL fLine) { DWORD n = 0; SpyHookWait (); n = (fLine ? SpyReadLine : SpyReadData) (&gpDeviceContext->SpyProtocol, pbData, dData); SpyHookRelease (); return n; }// -----------------------------------------------------------------DWORD SpyHookWrite (PBYTE pbData, DWORD dData) { DWORD n = 0; SpyHookWait (); n = SpyWriteData (&gpDeviceContext->SpyProtocol, pbData, dData); SpyHookRelease (); return n; }// -----------------------------------------------------------------// <#>:<status>=<function>(<arguments>)<time>,<thread>,<handles>void SpyHookProtocol (PSPY_CALL psc) { LARGE_INTEGER liTime; PSPY_PROTOCOL psp = &gpDeviceContext->SpyProtocol; KeQuerySystemTime (&liTime); SpyHookWait (); if (SpyWriteFilter (psp, psc->pshe->pbFormat, psc->adParameters, psc->dParameters)) { SpyWriteNumber (psp, 0, ++(psp->sh.dCalls)); // <#>: SpyWriteChar (psp, 0, ':'); // <status>= SpyWriteFormat (psp, psc->pshe->pbFormat, // <function> psc->adParameters); // (<arguments>) SpyWriteLarge (psp, 0, &liTime); // <time>, SpyWriteChar (psp, 0, ','); SpyWriteNumber (psp, 0, (DWORD) psc->hThread); // <thread>, SpyWriteChar (psp, 0, ','); SpyWriteNumber (psp, 0, psp->sh.dHandles); // <handles> SpyWriteChar (psp, 0, '\n'); } SpyHookRelease (); return; }// -----------------------------------------------------------------BOOL SpyHookPause (BOOL fPause) { BOOL fPause1 = (BOOL) InterlockedExchange ((PLONG) &gfSpyHookPause, ( LONG) fPause); if (!fPause) SpyHookReset (); return fPause1; }// -----------------------------------------------------------------BOOL SpyHookFilter (BOOL fFilter) { return (BOOL) InterlockedExchange ((PLONG) &gfSpyHookFilter, ( LONG) fFilter); }// -----------------------------------------------------------------// The SpyHook macro defines a hook entry point in inline assembly// language. The common entry point SpyHook2 is entered by a call// instruction, allowing the hook to be identified by its return// address on the stack. The call is executed through a register to// remove any degrees of freedom from the encoding of the call.#define SpyHook \ __asm push eax \ __asm mov eax, offset SpyHook2 \ __asm call eax// -----------------------------------------------------------------// The SpyHookInitializeEx() function initializes the aSpyHooks[]// array with the hook entry points and format strings. It also// hosts the hook entry points and the hook dispatcher.void SpyHookInitializeEx (PPBYTE ppbSymbols, PPBYTE ppbFormats) { DWORD dHooks1, dHooks2, i, j, n; __asm { jmp SpyHook9 ALIGN 8SpyHook1: ; start of hook entry point section }// the number of entry points defined in this section// must be equal to SDT_SYMBOLS_MAX (i.e. 0xF8)SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //08SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //10SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //18SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //20SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //28SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //30SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //38SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //40SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //48SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //50SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //58SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //60SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //68SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //70SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //78SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //80SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //88SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //90SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //98SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //A0SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //A8SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //B0SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //B8SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //C0SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //C8SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //D0SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //D8SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //E0SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //E8SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //F0SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook SpyHook //F8 __asm {SpyHook2: ; end of hook entry point section pop eax ; get stub return address pushfd push ebx push ecx push edx push ebp push esi push edi sub eax, offset SpyHook1 ; compute entry point index mov ecx, SDT_SYMBOLS_MAX mul ecx mov ecx, offset SpyHook2 sub ecx, offset SpyHook1 div ecx dec eax mov ecx, gfSpyHookPause ; test pause flag add ecx, -1 sbb ecx, ecx not ecx lea edx, [aSpyHooks + eax * SIZE SPY_HOOK_ENTRY] test ecx, [edx.pbFormat] ; format string == NULL? jz SpyHook5 push eax push edx call PsGetCurrentThreadId ; get thread id mov ebx, eax pop edx pop eax cmp ebx, ghSpyHookThread ; ignore hook installer jz SpyHook5 mov edi, gpDeviceContext lea edi, [edi.SpyCalls] ; get call context array mov esi, SPY_CALLS ; get number of entriesSpyHook3: mov ecx, 1 ; set in-use flag xchg ecx, [edi.fInUse] jecxz SpyHook4 ; unused entry found add edi, SIZE SPY_CALL ; try next entry dec esi jnz SpyHook3 mov edi, gpDeviceContext inc [edi.dMisses] ; count misses jmp SpyHook5 ; array overflowSpyHook4: mov esi, gpDeviceContext inc [esi.dLevel] ; set nesting level mov [edi.hThread], ebx ; save thread id mov [edi.pshe], edx ; save PSPY_HOOK_ENTRY mov ecx, offset SpyHook6 ; set new return address xchg ecx, [esp+20h] mov [edi.pCaller], ecx ; save old return address mov ecx, KeServiceDescriptorTable mov ecx, [ecx].ntoskrnl.ArgumentTable movzx ecx, byte ptr [ecx+eax] ; get argument stack size shr ecx, 2 inc ecx ; add 1 for result slot mov [edi.dParameters], ecx ; save number of parameters lea edi, [edi.adParameters] xor eax, eax ; initialize result slot stosd dec ecx jz SpyHook5 ; no arguments lea esi, [esp+24h] ; save argument stack rep movsdSpyHook5: mov eax, [edx.Handler] ; get original handler pop edi pop esi pop ebp pop edx pop ecx pop ebx popfd xchg eax, [esp] ; restore eax and... ret ; ...jump to handlerSpyHook6: push eax pushfd push ebx push ecx push edx push ebp push esi push edi push eax call PsGetCurrentThreadId ; get thread id mov ebx, eax pop eax mov edi, gpDeviceContext lea edi, [edi.SpyCalls] ; get call context array mov esi, SPY_CALLS ; get number of entriesSpyHook7: cmp ebx, [edi.hThread] ; find matching thread id jz SpyHook8 add edi, SIZE SPY_CALL ; try next entry dec esi jnz SpyHook7 push ebx ; entry not found ?!? call KeBugCheckSpyHook8: push edi ; save SPY_CALL pointer mov [edi.adParameters], eax ; store NTSTATUS push edi call SpyHookProtocol pop edi ; restore SPY_CALL pointer mov eax, [edi.pCaller] mov [edi.hThread], 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -