mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 03:13:55 +00:00
Merge remote-tracking branch 'origin/main' into unhandled-exceptions
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user