一、项目说明
HOOK NtUserFindWindowEx函数,用dbgview显示所有的参数
二、知识说明
本节内容需要前面的知识:SSDT HOOK模板和ring0与ring3通信。
FindWindow最终调用的是NtUserFindWindowEx函数,NtUserFindWindowEx在win32k.sys中,所以最终调用的是W32pServiceTable(SSDT Shadow)里的函数。
dds W32pServiceTable L000001ad
查看SSDT shadow表里所有函数
kd> dds bf999b80 L000001ad
bf999b80 bf935f7e win32k!NtGdiAbortDoc
bf999b84 bf947b29 win32k!NtGdiAbortPath
bf999b88 bf88ca52 win32k!NtGdiAddFontResourceW
bf999b8c bf93f6f0 win32k!NtGdiAddRemoteFontToDC
bf999b90 bf949140 win32k!NtGdiAddFontMemResourceEx
bf999b94 bf936212 win32k!NtGdiRemoveMergeFont
bf999b98 bf9362b7 win32k!NtGdiAddRemoteMMInstanceToDC
bf999b9c bf83b4cd win32k!NtGdiAlphaBlend
bf999ba0 bf948a67 win32k!NtGdiAngleArc
bf999ba4 bf934a17 win32k!NtGdiAnyLinkedFonts
bf999ba8 bf94905f win32k!NtGdiFontIsLinked
bf999bac bf90f2f4 win32k!NtGdiArcInternal
bf999bb0 bf902318 win32k!NtGdiBeginPath
bf999bb4 bf809fdf win32k!NtGdiBitBlt
bf999bb8 bf948f31 win32k!NtGdiCancelDC
bf999bbc bf94a72d win32k!NtGdiCheckBitmapBits
bf999bc0 bf900c15 win32k!NtGdiCloseFigure
.......
太长了 我这里就不写了
经过计算得知NtUserFindWindowEx的索引为0x117A
kd> u bf999b80+4*17A
win32k!W32pServiceTable+0x5e8:
bf99a168 69138bbf0e54 imul edx,dword ptr [ebx],540EBF8Bh
bf99a16e 91 xchg eax,ecx
bf99a16f bf88868ebf mov edi,offset win32k!NtUserGetAltTabInfo (bf8e8688)
bf99a174 37 aaa
bf99a175 c882bf9e enter 0BF82h,9Eh
bf99a179 4d dec ebp
bf99a17a 91 xchg eax,ecx
bf99a17b bf8e9284bf mov edi,offset win32k!NtUserGetAsyncKeyState (bf84928e)
注意:当使用>0x1000的调用号时,要将第12位清0,相当于调用号 - 0x1000,因为第12位只是说明要查第几张表,函数具体的索引还是由0-11位决定的!
三、代码实现
Ring3
#include "StdAfx.h"
#include <windows.h>
#include <winioctl.h>
#define SYMBOLIOLINK_NAME L"\\\\.\\Mikasys"
#define HOOKNtUserFindWindowEx CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define UNHOOKNtUserFindWindowEx CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS)
HANDLE g_hDevice;
/***************************************************/
//打开驱动服务句柄
//3环链接名:\\\\.\\AABB
/***************************************************/
int main(int argc, char* argv[])
{
DWORD code = 0;
// 获取设备句柄
HANDLE hDevice = CreateFileW(SYMBOLIOLINK_NAME,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
DWORD dwError = GetLastError();
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("获取设备句柄失败 %d.\n", dwError); // 如果返回1,请在驱动中指定 IRP_MJ_CREATE 处理函数
getchar();
return 1;
}
else
{
printf("获取设备句柄成功.\n");
}
printf("--------------------------\n");
printf(