- Attempt to initiate hook set from kernel space.

svn path=/trunk/; revision=34807
This commit is contained in:
James Tabor 2008-07-26 12:27:40 +00:00
parent 138fbd967b
commit e153b69952
4 changed files with 114 additions and 64 deletions

View file

@ -49,7 +49,8 @@ LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM l
LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, LONG, LONG); LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, LONG, LONG);
VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread); VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread);
PHOOK FASTCALL IntGetHookObject(HHOOK); PHOOK FASTCALL IntGetHookObject(HHOOK);
LRESULT FASTCALL UserCallNextHookEx( int HookId, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi); PHOOK FASTCALL IntGetNextHook(PHOOK Hook);
LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi);
#endif /* _WIN32K_HOOK_H */ #endif /* _WIN32K_HOOK_H */

View file

@ -19,14 +19,14 @@ IntDefWinHandleSysCommand( PWINDOW_OBJECT Window, WPARAM wParam, LPARAM lParam ,
if (!ISITHOOKED(WH_CBT)) return 0; if (!ISITHOOKED(WH_CBT)) return 0;
if (!UserCallNextHookEx(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam, Ansi)) // if (!UserCallNextHookEx(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam, Ansi))
return 0; return 0;
switch (wParam & 0xfff0) switch (wParam & 0xfff0)
{ {
case SC_MOVE: case SC_MOVE:
case SC_SIZE: case SC_SIZE:
return UserCallNextHookEx(WH_CBT, HCBT_MOVESIZE, (WPARAM)Window->hSelf, lParam, Ansi); // return UserCallNextHookEx(WH_CBT, HCBT_MOVESIZE, (WPARAM)Window->hSelf, lParam, Ansi);
break; break;
} }
return 1; return 1;

View file

@ -161,7 +161,8 @@ IntGetFirstValidHook(PHOOKTABLE Table, int HookId)
} }
/* find the next hook in the chain, skipping the deleted ones */ /* find the next hook in the chain, skipping the deleted ones */
static PHOOK FASTCALL PHOOK
FASTCALL
IntGetNextHook(PHOOK Hook) IntGetNextHook(PHOOK Hook)
{ {
PHOOKTABLE Table = IntGetTable(Hook); PHOOKTABLE Table = IntGetTable(Hook);
@ -279,11 +280,16 @@ IntCallLowLevelHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam, PHOOK Ho
return NT_SUCCESS(Status) ? uResult : 0; return NT_SUCCESS(Status) ? uResult : 0;
} }
LRESULT FASTCALL /*
Called from inside kernel space.
*/
LRESULT
FASTCALL
co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
{ {
PHOOK Hook; PHOOK Hook, SaveHook;
PW32THREAD Win32Thread; PW32THREAD Win32Thread;
PW32CLIENTINFO ClientInfo;
PHOOKTABLE Table; PHOOKTABLE Table;
LRESULT Result; LRESULT Result;
PWINSTATION_OBJECT WinStaObj; PWINSTATION_OBJECT WinStaObj;
@ -330,9 +336,15 @@ co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
GlobalHooks->Counts[HOOKID_TO_INDEX(HookId)]++; GlobalHooks->Counts[HOOKID_TO_INDEX(HookId)]++;
} }
ClientInfo = GetWin32ClientInfo();
SaveHook = ClientInfo->phkCurrent;
ClientInfo->phkCurrent = Hook; // Load the call.
Result = co_IntCallHookProc(HookId, Code, wParam, lParam, Hook->Proc, Result = co_IntCallHookProc(HookId, Code, wParam, lParam, Hook->Proc,
Hook->Ansi, &Hook->ModuleName); Hook->Ansi, &Hook->ModuleName);
ClientInfo->phkCurrent = SaveHook;
Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
KernelMode, KernelMode,
0, 0,
@ -397,9 +409,19 @@ HOOK_DestroyThreadHooks(PETHREAD Thread)
} }
} }
static LRESULT
FASTCALL
co_HOOK_CallHookNext(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam)
{
return co_IntCallHookProc(Hook->HookId, Code, wParam, lParam, Hook->Proc,
Hook->Ansi, &Hook->ModuleName);
}
LRESULT LRESULT
FASTCALL FASTCALL
IntCallDebugHook( IntCallDebugHook(
PHOOK Hook,
int Code, int Code,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
@ -514,15 +536,18 @@ IntCallDebugHook(
} }
if (HooklParam) Debug.lParam = (LPARAM)HooklParam; if (HooklParam) Debug.lParam = (LPARAM)HooklParam;
lResult = co_HOOK_CallHooks(WH_DEBUG, Code, wParam, (LPARAM)&Debug); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Debug);
if (HooklParam) ExFreePool(HooklParam); if (HooklParam) ExFreePool(HooklParam);
return lResult; return lResult;
} }
/*
Called from user space via CallNextHook.
*/
LRESULT LRESULT
FASTCALL FASTCALL
UserCallNextHookEx( UserCallNextHookEx(
int HookId, PHOOK Hook,
int Code, int Code,
WPARAM wParam, WPARAM wParam,
LPARAM lParam, LPARAM lParam,
@ -532,7 +557,8 @@ UserCallNextHookEx(
BOOL BadChk = FALSE; BOOL BadChk = FALSE;
// Handle this one first. // Handle this one first.
if ((HookId == WH_MOUSE) || (HookId == WH_CBT && Code == HCBT_CLICKSKIPPED)) if ((Hook->HookId == WH_MOUSE) ||
(Hook->HookId == WH_CBT && Code == HCBT_CLICKSKIPPED))
{ {
MOUSEHOOKSTRUCTEX Mouse; MOUSEHOOKSTRUCTEX Mouse;
if (lParam) if (lParam)
@ -558,12 +584,12 @@ UserCallNextHookEx(
} }
if (!BadChk) if (!BadChk)
{ {
lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Mouse); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Mouse);
} }
return lResult; return lResult;
} }
switch(HookId) switch(Hook->HookId)
{ {
case WH_MOUSE_LL: case WH_MOUSE_LL:
{ {
@ -591,7 +617,7 @@ UserCallNextHookEx(
} }
if (!BadChk) if (!BadChk)
{ {
lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Mouse); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Mouse);
} }
break; break;
} }
@ -622,7 +648,7 @@ UserCallNextHookEx(
} }
if (!BadChk) if (!BadChk)
{ {
lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Keyboard); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Keyboard);
} }
break; break;
} }
@ -655,8 +681,8 @@ UserCallNextHookEx(
} }
if (!BadChk) if (!BadChk)
{ {
lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&Msg); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Msg);
if (lParam && (HookId == WH_GETMESSAGE)) if (lParam && (Hook->HookId == WH_GETMESSAGE))
{ {
_SEH_TRY _SEH_TRY
{ {
@ -685,7 +711,7 @@ UserCallNextHookEx(
switch (Code) switch (Code)
{ {
case HCBT_CREATEWND: // Use Ansi. case HCBT_CREATEWND: // Use Ansi.
lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam);
break; break;
case HCBT_MOVESIZE: case HCBT_MOVESIZE:
@ -715,7 +741,7 @@ UserCallNextHookEx(
} }
if (!BadChk) if (!BadChk)
{ {
lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&rt); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&rt);
} }
break; break;
} }
@ -747,7 +773,7 @@ UserCallNextHookEx(
} }
if (!BadChk) if (!BadChk)
{ {
lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)&CbAs); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&CbAs);
} }
break; break;
} }
@ -755,7 +781,7 @@ UserCallNextHookEx(
The rest just use default. The rest just use default.
*/ */
default: default:
lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam);
break; break;
} }
break; break;
@ -787,7 +813,7 @@ UserCallNextHookEx(
} }
if (!BadChk) if (!BadChk)
{ {
lResult = co_HOOK_CallHooks(HookId, Code, wParam, (LPARAM)(lParam ? &EventMsg : NULL)); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)(lParam ? &EventMsg : NULL));
if (lParam) if (lParam)
{ {
_SEH_TRY _SEH_TRY
@ -814,7 +840,7 @@ UserCallNextHookEx(
} }
case WH_DEBUG: case WH_DEBUG:
lResult = IntCallDebugHook( Code, wParam, lParam); lResult = IntCallDebugHook(Hook, Code, wParam, lParam);
break; break;
/* /*
Default the rest like, WH_FOREGROUNDIDLE, WH_KEYBOARD and WH_SHELL. Default the rest like, WH_FOREGROUNDIDLE, WH_KEYBOARD and WH_SHELL.
@ -822,11 +848,11 @@ UserCallNextHookEx(
case WH_FOREGROUNDIDLE: case WH_FOREGROUNDIDLE:
case WH_KEYBOARD: case WH_KEYBOARD:
case WH_SHELL: case WH_SHELL:
lResult = co_HOOK_CallHooks(HookId, Code, wParam, lParam); lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam);
break; break;
default: default:
DPRINT1("Unsupported HOOK Id -> %d\n",HookId); DPRINT1("Unsupported HOOK Id -> %d\n",Hook->HookId);
break; break;
} }
return lResult; return lResult;
@ -844,8 +870,6 @@ NtUserCallNextHookEx(
PW32CLIENTINFO ClientInfo; PW32CLIENTINFO ClientInfo;
PWINSTATION_OBJECT WinStaObj; PWINSTATION_OBJECT WinStaObj;
NTSTATUS Status; NTSTATUS Status;
LRESULT lResult;
INT HookId;
DECLARE_RETURN(LRESULT); DECLARE_RETURN(LRESULT);
DPRINT("Enter NtUserCallNextHookEx\n"); DPRINT("Enter NtUserCallNextHookEx\n");
@ -855,7 +879,6 @@ NtUserCallNextHookEx(
KernelMode, KernelMode,
0, 0,
&WinStaObj); &WinStaObj);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
SetLastNtError(Status); SetLastNtError(Status);
@ -866,9 +889,14 @@ NtUserCallNextHookEx(
ClientInfo = GetWin32ClientInfo(); ClientInfo = GetWin32ClientInfo();
HookObj = ClientInfo->phkCurrent; // Use this one set from SetWindowHook. if (!ClientInfo) RETURN( 0);
HookObj = ClientInfo->phkCurrent;
if (!HookObj) RETURN( 0);
UserReferenceObject(HookObj);
HookId = HookObj->HookId;
Ansi = HookObj->Ansi; Ansi = HookObj->Ansi;
if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread())) if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread()))
@ -880,19 +908,11 @@ NtUserCallNextHookEx(
} }
NextObj = IntGetNextHook(HookObj); NextObj = IntGetNextHook(HookObj);
ClientInfo->phkCurrent = NextObj; // Preset next hook from list.
UserCallNextHookEx( HookObj, Code, wParam, lParam, Ansi);
UserDereferenceObject(HookObj); UserDereferenceObject(HookObj);
if (NULL != NextObj)
{
lResult = UserCallNextHookEx( HookId, Code, wParam, lParam, Ansi);
ClientInfo->phkCurrent = NextObj; RETURN( (LRESULT)NextObj);
if (lResult == 0) RETURN( 0);
RETURN( (LRESULT)NextObj);
}
ClientInfo->phkCurrent = NextObj;
RETURN( 0);
CLEANUP: CLEANUP:
DPRINT("Leave NtUserCallNextHookEx, ret=%i\n",_ret_); DPRINT("Leave NtUserCallNextHookEx, ret=%i\n",_ret_);
@ -1109,8 +1129,8 @@ NtUserSetWindowsHookEx(
Hook->Ansi = Ansi; Hook->Ansi = Ansi;
Handle = Hook->Self; Handle = Hook->Self;
// Set the client threads next hook based on the hooks type. // Clear the client threads next hook.
ClientInfo->phkCurrent = IntGetNextHook( Hook); ClientInfo->phkCurrent = 0;
UserDereferenceObject(Hook); UserDereferenceObject(Hook);
ObDereferenceObject(WinStaObj); ObDereferenceObject(WinStaObj);

View file

@ -2087,33 +2087,62 @@ NtUserMessageCall(
break; break;
case FNID_SENDMESSAGECALLBACK: case FNID_SENDMESSAGECALLBACK:
break; break;
// CallNextHook bypass.
case FNID_CALLWNDPROC: case FNID_CALLWNDPROC:
{
CWPSTRUCT CWP;
PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
CWP.hwnd = hWnd;
CWP.message = Msg;
CWP.wParam = wParam;
CWP.lParam = lParam;
lResult = co_HOOK_CallHooks( WH_CALLWNDPROC,
HC_ACTION,
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
(LPARAM)&CWP );
}
break;
case FNID_CALLWNDPROCRET: case FNID_CALLWNDPROCRET:
{ {
CWPRETSTRUCT CWPR;
PW32CLIENTINFO ClientInfo = GetWin32ClientInfo(); PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
CWPR.hwnd = hWnd; PHOOK NextObj, Hook = ClientInfo->phkCurrent;
CWPR.message = Msg;
CWPR.wParam = wParam; if (!ClientInfo || !Hook) break;
CWPR.lParam = lParam;
CWPR.lResult = ClientInfo->dwHookData; UserReferenceObject(Hook);
lResult = co_HOOK_CallHooks( WH_CALLWNDPROCRET,
HC_ACTION, if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0), {
(LPARAM)&CWPR ); UserDereferenceObject(Hook);
break;
}
NextObj = IntGetNextHook(Hook);
ClientInfo->phkCurrent = NextObj;
if ( Hook->HookId == WH_CALLWNDPROC)
{
CWPSTRUCT CWP;
CWP.hwnd = hWnd;
CWP.message = Msg;
CWP.wParam = wParam;
CWP.lParam = lParam;
DPRINT1("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
lResult = co_IntCallHookProc( Hook->HookId,
HC_ACTION,
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
(LPARAM)&CWP,
Hook->Proc,
Hook->Ansi,
&Hook->ModuleName);
}
else
{
CWPRETSTRUCT CWPR;
CWPR.hwnd = hWnd;
CWPR.message = Msg;
CWPR.wParam = wParam;
CWPR.lParam = lParam;
CWPR.lResult = ClientInfo->dwHookData;
lResult = co_IntCallHookProc( Hook->HookId,
HC_ACTION,
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
(LPARAM)&CWPR,
Hook->Proc,
Hook->Ansi,
&Hook->ModuleName);
}
UserDereferenceObject(Hook);
lResult = (LRESULT) NextObj;
} }
break; break;
} }