mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
Dereference callproc handles without a system call
svn path=/trunk/; revision=30455
This commit is contained in:
parent
1392564c0d
commit
bbf86d9a89
7 changed files with 133 additions and 60 deletions
|
@ -45,8 +45,9 @@ LONG STDCALL GdiGetCharDimensions(HDC, LPTEXTMETRICW, LONG *);
|
|||
BOOL FASTCALL IsMetaFile(HDC);
|
||||
|
||||
extern PW32PROCESSINFO g_pi;
|
||||
extern PW32PROCESSINFO g_kpi;
|
||||
|
||||
static PVOID __inline
|
||||
static __inline PVOID
|
||||
SharedPtrToUser(PVOID Ptr)
|
||||
{
|
||||
ASSERT(Ptr != NULL);
|
||||
|
@ -55,7 +56,7 @@ SharedPtrToUser(PVOID Ptr)
|
|||
return (PVOID)((ULONG_PTR)Ptr - g_pi->UserHeapDelta);
|
||||
}
|
||||
|
||||
static PVOID __inline
|
||||
static __inline PVOID
|
||||
DesktopPtrToUser(PVOID Ptr)
|
||||
{
|
||||
PW32THREADINFO ti = GetW32ThreadInfo();
|
||||
|
@ -65,3 +66,13 @@ DesktopPtrToUser(PVOID Ptr)
|
|||
return (PVOID)((ULONG_PTR)Ptr - ti->DesktopHeapDelta);
|
||||
}
|
||||
|
||||
static __inline PVOID
|
||||
SharedPtrToKernel(PVOID Ptr)
|
||||
{
|
||||
ASSERT(Ptr != NULL);
|
||||
ASSERT(g_pi != NULL);
|
||||
ASSERT(g_pi->UserHeapDelta != 0);
|
||||
return (PVOID)((ULONG_PTR)Ptr + g_pi->UserHeapDelta);
|
||||
}
|
||||
|
||||
PCALLPROC FASTCALL ValidateCallProc(HANDLE hCallProc);
|
||||
|
|
|
@ -200,7 +200,12 @@ extern int SPY_Init(void);
|
|||
typedef struct _USER_HANDLE_ENTRY
|
||||
{
|
||||
void *ptr; /* pointer to object */
|
||||
PW32THREADINFO pti; // pointer to Win32ThreadInfo
|
||||
union
|
||||
{
|
||||
PVOID pi;
|
||||
PW32THREADINFO pti; // pointer to Win32ThreadInfo
|
||||
PW32PROCESSINFO ppi; // pointer to W32ProcessInfo
|
||||
};
|
||||
unsigned short type; /* object type (0 if free) */
|
||||
unsigned short generation; /* generation counter */
|
||||
} USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
|
||||
|
@ -214,6 +219,7 @@ typedef struct _USER_HANDLE_TABLE
|
|||
} USER_HANDLE_TABLE, * PUSER_HANDLE_TABLE;
|
||||
|
||||
extern PUSER_HANDLE_TABLE gHandleTable;
|
||||
extern PUSER_HANDLE_ENTRY gHandleEntries;
|
||||
|
||||
PUSER_HANDLE_ENTRY FASTCALL GetUser32Handle(HANDLE);
|
||||
PVOID FASTCALL ValidateHandle(HANDLE, UINT);
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
static ULONG User32TlsIndex;
|
||||
HINSTANCE User32Instance;
|
||||
PUSER_HANDLE_TABLE gHandleTable = NULL;
|
||||
PW32PROCESSINFO g_pi = NULL;
|
||||
PUSER_HANDLE_ENTRY gHandleEntries = NULL;
|
||||
PW32PROCESSINFO g_pi = NULL; /* User Mode Pointer */
|
||||
PW32PROCESSINFO g_kpi = NULL; /* Kernel Mode Pointer */
|
||||
|
||||
PW32PROCESSINFO
|
||||
GetW32ProcessInfo(VOID);
|
||||
|
@ -56,7 +58,9 @@ Init(VOID)
|
|||
(PVOID)User32CallHookProcFromKernel;
|
||||
|
||||
g_pi = GetW32ProcessInfo();
|
||||
g_kpi = SharedPtrToKernel(g_pi);
|
||||
gHandleTable = SharedPtrToUser(g_pi->UserHandleTable);
|
||||
gHandleEntries = SharedPtrToUser(gHandleTable->handles);
|
||||
|
||||
/* Allocate an index for user32 thread local data. */
|
||||
User32TlsIndex = TlsAlloc();
|
||||
|
|
|
@ -314,23 +314,23 @@ PUSER_HANDLE_ENTRY
|
|||
FASTCALL
|
||||
GetUser32Handle(HANDLE handle)
|
||||
{
|
||||
PUSER_HANDLE_TABLE ht = gHandleTable;
|
||||
USHORT generation;
|
||||
INT Index;
|
||||
USHORT generation;
|
||||
|
||||
TRACE("Main Handle Table %x\n", ht);
|
||||
Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
|
||||
|
||||
INT Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
|
||||
if (Index < 0 || Index >= gHandleTable->nb_handles)
|
||||
return NULL;
|
||||
|
||||
if (Index < 0 || Index >= ht->nb_handles) return NULL;
|
||||
if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
|
||||
return NULL;
|
||||
|
||||
if (!ht->handles[Index].type) return NULL;
|
||||
generation = (UINT)handle >> 16;
|
||||
|
||||
generation = (UINT)handle >> 16;
|
||||
if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
|
||||
return &gHandleEntries[Index];
|
||||
|
||||
if (generation == ht->handles[Index].generation || !generation || generation == 0xffff)
|
||||
return &ht->handles[Index];
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -345,8 +345,8 @@ static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_MONITOR + 1] =
|
|||
TRUE, /* VALIDATE_TYPE_MWPOS */
|
||||
TRUE, /* VALIDATE_TYPE_HOOK */
|
||||
FALSE, /* (not used) */
|
||||
FALSE, /* VALIDATE_TYPE_CALLPROC */
|
||||
FALSE, /* VALIDATE_TYPE_ACCEL */
|
||||
TRUE, /* VALIDATE_TYPE_CALLPROC */
|
||||
TRUE, /* VALIDATE_TYPE_ACCEL */
|
||||
FALSE, /* (not used) */
|
||||
FALSE, /* (not used) */
|
||||
FALSE, /* (not used) */
|
||||
|
@ -361,6 +361,7 @@ FASTCALL
|
|||
ValidateHandle(HANDLE handle, UINT uType)
|
||||
{
|
||||
PVOID ret;
|
||||
PUSER_HANDLE_ENTRY pEntry;
|
||||
PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
|
||||
|
||||
ASSERT(uType <= VALIDATE_TYPE_MONITOR);
|
||||
|
@ -372,13 +373,13 @@ ValidateHandle(HANDLE handle, UINT uType)
|
|||
if (handle == ClientInfo->hWND) return ClientInfo->pvWND;
|
||||
}
|
||||
|
||||
PUSER_HANDLE_ENTRY pEntry = GetUser32Handle(handle);
|
||||
pEntry = GetUser32Handle(handle);
|
||||
|
||||
if (pEntry && uType == 0)
|
||||
uType = pEntry->type;
|
||||
|
||||
// Must have an entry and must be the same type!
|
||||
if ( (!pEntry) || (pEntry->type != uType) )
|
||||
if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
|
||||
{
|
||||
switch ( uType )
|
||||
{ // Test (with wine too) confirms these results!
|
||||
|
@ -407,8 +408,6 @@ ValidateHandle(HANDLE handle, UINT uType)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!(NtUserValidateHandleSecure(handle, FALSE))) return NULL;
|
||||
|
||||
if (g_ObjectHeapTypeShared[uType])
|
||||
ret = SharedPtrToUser(pEntry->ptr);
|
||||
else
|
||||
|
@ -427,3 +426,17 @@ ValidateHandle(HANDLE handle, UINT uType)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate callproc handle and return the pointer to the object.
|
||||
//
|
||||
PCALLPROC
|
||||
FASTCALL
|
||||
ValidateCallProc(HANDLE hCallProc)
|
||||
{
|
||||
PCALLPROC CallProc = ValidateHandle(hCallProc, VALIDATE_TYPE_CALLPROC);
|
||||
if (CallProc != NULL && CallProc->pi == g_kpi)
|
||||
return CallProc;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1233,27 +1233,29 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
|
|||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
WNDPROC_INFO wpInfo;
|
||||
PCALLPROC CallProc;
|
||||
|
||||
if (lpPrevWndFunc == NULL)
|
||||
if (lpPrevWndFunc == NULL)
|
||||
{
|
||||
WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
|
||||
return 0;
|
||||
WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!IsCallProcHandle(lpPrevWndFunc))
|
||||
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
if (!IsCallProcHandle(lpPrevWndFunc))
|
||||
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
{
|
||||
if (NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
|
||||
&wpInfo))
|
||||
return IntCallWindowProcA(!wpInfo.IsUnicode, wpInfo.WindowProc,
|
||||
hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
{
|
||||
WARN("CallWindowProcA: can not dereference WndProcHandle\n");
|
||||
return 0;
|
||||
}
|
||||
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
|
||||
if (CallProc != NULL)
|
||||
{
|
||||
return IntCallWindowProcA(!CallProc->Unicode, CallProc->WndProc,
|
||||
hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("CallWindowProcA: can not dereference WndProcHandle\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1268,29 +1270,31 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
|
|||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
WNDPROC_INFO wpInfo;
|
||||
PCALLPROC CallProc;
|
||||
|
||||
/* FIXME - can the first parameter be NULL? */
|
||||
if (lpPrevWndFunc == NULL)
|
||||
/* FIXME - can the first parameter be NULL? */
|
||||
if (lpPrevWndFunc == NULL)
|
||||
{
|
||||
WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
|
||||
return 0;
|
||||
WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!IsCallProcHandle(lpPrevWndFunc))
|
||||
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
{
|
||||
if (NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
|
||||
&wpInfo))
|
||||
return IntCallWindowProcW(!wpInfo.IsUnicode, wpInfo.WindowProc,
|
||||
hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
{
|
||||
WARN("CallWindowProcW: can not dereference WndProcHandle\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!IsCallProcHandle(lpPrevWndFunc))
|
||||
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
{
|
||||
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
|
||||
if (CallProc != NULL)
|
||||
{
|
||||
return IntCallWindowProcW(!CallProc->Unicode, CallProc->WndProc,
|
||||
hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("CallWindowProcW: can not dereference WndProcHandle\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,12 @@
|
|||
typedef struct _USER_HANDLE_ENTRY
|
||||
{
|
||||
void *ptr; /* pointer to object */
|
||||
PW32THREADINFO pti; // pointer to Win32ThreadInfo
|
||||
union
|
||||
{
|
||||
PVOID pi;
|
||||
PW32THREADINFO pti; // pointer to Win32ThreadInfo
|
||||
PW32PROCESSINFO ppi; // pointer to W32ProcessInfo
|
||||
};
|
||||
unsigned short type; /* object type (0 if free) */
|
||||
unsigned short generation; /* generation counter */
|
||||
} USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
|
||||
|
|
|
@ -108,7 +108,7 @@ __inline static void *free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY
|
|||
ret = entry->ptr;
|
||||
entry->ptr = ht->freelist;
|
||||
entry->type = 0;
|
||||
entry->pti = 0;
|
||||
entry->pi = NULL;
|
||||
ht->freelist = entry;
|
||||
|
||||
usedHandles--;
|
||||
|
@ -116,6 +116,37 @@ __inline static void *free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY
|
|||
return ret;
|
||||
}
|
||||
|
||||
static __inline PVOID
|
||||
UserHandleOwnerByType(USER_OBJECT_TYPE type)
|
||||
{
|
||||
PVOID pi;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case otWindow:
|
||||
pi = GetW32ThreadInfo();
|
||||
break;
|
||||
|
||||
case otMenu:
|
||||
case otCursorIcon:
|
||||
case otHook:
|
||||
case otCallProc:
|
||||
case otAccel:
|
||||
pi = GetW32ProcessInfo();
|
||||
break;
|
||||
|
||||
case otMonitor:
|
||||
pi = NULL; /* System */
|
||||
break;
|
||||
|
||||
default:
|
||||
pi = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
/* allocate a user handle for a given object */
|
||||
HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE type )
|
||||
{
|
||||
|
@ -124,8 +155,7 @@ HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE typ
|
|||
return 0;
|
||||
entry->ptr = object;
|
||||
entry->type = type;
|
||||
entry->pti = GetW32ThreadInfo();
|
||||
if (entry->pti->pi->UserHandleTable == NULL) GetW32ProcessInfo();
|
||||
entry->pi = UserHandleOwnerByType(type);
|
||||
if (++entry->generation >= 0xffff)
|
||||
entry->generation = 1;
|
||||
return entry_to_handle(ht, entry );
|
||||
|
|
Loading…
Reference in a new issue