ntdll: Raise debug exceptions when invalid heap is destroyed.
And when PEB->BeingDebugged is set to 1. Lords Of The Fallen anti-tamper does this and only continues if a DBG_PRINTEXCEPTION_C is received. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c5129d6fc0
commit
255270373e
|
@ -1589,6 +1589,12 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
TRACE("%p\n", heap );
|
TRACE("%p\n", heap );
|
||||||
|
if (!heapPtr && heap && (((HEAP *)heap)->flags & HEAP_VALIDATE_PARAMS) &&
|
||||||
|
NtCurrentTeb()->Peb->BeingDebugged)
|
||||||
|
{
|
||||||
|
DbgPrint( "Attempt to destroy an invalid heap\n" );
|
||||||
|
DbgBreakPoint();
|
||||||
|
}
|
||||||
if (!heapPtr) return heap;
|
if (!heapPtr) return heap;
|
||||||
|
|
||||||
if (heap == processHeap) return heap; /* cannot delete the main process heap */
|
if (heap == processHeap) return heap; /* cannot delete the main process heap */
|
||||||
|
|
|
@ -3599,6 +3599,71 @@ static void test_DbgPrint(void)
|
||||||
RtlRemoveVectoredExceptionHandler( handler );
|
RtlRemoveVectoredExceptionHandler( handler );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL test_heap_destroy_dbgstr = FALSE;
|
||||||
|
static BOOL test_heap_destroy_break = FALSE;
|
||||||
|
|
||||||
|
static LONG CALLBACK test_heap_destroy_except_handler( EXCEPTION_POINTERS *eptrs )
|
||||||
|
{
|
||||||
|
if (eptrs->ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
|
||||||
|
{
|
||||||
|
#if defined( __i386__ )
|
||||||
|
eptrs->ContextRecord->Eip += 1;
|
||||||
|
test_heap_destroy_break = TRUE;
|
||||||
|
return (LONG)EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
#elif defined( __x86_64__ )
|
||||||
|
eptrs->ContextRecord->Rip += 1;
|
||||||
|
test_heap_destroy_break = TRUE;
|
||||||
|
return (LONG)EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eptrs->ExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C)
|
||||||
|
{
|
||||||
|
test_heap_destroy_dbgstr = TRUE;
|
||||||
|
return (LONG)EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LONG)EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* partially copied from ntdll/heap.c */
|
||||||
|
#define HEAP_VALIDATE_PARAMS 0x40000000
|
||||||
|
|
||||||
|
struct heap
|
||||||
|
{
|
||||||
|
DWORD_PTR unknown1[2];
|
||||||
|
DWORD unknown2[2];
|
||||||
|
DWORD_PTR unknown3[4];
|
||||||
|
DWORD unknown4;
|
||||||
|
DWORD_PTR unknown5[2];
|
||||||
|
DWORD unknown6[3];
|
||||||
|
DWORD_PTR unknown7[2];
|
||||||
|
DWORD flags;
|
||||||
|
DWORD force_flags;
|
||||||
|
DWORD_PTR unknown8[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_RtlDestroyHeap(void)
|
||||||
|
{
|
||||||
|
const struct heap invalid = {{0, 0}, {0, HEAP_VALIDATE_PARAMS}, {0, 0, 0, 0}, 0, {0, 0}, {0, 0, 0}, {0, 0}, HEAP_VALIDATE_PARAMS, 0, {0}};
|
||||||
|
HANDLE heap = (HANDLE)&invalid, ret;
|
||||||
|
PEB *Peb = NtCurrentTeb()->Peb;
|
||||||
|
BOOL debugged;
|
||||||
|
void *handler = RtlAddVectoredExceptionHandler( TRUE, test_heap_destroy_except_handler );
|
||||||
|
|
||||||
|
test_heap_destroy_dbgstr = FALSE;
|
||||||
|
test_heap_destroy_break = FALSE;
|
||||||
|
debugged = Peb->BeingDebugged;
|
||||||
|
Peb->BeingDebugged = TRUE;
|
||||||
|
ret = RtlDestroyHeap( heap );
|
||||||
|
ok( ret == heap, "RtlDestroyHeap(%p) returned %p\n", heap, ret );
|
||||||
|
ok( test_heap_destroy_dbgstr, "HeapDestroy didn't call OutputDebugStrA\n" );
|
||||||
|
ok( test_heap_destroy_break, "HeapDestroy didn't call DbgBreakPoint\n" );
|
||||||
|
Peb->BeingDebugged = debugged;
|
||||||
|
|
||||||
|
RtlRemoveVectoredExceptionHandler( handler );
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(rtl)
|
START_TEST(rtl)
|
||||||
{
|
{
|
||||||
InitFunctionPtrs();
|
InitFunctionPtrs();
|
||||||
|
@ -3640,4 +3705,5 @@ START_TEST(rtl)
|
||||||
test_RtlMakeSelfRelativeSD();
|
test_RtlMakeSelfRelativeSD();
|
||||||
test_LdrRegisterDllNotification();
|
test_LdrRegisterDllNotification();
|
||||||
test_DbgPrint();
|
test_DbgPrint();
|
||||||
|
test_RtlDestroyHeap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue