mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 11:21:51 +00:00
[Win32SS] Form Sanity to Hook Callbacks
Fix WH_CALLWNDPROC/RET data to user hook calls. See CORE-13019 and CORE-13907.
This commit is contained in:
parent
d8add40e89
commit
915a5764a9
3 changed files with 69 additions and 36 deletions
|
@ -61,6 +61,7 @@ typedef struct _HOOKPROC_CALLBACK_ARGUMENTS
|
||||||
ULONG_PTR offPfn;
|
ULONG_PTR offPfn;
|
||||||
BOOLEAN Ansi;
|
BOOLEAN Ansi;
|
||||||
LRESULT Result;
|
LRESULT Result;
|
||||||
|
UINT lParamSize;
|
||||||
WCHAR ModuleName[512];
|
WCHAR ModuleName[512];
|
||||||
} HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS;
|
} HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS;
|
||||||
|
|
||||||
|
@ -72,6 +73,20 @@ typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
|
||||||
/* WCHAR szClass[] */
|
/* WCHAR szClass[] */
|
||||||
} HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS, *PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS;
|
} HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS, *PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS;
|
||||||
|
|
||||||
|
typedef struct tagCWP_Struct
|
||||||
|
{
|
||||||
|
HOOKPROC_CALLBACK_ARGUMENTS hpca;
|
||||||
|
CWPSTRUCT cwps;
|
||||||
|
PBYTE Extra[4];
|
||||||
|
} CWP_Struct, *PCWP_Struct;
|
||||||
|
|
||||||
|
typedef struct tagCWPR_Struct
|
||||||
|
{
|
||||||
|
HOOKPROC_CALLBACK_ARGUMENTS hpca;
|
||||||
|
CWPRETSTRUCT cwprs;
|
||||||
|
PBYTE Extra[4];
|
||||||
|
} CWPR_Struct, *PCWPR_Struct;
|
||||||
|
|
||||||
typedef struct _EVENTPROC_CALLBACK_ARGUMENTS
|
typedef struct _EVENTPROC_CALLBACK_ARGUMENTS
|
||||||
{
|
{
|
||||||
HWINEVENTHOOK hook;
|
HWINEVENTHOOK hook;
|
||||||
|
|
|
@ -509,6 +509,8 @@ co_IntLoadDefaultCursors(VOID)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INT iTheId = -2; // Set it out of range.
|
||||||
|
|
||||||
LRESULT APIENTRY
|
LRESULT APIENTRY
|
||||||
co_IntCallHookProc(INT HookId,
|
co_IntCallHookProc(INT HookId,
|
||||||
INT Code,
|
INT Code,
|
||||||
|
@ -535,6 +537,8 @@ co_IntCallHookProc(INT HookId,
|
||||||
PMSG pMsg = NULL;
|
PMSG pMsg = NULL;
|
||||||
BOOL Hit = FALSE;
|
BOOL Hit = FALSE;
|
||||||
UINT lParamSize = 0;
|
UINT lParamSize = 0;
|
||||||
|
CWPSTRUCT* pCWP = NULL;
|
||||||
|
CWPRETSTRUCT* pCWPR = NULL;
|
||||||
|
|
||||||
ASSERT(Proc);
|
ASSERT(Proc);
|
||||||
/* Do not allow the desktop thread to do callback to user mode */
|
/* Do not allow the desktop thread to do callback to user mode */
|
||||||
|
@ -593,27 +597,27 @@ co_IntCallHookProc(INT HookId,
|
||||||
goto Fault_Exit;
|
goto Fault_Exit;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WH_KEYBOARD_LL:
|
case WH_KEYBOARD_LL:
|
||||||
ArgumentLength += sizeof(KBDLLHOOKSTRUCT);
|
ArgumentLength += sizeof(KBDLLHOOKSTRUCT);
|
||||||
break;
|
break;
|
||||||
case WH_MOUSE_LL:
|
case WH_MOUSE_LL:
|
||||||
ArgumentLength += sizeof(MSLLHOOKSTRUCT);
|
ArgumentLength += sizeof(MSLLHOOKSTRUCT);
|
||||||
break;
|
break;
|
||||||
case WH_MOUSE:
|
case WH_MOUSE:
|
||||||
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
|
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROC:
|
case WH_CALLWNDPROC:
|
||||||
{
|
{
|
||||||
CWPSTRUCT* pCWP = (CWPSTRUCT*) lParam;
|
pCWP = (CWPSTRUCT*) lParam;
|
||||||
ArgumentLength += sizeof(CWPSTRUCT);
|
ArgumentLength = sizeof(CWP_Struct);
|
||||||
lParamSize = lParamMemorySize(pCWP->message, pCWP->wParam, pCWP->lParam);
|
lParamSize = lParamMemorySize(pCWP->message, pCWP->wParam, pCWP->lParam);
|
||||||
ArgumentLength += lParamSize;
|
ArgumentLength += lParamSize;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WH_CALLWNDPROCRET:
|
case WH_CALLWNDPROCRET:
|
||||||
{
|
{
|
||||||
CWPRETSTRUCT* pCWPR = (CWPRETSTRUCT*) lParam;
|
pCWPR = (CWPRETSTRUCT*) lParam;
|
||||||
ArgumentLength += sizeof(CWPRETSTRUCT);
|
ArgumentLength = sizeof(CWPR_Struct);
|
||||||
lParamSize = lParamMemorySize(pCWPR->message, pCWPR->wParam, pCWPR->lParam);
|
lParamSize = lParamMemorySize(pCWPR->message, pCWPR->wParam, pCWPR->lParam);
|
||||||
ArgumentLength += lParamSize;
|
ArgumentLength += lParamSize;
|
||||||
break;
|
break;
|
||||||
|
@ -647,6 +651,7 @@ co_IntCallHookProc(INT HookId,
|
||||||
Common->Mod = Mod;
|
Common->Mod = Mod;
|
||||||
Common->offPfn = offPfn;
|
Common->offPfn = offPfn;
|
||||||
Common->Ansi = Ansi;
|
Common->Ansi = Ansi;
|
||||||
|
Common->lParamSize = lParamSize;
|
||||||
RtlZeroMemory(&Common->ModuleName, sizeof(Common->ModuleName));
|
RtlZeroMemory(&Common->ModuleName, sizeof(Common->ModuleName));
|
||||||
if (ModuleName->Buffer && ModuleName->Length)
|
if (ModuleName->Buffer && ModuleName->Length)
|
||||||
{
|
{
|
||||||
|
@ -697,25 +702,27 @@ co_IntCallHookProc(INT HookId,
|
||||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROC:
|
case WH_CALLWNDPROC:
|
||||||
|
{
|
||||||
|
PCWP_Struct pcwps = (PCWP_Struct)Common;
|
||||||
|
RtlCopyMemory( &pcwps->cwps, pCWP, sizeof(CWPSTRUCT));
|
||||||
/* For CALLWNDPROC and CALLWNDPROCRET, we must be wary of the fact that
|
/* For CALLWNDPROC and CALLWNDPROCRET, we must be wary of the fact that
|
||||||
* lParam could be a pointer to a buffer. This buffer must be exported
|
* lParam could be a pointer to a buffer. This buffer must be exported
|
||||||
* to user space too */
|
* to user space too */
|
||||||
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPSTRUCT));
|
if ( lParamSize )
|
||||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
|
||||||
if(lParamSize)
|
|
||||||
{
|
{
|
||||||
RtlCopyMemory(Extra + sizeof(CWPSTRUCT), (PVOID)((CWPSTRUCT*)lParam)->lParam, lParamSize);
|
RtlCopyMemory( &pcwps->Extra, (PVOID)pCWP->lParam, lParamSize );
|
||||||
((CWPSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROCRET:
|
case WH_CALLWNDPROCRET:
|
||||||
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
|
{
|
||||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
PCWPR_Struct pcwprs = (PCWPR_Struct)Common;
|
||||||
if(lParamSize)
|
RtlCopyMemory( &pcwprs->cwprs, pCWPR, sizeof(CWPRETSTRUCT));
|
||||||
|
if ( lParamSize )
|
||||||
{
|
{
|
||||||
RtlCopyMemory(Extra + sizeof(CWPRETSTRUCT), (PVOID)((CWPRETSTRUCT*)lParam)->lParam, lParamSize);
|
RtlCopyMemory( &pcwprs->Extra, (PVOID)pCWPR->lParam, lParamSize );
|
||||||
((CWPRETSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WH_MSGFILTER:
|
case WH_MSGFILTER:
|
||||||
case WH_SYSMSGFILTER:
|
case WH_SYSMSGFILTER:
|
||||||
|
@ -745,7 +752,11 @@ co_IntCallHookProc(INT HookId,
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("Failure to make Callback! Status 0x%x\n",Status);
|
if ( iTheId != HookId ) // Hook ID can change.
|
||||||
|
{
|
||||||
|
ERR("Failure to make Callback %d! Status 0x%x\n",HookId,Status);
|
||||||
|
iTheId = HookId;
|
||||||
|
}
|
||||||
goto Fault_Exit;
|
goto Fault_Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,12 +1227,13 @@ APIENTRY
|
||||||
co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData, INT OutSize )
|
co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData, INT OutSize )
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PVOID ResultPointer;
|
||||||
|
|
||||||
Status = KeUserModeCallback(USER32_CALLBACK_UMPD,
|
Status = KeUserModeCallback( USER32_CALLBACK_UMPD,
|
||||||
pkt,
|
pkt,
|
||||||
InSize,
|
InSize,
|
||||||
pvOutData,
|
&ResultPointer,
|
||||||
(PULONG)&OutSize);
|
(PULONG)&OutSize );
|
||||||
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1230,6 +1242,8 @@ co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData, INT OutSize
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OutSize) RtlMoveMemory( pvOutData, ResultPointer, OutSize );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -699,35 +699,39 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROC:
|
case WH_CALLWNDPROC:
|
||||||
// ERR("WH_CALLWNDPROC: Code %d, wParam %d\n",Common->Code,Common->wParam);
|
{
|
||||||
pCWP = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
|
PCWP_Struct pcwps = (PCWP_Struct)Common;
|
||||||
RtlCopyMemory(pCWP, (PCHAR) Common + Common->lParam, sizeof(CWPSTRUCT));
|
CWPSTRUCT *pCWPT = &pcwps->cwps;
|
||||||
|
pCWP = HeapAlloc(GetProcessHeap(), 0, Common->lParamSize + sizeof(CWPSTRUCT));
|
||||||
|
RtlCopyMemory(pCWP, pCWPT, sizeof(CWPSTRUCT));
|
||||||
|
// ERR("WH_CALLWNDPROC: Code %d, wParam %d msg %d\n",Common->Code,Common->wParam,pCWP->message);
|
||||||
/* If more memory is reserved, then lParam is a pointer.
|
/* If more memory is reserved, then lParam is a pointer.
|
||||||
* Size of the buffer is stocked in the lParam member, and its content
|
* Size of the buffer is stocked in the lParam member, and its content
|
||||||
* is at the end of the argument buffer */
|
* is at the end of the argument buffer */
|
||||||
if(ArgumentLength > (sizeof(CWPSTRUCT) + sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
|
if ( Common->lParamSize )
|
||||||
{
|
{
|
||||||
RtlCopyMemory((PCHAR)pCWP + sizeof(CWPSTRUCT),
|
|
||||||
(PCHAR)Common + Common->lParam + sizeof(CWPSTRUCT),
|
|
||||||
pCWP->lParam);
|
|
||||||
pCWP->lParam = (LPARAM)((PCHAR)pCWP + sizeof(CWPSTRUCT));
|
pCWP->lParam = (LPARAM)((PCHAR)pCWP + sizeof(CWPSTRUCT));
|
||||||
|
RtlCopyMemory( (PCHAR)pCWP + sizeof(CWPSTRUCT), &pcwps->Extra, Common->lParamSize );
|
||||||
}
|
}
|
||||||
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
|
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
|
||||||
HeapFree(GetProcessHeap(), 0, pCWP);
|
HeapFree(GetProcessHeap(), 0, pCWP);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WH_CALLWNDPROCRET:
|
case WH_CALLWNDPROCRET:
|
||||||
/* Almost the same as WH_CALLWNDPROC */
|
/* Almost the same as WH_CALLWNDPROC */
|
||||||
pCWPR = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
|
{
|
||||||
RtlCopyMemory(pCWPR, (PCHAR) Common + Common->lParam, sizeof(CWPRETSTRUCT));
|
PCWPR_Struct pcwprs = (PCWPR_Struct)Common;
|
||||||
if(ArgumentLength > (sizeof(CWPRETSTRUCT) + sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
|
CWPRETSTRUCT *pCWPRT = &pcwprs->cwprs;
|
||||||
|
pCWPR = HeapAlloc(GetProcessHeap(), 0, Common->lParamSize + sizeof(CWPRETSTRUCT));
|
||||||
|
RtlCopyMemory(pCWPR, pCWPRT, sizeof(CWPSTRUCT));
|
||||||
|
if ( Common->lParamSize )
|
||||||
{
|
{
|
||||||
RtlCopyMemory((PCHAR)pCWPR + sizeof(CWPRETSTRUCT),
|
|
||||||
(PCHAR)Common + Common->lParam + sizeof(CWPRETSTRUCT),
|
|
||||||
pCWPR->lParam);
|
|
||||||
pCWPR->lParam = (LPARAM)((PCHAR)pCWPR + sizeof(CWPRETSTRUCT));
|
pCWPR->lParam = (LPARAM)((PCHAR)pCWPR + sizeof(CWPRETSTRUCT));
|
||||||
|
RtlCopyMemory( (PCHAR)pCWPR + sizeof(CWPRETSTRUCT), &pcwprs->Extra, Common->lParamSize );
|
||||||
}
|
}
|
||||||
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
|
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
|
||||||
HeapFree(GetProcessHeap(), 0, pCWPR);
|
HeapFree(GetProcessHeap(), 0, pCWPR);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WH_MSGFILTER: /* All SEH support */
|
case WH_MSGFILTER: /* All SEH support */
|
||||||
case WH_SYSMSGFILTER:
|
case WH_SYSMSGFILTER:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue