第五章 监控Native API调用 翻译:Kendiv( fcczj@263.net ) 更新:Friday, April 29, 2005
声明:转载请注明出处,并保证文章的完整性,本人保留译文的所有权利。
一个简单的Hook协议读取程序 为了帮助你编写自己的API Hook Client程序,我给出了一个简单的示例行的程序,该程序可以读取Hook协议缓冲区中的数据并在控制台窗口中显示。通过按下P、F和R键,可以实现暂停、过滤和重置功能,输出可以按照用户自定义的函数名模板进行过滤。这个示例程序叫做“SBS Windows 2000 API Hook Viewer”,其源代码位于本书光盘的\src\w2k_hook目录下。
控制Spy Device 为了方便,w2k_hook.exe程序使用了一组针对SPY_IO_HOOK_*函数的外包函数,列表5-19给出了这些函数。这些工具函数使得代码的可读性更好,并且在开发Spy Device的客户端程序时,大大降低了参数出错的可能性。
BOOL WINAPI SpyIoControl (HANDLE hDevice, DWORD dCode, PVOID pInput, DWORD dInput, PVOID pOutput, DWORD dOutput) { DWORD dInfo = 0;
return DeviceIoControl (hDevice, dCode, pInput, dInput, pOutput, dOutput, &dInfo, NULL) && (dInfo == dOutput); }
// -----------------------------------------------------------------
BOOL WINAPI SpyVersionInfo (HANDLE hDevice, PSPY_VERSION_INFO psvi) { return SpyIoControl (hDevice, SPY_IO_VERSION_INFO, NULL, 0, psvi, SPY_VERSION_INFO_); }
// -----------------------------------------------------------------
BOOL WINAPI SpyHookInfo (HANDLE hDevice, PSPY_HOOK_INFO pshi) { return SpyIoControl (hDevice, SPY_IO_HOOK_INFO, NULL, 0, pshi, SPY_HOOK_INFO_); }
// -----------------------------------------------------------------
BOOL WINAPI SpyHookInstall (HANDLE hDevice, BOOL fReset, PDWORD pdCount) { return SpyIoControl (hDevice, SPY_IO_HOOK_INSTALL, &fReset, BOOL_, pdCount, DWORD_); }
// -----------------------------------------------------------------
BOOL WINAPI SpyHookRemove (HANDLE hDevice, BOOL fReset, PDWORD pdCount) { return SpyIoControl (hDevice, SPY_IO_HOOK_REMOVE, &fReset, BOOL_, pdCount, DWORD_); }
// -----------------------------------------------------------------
BOOL WINAPI SpyHookPause (HANDLE hDevice, BOOL fPause, PBOOL pfPause) { return SpyIoControl (hDevice, SPY_IO_HOOK_PAUSE, &fPause, BOOL_, pfPause, BOOL_); }
// -----------------------------------------------------------------
BOOL WINAPI SpyHookFilter (HANDLE hDevice, BOOL fFilter, PBOOL pfFilter) { return SpyIoControl (hDevice, SPY_IO_HOOK_FILTER, &fFilter, BOOL_, pfFilter, BOOL_); }
// -----------------------------------------------------------------
BOOL WINAPI SpyHookReset (HANDLE hDevice) { return SpyIoControl (hDevice, SPY_IO_HOOK_RESET, NULL, 0, NULL, 0); }
// -----------------------------------------------------------------
DWORD WINAPI SpyHookRead (HANDLE hDevice, BOOL fLine, PBYTE pbData, DWORD dData) { DWORD dInfo;
if (!DeviceIoControl (hDevice, SPY_IO_HOOK_READ, &fLine, BOOL_, pbData, dData, &dInfo, NULL)) { dInfo = 0; } return dInfo; }
// -----------------------------------------------------------------
BOOL WINAPI SpyHookWrite (HANDLE hDevice, PBYTE pbData) { return SpyIoControl (hDevice, SPY_IO_HOOK_WRITE, pbData, lstrlenA (pbData), NULL, 0); } 列表5-19. Device I/O Control工具函数
在使用列表5-19中的函数之前,Spy 设备驱动程序必须首先被加载并启动。这一操作和在第四章讨论的内存Spy程序w2k_mem.exe的要求大致相同。列表5-20给出了该程序的主函数:Execute(),该函数可加载/卸载Spy 设备驱动程序、打开/关闭一个设备句柄并可通过IOCTL和设备进行交互。如果你对比一下列表5-20和列表4-29,它们在开始和结尾处显然都是相似的。只是在中间部分,有所不同,因为这部分的代码依赖于具体的程序。
void WINAPI Execute (PPWORD ppwFilters, DWORD dFilters) { SPY_VERSION_INFO svi; SPY_HOOK_INFO shi; DWORD dCount, i, j, k, n; BOOL fPause, fFilter, fRepeat; BYTE abData [HOOK_MAX_DATA]; WORD awData [HOOK_MAX_DATA]; WORD awPath [MAX_PATH] = L"?"; SC_HANDLE hControl = NULL; HANDLE hDevice = INVALID_HANDLE_VALUE;
_printf (L"\r\nLoading \"%s\" (%s) ...\r\n", awSpyDisplay, awSpyDevice);
if (w2kFilePath (NULL, awSpyFile, awPath, MAX_PATH)) { _printf (L"Driver: \"%s\"\r\n", awPath);
hControl = w2kServiceLoad (awSpyDevice, awSpyDisplay, awPath, TRUE); } if (hControl != NULL) { _printf (L"Opening \"%s\" ...\r\n", awSpyPath);
hDevice = CreateFile (awSpyPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } else { _printf (L"Unable to load the spy device driver.\r\n"); } if (hDevice != INVALID_HANDLE_VALUE) { if (SpyVersionInfo (hDevice, &svi)) { _printf (L"\r\n" L"%s V%lu.%02lu ready\r\n", svi.awName, svi.dVersion / 100, svi.dVersion % 100); } if (SpyHookInfo (hDevice, &shi)) { _printf (L"\r\n" L"API hook parameters: 0x%08lX\r\n" L"SPY_PROTOCOL structure: 0x%08lX\r\n" L"SPY_PROTOCOL data buffer: 0x%08lX\r\n" L"KeServiceDescriptorTable: 0x%08lX\r\n" L"KiServiceTable: 0x%08lX\r\n" L"KiArgumentTable: 0x%08lX\r\n" L"Service table size: 0x%lX (%lu)\r\n", shi.psc, shi.psp, shi.psp->abData, shi.psdt, shi.sdt.ntoskrnl.ServiceTable, shi.sdt.ntoskrnl.ArgumentTable, shi.ServiceLimit, shi.ServiceLimit); } SpyHookPause (hDevice, TRUE, &fPause ); fPause = FALSE; SpyHookFilter (hDevice, TRUE, &fFilter); fFilter = FALSE;
if (SpyHookInstall (hDevice, TRUE, &dCount)) { _printf (L"\r\n" L"Installed %lu API hooks\r\n", dCount); } _printf (L"\r\n" L"Protocol control keys:\r\n" L"\r\n" L"P - pause ON/off\r\n" L"F - filter ON/off\r\n"
|