其他
高版本64位Win10(RS2或更高)下枚举消息钩子的一种思路
本文为看雪论坛优秀文章
看雪论坛作者ID:hhkqqs
首先是参考文章:
typedef struct tagHOOK
{
PVOID Handle;
PVOID cLockObj;
PW32THREAD Win32Thread;
ULONGLONG Patch1;
tagHOOK* pSelf; //指向结构体的首地址
tagHOOK* pNext; //指向下一个结构体
ULONG hType; //钩子的类型
ULONG Patch2;
PVOID offPfn; //ihmod为-1时,表示钩子函数绝对地址,否则为函数相对所在模块的偏移
ULONG flags; //取值1或3为全局钩子
int ihmod; //钩子所在模块的索引
PTHREADINFO ptiHooked; //被hook线程的THREADINFO
} HOOK, *PHOOK;
typedef struct _HANDLEENTRY
{
PVOID phead;
PVOID pOwner;
UCHAR bType;
UCHAR bFlags;
USHORT wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
typedef struct _HANDLEENTRY_RS2
{
PVOID Unknown1;
PVOID UniqueThreadId;
PVOID Unknown2;
UCHAR bType;
UCHAR bFlags;
USHORT wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
enum HANDLE_TYPE {
TYPE_FREE = 0,
TYPE_WINDOW = 1,
TYPE_MENU = 2,
TYPE_CURSOR = 3,
TYPE_SETWINDOWPOS = 4,
TYPE_HOOK = 5,
TYPE_CLIPDATA = 6,
TYPE_CALLPROC = 7,
TYPE_ACCELTABLE = 8,
TYPE_DDEACCESS = 9,
TYPE_DDECONV = 10,
TYPE_DDEXACT = 11,
TYPE_MONITOR = 12,
TYPE_KBDLAYOUT = 13,
TYPE_KBDFILE = 14,
TYPE_WINEVENTHOOK = 15,
TYPE_TIMER = 16,
TYPE_INPUTCONTEXT = 17,
TYPE_HIDDATA = 18,
TYPE_DEVICEINFO = 19,
TYPE_TOUCHINPUT = 20,
TYPE_GESTUREINFO = 21,
TYPE_CTYPES = 22,
TYPE_GENERIC = 255
};
PVOID HMValidateHandle(HANDLE Handle, HANDLE_TYPE hType)
{
PVOID Object = 0;
if ((USHORT)Handle < gSharedInfo->psi->cHandleEntries)
{
PHANDLEENTRY hEntry = &gSharedInfo->aheList[(USHORT)Handle];
PVOID *pObject = &gpKernelHandleTable[2 * (USHORT)Handle];
USHORT Handle_HIWORD = (USHORT)(Handle >> 0x10);
if ((Handle_HIWORD == hEntry->wUniq || Handle_HIWORD == -1 || !Handle_HIWORD && PsGetCurrentProcessWow64Process())
&& !(hEntry->bFlags & 1)
&& hEntry->bType == hType )
{
Object = *pObject;
}
}
if (W32GetThreadWin32Thread(PsGetCurrentThread())->TIF_flags & 0x20000000)
{
if (!ValidateHandleSecure(Handle, 3)) Object = 0;
}
else
{
if (!ValidateHandleSecure(Handle, 2)) Object = 0;
}
if (!Object)
{
DWORD dwErrorCode;
switch (hType)
{
case TYPE_WINDOW:
dwErrorCode = 1400;
break;
case TYPE_MENU:
dwErrorCode = 1401;
break;
case TYPE_CURSOR:
dwErrorCode = 1402;
break;
case TYPE_SETWINDOWPOS:
dwErrorCode = 1405;
break;
case TYPE_HOOK:
dwErrorCode = 1404;
break;
case TYPE_ACCELTABLE:
dwErrorCode = 1403;
break;
default:
dwErrorCode = 6;
break;
}
UserSetLastError(dwErrorCode);
}
return Object;
}
tagSHAREDINFO* gSharedInfo = 0;
typedef PVOID(*HMValidateHandleFn)(HANDLE Handle, HANDLE_TYPE hType);
HMValidateHandleFn HMValidateHandle = 0;
void GetWinHook_15063orHigher(PKPROCESS GUIProcess, PHOOK OutputBuffer)
{
_KAPC_STATE ApcState;
KeStackAttachProcess(GUIProcess, &ApcState);
if (!gSharedInfo)
gSharedInfo = (tagSHAREDINFO*)GetKernelProcAddress(GetKernelModuleHandle(L"win32kbase.sys"), "gSharedInfo");
if (!HMValidateHandle)
{
ULONGLONG p = GetKernelProcAddress(GetKernelModuleHandle(L"win32kfull.sys"), "NtUserUnhookWindowsHookEx");
//Pattern B2 05 ?? ?? ?? E8 ?? ?? ?? ??
while ((*(PULONGLONG)p & 0xFF000000FFFF) != 0xE800000005B2) p++;
HmValidateHandle = (HMValidateHandleFn)((p & 0xFFFFFFFF00000000) + (DWORD)(p + *(PDWORD)(p + 6) + 10));
}
PHOOK Hook = OutputBuffer;
ULONG HandleEntryCount = (ULONG)gSharedInfo->psi->cHandleEntries;
for (ULONG i = 0; i < HandleEntryCount; i++)
{
if (gSharedInfo->aheList[i].bType == TYPE_HOOK)
{
HANDLE ObjectHandle = (HANDLE)(i | (gSharedInfo->aheList[i].wUniq << 0x10));
PHOOK HookObject = HmValidateHandle(ObjectHandle, TYPE_HOOK);
if (HookObject)
{
memcpy(Hook, HookObject, sizeof(HANDLEENTRY));
Hook++;
}
}
}
KeUnstackDetachProcess(&ApcState);
}
typedef USHORT ATOM;
typedef NTSTATUS(*RtlQueryAtomInAtomTableFn)(PVOID AtomTable, ATOM Atom, PULONG RefCount, PULONG PinCount, PWSTR AtomName, PULONG NameLength);
ATOM* aatomSysLoaded = 0;
PVOID UserAtomTableHandle = 0;
RtlQueryAtomInAtomTableFn RtlQueryAtomInAtomTable = 0;
//使用前先挂靠GUI进程
NTSTATUS QueryModuleImageFileNameFromHookObject(IN PHOOK HookObject, OUT LPWSTR NameBuffer)
{
if (!aatomSysLoaded) aatomSysLoaded = (ATOM*)DBGLocateSymbol(L"win32kfull.sys", "aatomSysLoaded");
if (!UserAtomTableHandle) UserAtomTableHandle = (PVOID)GetKernelProcAddress(GetKernelModuleHandle(L"win32kbase.sys"), "UserAtomTableHandle");
if (!RtlQueryAtomInAtomTable) RtlQueryAtomInAtomTable = (RtlQueryAtomInAtomTableFn)GetKernelProcAddress(GetKernelModuleHandle(L"ntoskrnl.exe"), "RtlQueryAtomInAtomTable");
ULONG MaxLength = sizeof(WCHAR) * MAX_PATH;
return RtlQueryAtomInAtomTable(UserAtomTableHandle, aatomSysLoaded[HookObject->ihmod], 0, 0, NameBuffer, &MaxLength);
}
PVOID GetWinHookFunctionAddress(IN PHOOK HookObject, IN LPWSTR szDllPath)
{
if (HookObject->ihmod == -1) return HookObject->offPfn;
PVOID HookFunctionAddress = 0;
_KAPC_STATE ApcState;
PKPROCESS Process = IoThreadToProcess(HookObject->ptiHooked->Win32Thread.pEThread);
PPEB Peb = (PPEB)PsGetProcessPeb(Process);
KeStackAttachProcess(Process, &ApcState);
PLIST_ENTRY pFirstLoadOrderFlink = &Peb->Ldr->InLoadOrderModuleList;
for (PLIST_ENTRY pListEntry = pFirstLoadOrderFlink->Flink; pListEntry != pFirstLoadOrderFlink; pListEntry = pListEntry->Flink)
{
LPWSTR FullDllNameBuffer = ((PLDR_DATA_TABLE_ENTRY)pListEntry)->FullDllName.Buffer;
if (FullDllNameBuffer && !wcsicmp(FullDllNameBuffer, szDllPath))
{
HookFunctionAddress = (PVOID)((ULONGLONG)((PLDR_DATA_TABLE_ENTRY)pListEntry)->DllBase + (ULONGLONG)HookObject->offPfn);
break;
}
}
KeUnstackDetachProcess(&ApcState);
return HookFunctionAddress;
}
看雪ID:hhkqqs
https://bbs.pediy.com/user-home-805252.htm
*本文由看雪论坛 hhkqqs 原创,转载请注明来自看雪社区。
推荐文章++++
求分享
求点赞
求在看