mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Add test for guard page in test-sample, formatting fix
This commit is contained in:
@@ -721,6 +721,101 @@ namespace
|
||||
SleepEx(1, TRUE);
|
||||
return executions == 2;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
#define RUN_TEST(func, name) \
|
||||
@@ -761,6 +856,7 @@ int main(const int argc, const char* argv[])
|
||||
RUN_TEST(test_tls, "TLS")
|
||||
RUN_TEST(test_socket, "Socket")
|
||||
RUN_TEST(test_apc, "APC")
|
||||
RUN_TEST(test_guard_page, "Guard Page")
|
||||
|
||||
return valid ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,8 @@ struct nt_memory_permission
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr bool is_guarded() const {
|
||||
constexpr bool is_guarded() const
|
||||
{
|
||||
return (this->extended & memory_permission_ext::guard) == memory_permission_ext::guard;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user