mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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;
|
||||
BOOLEAN Ansi;
|
||||
LRESULT Result;
|
||||
UINT lParamSize;
|
||||
WCHAR ModuleName[512];
|
||||
} HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS;
|
||||
|
||||
|
@ -72,6 +73,20 @@ typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
|
|||
/* WCHAR szClass[] */
|
||||
} 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
|
||||
{
|
||||
HWINEVENTHOOK hook;
|
||||
|
|
|
@ -509,6 +509,8 @@ co_IntLoadDefaultCursors(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static INT iTheId = -2; // Set it out of range.
|
||||
|
||||
LRESULT APIENTRY
|
||||
co_IntCallHookProc(INT HookId,
|
||||
INT Code,
|
||||
|
@ -535,6 +537,8 @@ co_IntCallHookProc(INT HookId,
|
|||
PMSG pMsg = NULL;
|
||||
BOOL Hit = FALSE;
|
||||
UINT lParamSize = 0;
|
||||
CWPSTRUCT* pCWP = NULL;
|
||||
CWPRETSTRUCT* pCWPR = NULL;
|
||||
|
||||
ASSERT(Proc);
|
||||
/* Do not allow the desktop thread to do callback to user mode */
|
||||
|
@ -593,27 +597,27 @@ co_IntCallHookProc(INT HookId,
|
|||
goto Fault_Exit;
|
||||
}
|
||||
break;
|
||||
case WH_KEYBOARD_LL:
|
||||
case WH_KEYBOARD_LL:
|
||||
ArgumentLength += sizeof(KBDLLHOOKSTRUCT);
|
||||
break;
|
||||
case WH_MOUSE_LL:
|
||||
case WH_MOUSE_LL:
|
||||
ArgumentLength += sizeof(MSLLHOOKSTRUCT);
|
||||
break;
|
||||
case WH_MOUSE:
|
||||
case WH_MOUSE:
|
||||
ArgumentLength += sizeof(MOUSEHOOKSTRUCT);
|
||||
break;
|
||||
case WH_CALLWNDPROC:
|
||||
{
|
||||
CWPSTRUCT* pCWP = (CWPSTRUCT*) lParam;
|
||||
ArgumentLength += sizeof(CWPSTRUCT);
|
||||
pCWP = (CWPSTRUCT*) lParam;
|
||||
ArgumentLength = sizeof(CWP_Struct);
|
||||
lParamSize = lParamMemorySize(pCWP->message, pCWP->wParam, pCWP->lParam);
|
||||
ArgumentLength += lParamSize;
|
||||
break;
|
||||
}
|
||||
case WH_CALLWNDPROCRET:
|
||||
{
|
||||
CWPRETSTRUCT* pCWPR = (CWPRETSTRUCT*) lParam;
|
||||
ArgumentLength += sizeof(CWPRETSTRUCT);
|
||||
pCWPR = (CWPRETSTRUCT*) lParam;
|
||||
ArgumentLength = sizeof(CWPR_Struct);
|
||||
lParamSize = lParamMemorySize(pCWPR->message, pCWPR->wParam, pCWPR->lParam);
|
||||
ArgumentLength += lParamSize;
|
||||
break;
|
||||
|
@ -647,6 +651,7 @@ co_IntCallHookProc(INT HookId,
|
|||
Common->Mod = Mod;
|
||||
Common->offPfn = offPfn;
|
||||
Common->Ansi = Ansi;
|
||||
Common->lParamSize = lParamSize;
|
||||
RtlZeroMemory(&Common->ModuleName, sizeof(Common->ModuleName));
|
||||
if (ModuleName->Buffer && ModuleName->Length)
|
||||
{
|
||||
|
@ -697,25 +702,27 @@ co_IntCallHookProc(INT HookId,
|
|||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||
break;
|
||||
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
|
||||
* lParam could be a pointer to a buffer. This buffer must be exported
|
||||
* to user space too */
|
||||
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPSTRUCT));
|
||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||
if(lParamSize)
|
||||
if ( lParamSize )
|
||||
{
|
||||
RtlCopyMemory(Extra + sizeof(CWPSTRUCT), (PVOID)((CWPSTRUCT*)lParam)->lParam, lParamSize);
|
||||
((CWPSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
|
||||
RtlCopyMemory( &pcwps->Extra, (PVOID)pCWP->lParam, lParamSize );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WH_CALLWNDPROCRET:
|
||||
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(CWPRETSTRUCT));
|
||||
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||
if(lParamSize)
|
||||
{
|
||||
PCWPR_Struct pcwprs = (PCWPR_Struct)Common;
|
||||
RtlCopyMemory( &pcwprs->cwprs, pCWPR, sizeof(CWPRETSTRUCT));
|
||||
if ( lParamSize )
|
||||
{
|
||||
RtlCopyMemory(Extra + sizeof(CWPRETSTRUCT), (PVOID)((CWPRETSTRUCT*)lParam)->lParam, lParamSize);
|
||||
((CWPRETSTRUCT*)Extra)->lParam = (LPARAM)lParamSize;
|
||||
RtlCopyMemory( &pcwprs->Extra, (PVOID)pCWPR->lParam, lParamSize );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WH_MSGFILTER:
|
||||
case WH_SYSMSGFILTER:
|
||||
|
@ -745,7 +752,11 @@ co_IntCallHookProc(INT HookId,
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1216,12 +1227,13 @@ APIENTRY
|
|||
co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData, INT OutSize )
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID ResultPointer;
|
||||
|
||||
Status = KeUserModeCallback(USER32_CALLBACK_UMPD,
|
||||
pkt,
|
||||
InSize,
|
||||
pvOutData,
|
||||
(PULONG)&OutSize);
|
||||
Status = KeUserModeCallback( USER32_CALLBACK_UMPD,
|
||||
pkt,
|
||||
InSize,
|
||||
&ResultPointer,
|
||||
(PULONG)&OutSize );
|
||||
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1230,6 +1242,8 @@ co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData, INT OutSize
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (OutSize) RtlMoveMemory( pvOutData, ResultPointer, OutSize );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -699,35 +699,39 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
|||
_SEH2_END;
|
||||
break;
|
||||
case WH_CALLWNDPROC:
|
||||
// ERR("WH_CALLWNDPROC: Code %d, wParam %d\n",Common->Code,Common->wParam);
|
||||
pCWP = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
|
||||
RtlCopyMemory(pCWP, (PCHAR) Common + Common->lParam, sizeof(CWPSTRUCT));
|
||||
{
|
||||
PCWP_Struct pcwps = (PCWP_Struct)Common;
|
||||
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.
|
||||
* Size of the buffer is stocked in the lParam member, and its content
|
||||
* 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));
|
||||
RtlCopyMemory( (PCHAR)pCWP + sizeof(CWPSTRUCT), &pcwps->Extra, Common->lParamSize );
|
||||
}
|
||||
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
|
||||
HeapFree(GetProcessHeap(), 0, pCWP);
|
||||
}
|
||||
break;
|
||||
case WH_CALLWNDPROCRET:
|
||||
/* Almost the same as WH_CALLWNDPROC */
|
||||
pCWPR = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
|
||||
RtlCopyMemory(pCWPR, (PCHAR) Common + Common->lParam, sizeof(CWPRETSTRUCT));
|
||||
if(ArgumentLength > (sizeof(CWPRETSTRUCT) + sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
|
||||
{
|
||||
PCWPR_Struct pcwprs = (PCWPR_Struct)Common;
|
||||
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));
|
||||
RtlCopyMemory( (PCHAR)pCWPR + sizeof(CWPRETSTRUCT), &pcwprs->Extra, Common->lParamSize );
|
||||
}
|
||||
Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
|
||||
HeapFree(GetProcessHeap(), 0, pCWPR);
|
||||
}
|
||||
break;
|
||||
case WH_MSGFILTER: /* All SEH support */
|
||||
case WH_SYSMSGFILTER:
|
||||
|
|
Loading…
Reference in a new issue