본문 바로가기
코드/kernel

NtQueryVirtualMemory MappedImageFileName 옵션 이해 코드

by WeZZ 2013. 3. 15.

 

RectOs 로 부터

 

 

 


NTSTATUS NTAPI NtQueryVirtualMemory  ( IN HANDLE  ProcessHandle, 
  IN PVOID  BaseAddress, 
  IN MEMORY_INFORMATION_CLASS  MemoryInformationClass, 
  OUT PVOID  MemoryInformation, 
  IN SIZE_T  MemoryInformationLength, 
  OUT PSIZE_T  ReturnLength 
 )  


Definition at line 3549 of file virtual.c.

{
    NTSTATUS Status = STATUS_SUCCESS;
    KPROCESSOR_MODE PreviousMode;

    DPRINT("Querying class %d about address: %p\n", MemoryInformationClass, BaseAddress);

    /* Bail out if the address is invalid */
    if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER;

    /* Probe return buffer */
    PreviousMode =  ExGetPreviousMode();
    if (PreviousMode != KernelMode)
    {
        _SEH2_TRY
        {
            ProbeForWrite(MemoryInformation,
                          MemoryInformationLength,
                          sizeof(ULONG_PTR));

            if (ReturnLength) ProbeForWriteSize_t(ReturnLength);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END;

        if (!NT_SUCCESS(Status))
        {
            return Status;
        }
    }

    switch(MemoryInformationClass)
    {
        case MemoryBasicInformation:
            /* Validate the size information of the class */
            if (MemoryInformationLength < sizeof(MEMORY_BASIC_INFORMATION))
            {
                /* The size is invalid */
                return STATUS_INFO_LENGTH_MISMATCH;
            }
            Status = MiQueryMemoryBasicInformation(ProcessHandle,
                                                   BaseAddress,
                                                   MemoryInformation,
                                                   MemoryInformationLength,
                                                   ReturnLength);
            break;

        case MemorySectionName:
            /* Validate the size information of the class */
            if (MemoryInformationLength < sizeof(MEMORY_SECTION_NAME))
            {
                /* The size is invalid */
                return STATUS_INFO_LENGTH_MISMATCH;
            }
            Status = MiQueryMemorySectionName(ProcessHandle,
                                              BaseAddress,
                                              MemoryInformation,
                                              MemoryInformationLength,
                                              ReturnLength);
            break;
        case MemoryWorkingSetList:
        case MemoryBasicVlmInformation:
        default:
            DPRINT1("Unhandled memory information class %d\n", MemoryInformationClass);
            break;
    }

    return Status;
}

 

 

 

NTSTATUS NTAPI MiQueryMemorySectionName  ( IN HANDLE  ProcessHandle, 
  IN PVOID  BaseAddress, 
  OUT PVOID  MemoryInformation, 
  IN SIZE_T  MemoryInformationLength, 
  OUT PSIZE_T  ReturnLength 
 )  


Definition at line 1658 of file section.c.

Referenced by NtQueryVirtualMemory().

{
    PEPROCESS Process;
    NTSTATUS Status;
    WCHAR ModuleFileNameBuffer[MAX_PATH] = {0};
    UNICODE_STRING ModuleFileName;
    PMEMORY_SECTION_NAME SectionName = NULL;
    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();

    Status = ObReferenceObjectByHandle(ProcessHandle,
                                       PROCESS_QUERY_INFORMATION,
                                       NULL,
                                       PreviousMode,
                                       (PVOID*)(&Process),
                                       NULL);

    if (!NT_SUCCESS(Status))
    {
        DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
        return Status;
    }

    RtlInitEmptyUnicodeString(&ModuleFileName, ModuleFileNameBuffer, sizeof(ModuleFileNameBuffer));
    Status = MmGetFileNameForAddress(BaseAddress, &ModuleFileName);

    if (NT_SUCCESS(Status))
    {
        SectionName = MemoryInformation;
        if (PreviousMode != KernelMode)
        {
            _SEH2_TRY
            {
                RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
                SectionName->SectionFileName.MaximumLength = (USHORT)MemoryInformationLength;
                RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);

                if (ReturnLength) *ReturnLength = ModuleFileName.Length;

            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                Status = _SEH2_GetExceptionCode();
            }
            _SEH2_END;
        }
        else
        {
            RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
            SectionName->SectionFileName.MaximumLength = (USHORT)MemoryInformationLength;
            RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);

            if (ReturnLength) *ReturnLength = ModuleFileName.Length;

        }
    }
    ObDereferenceObject(Process);
    return Status;
}

 

 

 

 

 

 


NTSTATUS NTAPI MmGetFileNameForAddress  ( IN PVOID  Address, 
  OUT PUNICODE_STRING  ModuleName 
 )  

Definition at line 1562 of file section.c.

Referenced by DbgkpPostFakeModuleMessages(), and MiQueryMemorySectionName().

{
   PVOID Section;
   PMEMORY_AREA MemoryArea;
   POBJECT_NAME_INFORMATION ModuleNameInformation;
   PVOID AddressSpace;
   NTSTATUS Status;
   PFILE_OBJECT FileObject = NULL;
   PMMVAD Vad;
   PCONTROL_AREA ControlArea;

   /* Lock address space */
   AddressSpace = MmGetCurrentAddressSpace();
   MmLockAddressSpace(AddressSpace);

   /* Locate the memory area for the process by address */
   MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
   if (!MemoryArea)
   {
       /* Fail, the address does not exist */
InvalidAddress:
       DPRINT1("Invalid address\n");
       MmUnlockAddressSpace(AddressSpace);
       return STATUS_INVALID_ADDRESS;
   }

   /* Check if it's a section view (RosMm section) or ARM3 section */
   if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
   {
      /* Get the section pointer to the SECTION_OBJECT */
      Section = MemoryArea->Data.SectionData.Section;

      /* Unlock address space */
      MmUnlockAddressSpace(AddressSpace);

      /* Get the filename of the section */
      Status = MmGetFileNameForSection(Section, &ModuleNameInformation);
   }
   else if (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)
   {
       /* Get the VAD */
       Vad = MiLocateAddress(Address);
       if (!Vad) goto InvalidAddress;

       /* Make sure it's not a VM VAD */
       if (Vad->u.VadFlags.PrivateMemory == 1)
       {
NotSection:
           DPRINT1("Address is not a section\n");
           MmUnlockAddressSpace(AddressSpace);
           return STATUS_SECTION_NOT_IMAGE;
       }

       /* Get the control area */
       ControlArea = Vad->ControlArea;
       if (!(ControlArea) || !(ControlArea->u.Flags.Image)) goto NotSection;

       /* Get the file object */
       FileObject = ControlArea->FilePointer;
       ASSERT(FileObject != NULL);
       ObReferenceObject(FileObject);

       /* Unlock address space */
       MmUnlockAddressSpace(AddressSpace);

       /* Get the filename of the file object */
       Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);

       /* Dereference it */
       ObDereferenceObject(FileObject);
   }
   else
   {
       /* Trying to access virtual memory or something */
       goto InvalidAddress;
   }

   /* Check if we were able to get the file object name */
   if (NT_SUCCESS(Status))
   {
        /* Init modulename */
       RtlCreateUnicodeString(ModuleName,
                              ModuleNameInformation->Name.Buffer);

       /* Free temp taged buffer from MmGetFileNameForFileObject() */
       ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
       DPRINT("Found ModuleName %S by address %p\n", ModuleName->Buffer, Address);
   }

   /* Return status */
   return Status;
}

 

FORCEINLINE PMMSUPPORT MmGetCurrentAddressSpace  ( VOID   ) 


Definition at line 1749 of file mm.h.

Referenced by MiProtectVirtualMemory(), MmAccessFault(), MmGetFileNameForAddress(), NtAllocateVirtualMemory(), NtAreMappedFilesTheSame(), and NtFreeVirtualMemory().

{
    return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm;
}

 

PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress  ( PMMSUPPORT  AddressSpace, 
  PVOID  Address 
 )  


Definition at line 163 of file marea.c.

Referenced by _MiFlushMappedSection(), KdbSymPrintAddress(), MiProtectVirtualMemory(), MiQueryMemoryBasicInformation(), MiRosProtectVirtualMemory(), MiRosUnmapViewOfSection(), MiUnmapViewOfSection(), MiZeroFillSection(), MmAccessFault(), MmAlterViewAttributes(), MmGetFileNameForAddress(), MmNotPresentFault(), MmNotPresentFaultCacheSectionInner(), MmpAccessFault(), MmPageOutPhysicalAddress(), MmpPageOutPhysicalAddress(), MmpSectionAccessFaultInner(), MmUnmapViewInSystemSpace(), MmUnmapViewOfCacheSegment(), MmUnmapViewOfSegment(), NtAllocateVirtualMemory(), NtAreMappedFilesTheSame(), and NtFreeVirtualMemory().

{
   PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;

   DPRINT("MmLocateMemoryAreaByAddress(AddressSpace %p, Address %p)\n",
           AddressSpace, Address);

   while (Node != NULL)
   {
      if (Address < Node->StartingAddress)
         Node = Node->LeftChild;
      else if (Address >= Node->EndingAddress)
         Node = Node->RightChild;
      else
      {
         DPRINT("MmLocateMemoryAreaByAddress(%p): %p [%p - %p]\n",
                Address, Node, Node->StartingAddress, Node->EndingAddress);
         return Node;
      }
   }

   DPRINT("MmLocateMemoryAreaByAddress(%p): 0\n", Address);
   return NULL;
}


NTSTATUS NTAPI MmGetFileNameForSection  ( IN PVOID  Section, 
  OUT POBJECT_NAME_INFORMATION *  ModuleName 
 )  


Definition at line 1532 of file section.c.

Referenced by DbgkCreateThread(), DbgkpSectionToFileHandle(), and MmGetFileNameForAddress().

{
    PFILE_OBJECT FileObject;

    /* Make sure it's an image section */
    if (MiIsRosSectionObject(Section) == FALSE)
    {
        /* Check ARM3 Section flag */
        if (((PSECTION)Section)->u.Flags.Image == 0)
        {
            /* It's not, fail */
            DPRINT1("Not an image section\n");
            return STATUS_SECTION_NOT_IMAGE;
        }
    }
    else if (!(((PROS_SECTION_OBJECT)Section)->AllocationAttributes & SEC_IMAGE))
    {
        /* It's not, fail */
        DPRINT1("Not an image section\n");
        return STATUS_SECTION_NOT_IMAGE;
    }

    /* Get the file object */
    FileObject = MmGetFileObjectForSection(Section);
    return MmGetFileNameForFileObject(FileObject, ModuleName);
}

 

PFILE_OBJECT NTAPI MmGetFileObjectForSection  ( IN PVOID  Section ) 


Definition at line 1480 of file section.c.

Referenced by CcGetFileObjectFromBcb(), CcGetFileObjectFromSectionPtrs(), CcShutdownSystem(), MmGetFileNameForSection(), and PsReferenceProcessFilePointer().

{
    PSECTION_OBJECT Section;
    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
    ASSERT(SectionObject != NULL);

    /* Check if it's an ARM3, or ReactOS section */
    if (MiIsRosSectionObject(SectionObject) == FALSE)
    {
        /* Return the file pointer stored in the control area */
        Section = SectionObject;
        return Section->Segment->ControlArea->FilePointer;
    }

    /* Return the file object */
    return ((PROS_SECTION_OBJECT)SectionObject)->FileObject;
}

 

 

NTSTATUS NTAPI MmGetFileNameForFileObject  ( IN PFILE_OBJECT  FileObject, 
  OUT POBJECT_NAME_INFORMATION *  ModuleName 
 )  


Definition at line 1500 of file section.c.

Referenced by MmGetFileNameForAddress(), and MmGetFileNameForSection().

{
    POBJECT_NAME_INFORMATION ObjectNameInfo;
    NTSTATUS Status;
    ULONG ReturnLength;

    /* Allocate memory for our structure */
    ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, 1024, TAG_MM);
    if (!ObjectNameInfo) return STATUS_NO_MEMORY;

    /* Query the name */
    Status = ObQueryNameString(FileObject,
                               ObjectNameInfo,
                               1024,
                               &ReturnLength);
    if (!NT_SUCCESS(Status))
    {
        /* Failed, free memory */
        DPRINT1("Name query failed\n");
        ExFreePoolWithTag(ObjectNameInfo, TAG_MM);
        *ModuleName = NULL;
        return Status;
    }

    /* Success */
    *ModuleName = ObjectNameInfo;
    return STATUS_SUCCESS;
}