VirtualQueryEx() is the way to go if you want a memory map of a target process.
However, if you want information about modules only, you can extract it from the PEB of the target process.
Get the PEB address using NtQueryInformationProcess, using ProcessBasicInformation for the ProcessInformationClass, so it writes a PROCESS_BASIC_INFORMATION. This structure has a PebBaseAddress field that gives you the PEB address.
Using this PEB address, access to the PPEB_LDR_DATA Ldr field, it contains a list named InMemoryOrderModuleList that you can use to iterate through all the modules of the process.
Here is a demonstration of that technique.
Output :
modules.exe : 0x00400000 -> 0x00422fff (C:\Users\Spl3en\Desktop\modules.exe)
ntdll.dll : 0x81d20000 -> 0x81ec8fff (C:\Windows\SYSTEM32\ntdll.dll)
KERNEL32.DLL : 0x7f660000 -> 0x7f798fff (C:\Windows\system32\KERNEL32.DLL)
KERNELBASE.dll : 0x7f450000 -> 0x7f55dfff (C:\Windows\system32\KERNELBASE.dll)
msvcrt.dll : 0x7f970000 -> 0x7fa16fff (C:\Windows\system32\msvcrt.dll)
SystemModuleInformationinZwQuerySystemInformation. Take a look here if you want an implementation : https://github.com/zer0box/zer0m0n/blob/master/src/driver/module.c#L89 – Spl3en May 09 '15 at 15:28