Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

readwrt.c File Reference

#include "mi.h"

Go to the source code of this file.

Defines

#define MAX_LOCK_SIZE   ((ULONG)(14 * PAGE_SIZE))
#define MAX_MOVE_SIZE   (LONG)0x10000
#define MINIMUM_ALLOCATION   (LONG)128
#define POOL_MOVE_THRESHOLD   511
#define COPY_STACK_SIZE   64

Functions

NTSTATUS MiValidateUserTransfer (IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG BufferSize)
ULONG MiGetExceptionInfo (IN PEXCEPTION_POINTERS ExceptionPointers, IN PULONG_PTR BadVa1, IN PULONG_PTR BadVa2)
NTSTATUS MiDoMappedCopy (IN PEPROCESS FromProcess, IN PVOID FromAddress, IN PEPROCESS ToProcess, OUT PVOID ToAddress, IN ULONG BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PULONG NumberOfBytesRead)
NTSTATUS MiDoPoolCopy (IN PEPROCESS FromProcess, IN PVOID FromAddress, IN PEPROCESS ToProcess, OUT PVOID ToAddress, IN ULONG BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PULONG NumberOfBytesRead)
NTSTATUS NtReadVirtualMemory (IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG NumberOfBytesRead OPTIONAL)
NTSTATUS NtWriteVirtualMemory (IN HANDLE ProcessHandle, OUT PVOID BaseAddress, IN PVOID Buffer, IN ULONG BufferSize, OUT PULONG NumberOfBytesWritten OPTIONAL)
NTSTATUS MmCopyVirtualMemory (IN PEPROCESS FromProcess, IN PVOID FromAddress, IN PEPROCESS ToProcess, OUT PVOID ToAddress, IN ULONG BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PULONG NumberOfBytesCopied)


Define Documentation

#define COPY_STACK_SIZE   64
 

Definition at line 99 of file readwrt.c.

#define MAX_LOCK_SIZE   ((ULONG)(14 * PAGE_SIZE))
 

Definition at line 30 of file readwrt.c.

Referenced by MiDoMappedCopy().

#define MAX_MOVE_SIZE   (LONG)0x10000
 

Definition at line 36 of file readwrt.c.

Referenced by MiDoPoolCopy().

#define MINIMUM_ALLOCATION   (LONG)128
 

Definition at line 42 of file readwrt.c.

#define POOL_MOVE_THRESHOLD   511
 

Definition at line 48 of file readwrt.c.

Referenced by MmCopyVirtualMemory().


Function Documentation

NTSTATUS MiDoMappedCopy IN PEPROCESS  FromProcess,
IN PVOID  FromAddress,
IN PEPROCESS  ToProcess,
OUT PVOID  ToAddress,
IN ULONG  BufferSize,
IN KPROCESSOR_MODE  PreviousMode,
OUT PULONG  NumberOfBytesRead
 

Definition at line 529 of file readwrt.c.

References BufferSize, CHAR, ExRaiseStatus(), FALSE, HighPagePriority, IoReadAccess, KeAttachProcess(), KeDetachProcess(), KernelMode, MAX_LOCK_SIZE, MiGetExceptionInfo(), MmCached, MmInitializeMdl, MmMapLockedPagesSpecifyCache(), MmProbeAndLockPages(), MmUnlockPages(), MmUnmapLockedPages(), NULL, PAGE_SHIFT, PAGED_CODE, ProbeForRead, ProbeForWrite(), PsGetCurrentProcess, and TRUE.

Referenced by MmCopyVirtualMemory().

00541 : 00542 00543 This function copies the specified address range from the specified 00544 process into the specified address range of the current process. 00545 00546 Arguments: 00547 00548 FromProcess - Supplies an open handle to a process object. 00549 00550 FromAddress - Supplies the base address in the specified process 00551 to be read. 00552 00553 ToProcess - Supplies an open handle to a process object. 00554 00555 ToAddress - Supplies the address of a buffer which receives the 00556 contents from the specified process address space. 00557 00558 BufferSize - Supplies the requested number of bytes to read from 00559 the specified process. 00560 00561 PreviousMode - Supplies the previous processor mode. 00562 00563 NumberOfBytesRead - Receives the actual number of bytes 00564 transferred into the specified buffer. 00565 00566 Return Value: 00567 00568 TBS 00569 00570 --*/ 00571 00572 { 00573 00574 ULONG AmountToMove; 00575 ULONG_PTR BadVa1; 00576 ULONG_PTR BadVa2; 00577 PEPROCESS CurrentProcess; 00578 LOGICAL Moving; 00579 LOGICAL Probing; 00580 BOOLEAN LockedMdlPages; 00581 PVOID InVa; 00582 ULONG LeftToMove; 00583 PULONG MappedAddress; 00584 ULONG MaximumMoved; 00585 PMDL Mdl; 00586 PFN_NUMBER MdlHack[(sizeof(MDL)/sizeof(PFN_NUMBER)) + (MAX_LOCK_SIZE >> PAGE_SHIFT) + 1]; 00587 PVOID OutVa; 00588 LOGICAL MappingFailed; 00589 00590 PAGED_CODE(); 00591 00592 MappingFailed = FALSE; 00593 00594 // 00595 // Get the address of the current process object and initialize copy 00596 // parameters. 00597 // 00598 00599 CurrentProcess = PsGetCurrentProcess(); 00600 00601 InVa = FromAddress; 00602 OutVa = ToAddress; 00603 00604 MaximumMoved = MAX_LOCK_SIZE; 00605 if (BufferSize <= MAX_LOCK_SIZE) { 00606 MaximumMoved = BufferSize; 00607 } 00608 00609 Mdl = (PMDL)&MdlHack[0]; 00610 00611 // 00612 // Map the data into the system part of the address space, then copy it. 00613 // 00614 00615 LeftToMove = BufferSize; 00616 AmountToMove = MaximumMoved; 00617 while (LeftToMove > 0) { 00618 00619 if (LeftToMove < AmountToMove) { 00620 00621 // 00622 // Set to move the remaining bytes. 00623 // 00624 00625 AmountToMove = LeftToMove; 00626 } 00627 00628 KeDetachProcess(); 00629 KeAttachProcess (&FromProcess->Pcb); 00630 00631 // 00632 // We may be touching a user's memory which could be invalid, 00633 // declare an exception handler. 00634 // 00635 00636 try { 00637 00638 // 00639 // Probe to make sure that the specified buffer is accessible in 00640 // the target process. 00641 // 00642 00643 MappedAddress = NULL; 00644 LockedMdlPages = FALSE; 00645 00646 if ((InVa == FromAddress) && (PreviousMode != KernelMode)){ 00647 Probing = TRUE; 00648 ProbeForRead (FromAddress, BufferSize, sizeof(CHAR)); 00649 } 00650 Probing = FALSE; 00651 00652 // 00653 // Initialize MDL for request. 00654 // 00655 00656 MmInitializeMdl (Mdl, (PVOID)InVa, AmountToMove); 00657 00658 Moving = TRUE; 00659 MmProbeAndLockPages (Mdl, PreviousMode, IoReadAccess); 00660 Moving = FALSE; 00661 00662 LockedMdlPages = TRUE; 00663 00664 MappedAddress = MmMapLockedPagesSpecifyCache (Mdl, 00665 KernelMode, 00666 MmCached, 00667 NULL, 00668 FALSE, 00669 HighPagePriority); 00670 00671 if (MappedAddress == NULL) { 00672 MappingFailed = TRUE; 00673 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); 00674 } 00675 00676 // 00677 // Deattach from the FromProcess and attach to the ToProcess. 00678 // 00679 00680 KeDetachProcess(); 00681 KeAttachProcess (&ToProcess->Pcb); 00682 00683 // 00684 // Now operating in the context of the ToProcess. 00685 // 00686 if ((InVa == FromAddress) && (PreviousMode != KernelMode)){ 00687 Probing = TRUE; 00688 ProbeForWrite (ToAddress, BufferSize, sizeof(CHAR)); 00689 } 00690 Probing = FALSE; 00691 00692 RtlCopyMemory (OutVa, MappedAddress, AmountToMove); 00693 00694 } except (MiGetExceptionInfo (GetExceptionInformation(), 00695 &BadVa1, 00696 &BadVa2)) { 00697 00698 00699 // 00700 // If an exception occurs during the move operation or probe, 00701 // return the exception code as the status value. 00702 // 00703 00704 KeDetachProcess(); 00705 if (MappedAddress != NULL) { 00706 MmUnmapLockedPages (MappedAddress, Mdl); 00707 } 00708 if (LockedMdlPages == TRUE) { 00709 MmUnlockPages (Mdl); 00710 } 00711 00712 if (GetExceptionCode() == STATUS_WORKING_SET_QUOTA) { 00713 return STATUS_WORKING_SET_QUOTA; 00714 } 00715 00716 if ((Probing == TRUE) || (MappingFailed == TRUE)) { 00717 return GetExceptionCode(); 00718 00719 } else { 00720 00721 // 00722 // The failure occurred during the move operation, determine 00723 // which move failed, and calculate the number of bytes 00724 // actually moved. 00725 // 00726 00727 if (Moving == TRUE) { 00728 if (BadVa1 != 0xFFFFFFFF) { 00729 *NumberOfBytesRead = (ULONG)((ULONG_PTR)BadVa2 - (ULONG_PTR)FromAddress); 00730 } 00731 00732 } else { 00733 *NumberOfBytesRead = BufferSize - LeftToMove; 00734 } 00735 } 00736 00737 return STATUS_PARTIAL_COPY; 00738 } 00739 MmUnmapLockedPages (MappedAddress, Mdl); 00740 MmUnlockPages (Mdl); 00741 00742 LeftToMove -= AmountToMove; 00743 InVa = (PVOID)((ULONG_PTR)InVa + AmountToMove); 00744 OutVa = (PVOID)((ULONG_PTR)OutVa + AmountToMove); 00745 } 00746 00747 KeDetachProcess(); 00748 00749 // 00750 // Set number of bytes moved. 00751 // 00752 00753 *NumberOfBytesRead = BufferSize; 00754 return STATUS_SUCCESS; 00755 }

NTSTATUS MiDoPoolCopy IN PEPROCESS  FromProcess,
IN PVOID  FromAddress,
IN PEPROCESS  ToProcess,
OUT PVOID  ToAddress,
IN ULONG  BufferSize,
IN KPROCESSOR_MODE  PreviousMode,
OUT PULONG  NumberOfBytesRead
 

Definition at line 758 of file readwrt.c.

References ASSERT, BufferSize, CHAR, COPY_STACK_SIZE, ExAllocatePoolWithTag, ExFreePool(), FALSE, KeAttachProcess(), KeDetachProcess(), KernelMode, MAX_MOVE_SIZE, MiGetExceptionInfo(), NonPagedPool, NULL, PAGED_CODE, ProbeForRead, ProbeForWrite(), PsGetCurrentProcess, and TRUE.

Referenced by MmCopyVirtualMemory().

00770 : 00771 00772 This function copies the specified address range from the specified 00773 process into the specified address range of the current process. 00774 00775 Arguments: 00776 00777 ProcessHandle - Supplies an open handle to a process object. 00778 00779 BaseAddress - Supplies the base address in the specified process 00780 to be read. 00781 00782 Buffer - Supplies the address of a buffer which receives the 00783 contents from the specified process address space. 00784 00785 BufferSize - Supplies the requested number of bytes to read from 00786 the specified process. 00787 00788 PreviousMode - Supplies the previous processor mode. 00789 00790 NumberOfBytesRead - Receives the actual number of bytes 00791 transferred into the specified buffer. 00792 00793 Return Value: 00794 00795 TBS 00796 00797 --*/ 00798 00799 { 00800 00801 ULONG AmountToMove; 00802 ULONG_PTR BadVa1; 00803 ULONG_PTR BadVa2; 00804 PEPROCESS CurrentProcess; 00805 LOGICAL Moving; 00806 LOGICAL Probing; 00807 PVOID InVa; 00808 ULONG LeftToMove; 00809 ULONG MaximumMoved; 00810 PVOID OutVa; 00811 PVOID PoolArea; 00812 LONGLONG StackArray[COPY_STACK_SIZE]; 00813 ULONG FreePool; 00814 00815 PAGED_CODE(); 00816 00817 ASSERT (BufferSize != 0); 00818 00819 // 00820 // Get the address of the current process object and initialize copy 00821 // parameters. 00822 // 00823 00824 CurrentProcess = PsGetCurrentProcess(); 00825 00826 InVa = FromAddress; 00827 OutVa = ToAddress; 00828 00829 // 00830 // Allocate non-paged memory to copy in and out of. 00831 // 00832 00833 MaximumMoved = MAX_MOVE_SIZE; 00834 if (BufferSize <= MAX_MOVE_SIZE) { 00835 MaximumMoved = BufferSize; 00836 } 00837 00838 FreePool = FALSE; 00839 if (BufferSize <= sizeof(StackArray)) { 00840 PoolArea = (PULONG)&StackArray[0]; 00841 } else { 00842 do { 00843 PoolArea = ExAllocatePoolWithTag (NonPagedPool, MaximumMoved, 'wRmM'); 00844 if (PoolArea != NULL) { 00845 FreePool = TRUE; 00846 break; 00847 } 00848 00849 MaximumMoved = MaximumMoved >> 1; 00850 if (MaximumMoved <= sizeof(StackArray)) { 00851 PoolArea = (PULONG)&StackArray[0]; 00852 break; 00853 } 00854 } while (TRUE); 00855 } 00856 00857 // 00858 // Copy the data into pool, then copy back into the ToProcess. 00859 // 00860 00861 LeftToMove = BufferSize; 00862 AmountToMove = MaximumMoved; 00863 while (LeftToMove > 0) { 00864 00865 if (LeftToMove < AmountToMove) { 00866 00867 // 00868 // Set to move the remaining bytes. 00869 // 00870 00871 AmountToMove = LeftToMove; 00872 } 00873 00874 KeDetachProcess(); 00875 KeAttachProcess (&FromProcess->Pcb); 00876 00877 // 00878 // We may be touching a user's memory which could be invalid, 00879 // declare an exception handler. 00880 // 00881 00882 try { 00883 00884 // 00885 // Probe to make sure that the specified buffer is accessible in 00886 // the target process. 00887 // 00888 00889 if ((InVa == FromAddress) && (PreviousMode != KernelMode)){ 00890 Probing = TRUE; 00891 ProbeForRead (FromAddress, BufferSize, sizeof(CHAR)); 00892 } 00893 00894 Probing = FALSE; 00895 00896 Moving = TRUE; 00897 00898 RtlCopyMemory (PoolArea, InVa, AmountToMove); 00899 00900 Moving = FALSE; 00901 00902 KeDetachProcess(); 00903 KeAttachProcess (&ToProcess->Pcb); 00904 00905 // 00906 // Now operating in the context of the ToProcess. 00907 // 00908 00909 if ((InVa == FromAddress) && (PreviousMode != KernelMode)){ 00910 Probing = TRUE; 00911 ProbeForWrite (ToAddress, BufferSize, sizeof(CHAR)); 00912 } 00913 Probing = FALSE; 00914 00915 RtlCopyMemory (OutVa, PoolArea, AmountToMove); 00916 00917 } except (MiGetExceptionInfo (GetExceptionInformation(), 00918 &BadVa1, 00919 &BadVa2)) { 00920 00921 // 00922 // If an exception occurs during the move operation or probe, 00923 // return the exception code as the status value. 00924 // 00925 00926 KeDetachProcess(); 00927 00928 if (FreePool) { 00929 ExFreePool (PoolArea); 00930 } 00931 if (Probing == TRUE) { 00932 return GetExceptionCode(); 00933 00934 } else { 00935 00936 // 00937 // The failure occurred during the move operation, determine 00938 // which move failed, and calculate the number of bytes 00939 // actually moved. 00940 // 00941 00942 if (Moving == TRUE) { 00943 00944 // 00945 // The failure occurred getting the data. 00946 // 00947 00948 if (BadVa1 != 0xFFFFFFFF) { 00949 *NumberOfBytesRead = (ULONG)((ULONG_PTR)(BadVa2 - (ULONG_PTR)FromAddress)); 00950 } 00951 00952 } else { 00953 00954 // 00955 // The failure occurred writing the data. 00956 // 00957 00958 *NumberOfBytesRead = BufferSize - LeftToMove; 00959 } 00960 } 00961 00962 return STATUS_PARTIAL_COPY; 00963 } 00964 00965 LeftToMove -= AmountToMove; 00966 InVa = (PVOID)((ULONG_PTR)InVa + AmountToMove); 00967 OutVa = (PVOID)((ULONG_PTR)OutVa + AmountToMove); 00968 } 00969 00970 if (FreePool) { 00971 ExFreePool (PoolArea); 00972 } 00973 KeDetachProcess(); 00974 00975 // 00976 // Set number of bytes moved. 00977 // 00978 00979 *NumberOfBytesRead = BufferSize; 00980 return STATUS_SUCCESS; 00981 }

ULONG MiGetExceptionInfo IN PEXCEPTION_POINTERS  ExceptionPointers,
IN PULONG_PTR  BadVa1,
IN PULONG_PTR  BadVa2
 

Definition at line 464 of file readwrt.c.

References EXCEPTION_EXECUTE_HANDLER, and PAGED_CODE.

Referenced by MiDoMappedCopy(), and MiDoPoolCopy().

00472 : 00473 00474 This routine examines a exception record and extracts the virtual 00475 address of an access violation, guard page violation, or in-page error. 00476 00477 Arguments: 00478 00479 ExceptionPointers - Supplies a pointer to the exception record. 00480 00481 BadVa - Receives the virtual address which caused the access violation. 00482 00483 Return Value: 00484 00485 EXECUTE_EXCEPTION_HANDLER 00486 00487 --*/ 00488 00489 { 00490 PEXCEPTION_RECORD ExceptionRecord; 00491 00492 PAGED_CODE(); 00493 00494 // 00495 // If the exception code is an access violation, guard page violation, 00496 // or an in-page read error, then return the faulting address. Otherwise. 00497 // return a special address value. 00498 // 00499 00500 *BadVa2 = 0; 00501 ExceptionRecord = ExceptionPointers->ExceptionRecord; 00502 if ((ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) || 00503 (ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) || 00504 (ExceptionRecord->ExceptionCode == STATUS_IN_PAGE_ERROR)) { 00505 00506 // 00507 // The virtual address which caused the exception is the 2nd 00508 // parameter in the exception information array. 00509 // 00510 00511 *BadVa1 = ExceptionRecord->ExceptionInformation[1]; 00512 if (ExceptionRecord->NumberParameters == 3) { 00513 *BadVa2 = ExceptionRecord->ExceptionInformation[2]; 00514 } 00515 00516 } else { 00517 00518 // 00519 // Unexpected exception - set the number of bytes copied to zero. 00520 // 00521 00522 *BadVa2 = 0xFFFFFFFF; 00523 } 00524 00525 return EXCEPTION_EXECUTE_HANDLER; 00526 }

NTSTATUS MiValidateUserTransfer IN PVOID  BaseAddress,
IN PVOID  Buffer,
IN ULONG  BufferSize
 

Definition at line 985 of file readwrt.c.

References Buffer, BufferSize, and PAGED_CODE.

Referenced by NtReadVirtualMemory(), and NtWriteVirtualMemory().

00993 : 00994 00995 This function checks whether the parameter source and destination address 00996 ranges lie within the user virtual address space. This function does NOT 00997 guarantee that the addresses are in fact mapped or that faults will not 00998 occur - it just validates the address range. 00999 01000 Arguments: 01001 01002 BaseAddress - Supplies the base address within a process to be read. 01003 01004 Buffer - Supplies the address of a buffer which sends or receives the 01005 contents from the specified process address space. 01006 01007 BufferSize - Supplies the requested number of bytes to read or write from 01008 the specified process. 01009 01010 Return Value: 01011 01012 STATUS_SUCCESS if valid user ranges, error otherwise. 01013 01014 Environment: 01015 01016 None. 01017 01018 --*/ 01019 01020 { 01021 ULONG_PTR BaseAddress; 01022 ULONG_PTR Buffer; 01023 01024 BaseAddress = (ULONG_PTR)BaseAddressPointer; 01025 Buffer = (ULONG_PTR)BufferPointer; 01026 01027 PAGED_CODE(); 01028 01029 // 01030 // check that both the base address and the target buffer qualify 01031 // as valid user address ranges. Wrapping is not allowed. 01032 // 01033 if (BaseAddress + BufferSize < BaseAddress) { 01034 return STATUS_ACCESS_VIOLATION; 01035 } 01036 01037 if (((PVOID)BaseAddress > MM_HIGHEST_USER_ADDRESS) || 01038 ((PVOID)(BaseAddress + BufferSize) > MM_HIGHEST_USER_ADDRESS)) { 01039 01040 return STATUS_ACCESS_VIOLATION; 01041 } 01042 01043 if (Buffer + BufferSize < Buffer) { 01044 return STATUS_ACCESS_VIOLATION; 01045 } 01046 01047 if (((PVOID)Buffer > MM_HIGHEST_USER_ADDRESS) || 01048 ((PVOID)(Buffer + BufferSize) > MM_HIGHEST_USER_ADDRESS)) { 01049 01050 return STATUS_ACCESS_VIOLATION; 01051 } 01052 01053 return STATUS_SUCCESS; 01054 } }

NTSTATUS MmCopyVirtualMemory IN PEPROCESS  FromProcess,
IN PVOID  FromAddress,
IN PEPROCESS  ToProcess,
OUT PVOID  ToAddress,
IN ULONG  BufferSize,
IN KPROCESSOR_MODE  PreviousMode,
OUT PULONG  NumberOfBytesCopied
 

Definition at line 362 of file readwrt.c.

References _EPROCESS::AddressSpaceDeleted, ASSERT, BufferSize, FALSE, KeSetEvent(), MiDoMappedCopy(), MiDoPoolCopy(), MiLockSystemSpace, MiUnlockSystemSpace, NTSTATUS(), NULL, POOL_MOVE_THRESHOLD, PsGetCurrentProcess, Status, _EPROCESS::VmOperation, and _EPROCESS::VmOperationEvent.

Referenced by LpcpCopyRequestData(), NtReadVirtualMemory(), and NtWriteVirtualMemory().

00371 { 00372 NTSTATUS Status; 00373 KIRQL OldIrql; 00374 PEPROCESS ProcessToLock; 00375 00376 if (BufferSize == 0) { 00377 ASSERT (FALSE); // No one should call with a zero size. 00378 return STATUS_SUCCESS; 00379 } 00380 00381 ProcessToLock = FromProcess; 00382 if (FromProcess == PsGetCurrentProcess()) { 00383 ProcessToLock = ToProcess; 00384 } 00385 00386 // 00387 // Make sure the process still has an address space. 00388 // 00389 00390 MiLockSystemSpace(OldIrql); 00391 if (ProcessToLock->AddressSpaceDeleted != 0) { 00392 MiUnlockSystemSpace(OldIrql); 00393 return STATUS_PROCESS_IS_TERMINATING; 00394 } 00395 ProcessToLock->VmOperation += 1; 00396 MiUnlockSystemSpace(OldIrql); 00397 00398 00399 // 00400 // If the buffer size is greater than the pool move threshold, 00401 // then attempt to write the memory via direct mapping. 00402 // 00403 00404 if (BufferSize > POOL_MOVE_THRESHOLD) { 00405 Status = MiDoMappedCopy(FromProcess, 00406 FromAddress, 00407 ToProcess, 00408 ToAddress, 00409 BufferSize, 00410 PreviousMode, 00411 NumberOfBytesCopied); 00412 00413 // 00414 // If the completion status is not a working quota problem, 00415 // then finish the service. Otherwise, attempt to write the 00416 // memory through nonpaged pool. 00417 // 00418 00419 if (Status != STATUS_WORKING_SET_QUOTA) { 00420 goto CompleteService; 00421 } 00422 00423 *NumberOfBytesCopied = 0; 00424 } 00425 00426 // 00427 // There was not enough working set quota to write the memory via 00428 // direct mapping or the size of the write was below the pool move 00429 // threshold. Attempt to write the specified memory through nonpaged 00430 // pool. 00431 // 00432 00433 Status = MiDoPoolCopy(FromProcess, 00434 FromAddress, 00435 ToProcess, 00436 ToAddress, 00437 BufferSize, 00438 PreviousMode, 00439 NumberOfBytesCopied); 00440 00441 // 00442 // Dereference the target process. 00443 // 00444 00445 CompleteService: 00446 00447 // 00448 // Indicate that the vm operation is complete. 00449 // 00450 00451 MiLockSystemSpace(OldIrql); 00452 ProcessToLock->VmOperation -= 1; 00453 if ((ProcessToLock->VmOperation == 0) && 00454 (ProcessToLock->VmOperationEvent != NULL)) { 00455 KeSetEvent (ProcessToLock->VmOperationEvent, 0, FALSE); 00456 } 00457 MiUnlockSystemSpace(OldIrql); 00458 00459 return Status; 00460 }

NTSTATUS NtReadVirtualMemory IN HANDLE  ProcessHandle,
IN PVOID  BaseAddress,
OUT PVOID  Buffer,
IN ULONG  BufferSize,
OUT PULONG NumberOfBytesRead  OPTIONAL
 

Definition at line 102 of file readwrt.c.

References Buffer, BufferSize, EXCEPTION_EXECUTE_HANDLER, KernelMode, KPROCESSOR_MODE, MiValidateUserTransfer(), MmCopyVirtualMemory(), NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, ProbeForWriteUlong, PsGetCurrentProcess, PsProcessType, and Status.

Referenced by ConsoleClientConnectRoutine(), GetHardErrorText(), RtlCheckForOrphanedCriticalSections(), RtlDestroyQueryDebugBuffer(), RtlFreeUserThreadStack(), RtlQueryProcessDebugInformation(), and SrvWriteConsoleOutput().

00112 : 00113 00114 This function copies the specified address range from the specified 00115 process into the specified address range of the current process. 00116 00117 Arguments: 00118 00119 ProcessHandle - Supplies an open handle to a process object. 00120 00121 BaseAddress - Supplies the base address in the specified process 00122 to be read. 00123 00124 Buffer - Supplies the address of a buffer which receives the 00125 contents from the specified process address space. 00126 00127 BufferSize - Supplies the requested number of bytes to read from 00128 the specified process. 00129 00130 NumberOfBytesRead - Receives the actual number of bytes 00131 transferred into the specified buffer. 00132 00133 Return Value: 00134 00135 TBS 00136 00137 --*/ 00138 00139 { 00140 00141 ULONG BytesCopied; 00142 KPROCESSOR_MODE PreviousMode; 00143 PEPROCESS Process; 00144 NTSTATUS Status; 00145 00146 PAGED_CODE(); 00147 00148 // 00149 // Get the previous mode and probe output argument if necessary. 00150 // 00151 00152 PreviousMode = KeGetPreviousMode(); 00153 if (PreviousMode != KernelMode) { 00154 00155 Status = MiValidateUserTransfer(BaseAddress, Buffer, BufferSize); 00156 if (Status != STATUS_SUCCESS) { 00157 return Status; 00158 } 00159 00160 if (ARGUMENT_PRESENT(NumberOfBytesRead)) { 00161 try { 00162 ProbeForWriteUlong(NumberOfBytesRead); 00163 00164 } except(EXCEPTION_EXECUTE_HANDLER) { 00165 return GetExceptionCode(); 00166 } 00167 } 00168 } 00169 00170 // 00171 // If the buffer size is not zero, then attempt to read data from the 00172 // specified process address space into the current process address 00173 // space. 00174 // 00175 00176 BytesCopied = 0; 00177 Status = STATUS_SUCCESS; 00178 if (BufferSize != 0) { 00179 00180 // 00181 // Reference the target process. 00182 // 00183 00184 Status = ObReferenceObjectByHandle(ProcessHandle, 00185 PROCESS_VM_READ, 00186 PsProcessType, 00187 PreviousMode, 00188 (PVOID *)&Process, 00189 NULL); 00190 00191 // 00192 // If the process was successfully referenced, then attempt to 00193 // read the specified memory either by direct mapping or copying 00194 // through nonpaged pool. 00195 // 00196 00197 if (Status == STATUS_SUCCESS) { 00198 00199 Status = MmCopyVirtualMemory (Process, 00200 BaseAddress, 00201 PsGetCurrentProcess(), 00202 Buffer, 00203 BufferSize, 00204 PreviousMode, 00205 &BytesCopied); 00206 00207 // 00208 // Dereference the target process. 00209 // 00210 00211 ObDereferenceObject(Process); 00212 } 00213 } 00214 00215 // 00216 // If requested, return the number of bytes read. 00217 // 00218 00219 if (ARGUMENT_PRESENT(NumberOfBytesRead)) { 00220 try { 00221 *NumberOfBytesRead = BytesCopied; 00222 00223 } except(EXCEPTION_EXECUTE_HANDLER) { 00224 NOTHING; 00225 } 00226 } 00227 00228 return Status; 00229 } NTSTATUS

NTSTATUS NtWriteVirtualMemory IN HANDLE  ProcessHandle,
OUT PVOID  BaseAddress,
IN PVOID  Buffer,
IN ULONG  BufferSize,
OUT PULONG NumberOfBytesWritten  OPTIONAL
 

Definition at line 231 of file readwrt.c.

References Buffer, BufferSize, EXCEPTION_EXECUTE_HANDLER, KernelMode, KPROCESSOR_MODE, MiValidateUserTransfer(), MmCopyVirtualMemory(), NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, ProbeForWriteUlong, PsGetCurrentProcess, PsProcessType, and Status.

Referenced by RtlRemoteCall().

00241 : 00242 00243 This function copies the specified address range from the current 00244 process into the specified address range of the specified process. 00245 00246 Arguments: 00247 00248 ProcessHandle - Supplies an open handle to a process object. 00249 00250 BaseAddress - Supplies the base address to be written to in the 00251 specified process. 00252 00253 Buffer - Supplies the address of a buffer which contains the 00254 contents to be written into the specified process 00255 address space. 00256 00257 BufferSize - Supplies the requested number of bytes to write 00258 into the specified process. 00259 00260 NumberOfBytesWritten - Receives the actual number of 00261 bytes transferred into the specified address 00262 space. 00263 00264 Return Value: 00265 00266 TBS 00267 00268 --*/ 00269 00270 { 00271 ULONG BytesCopied; 00272 KPROCESSOR_MODE PreviousMode; 00273 PEPROCESS Process; 00274 NTSTATUS Status; 00275 00276 PAGED_CODE(); 00277 00278 // 00279 // Get the previous mode and probe output argument if necessary. 00280 // 00281 00282 PreviousMode = KeGetPreviousMode(); 00283 if (PreviousMode != KernelMode) { 00284 00285 Status = MiValidateUserTransfer(BaseAddress, Buffer, BufferSize); 00286 if (Status != STATUS_SUCCESS) { 00287 return Status; 00288 } 00289 00290 if (ARGUMENT_PRESENT(NumberOfBytesWritten)) { 00291 try { 00292 ProbeForWriteUlong(NumberOfBytesWritten); 00293 00294 } except(EXCEPTION_EXECUTE_HANDLER) { 00295 return GetExceptionCode(); 00296 } 00297 } 00298 } 00299 00300 // 00301 // If the buffer size is not zero, then attempt to write data from the 00302 // current process address space into the target process address space. 00303 // 00304 00305 BytesCopied = 0; 00306 Status = STATUS_SUCCESS; 00307 if (BufferSize != 0) { 00308 00309 // 00310 // Reference the target process. 00311 // 00312 00313 Status = ObReferenceObjectByHandle(ProcessHandle, 00314 PROCESS_VM_WRITE, 00315 PsProcessType, 00316 PreviousMode, 00317 (PVOID *)&Process, 00318 NULL); 00319 00320 // 00321 // If the process was successfully referenced, then attempt to 00322 // write the specified memory either by direct mapping or copying 00323 // through nonpaged pool. 00324 // 00325 00326 if (Status == STATUS_SUCCESS) { 00327 00328 Status = MmCopyVirtualMemory (PsGetCurrentProcess(), 00329 Buffer, 00330 Process, 00331 BaseAddress, 00332 BufferSize, 00333 PreviousMode, 00334 &BytesCopied); 00335 00336 // 00337 // Dereference the target process. 00338 // 00339 00340 ObDereferenceObject(Process); 00341 } 00342 } 00343 00344 // 00345 // If requested, return the number of bytes read. 00346 // 00347 00348 if (ARGUMENT_PRESENT(NumberOfBytesWritten)) { 00349 try { 00350 *NumberOfBytesWritten = BytesCopied; 00351 00352 } except(EXCEPTION_EXECUTE_HANDLER) { 00353 NOTHING; 00354 } 00355 } 00356 00357 return Status; 00358 }


Generated on Sat May 15 19:45:27 2004 for test by doxygen 1.3.7