VIRTUALS

the virtual labs for the virtuals

0%

【游戏逆向】判断内存Page是否可读

摘要:
这个方法可以判断指定内存地址是否可读。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Memory access check
static bool IsMemoryReadable(uintptr_t base)
{
size_t length = sizeof(uintptr_t);
constexpr size_t read_access
= (PAGE_READONLY
| PAGE_READWRITE
| PAGE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_WRITECOPY);
//structure to pass to virtual query which will be populated with the page's information
MEMORY_BASIC_INFORMATION mbi = { 0 };

//virtual query returns information on a page
//if you don't know what a page is , it's basically a contiguous block of memory
//query for information starting at base
if (VirtualQuery(reinterpret_cast<void*>(base), &mbi, sizeof(mbi)))
{
//check read protections. if the page has one of the listed access protections, we can successfully read from it
if (!(mbi.Protect & read_access))
return false;

//When a process COMMITS a region of virtual memory, the operating system guarantees that it can maintain all the data
//the process stores in the memory either in physical memory or on disk.
//so check for MEM_COMMIT because this means the page is able to store data
//if this is MEM_RESERVE OR MEM_FREE we don't want to attempt a read
if (!(mbi.State & MEM_COMMIT))
return false;

//make sure the page is not guarded and has access. attempts to read or access these kinds of pages will result in an access violation
if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS))
return false;

//get the start and end of the page
const auto start = reinterpret_cast<uintptr_t>(mbi.BaseAddress);
const auto end = static_cast<uintptr_t>(start + mbi.RegionSize);

//check if our memory is within the readable region.
return (base >= start) && ((base + length) <= end);
}
return false;
}