#include "sanitizer\allocator_interface.h" #include #include #include // RUN: %clang_cl_asan %s -o%t // RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s // UNSUPPORTED: asan-64-bits using AllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, SIZE_T); using ReAllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID, SIZE_T); using FreeFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID); int main() { HMODULE NtDllHandle = GetModuleHandle("ntdll.dll"); if (!NtDllHandle) { puts("Couldn't load ntdll??"); return -1; } auto RtlAllocateHeap_ptr = (AllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlAllocateHeap"); if (RtlAllocateHeap_ptr == 0) { puts("Couldn't find RtlAllocateHeap"); return -1; } auto RtlReAllocateHeap_ptr = (ReAllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlReAllocateHeap"); if (RtlReAllocateHeap_ptr == 0) { puts("Couldn't find RtlReAllocateHeap"); return -1; } //owned by rtl void *alloc = RtlAllocateHeap_ptr(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, 100); assert(alloc); for (int i = 0; i < 100; i++) { assert(((char *)alloc)[i] == 0); ((char *)alloc)[i] = '\xcc'; } // still owned by rtl alloc = RtlReAllocateHeap_ptr(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, alloc, 500); assert(alloc && !__sanitizer_get_ownership(alloc) && HeapValidate(GetProcessHeap(), 0, alloc)); for (int i = 0; i < 100; i++) { assert(((char *)alloc)[i] == '\xcc'); } for (int i = 100; i < 500; i++) { assert(((char *)alloc)[i] == 0); ((char *)alloc)[i] = '\xcc'; } //convert to asan owned void *realloc = RtlReAllocateHeap_ptr(GetProcessHeap(), HEAP_ZERO_MEMORY, alloc, 600); alloc = nullptr; assert(realloc && __sanitizer_get_ownership(realloc)); for (int i = 0; i < 500; i++) { assert(((char *)realloc)[i] == '\xcc'); } for (int i = 500; i < 600; i++) { assert(((char *)realloc)[i] == 0); ((char *)realloc)[i] = '\xcc'; } realloc = RtlReAllocateHeap_ptr(GetProcessHeap(), HEAP_ZERO_MEMORY, realloc, 2048); assert(realloc && __sanitizer_get_ownership(realloc)); for (int i = 0; i < 600; i++) { assert(((char *)realloc)[i] == '\xcc'); } for (int i = 600; i < 2048; i++) { assert(((char *)realloc)[i] == 0); ((char *)realloc)[i] = '\xcc'; } //convert back to rtl owned; alloc = RtlReAllocateHeap_ptr(GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, realloc, 100); assert(alloc && !__sanitizer_get_ownership(alloc) && HeapValidate(GetProcessHeap(), 0, alloc)); for (int i = 0; i < 100; i++) { assert(((char *)alloc)[i] == '\xcc'); ((char *)alloc)[i] = 0; } auto usable_size = HeapSize(GetProcessHeap(), 0, alloc); for (int i = 100; i < usable_size; i++) { assert(((char *)alloc)[i] == 0); } printf("Success\n"); } // CHECK-NOT: Assertion failed: // CHECK-NOT: AddressSanitizer // CHECK: Success