1
/**//******************************************************************************
2
Module: VMQuery.cpp
3
Notices: Copyright (c) 2000 Jeffrey Richter
4
******************************************************************************/
5
6
7
#include "..\CmnHdr.h" /**//* See Appendix A. */
8
#include <windowsx.h>
9
#include "VMQuery.h"
10
11
12
/**////////////////////////////////////////////////////////////////////////////////
13
14
15
// Helper structure
16
typedef struct
{
17
SIZE_T RgnSize; //段大小
18
//段类型
19
DWORD dwRgnStorage; // MEM_*: Free, Image, Mapped, Private
20
//该段内的块的数量
21
DWORD dwRgnBlocks;
22
DWORD dwRgnGuardBlks; // If > 0, region contains thread stack
23
//是否是线程栈
24
BOOL fRgnIsAStack; // TRUE if region contains thread stack
25
} VMQUERY_HELP;
26
27
28
// This global, static variable holds the allocation granularity value for
29
// this CPU platform. Initialized the first time VMQuery is called.
30
static DWORD gs_dwAllocGran = 0;
31
32
33
/**////////////////////////////////////////////////////////////////////////////////
34
35
36
// Iterates through a region's blocks and returns findings in VMQUERY_HELP
37
static BOOL VMQueryHelp(HANDLE hProcess, LPCVOID pvAddress,
38
VMQUERY_HELP *pVMQHelp)
{
39
40
// Each element contains a page protection
41
// (i.e.: 0=reserved, PAGE_NOACCESS, PAGE_READWRITE, etc.)
42
DWORD dwProtectBlock[4] =
{ 0 };
43
//将*pVMQHelp指向的结构体的内存置0
44
ZeroMemory(pVMQHelp, sizeof(*pVMQHelp));
45
46
// Get address of region containing passed memory address.
47
//通过指定的内存地址获得段的地址
48
MEMORY_BASIC_INFORMATION mbi;
49
//没有填充mbi则失败
这是一种很另类的判断方法?
50
BOOL fOk = (VirtualQueryEx(hProcess, pvAddress, &mbi, sizeof(mbi))
51
== sizeof(mbi));
52
53
if (!fOk)
54
return(fOk); // Bad memory address, return failure
55
56
// Walk starting at the region's base address (which never changes)
57
//存储段的基地址这个地址不会改变
58
PVOID pvRgnBaseAddress = mbi.AllocationBase;
59
60
// Walk starting at the first block in the region (changes in the loop)
61
//存储段中第一个块的基地址,其实也就是这个段的基地址,不过当前块的基地址一会会变成别的块的基地址
62
PVOID pvAddressBlk = pvRgnBaseAddress;
63
64
// Save the memory type of the physical storage block.
65
//给dwRgnStorage赋值当前段的类型 重申一下类型的分配MEM_IMAGE、MEM_MAPPED、MEM_PRIVATE只有这三种
66
pVMQHelp->dwRgnStorage = mbi.Type;
67
68
for (;;)
{
69
// Get info about the current block.
70
// 获取当前块的信息
71
//调试了一阵程序纠正了自己理解上的一些偏差
72
//VirtualQueryEx返回的是页面类型以及保护属性完全相同的相邻的页面的集合的信息
73
//换句话说就是一个内存块的信息
74
//基于内存区域和内存块分析一下_MEMORY_BASIC_INFORMATION 的成员到底存的是什么!!
75
// typedef struct _MEMORY_BASIC_INFORMATION
76
// {
77
// PVOID BaseAddress;//这是内存块的基地址
78
// PVOID AllocationBase;//这是内存区域的基地址,也就是VirtualAlloc的第一个参数的值
79
// DWORD AllocationProtect;//区域的保护属性
80
// SIZE_T RegionSize;//这个是内存块的大小
81
// DWORD State;//内存块的状态
82
// DWORD Protect;//内存块的保护属性
83
// DWORD Type;//内存块的类型这个也可以说是内存区域的类型两者是一样的(在值上和定义上可以推导)。
84
// } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
85
//VirtualAlloc这个函数是标准是内存区域不是内存块
86
//它里面的保护属性是准许段内部的页面设置的保护属性,区域中的所有页保护的属性是它的子集
87
//LPVOID VirtualAlloc(
88
// LPVOID lpAddress,
89
// SIZE_T dwSize,
90
// DWORD flAllocationType,
91
// DWORD flProtect
92
//);
93
//好了知道了这些在通过对VirtualAlloc参数的比较我可以肯定页面类型相同的地址相邻的页面构成了一个内存区域


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

44

45

46

47

48

49


50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68



69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93
