A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about user-mode development.
 #612  by NOP
 Fri Apr 09, 2010 6:59 pm
Hi. Just wondering if you guys know how you go about listing memory allocated within a process, like LordPE or PETools does. Want to add to my PE editor but not sure where to start.

Example: http://i40.tinypic.com/4pxibn.png
Last edited by NOP on Sat Apr 10, 2010 11:28 am, edited 1 time in total.
 #614  by Alex
 Fri Apr 09, 2010 8:11 pm
Hi,

Here is a sample code based on native apis. You can also invoke NtQueryVirtualMemory with MemorySectionName class to obtain paths of mapped files.
Code: Select all
    OBJECT_ATTRIBUTES ObjectAttributes;
    CLIENT_ID ClientId;
    MEMORY_BASIC_INFORMATION MemoryInformation;

    ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
    ObjectAttributes.RootDirectory = NULL;
    ObjectAttributes.ObjectName = NULL;
    ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
    ObjectAttributes.SecurityDescriptor = NULL;
    ObjectAttributes.SecurityQualityOfService = NULL;

    ClientId.UniqueProcess = ProcessId;
    ClientId.UniqueThread = NULL;		
					
 	NtStatus = NtOpenProcess(
							&ProcessHandle,     // ProcessHandle
							PROCESS_ALL_ACCESS, // DesiredAccess
							&ObjectAttributes,  // ObjectAttributes
							&ClientId);         // ClientId

	if(NtStatus == STATUS_SUCCESS)
	{
		for(Base=MmLowestUserAddress;
			Base<MmHighestUserAddress;
			Base+=PAGE_SIZE)
		{
			NtStatus = NtQueryVirtualMemory(
											ProcessHandle,                    // ProcessHandle
											(PVOID)Base,                      // BaseAddress
											MemoryBasicInformation,           // MemoryInformationClass
											&MemoryInformation,               // MemoryInformation
											sizeof(MEMORY_BASIC_INFORMATION), // MemoryInformationLength
											NULL);

			if(NtStatus == STATUS_SUCCESS)
			{
				/*
				MemoryInformation.AllocationBase;
				MemoryInformation.BaseAddress;
				MemoryInformation.RegionSize;
				MemoryInformation.State;
				MemoryInformation.Protect;
				MemoryInformation.Type;
				*/

				Base = (ULONG)MemoryInformation.BaseAddress + MemoryInformation.RegionSize;
			}
		}

		NtClose(ProcessHandle);
	}
 #617  by EP_X0FF
 Sat Apr 10, 2010 2:33 am
Or even more simple with VirtualQueryEx.
If you like a driver, then you need to walk VAD tree.
 #621  by Eric_71
 Sat Apr 10, 2010 9:07 am
Hi,
Or even more simple with VirtualQueryEx
and GetMappedFileName to obtain mapped files ( + QueryDosDevice to obtain Dos path)

@NOP, for example you can use (or other solutions) :
Code: Select all
    ....

    DWORD                    Address;
    SYSTEM_INFO              SysInfo;
    MEMORY_BASIC_INFORMATION MemInfo;
	
    RtlZeroMemory ....
    GetSystemInfo ....
	
    (DWORD)Address = (DWORD)SysInfo.lpMinimumApplicationAddress;

    do
    {
        if(VirtualQueryEx(hProcess, (PDWORD)Address, &MemInfo, sizeof(MEMORY_BASIC_INFORMATION)) !=0 )
        {


            // MemInfo.BaseAddress 
            // MemInfo.RegionSize   

            switch(MemInfo.State)
            {
                case 0x10000: //FREE
                case 0x2000:  //RESERVE
                case ....

            }

            switch(MemInfo.Type)
            {
                case 0x1000000: //IMAGE
                case 0x40000:   //MAPPED
                case ....
            }

            
            switch(MemInfo.Protect)
            {
                case 0x80:   //EXECUTE_WRITECOPY
                case 0x40:   //EXECUTE_READWRITE
                case ....
            }

        }
        (DWORD)Address += MemInfo.RegionSize;
    }
    while((DWORD)Address <= (DWORD)SysInfo.lpMaximumApplicationAddress);

    ....

you'll get what you're looking for (private tool):

Image

Regards,

Eric
 #622  by NOP
 Sat Apr 10, 2010 11:16 am
Great thanks for the replies.

@Alex: What are MmLowestUserAddress and MmHighestUserAddress? I'm using Delphi so I guess the loop would come out something like this?
Code: Select all
while Base < MmHighestUserAddress do
*things*
Base := ...
@Eric_71: Thanks, looks simpler that using native API. Will give it a try now... :)

Edit: Great, my basic example is listing perfectly, now to add the details. Thanks all for your time.
 #623  by Vrtule
 Sat Apr 10, 2010 1:38 pm
MmLowestUserAddress - the lowest address, user mode code can access (0x00000000 on x86)
MmHighestUserAddress - the highest address, user mode code can access (usually 0x7FFFFFFF on x86).
 #624  by EP_X0FF
 Sat Apr 10, 2010 1:46 pm
GetSystemInfo returns these values (of course under win32 names lol).
 #626  by Alex
 Sat Apr 10, 2010 2:42 pm
Code: Select all
        NtStatus = NtQuerySystemInformation(
                                            SystemBasicInformation,
                                            &SystemInformation,
                                            sizeof(SYSTEM_BASIC_INFORMATION),
                                            NULL);

        if(NtStatus == STATUS_SUCCESS)
        {
            MmLowestUserAddress = SystemInformation.LowestUserAddress;
            MmHighestUserAddress = SystemInformation.HighestUserAddress;
            MmHighestUserAddress = MmHighestUserAddress & 0xFFFFF000;
        }
        else
        {
            MmLowestUserAddress = 0x00010000;
            MmHighestUserAddress = 0x7FFFF000;
        }
NtQuerySystemInformation returns 0x00010000 for LowestUserAddress and 0x7FFEFFFF for HighestUserAddress, but as Vrtule wrote user mode application can allocate virtual memory at 0x00000000 as well, so I did mistake in my code takeing LowestUserAddress from this function instead of attribute NULL to it.

Alex