Merge remote-tracking branch 'origin/main' into unhandled-exceptions

This commit is contained in:
momo5502
2025-08-24 12:45:31 +02:00
142 changed files with 9276 additions and 8583 deletions

View File

@@ -295,8 +295,7 @@ namespace
for (DWORD i = 0;; ++i)
{
auto name_buffer_len = static_cast<DWORD>(name_buffer.size());
const LSTATUS status =
RegEnumKeyExA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
const LSTATUS status = RegEnumKeyExA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
if (status == ERROR_SUCCESS)
{
keys.emplace_back(name_buffer.data(), name_buffer_len);
@@ -340,8 +339,7 @@ namespace
for (DWORD i = 0;; ++i)
{
auto name_buffer_len = static_cast<DWORD>(name_buffer.size());
const auto status =
RegEnumValueA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
const auto status = RegEnumValueA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
if (status == ERROR_SUCCESS)
{
values.emplace_back(name_buffer.data(), name_buffer_len);
@@ -383,16 +381,14 @@ namespace
// WOW64 Redirection Test
const auto pst_display = read_registry_string(
HKEY_LOCAL_MACHINE,
R"(SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Time Zones\Pacific Standard Time)", "Display");
HKEY_LOCAL_MACHINE, R"(SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Time Zones\Pacific Standard Time)", "Display");
if (!pst_display || pst_display->empty())
{
return false;
}
// Key Sub-keys Enumeration Test
const auto subkeys_opt =
get_all_registry_keys(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
const auto subkeys_opt = get_all_registry_keys(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
if (!subkeys_opt)
{
return false;
@@ -413,8 +409,7 @@ namespace
}
// Key Values Enumeration Test
const auto values_opt =
get_all_registry_values(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
const auto values_opt = get_all_registry_values(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
if (!values_opt)
{
return false;
@@ -489,17 +484,15 @@ namespace
return false;
}
if (current_dtzi.StandardDate.wYear != 0 || current_dtzi.StandardDate.wMonth != 10 ||
current_dtzi.StandardDate.wDayOfWeek != 0 || current_dtzi.StandardDate.wDay != 5 ||
current_dtzi.StandardDate.wHour != 3 || current_dtzi.StandardDate.wMinute != 0 ||
if (current_dtzi.StandardDate.wYear != 0 || current_dtzi.StandardDate.wMonth != 10 || current_dtzi.StandardDate.wDayOfWeek != 0 ||
current_dtzi.StandardDate.wDay != 5 || current_dtzi.StandardDate.wHour != 3 || current_dtzi.StandardDate.wMinute != 0 ||
current_dtzi.StandardDate.wSecond != 0 || current_dtzi.StandardDate.wMilliseconds != 0)
{
return false;
}
if (current_dtzi.DaylightDate.wYear != 0 || current_dtzi.DaylightDate.wMonth != 3 ||
current_dtzi.DaylightDate.wDayOfWeek != 0 || current_dtzi.DaylightDate.wDay != 5 ||
current_dtzi.DaylightDate.wHour != 2 || current_dtzi.DaylightDate.wMinute != 0 ||
if (current_dtzi.DaylightDate.wYear != 0 || current_dtzi.DaylightDate.wMonth != 3 || current_dtzi.DaylightDate.wDayOfWeek != 0 ||
current_dtzi.DaylightDate.wDay != 5 || current_dtzi.DaylightDate.wHour != 2 || current_dtzi.DaylightDate.wMinute != 0 ||
current_dtzi.DaylightDate.wSecond != 0 || current_dtzi.DaylightDate.wMilliseconds != 0)
{
return false;
@@ -583,8 +576,7 @@ namespace
sockaddr_in sender_addr{};
int sender_length = sizeof(sender_addr);
const auto len =
recvfrom(receiver, buffer, sizeof(buffer), 0, reinterpret_cast<sockaddr*>(&sender_addr), &sender_length);
const auto len = recvfrom(receiver, buffer, sizeof(buffer), 0, reinterpret_cast<sockaddr*>(&sender_addr), &sender_length);
if (len != send_data.size())
{
@@ -664,11 +656,108 @@ namespace
return res;
}
INT32 test_guard_page_seh_filter(LPVOID address, DWORD code, struct _EXCEPTION_POINTERS* ep)
{
// We are only looking for guard page exceptions.
if (code != STATUS_GUARD_PAGE_VIOLATION)
{
return EXCEPTION_CONTINUE_SEARCH;
}
// The number of defined elements in the ExceptionInformation array for
// a guard page violation should be 2.
if (ep->ExceptionRecord->NumberParameters != 2)
{
return EXCEPTION_CONTINUE_SEARCH;
}
// The ExceptionInformation array specifies additional arguments that
// describe the exception.
auto* exception_information = ep->ExceptionRecord->ExceptionInformation;
// If this value is zero, the thread attempted to read the inaccessible
// data. If this value is 1, the thread attempted to write to an
// inaccessible address.
if (exception_information[0] != 1)
{
return EXCEPTION_CONTINUE_SEARCH;
}
// The second array element specifies the virtual address of the
// inaccessible data.
if (exception_information[1] != (ULONG_PTR)address)
{
return EXCEPTION_CONTINUE_SEARCH;
}
return EXCEPTION_EXECUTE_HANDLER;
}
bool test_guard_page_exception()
{
SYSTEM_INFO sys_info;
GetSystemInfo(&sys_info);
// Allocate a guarded memory region with the length of the system page
// size.
auto* addr = static_cast<LPBYTE>(VirtualAlloc(nullptr, sys_info.dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD));
if (addr == nullptr)
{
puts("Failed to allocate guard page");
return false;
}
bool success = false;
// We want to access some arbitrary offset into the guarded page, to
// ensure that ExceptionInformation correctly contains the virtual
// address of the inaccessible data, not the base address of the region.
constexpr size_t offset = 10;
// Trigger a guard page violation
__try
{
addr[offset] = 255;
}
// If the filter function returns EXCEPTION_CONTINUE_SEARCH, the
// exception contains all of the correct information.
__except (test_guard_page_seh_filter(addr + offset, GetExceptionCode(), GetExceptionInformation()))
{
success = true;
}
// The page guard should be lifted, so no exception should be raised.
__try
{
// The previous write should not have went through, this is probably
// superflous.
if (addr[offset] == 255)
{
success = false;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
puts("Failed to read from page after guard exception!");
success = false;
}
// Free the allocated memory
if (!VirtualFree(addr, 0, MEM_RELEASE))
{
puts("Failed to free allocated region");
success = false;
}
return success;
}
bool test_native_exceptions()
{
return test_access_violation_exception() //
&& test_illegal_instruction_exception() //
&& test_unhandled_exception();
&& test_unhandled_exception() //
&& test_guard_page_exception();
}
#endif
@@ -714,6 +803,11 @@ namespace
bool test_apis()
{
if (VirtualProtect(nullptr, 0, 0, nullptr))
{
return false;
}
wchar_t buffer[0x100];
DWORD size = sizeof(buffer) / 2;
return GetComputerNameExW(ComputerNameNetBIOS, buffer, &size);