| 404 | |
| 405 | _IRQL_requires_max_(APC_LEVEL) |
| 406 | static NTSTATUS OperateProcessMemory( |
| 407 | PEPROCESS Process, |
| 408 | PVOID BaseAddress, |
| 409 | PVOID Buffer, |
| 410 | ULONG Size, |
| 411 | MEMORY_OPERATION_TYPE Operation |
| 412 | ) { |
| 413 | if (!Process) return STATUS_INVALID_PARAMETER_1; |
| 414 | if (!BaseAddress) return STATUS_INVALID_PARAMETER_2; |
| 415 | if (!Buffer) return STATUS_INVALID_PARAMETER_3; |
| 416 | if (!Size) return STATUS_INVALID_PARAMETER_4; |
| 417 | |
| 418 | if (AddressRange::IsKernelAddress(BaseAddress)) { |
| 419 | if (!VirtualMemory::IsMemoryRangePresent(BaseAddress, Size)) |
| 420 | return STATUS_MEMORY_NOT_ALLOCATED; |
| 421 | } |
| 422 | |
| 423 | if (AddressRange::IsKernelAddress(Buffer)) { |
| 424 | if (!VirtualMemory::IsMemoryRangePresent(Buffer, Size)) |
| 425 | return STATUS_MEMORY_NOT_ALLOCATED; |
| 426 | } |
| 427 | |
| 428 | // Attempt to lock process memory from freeing: |
| 429 | HANDLE hProcessSecure = NULL; |
| 430 | if (AddressRange::IsUserAddress(BaseAddress)) { |
| 431 | if (!VirtualMemory::SecureProcessMemory(Process, BaseAddress, Size, PAGE_READONLY, &hProcessSecure)) |
| 432 | return STATUS_NOT_LOCKED; |
| 433 | } |
| 434 | |
| 435 | // Attempt to lock buffer memory if it is usermode memory: |
| 436 | HANDLE hBufferSecure = NULL; |
| 437 | if (AddressRange::IsUserAddress(Buffer)) { |
| 438 | if (!VirtualMemory::SecureMemory(Buffer, Size, PAGE_READWRITE, &hBufferSecure)) { |
| 439 | if (hProcessSecure) VirtualMemory::UnsecureProcessMemory(Process, hProcessSecure); |
| 440 | return STATUS_NOT_LOCKED; |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | // Attempt to map process memory: |
| 445 | Mdl::MAPPING_INFO ProcessMapping = {}; |
| 446 | NTSTATUS Status = Mdl::MapMemory( |
| 447 | &ProcessMapping, |
| 448 | Process, |
| 449 | NULL, |
| 450 | BaseAddress, |
| 451 | Size |
| 452 | ); |
| 453 | |
| 454 | if (!NT_SUCCESS(Status)) { |
| 455 | if (hProcessSecure) VirtualMemory::UnsecureProcessMemory(Process, hProcessSecure); |
| 456 | if (hBufferSecure) VirtualMemory::UnsecureMemory(hBufferSecure); |
| 457 | return STATUS_NOT_MAPPED_VIEW; |
| 458 | } |
| 459 | |
| 460 | // Attempt to map buffer memory: |
| 461 | Mdl::MAPPING_INFO BufferMapping = {}; |
| 462 | Status = Mdl::MapMemory( |
| 463 | &BufferMapping, |
no test coverage detected