00072 :
00073
00074 This function provides
the capability to determine
the state,
00075 protection, and
type of a region of pages within
the virtual address
00076 space of
the subject process.
00077
00078 The state of
the first page within
the region
is determined and then
00079 subsequent entries in
the process address map are scanned from
the
00080 base address upward until either
the entire range of pages has been
00081 scanned or until a page with a nonmatching set of attributes
is
00082 encountered. The region attributes,
the length of
the region of pages
00083 with
matching attributes, and an appropriate status value are
00084 returned.
00085
00086 If
the entire region of pages does not have a
matching set of
00087 attributes, then
the returned length parameter value can be used to
00088 calculate
the address and length of
the region of pages that was not
00089 scanned.
00090
00091 Arguments:
00092
00093
00094 ProcessHandle - An open handle to a process object.
00095
00096 BaseAddress - The base address of
the region of pages to be
00097 queried. This value
is rounded down to
the next host-page-
00098 address boundary.
00099
00100 MemoryInformationClass - The memory information
class about which
00101 to retrieve information.
00102
00103 MemoryInformation -
A pointer to a buffer that receives
the
00104 specified information. The
format and content of
the buffer
00105 depend on
the specified information class.
00106
00107
00108 MemoryBasicInformation - Data
type is PMEMORY_BASIC_INFORMATION.
00109
00110 MEMORY_BASIC_INFORMATION Structure
00111
00112
00113 ULONG RegionSize - The size of
the region in bytes
00114 beginning at
the base address in which all pages have
00115 identical attributes.
00116
00117 ULONG State - The state of
the pages within
the region.
00118
00119 State Values State Values
00120
00121 MEM_COMMIT - The state of
the pages within
the region
00122
is committed.
00123
00124 MEM_FREE - The state of
the pages within
the region
00125
is free.
00126
00127 MEM_RESERVE - The state of
the pages within
the
00128 region
is reserved.
00129
00130 ULONG Protect - The protection of
the pages within
the
00131 region.
00132
00133
00134 Protect Values Protect Values
00135
00136 PAGE_NOACCESS - No access to
the region of pages
is
00137 allowed. An attempt to read, write, or execute
00138 within
the region results in an access violation
00139 (i.e., a GP fault).
00140
00141 PAGE_EXECUTE - Execute access to
the region of pages
00142
is allowed. An attempt to read or write within
00143
the region results in an access violation.
00144
00145 PAGE_READONLY - Read-
only and execute access to
the
00146 region of pages
is allowed. An attempt to write
00147 within
the region results in an access violation.
00148
00149 PAGE_READWRITE - Read, write, and execute access to
00150
the region of pages
is allowed. If write access
00151 to
the underlying section
is allowed, then a
00152 single copy of
the pages are shared. Otherwise,
00153
the pages are shared read-
only/copy-on-write.
00154
00155 PAGE_GUARD - Read, write, and execute access to
the
00156 region of pages
is allowed; however, access to
00157
the region causes a
"guard region entered"
00158 condition to be raised in
the subject process.
00159
00160 PAGE_NOCACHE - Disable
the placement of committed
00161 pages into
the data cache.
00162
00163 ULONG Type - The
type of pages within
the region.
00164
00165
00166 Type Values
00167
00168 MEM_PRIVATE - The pages within
the region are
00169
private.
00170
00171 MEM_MAPPED - The pages within
the region are mapped
00172 into
the view of a section.
00173
00174 MEM_IMAGE - The pages within
the region are mapped
00175 into
the view of an image section.
00176
00177 MemoryInformationLength - Specifies
the length in bytes of
00178
the memory information buffer.
00179
00180 ReturnLength - An optional pointer which,
if specified,
00181 receives
the number of bytes placed in
the process
00182 information buffer.
00183
00184
00185 Return Value:
00186
00187 Returns
the status
00188
00189 TBS
00190
00191
00192 Environment:
00193
00194 Kernel mode.
00195
00196 --*/
00197
00198 {
00199
KPROCESSOR_MODE PreviousMode;
00200
PEPROCESS TargetProcess;
00201
NTSTATUS Status;
00202
PMMVAD Vad;
00203 BOOLEAN PteIsZero;
00204 PVOID Va;
00205 BOOLEAN Found;
00206 SIZE_T TheRegionSize;
00207 ULONG NewProtect;
00208 ULONG NewState;
00209 PVOID FilePointer;
00210 ULONG_PTR BaseVpn;
00211 MEMORY_BASIC_INFORMATION Info;
00212 LOGICAL Attached;
00213
00214 Found =
FALSE;
00215 PteIsZero =
FALSE;
00216
00217
00218
00219
00220
00221
00222
00223
00224
switch (MemoryInformationClass) {
00225
case MemoryBasicInformation:
00226
if (MemoryInformationLength <
sizeof(MEMORY_BASIC_INFORMATION)) {
00227
return STATUS_INFO_LENGTH_MISMATCH;
00228 }
00229
break;
00230
00231
case MemoryWorkingSetInformation:
00232
if (MemoryInformationLength <
sizeof(ULONG)) {
00233
return STATUS_INFO_LENGTH_MISMATCH;
00234 }
00235
break;
00236
00237
case MemoryMappedFilenameInformation:
00238 FilePointer =
NULL;
00239
break;
00240
default:
00241
return STATUS_INVALID_INFO_CLASS;
00242 }
00243
00244 PreviousMode = KeGetPreviousMode();
00245
00246
if (PreviousMode !=
KernelMode) {
00247
00248
00249
00250
00251
00252
try {
00253
00254
ProbeForWrite(MemoryInformation,
00255 MemoryInformationLength,
00256
sizeof(ULONG_PTR));
00257
00258
if (ARGUMENT_PRESENT(ReturnLength)) {
00259
ProbeForWriteUlong(ReturnLength);
00260 }
00261
00262 } except (EXCEPTION_EXECUTE_HANDLER) {
00263
00264
00265
00266
00267
00268
00269
00270
return GetExceptionCode();
00271 }
00272 }
00273
if (BaseAddress > MM_HIGHEST_USER_ADDRESS) {
00274
return STATUS_INVALID_PARAMETER;
00275 }
00276
00277
if ((BaseAddress >=
MM_HIGHEST_VAD_ADDRESS)
00278
#if defined(MM_SHARED_USER_DATA_VA)
00279
||
00280 (
PAGE_ALIGN(BaseAddress) == (PVOID)MM_SHARED_USER_DATA_VA)
00281
#endif
00282
) {
00283
00284
00285
00286
00287
00288
if ( MemoryInformationClass == MemoryBasicInformation ) {
00289
00290
try {
00291 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase =
00292 (PCHAR)
MM_HIGHEST_VAD_ADDRESS + 1;
00293 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationProtect =
00294 PAGE_READONLY;
00295 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->BaseAddress =
00296
PAGE_ALIGN(BaseAddress);
00297 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize =
00298 ((PCHAR)MM_HIGHEST_USER_ADDRESS + 1) -
00299 (PCHAR)
PAGE_ALIGN(BaseAddress);
00300 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State = MEM_RESERVE;
00301 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect = PAGE_NOACCESS;
00302 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Type = MEM_PRIVATE;
00303
00304
if (ARGUMENT_PRESENT(ReturnLength)) {
00305 *ReturnLength =
sizeof(MEMORY_BASIC_INFORMATION);
00306 }
00307
00308
#if defined(MM_SHARED_USER_DATA_VA)
00309
if (
PAGE_ALIGN(BaseAddress) == (PVOID)MM_SHARED_USER_DATA_VA) {
00310
00311
00312
00313
00314
00315
00316 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase =
00317 (PVOID)MM_SHARED_USER_DATA_VA;
00318 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect =
00319 PAGE_READONLY;
00320 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize =
00321
PAGE_SIZE;
00322 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State =
00323 MEM_COMMIT;
00324 }
00325
#endif
00326
00327 } except (EXCEPTION_EXECUTE_HANDLER) {
00328
00329
00330
00331
00332 }
00333
00334
return STATUS_SUCCESS;
00335 }
else {
00336
return STATUS_INVALID_ADDRESS;
00337 }
00338 }
00339
00340
if ( ProcessHandle == NtCurrentProcess() ) {
00341 TargetProcess =
PsGetCurrentProcess();
00342 }
else {
00343
Status =
ObReferenceObjectByHandle ( ProcessHandle,
00344 PROCESS_QUERY_INFORMATION,
00345 PsProcessType,
00346 PreviousMode,
00347 (PVOID *)&TargetProcess,
00348 NULL );
00349
00350
if (!
NT_SUCCESS(Status)) {
00351
return Status;
00352 }
00353 }
00354
00355
if (MemoryInformationClass == MemoryWorkingSetInformation) {
00356
00357
MmLockPagableSectionByHandle(ExPageLockHandle);
00358
00359
Status =
MiGetWorkingSetInfo (MemoryInformation,
00360 MemoryInformationLength,
00361 TargetProcess);
00362
MmUnlockPagableImageSection(ExPageLockHandle);
00363
00364
if ( ProcessHandle != NtCurrentProcess() ) {
00365
ObDereferenceObject (TargetProcess);
00366 }
00367
try {
00368
00369
if (ARGUMENT_PRESENT(ReturnLength)) {
00370 *ReturnLength = ((((PMEMORY_WORKING_SET_INFORMATION)
00371 MemoryInformation)->NumberOfEntries - 1) *
00372
sizeof(ULONG)) +
00373
sizeof(MEMORY_WORKING_SET_INFORMATION);
00374 }
00375
00376 } except (EXCEPTION_EXECUTE_HANDLER) {
00377 }
00378
00379
return STATUS_SUCCESS;
00380 }
00381
00382
00383
00384
00385
00386
00387
if ( ProcessHandle != NtCurrentProcess() ) {
00388
KeAttachProcess (&TargetProcess->
Pcb);
00389 Attached =
TRUE;
00390 }
00391
else {
00392 Attached =
FALSE;
00393 }
00394
00395
00396
00397
00398
00399
LOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00400
00401
00402
00403
00404
00405
if (TargetProcess->
AddressSpaceDeleted != 0) {
00406
UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00407
if (Attached ==
TRUE) {
00408
KeDetachProcess();
00409
ObDereferenceObject (TargetProcess);
00410 }
00411
return STATUS_PROCESS_IS_TERMINATING;
00412 }
00413
00414
00415
00416
00417
00418
00419 Vad = TargetProcess->
VadRoot;
00420 BaseVpn =
MI_VA_TO_VPN (BaseAddress);
00421
00422
for (;;) {
00423
00424
if (Vad == (
PMMVAD)
NULL) {
00425
break;
00426 }
00427
00428
if ((BaseVpn >= Vad->
StartingVpn) &&
00429 (BaseVpn <= Vad->
EndingVpn)) {
00430 Found =
TRUE;
00431
break;
00432 }
00433
00434
if (BaseVpn < Vad->
StartingVpn) {
00435
if (Vad->
LeftChild == (
PMMVAD)
NULL) {
00436
break;
00437 }
00438 Vad = Vad->
LeftChild;
00439
00440 }
else {
00441
if (BaseVpn < Vad->
EndingVpn) {
00442
break;
00443 }
00444
if (Vad->
RightChild == (
PMMVAD)
NULL) {
00445
break;
00446 }
00447 Vad = Vad->
RightChild;
00448 }
00449 }
00450
00451
if (!Found) {
00452
00453
00454
00455
00456
00457
00458
00459
if (Vad ==
NULL) {
00460 TheRegionSize = ((PCHAR)
MM_HIGHEST_VAD_ADDRESS + 1) -
00461 (PCHAR)
PAGE_ALIGN(BaseAddress);
00462 }
else {
00463
if (Vad->
StartingVpn < BaseVpn) {
00464
00465
00466
00467
00468
00469
00470 Vad =
MiGetNextVad (Vad);
00471
if (Vad ==
NULL) {
00472 TheRegionSize = ((PCHAR)
MM_HIGHEST_VAD_ADDRESS + 1) -
00473 (PCHAR)
PAGE_ALIGN(BaseAddress);
00474 }
else {
00475 TheRegionSize = (PCHAR)
MI_VPN_TO_VA (Vad->
StartingVpn) -
00476 (PCHAR)
PAGE_ALIGN(BaseAddress);
00477 }
00478 }
else {
00479 TheRegionSize = (PCHAR)
MI_VPN_TO_VA (Vad->
StartingVpn) -
00480 (PCHAR)
PAGE_ALIGN(BaseAddress);
00481 }
00482 }
00483
00484
UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00485
00486
if (Attached ==
TRUE) {
00487
KeDetachProcess();
00488
ObDereferenceObject (TargetProcess);
00489 }
00490
00491
00492
00493
00494
00495
00496
if ( MemoryInformationClass == MemoryBasicInformation ) {
00497
try {
00498
00499 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase =
00500
NULL;
00501 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationProtect =
00502 0;
00503 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->BaseAddress =
00504
PAGE_ALIGN(BaseAddress);
00505 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize =
00506 TheRegionSize;
00507 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State = MEM_FREE;
00508 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect = PAGE_NOACCESS;
00509 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Type = 0;
00510
00511
if (ARGUMENT_PRESENT(ReturnLength)) {
00512 *ReturnLength =
sizeof(MEMORY_BASIC_INFORMATION);
00513 }
00514
00515 } except (EXCEPTION_EXECUTE_HANDLER) {
00516
00517
00518
00519
00520 }
00521
00522
return STATUS_SUCCESS;
00523 }
00524
return STATUS_INVALID_ADDRESS;
00525 }
00526
00527
00528
00529
00530
00531 Va =
PAGE_ALIGN(BaseAddress);
00532 Info.BaseAddress = Va;
00533
00534
00535
00536
00537
00538
if (Vad->
u.VadFlags.PrivateMemory) {
00539 Info.Type = MEM_PRIVATE;
00540 }
else if (Vad->
u.VadFlags.ImageMap == 0) {
00541 Info.Type = MEM_MAPPED;
00542
00543
if ( MemoryInformationClass == MemoryMappedFilenameInformation ) {
00544
if (Vad->
ControlArea) {
00545 FilePointer = Vad->
ControlArea->
FilePointer;
00546 }
00547
if ( !FilePointer ) {
00548 FilePointer = (PVOID)1;
00549 }
else {
00550
ObReferenceObject(FilePointer);
00551 }
00552 }
00553
00554 }
else {
00555 Info.Type = MEM_IMAGE;
00556 }
00557
00558 Info.State =
MiQueryAddressState (Va, Vad, TargetProcess, &Info.Protect);
00559
00560 Va = (PVOID)((PCHAR)Va +
PAGE_SIZE);
00561
00562
while (
MI_VA_TO_VPN (Va) <= Vad->
EndingVpn) {
00563
00564 NewState =
MiQueryAddressState (Va,
00565 Vad,
00566 TargetProcess,
00567 &NewProtect);
00568
00569
if ((NewState != Info.State) || (NewProtect != Info.Protect)) {
00570
00571
00572
00573
00574
00575
00576
break;
00577 }
00578 Va = (PVOID)((PCHAR)Va +
PAGE_SIZE);
00579 }
00580
00581 Info.RegionSize = ((PCHAR)Va - (PCHAR)Info.BaseAddress);
00582 Info.AllocationBase =
MI_VPN_TO_VA (Vad->
StartingVpn);
00583 Info.AllocationProtect =
MI_CONVERT_FROM_PTE_PROTECTION (
00584 Vad->
u.VadFlags.Protection);
00585
00586
00587
00588
00589
00590
00591
#if !(defined(_MIALT4K_))
00592
00593
UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00594
00595
#else
00596
00597
UNLOCK_WS_UNSAFE (TargetProcess);
00598
00599
if (TargetProcess->
Wow64Process !=
NULL) {
00600
00601 Info.BaseAddress =
PAGE_4K_ALIGN(BaseAddress);
00602
00603
MiQueryRegionFor4kPage(Info.BaseAddress,
00604
MI_VPN_TO_VA_ENDING(Vad->
EndingVpn),
00605 &Info.RegionSize,
00606 &Info.State,
00607 &Info.Protect,
00608 TargetProcess);
00609 }
00610
00611
UNLOCK_ADDRESS_SPACE (TargetProcess);
00612
00613
#endif
00614
00615
if (Attached ==
TRUE) {
00616
KeDetachProcess();
00617
ObDereferenceObject (TargetProcess);
00618 }
00619
00620
#if DBG
00621
if (MmDebug &
MM_DBG_SHOW_NT_CALLS) {
00622
if ( !MmWatchProcess ) {
00623
DbgPrint(
"queryvm base %lx allocbase %lx protect %lx size %lx\n",
00624 Info.BaseAddress, Info.AllocationBase, Info.AllocationProtect,
00625 Info.RegionSize);
00626
DbgPrint(
" state %lx protect %lx type %lx\n",
00627 Info.State, Info.Protect, Info.Type);
00628 }
00629 }
00630
#endif //DBG
00631
00632
if ( MemoryInformationClass == MemoryBasicInformation ) {
00633
try {
00634
00635 *(PMEMORY_BASIC_INFORMATION)MemoryInformation = Info;
00636
00637
if (ARGUMENT_PRESENT(ReturnLength)) {
00638 *ReturnLength =
sizeof(MEMORY_BASIC_INFORMATION);
00639 }
00640
00641 } except (EXCEPTION_EXECUTE_HANDLER) {
00642 }
00643
return STATUS_SUCCESS;
00644 }
00645
00646
00647
00648
00649
00650
if ( !FilePointer ) {
00651
return STATUS_INVALID_ADDRESS;
00652 }
else if ( FilePointer == (PVOID)1 ) {
00653
return STATUS_FILE_INVALID;
00654 }
00655
00656
00657
00658
00659
00660
00661
Status =
ObQueryNameString(
00662 FilePointer,
00663 MemoryInformation,
00664 MemoryInformationLength,
00665 ReturnLength
00666 );
00667
ObDereferenceObject(FilePointer);
00668
return Status;
00669 }